summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.cpp6
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.h2
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp152
-rw-r--r--Source/JavaScriptCore/heap/Heap.h11
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp15
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp78
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.h19
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h12
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h52
9 files changed, 143 insertions, 204 deletions
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp
index 028c84c2d..ce6024079 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.cpp
+++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp
@@ -33,6 +33,7 @@ namespace JSC {
BlockAllocator::BlockAllocator()
: m_numberOfFreeBlocks(0)
+ , m_isCurrentlyAllocating(false)
, m_blockFreeingThreadShouldQuit(false)
, m_blockFreeingThread(createThread(blockFreeingThreadStartFunc, this, "JavaScriptCore::BlockFree"))
{
@@ -104,6 +105,11 @@ void BlockAllocator::blockFreeingThreadMain()
if (m_blockFreeingThreadShouldQuit)
break;
+ if (m_isCurrentlyAllocating) {
+ m_isCurrentlyAllocating = false;
+ continue;
+ }
+
// Now process the list of free blocks. Keep freeing until half of the
// blocks that are currently on the list are gone. Assume that a size_t
// field can be accessed atomically.
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h
index 4b90d28b9..cc9557f85 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.h
+++ b/Source/JavaScriptCore/heap/BlockAllocator.h
@@ -56,6 +56,7 @@ private:
DoublyLinkedList<HeapBlock> m_freeBlocks;
size_t m_numberOfFreeBlocks;
+ bool m_isCurrentlyAllocating;
bool m_blockFreeingThreadShouldQuit;
Mutex m_freeBlockLock;
ThreadCondition m_freeBlockCondition;
@@ -65,6 +66,7 @@ private:
inline HeapBlock* BlockAllocator::allocate()
{
MutexLocker locker(m_freeBlockLock);
+ m_isCurrentlyAllocating = true;
if (!m_numberOfFreeBlocks) {
ASSERT(m_freeBlocks.isEmpty());
return 0;
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index d43ec1242..2254b5b01 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -178,100 +178,20 @@ static inline bool isValidThreadState(JSGlobalData* globalData)
return true;
}
-class CountFunctor {
-public:
- typedef size_t ReturnType;
-
- CountFunctor();
- void count(size_t);
- ReturnType returnValue();
-
-private:
- ReturnType m_count;
-};
-
-inline CountFunctor::CountFunctor()
- : m_count(0)
-{
-}
-
-inline void CountFunctor::count(size_t count)
-{
- m_count += count;
-}
-
-inline CountFunctor::ReturnType CountFunctor::returnValue()
-{
- return m_count;
-}
-
-struct ClearMarks : MarkedBlock::VoidFunctor {
- void operator()(MarkedBlock*);
-};
-
-inline void ClearMarks::operator()(MarkedBlock* block)
-{
- block->clearMarks();
-}
-
-struct Sweep : MarkedBlock::VoidFunctor {
- void operator()(MarkedBlock*);
-};
-
-inline void Sweep::operator()(MarkedBlock* block)
-{
- block->sweep();
-}
-
-struct MarkCount : CountFunctor {
- void operator()(MarkedBlock*);
-};
-
-inline void MarkCount::operator()(MarkedBlock* block)
-{
- count(block->markCount());
-}
-
-struct Size : CountFunctor {
- void operator()(MarkedBlock*);
-};
-
-inline void Size::operator()(MarkedBlock* block)
-{
- count(block->markCount() * block->cellSize());
-}
-
-struct Capacity : CountFunctor {
- void operator()(MarkedBlock*);
+struct Count : public MarkedBlock::CountFunctor {
+ void operator()(JSCell*) { count(1); }
};
-inline void Capacity::operator()(MarkedBlock* block)
-{
- count(block->capacity());
-}
-
-struct Count : public CountFunctor {
- void operator()(JSCell*);
-};
-
-inline void Count::operator()(JSCell*)
-{
- count(1);
-}
-
-struct CountIfGlobalObject : CountFunctor {
- void operator()(JSCell*);
+struct CountIfGlobalObject : MarkedBlock::CountFunctor {
+ void operator()(JSCell* cell) {
+ if (!cell->isObject())
+ return;
+ if (!asObject(cell)->isGlobalObject())
+ return;
+ count(1);
+ }
};
-inline void CountIfGlobalObject::operator()(JSCell* cell)
-{
- if (!cell->isObject())
- return;
- if (!asObject(cell)->isGlobalObject())
- return;
- count(1);
-}
-
class RecordType {
public:
typedef PassOwnPtr<TypeCountSet> ReturnType;
@@ -363,9 +283,9 @@ void Heap::lastChanceToFinalize()
WTFLogAlways("ERROR: JavaScriptCore heap deallocated while %ld values were still protected", static_cast<unsigned long>(size));
m_weakSet.finalizeAll();
- canonicalizeCellLivenessData();
- clearMarks();
- sweep();
+ m_objectSpace.canonicalizeCellLivenessData();
+ m_objectSpace.clearMarks();
+ m_objectSpace.sweep();
m_globalData->smallStrings.finalizeSmallStrings();
#if ENABLE(SIMPLE_HEAP_PROFILING)
@@ -540,7 +460,7 @@ void Heap::markRoots(bool fullGC)
#endif
{
GCPHASE(clearMarks);
- clearMarks();
+ m_objectSpace.clearMarks();
}
m_storageSpace.startedCopying();
@@ -656,37 +576,24 @@ void Heap::markRoots(bool fullGC)
visitor.doneCopying();
visitor.reset();
m_sharedData.reset();
-#if ENABLE(PARALLEL_GC)
- m_sharedData.resetChildren();
-#endif
m_storageSpace.doneCopying();
m_operationInProgress = NoOperation;
}
-void Heap::clearMarks()
-{
- m_objectSpace.forEachBlock<ClearMarks>();
-}
-
-void Heap::sweep()
-{
- m_objectSpace.forEachBlock<Sweep>();
-}
-
size_t Heap::objectCount()
{
- return m_objectSpace.forEachBlock<MarkCount>();
+ return m_objectSpace.objectCount();
}
size_t Heap::size()
{
- return m_objectSpace.forEachBlock<Size>() + m_storageSpace.size();
+ return m_objectSpace.size() + m_storageSpace.size();
}
size_t Heap::capacity()
{
- return m_objectSpace.forEachBlock<Capacity>() + m_storageSpace.capacity();
+ return m_objectSpace.capacity() + m_storageSpace.capacity();
}
size_t Heap::protectedGlobalObjectCount()
@@ -761,7 +668,7 @@ void Heap::collect(SweepToggle sweepToggle)
#endif
{
GCPHASE(Canonicalize);
- canonicalizeCellLivenessData();
+ m_objectSpace.canonicalizeCellLivenessData();
}
markRoots(fullGC);
@@ -780,8 +687,9 @@ void Heap::collect(SweepToggle sweepToggle)
JAVASCRIPTCORE_GC_MARKED();
{
- GCPHASE(ResetAllocator);
- resetAllocators();
+ GCPHASE(ResetAllocators);
+ m_objectSpace.resetAllocators();
+ m_weakSet.resetAllocator();
}
{
@@ -792,7 +700,7 @@ void Heap::collect(SweepToggle sweepToggle)
if (sweepToggle == DoSweep) {
SamplingRegion samplingRegion("Garbage Collection: Sweeping");
GCPHASE(Sweeping);
- sweep();
+ m_objectSpace.sweep();
m_objectSpace.shrink();
m_weakSet.shrink();
m_bytesAbandoned = 0;
@@ -814,17 +722,6 @@ void Heap::collect(SweepToggle sweepToggle)
JAVASCRIPTCORE_GC_END();
}
-void Heap::canonicalizeCellLivenessData()
-{
- m_objectSpace.canonicalizeCellLivenessData();
-}
-
-void Heap::resetAllocators()
-{
- m_objectSpace.resetAllocators();
- m_weakSet.resetAllocator();
-}
-
void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
{
m_activityCallback = activityCallback;
@@ -835,6 +732,11 @@ GCActivityCallback* Heap::activityCallback()
return m_activityCallback.get();
}
+void Heap::setGarbageCollectionTimerEnabled(bool enable)
+{
+ activityCallback()->setEnabled(enable);
+}
+
void Heap::didAllocate(size_t bytes)
{
m_activityCallback->didAllocate(m_bytesAllocated + m_bytesAbandoned);
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index 10fdb07be..6bf82e4a5 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -100,6 +100,7 @@ namespace JSC {
JS_EXPORT_PRIVATE GCActivityCallback* activityCallback();
JS_EXPORT_PRIVATE void setActivityCallback(PassOwnPtr<GCActivityCallback>);
+ JS_EXPORT_PRIVATE void setGarbageCollectionTimerEnabled(bool);
// true if an allocation or collection is in progress
inline bool isBusy();
@@ -187,22 +188,12 @@ namespace JSC {
JS_EXPORT_PRIVATE bool isValidAllocation(size_t);
JS_EXPORT_PRIVATE void reportExtraMemoryCostSlowCase(size_t);
- // Call this function before any operation that needs to know which cells
- // in the heap are live. (For example, call this function before
- // conservative marking, eager sweeping, or iterating the cells in a MarkedBlock.)
- void canonicalizeCellLivenessData();
-
- void resetAllocators();
-
- void clearMarks();
void markRoots(bool fullGC);
void markProtectedObjects(HeapRootVisitor&);
void markTempSortVectors(HeapRootVisitor&);
void harvestWeakReferences();
void finalizeUnconditionalFinalizers();
- void sweep();
-
RegisterFile& registerFile();
BlockAllocator& blockAllocator();
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 30915eaf8..affd833eb 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -452,8 +452,6 @@ static void freePlatformThreadRegisters(PlatformThreadRegisters& regs)
void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, Thread* thread)
{
- suspendThread(thread->platformThread);
-
PlatformThreadRegisters regs;
size_t regSize = getPlatformThreadRegisters(thread->platformThread, regs);
@@ -464,8 +462,6 @@ void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots,
swapIfBackwards(stackPointer, stackBase);
conservativeRoots.add(stackPointer, stackBase);
- resumeThread(thread->platformThread);
-
freePlatformThreadRegisters(regs);
}
@@ -484,12 +480,23 @@ void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoot
// thread that had been suspended while holding the malloc lock.
fastMallocForbid();
#endif
+ for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+ if (!equalThread(thread->platformThread, currentPlatformThread))
+ suspendThread(thread->platformThread);
+ }
+
// It is safe to access the registeredThreads list, because we earlier asserted that locks are being held,
// and since this is a shared heap, they are real locks.
for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
if (!equalThread(thread->platformThread, currentPlatformThread))
gatherFromOtherThread(conservativeRoots, thread);
}
+
+ for (Thread* thread = m_registeredThreads; thread; thread = thread->next) {
+ if (!equalThread(thread->platformThread, currentPlatformThread))
+ resumeThread(thread->platformThread);
+ }
+
#ifndef NDEBUG
fastMallocAllow();
#endif
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 785444e55..678f1cb45 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -36,8 +36,8 @@
#include "JSObject.h"
#include "ScopeChain.h"
#include "Structure.h"
-#include "UString.h"
#include "WriteBarrier.h"
+#include <wtf/DataLog.h>
#include <wtf/MainThread.h>
namespace JSC {
@@ -219,24 +219,19 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other)
}
#if ENABLE(PARALLEL_GC)
-void MarkStackThreadSharedData::resetChildren()
-{
- for (unsigned i = 0; i < m_slaveMarkStacks.size(); ++i)
- m_slaveMarkStacks[i]->reset();
-}
-
-void MarkStackThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor)
+void MarkStackThreadSharedData::markingThreadMain()
{
WTF::registerGCThread();
- ParallelModeEnabler enabler(*slotVisitor);
- slotVisitor->drainFromShared(SlotVisitor::SlaveDrain);
- delete slotVisitor;
+ {
+ SlotVisitor slotVisitor(*this);
+ ParallelModeEnabler enabler(slotVisitor);
+ slotVisitor.drainFromShared(SlotVisitor::SlaveDrain);
+ }
}
-void MarkStackThreadSharedData::markingThreadStartFunc(void* myVisitor)
+void MarkStackThreadSharedData::markingThreadStartFunc(void* shared)
{
- SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor);
- slotVisitor->sharedData().markingThreadMain(slotVisitor);
+ static_cast<MarkStackThreadSharedData*>(shared)->markingThreadMain();
}
#endif
@@ -249,9 +244,7 @@ MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData)
{
#if ENABLE(PARALLEL_GC)
for (unsigned i = 1; i < Options::numberOfGCMarkers; ++i) {
- SlotVisitor* slotVisitor = new SlotVisitor(*this);
- m_slaveMarkStacks.append(slotVisitor);
- m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking"));
+ m_markingThreads.append(createThread(markingThreadStartFunc, this, "JavaScriptCore::Marking"));
ASSERT(m_markingThreads.last());
}
#endif
@@ -283,6 +276,7 @@ void MarkStackThreadSharedData::reset()
#else
ASSERT(m_opaqueRoots.isEmpty());
#endif
+
m_weakReferenceHarvesters.removeAll();
}
@@ -295,7 +289,6 @@ void MarkStack::reset()
#else
m_opaqueRoots.clear();
#endif
- m_uniqueStrings.clear();
}
void MarkStack::append(ConservativeRoots& conservativeRoots)
@@ -496,34 +489,6 @@ void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes)
return CopiedSpace::allocateFromBlock(m_copyBlock, bytes);
}
-inline void MarkStack::internalAppend(JSValue* slot)
-{
- ASSERT(slot);
- JSValue value = *slot;
- ASSERT(value);
- if (!value.isCell())
- return;
-
- if (value.isString()) {
- JSString* string = jsCast<JSString*>(value.asCell());
- if (!string->isHashConstSingleton() && string->length() > 1 && !string->isRope()) {
- UniqueStringMap::AddResult addResult = m_uniqueStrings.add(string->string().impl(), value);
- if (addResult.isNewEntry)
- string->setHashConstSingleton();
- else {
- JSValue existingJSValue = addResult.iterator->second;
- if (value != existingJSValue)
- jsCast<JSString*>(existingJSValue.asCell())->clearHashConstSingleton();
- *slot = existingJSValue;
- return;
- }
- }
- }
-
- internalAppend(value.asCell());
-}
-
-
void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsigned length)
{
void* oldPtr = *ptr;
@@ -537,7 +502,7 @@ void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsig
newValues[i] = value;
if (!value)
continue;
- internalAppend(&newValues[i]);
+ internalAppend(value);
}
memcpy(newPtr, oldPtr, jsValuesOffset);
@@ -571,16 +536,29 @@ void SlotVisitor::finalizeUnconditionalFinalizers()
#if ENABLE(GC_VALIDATION)
void MarkStack::validate(JSCell* cell)
{
- if (!cell)
+ if (!cell) {
+ dataLog("cell is NULL\n");
CRASH();
+ }
- if (!cell->structure())
+ if (!cell->structure()) {
+ dataLog("cell at %p has a null structure\n" , cell);
CRASH();
+ }
// Both the cell's structure, and the cell's structure's structure should be the Structure Structure.
// I hate this sentence.
- if (cell->structure()->structure()->JSCell::classInfo() != cell->structure()->JSCell::classInfo())
+ if (cell->structure()->structure()->JSCell::classInfo() != cell->structure()->JSCell::classInfo()) {
+ const char* parentClassName = 0;
+ const char* ourClassName = 0;
+ if (cell->structure()->structure() && cell->structure()->structure()->JSCell::classInfo())
+ parentClassName = cell->structure()->structure()->JSCell::classInfo()->className;
+ if (cell->structure()->JSCell::classInfo())
+ ourClassName = cell->structure()->JSCell::classInfo()->className;
+ dataLog("parent structure (%p <%s>) of cell at %p doesn't match cell's structure (%p <%s>)\n",
+ cell->structure()->structure(), parentClassName, cell, cell->structure(), ourClassName);
CRASH();
+ }
}
#else
void MarkStack::validate(JSCell*)
diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h
index 48b65c069..0695b1b32 100644
--- a/Source/JavaScriptCore/heap/MarkStack.h
+++ b/Source/JavaScriptCore/heap/MarkStack.h
@@ -34,14 +34,12 @@
#include "UnconditionalFinalizer.h"
#include "VTableSpectrum.h"
#include "WeakReferenceHarvester.h"
-#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#include <wtf/Noncopyable.h>
#include <wtf/OSAllocator.h>
#include <wtf/PageBlock.h>
-#include <wtf/text/StringHash.h>
namespace JSC {
@@ -173,17 +171,13 @@ namespace JSC {
~MarkStackThreadSharedData();
void reset();
-
-#if ENABLE(PARALLEL_GC)
- void resetChildren();
-#endif
-
+
private:
friend class MarkStack;
friend class SlotVisitor;
#if ENABLE(PARALLEL_GC)
- void markingThreadMain(SlotVisitor*);
+ void markingThreadMain();
static void markingThreadStartFunc(void* heap);
#endif
@@ -193,7 +187,6 @@ namespace JSC {
MarkStackSegmentAllocator m_segmentAllocator;
Vector<ThreadIdentifier> m_markingThreads;
- Vector<MarkStack*> m_slaveMarkStacks;
Mutex m_markingLock;
ThreadCondition m_markingCondition;
@@ -228,14 +221,13 @@ namespace JSC {
void addOpaqueRoot(void*);
bool containsOpaqueRoot(void*);
int opaqueRootCount();
-
- MarkStackThreadSharedData& sharedData() { return m_shared; }
+
bool isEmpty() { return m_stack.isEmpty(); }
void reset();
size_t visitCount() const { return m_visitCount; }
-
+
#if ENABLE(SIMPLE_HEAP_PROFILING)
VTableSpectrum m_visitedTypeCounts;
#endif
@@ -259,7 +251,6 @@ namespace JSC {
void internalAppend(JSCell*);
void internalAppend(JSValue);
- void internalAppend(JSValue*);
JS_EXPORT_PRIVATE void mergeOpaqueRoots();
@@ -279,8 +270,6 @@ namespace JSC {
MarkStackArray m_stack;
HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
- typedef HashMap<StringImpl*, JSValue> UniqueStringMap;
- UniqueStringMap m_uniqueStrings;
#if !ASSERT_DISABLED
public:
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index 429b7c08e..aa99ebf48 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -100,6 +100,18 @@ namespace JSC {
void returnValue() { }
};
+ class CountFunctor {
+ public:
+ typedef size_t ReturnType;
+
+ CountFunctor() : m_count(0) { }
+ void count(size_t count) { m_count += count; }
+ ReturnType returnValue() { return m_count; }
+
+ private:
+ ReturnType m_count;
+ };
+
static MarkedBlock* create(Heap*, size_t cellSize, bool cellsNeedDestruction);
static MarkedBlock* recycle(MarkedBlock*, Heap*, size_t cellSize, bool cellsNeedDestruction);
static void destroy(MarkedBlock*);
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index 19061a12b..7bd5ca509 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -45,6 +45,26 @@ class LLIntOffsetsExtractor;
class WeakGCHandle;
class SlotVisitor;
+struct ClearMarks : MarkedBlock::VoidFunctor {
+ void operator()(MarkedBlock* block) { block->clearMarks(); }
+};
+
+struct Sweep : MarkedBlock::VoidFunctor {
+ void operator()(MarkedBlock* block) { block->sweep(); }
+};
+
+struct MarkCount : MarkedBlock::CountFunctor {
+ void operator()(MarkedBlock* block) { count(block->markCount()); }
+};
+
+struct Size : MarkedBlock::CountFunctor {
+ void operator()(MarkedBlock* block) { count(block->markCount() * block->cellSize()); }
+};
+
+struct Capacity : MarkedBlock::CountFunctor {
+ void operator()(MarkedBlock* block) { count(block->capacity()); }
+};
+
class MarkedSpace {
WTF_MAKE_NONCOPYABLE(MarkedSpace);
public:
@@ -73,11 +93,18 @@ public:
template<typename Functor> typename Functor::ReturnType forEachBlock();
void shrink();
+ void freeAllBlocks();
void freeBlocks(MarkedBlock* head);
void didAddBlock(MarkedBlock*);
void didConsumeFreeList(MarkedBlock*);
+ void clearMarks();
+ void sweep();
+ size_t objectCount();
+ size_t size();
+ size_t capacity();
+
bool isPagedOut(double deadline);
private:
@@ -185,6 +212,31 @@ inline void MarkedSpace::didAddBlock(MarkedBlock* block)
m_blocks.add(block);
}
+inline void MarkedSpace::clearMarks()
+{
+ forEachBlock<ClearMarks>();
+}
+
+inline void MarkedSpace::sweep()
+{
+ forEachBlock<Sweep>();
+}
+
+inline size_t MarkedSpace::objectCount()
+{
+ return forEachBlock<MarkCount>();
+}
+
+inline size_t MarkedSpace::size()
+{
+ return forEachBlock<Size>();
+}
+
+inline size_t MarkedSpace::capacity()
+{
+ return forEachBlock<Capacity>();
+}
+
} // namespace JSC
#endif // MarkedSpace_h