summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/MarkStack.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
commitcd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch)
tree8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/JavaScriptCore/heap/MarkStack.cpp
parentd11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff)
downloadqtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/JavaScriptCore/heap/MarkStack.cpp')
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp94
1 files changed, 89 insertions, 5 deletions
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 02cf328d4..9a3092396 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "MarkStack.h"
+#include "BumpSpace.h"
+#include "BumpSpaceInlineMethods.h"
#include "ConservativeRoots.h"
#include "Heap.h"
#include "Options.h"
@@ -233,6 +235,7 @@ void* MarkStackThreadSharedData::markingThreadStartFunc(void* shared)
MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData)
: m_globalData(globalData)
+ , m_bumpSpace(&globalData->heap.m_storageSpace)
, m_sharedMarkStack(m_segmentAllocator)
, m_numberOfActiveParallelMarkers(0)
, m_parallelMarkersShouldExit(false)
@@ -337,7 +340,7 @@ void SlotVisitor::donateSlow()
void SlotVisitor::drain()
{
ASSERT(m_isInParallelMode);
-
+
#if ENABLE(PARALLEL_GC)
if (Options::numberOfGCMarkers > 1) {
while (!m_stack.isEmpty()) {
@@ -398,8 +401,11 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
// for us to do.
while (true) {
// Did we reach termination?
- if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty())
+ if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty()) {
+ // Let any sleeping slaves know it's time for them to give their private BumpBlocks back
+ m_shared.m_markingCondition.broadcast();
return;
+ }
// Is there work to be done?
if (!m_shared.m_sharedMarkStack.isEmpty())
@@ -415,14 +421,19 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode)
if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty())
m_shared.m_markingCondition.broadcast();
- while (m_shared.m_sharedMarkStack.isEmpty() && !m_shared.m_parallelMarkersShouldExit)
+ while (m_shared.m_sharedMarkStack.isEmpty() && !m_shared.m_parallelMarkersShouldExit) {
+ if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty())
+ doneCopying();
m_shared.m_markingCondition.wait(m_shared.m_markingLock);
+ }
// Is the VM exiting? If so, exit this thread.
- if (m_shared.m_parallelMarkersShouldExit)
+ if (m_shared.m_parallelMarkersShouldExit) {
+ doneCopying();
return;
+ }
}
-
+
m_stack.stealSomeCellsFrom(m_shared.m_sharedMarkStack);
m_shared.m_numberOfActiveParallelMarkers++;
}
@@ -445,6 +456,79 @@ void MarkStack::mergeOpaqueRoots()
m_opaqueRoots.clear();
}
+void SlotVisitor::startCopying()
+{
+ ASSERT(!m_copyBlock);
+ if (!m_shared.m_bumpSpace->borrowBlock(&m_copyBlock))
+ CRASH();
+}
+
+void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes)
+{
+ if (BumpSpace::isOversize(bytes)) {
+ m_shared.m_bumpSpace->pin(BumpSpace::oversizeBlockFor(ptr));
+ return 0;
+ }
+
+ if (m_shared.m_bumpSpace->isPinned(ptr))
+ return 0;
+
+ // The only time it's possible to have a null copy block is if we have just started copying.
+ if (!m_copyBlock)
+ startCopying();
+
+ if (!BumpSpace::fitsInBlock(m_copyBlock, bytes)) {
+ // We don't need to lock across these two calls because the master thread won't
+ // call doneCopying() because this thread is considered active.
+ m_shared.m_bumpSpace->doneFillingBlock(m_copyBlock);
+ if (!m_shared.m_bumpSpace->borrowBlock(&m_copyBlock))
+ CRASH();
+ }
+ return BumpSpace::allocateFromBlock(m_copyBlock, bytes);
+}
+
+void SlotVisitor::copy(void** ptr, size_t bytes)
+{
+ void* newPtr = 0;
+ if (!(newPtr = allocateNewSpace(*ptr, bytes)))
+ return;
+
+ memcpy(newPtr, *ptr, bytes);
+ *ptr = newPtr;
+}
+
+void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsigned length)
+{
+ void* oldPtr = *ptr;
+ void* newPtr = allocateNewSpace(oldPtr, bytes);
+ if (newPtr) {
+ size_t jsValuesOffset = static_cast<size_t>(reinterpret_cast<char*>(values) - static_cast<char*>(oldPtr));
+
+ JSValue* newValues = reinterpret_cast<JSValue*>(static_cast<char*>(newPtr) + jsValuesOffset);
+ for (unsigned i = 0; i < length; i++) {
+ JSValue& value = values[i];
+ newValues[i] = value;
+ if (!value)
+ continue;
+ internalAppend(value);
+ }
+
+ memcpy(newPtr, oldPtr, jsValuesOffset);
+ *ptr = newPtr;
+ } else
+ append(values, length);
+}
+
+void SlotVisitor::doneCopying()
+{
+ if (!m_copyBlock)
+ return;
+
+ m_shared.m_bumpSpace->doneFillingBlock(m_copyBlock);
+
+ m_copyBlock = 0;
+}
+
void SlotVisitor::harvestWeakReferences()
{
for (WeakReferenceHarvester* current = m_shared.m_weakReferenceHarvesters.head(); current; current = current->next())