Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (88472 => 88473)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-09 19:44:37 UTC (rev 88473)
@@ -1,3 +1,77 @@
+2011-06-08 Geoffrey Garen <[email protected]>
+
+ Reviewed by Oliver Hunt.
+
+ Factored a bunch of Heap functionality into stand-alone functors
+ https://bugs.webkit.org/show_bug.cgi?id=62337
+
+ This is in preparation for making these functors operate on arbitrary
+ sets of MarkedBlocks.
+
+ * _javascript_Core.exp: This file is a small tragedy.
+
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions): Updated for type change and rename.
+
+ * heap/HandleHeap.h:
+ (JSC::HandleHeap::forEachStrongHandle): New function for iterating all
+ strong handles, so we can play along in the functor game.
+
+ * heap/Heap.cpp:
+ (JSC::CountFunctor::CountFunctor::CountFunctor):
+ (JSC::CountFunctor::CountFunctor::count):
+ (JSC::CountFunctor::CountFunctor::returnValue):
+ (JSC::CountFunctor::ClearMarks::operator()):
+ (JSC::CountFunctor::ResetAllocator::operator()):
+ (JSC::CountFunctor::Sweep::operator()):
+ (JSC::CountFunctor::MarkCount::operator()):
+ (JSC::CountFunctor::Size::operator()):
+ (JSC::CountFunctor::Capacity::operator()):
+ (JSC::CountFunctor::Count::operator()):
+ (JSC::CountFunctor::CountIfGlobalObject::operator()):
+ (JSC::CountFunctor::TakeIfEmpty::TakeIfEmpty):
+ (JSC::CountFunctor::TakeIfEmpty::operator()):
+ (JSC::CountFunctor::TakeIfEmpty::returnValue):
+ (JSC::CountFunctor::RecordType::RecordType):
+ (JSC::CountFunctor::RecordType::typeName):
+ (JSC::CountFunctor::RecordType::operator()):
+ (JSC::CountFunctor::RecordType::returnValue): These functors factor out
+ behavior that used to be in the functions below.
+
+ (JSC::Heap::clearMarks):
+ (JSC::Heap::sweep):
+ (JSC::Heap::objectCount):
+ (JSC::Heap::size):
+ (JSC::Heap::capacity):
+ (JSC::Heap::protectedGlobalObjectCount):
+ (JSC::Heap::protectedObjectCount):
+ (JSC::Heap::protectedObjectTypeCounts):
+ (JSC::Heap::objectTypeCounts):
+ (JSC::Heap::resetAllocator):
+ (JSC::Heap::freeBlocks):
+ (JSC::Heap::shrink): Factored out behavior into the functors above.
+
+ * heap/Heap.h:
+ (JSC::Heap::forEachProtectedCell):
+ (JSC::Heap::forEachCell):
+ (JSC::Heap::forEachBlock): Added forEach* iteration templates. I chose
+ functor-based templates instead of plain iterators because they're simpler
+ to implement in this case and they require a lot less code at the call site.
+
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::VoidFunctor::returnValue): Default parent class for
+ trivial functors.
+
+ (JSC::MarkedBlock::forEachCell): Renamed forEach to forEachCell because
+ we have a few different kind of "for each" now.
+
+ * runtime/JSGlobalData.cpp:
+ (WTF::Recompile::operator()):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::recompileAllJSFunctions): Updated for type change and rename.
+
+ * runtime/JSGlobalData.h: Removed globalObjectCount because it was unused.
+
2011-06-08 Mikołaj Małecki <[email protected]>
Reviewed by Pavel Feldman.
Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (88472 => 88473)
--- trunk/Source/_javascript_Core/_javascript_Core.exp 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp 2011-06-09 19:44:37 UTC (rev 88473)
@@ -221,6 +221,7 @@
__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
__ZN3JSC3NaNE
__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3JSC4Heap11objectCountEv
__ZN3JSC4Heap16activityCallbackEv
__ZN3JSC4Heap16objectTypeCountsEv
__ZN3JSC4Heap17collectAllGarbageEv
@@ -231,9 +232,11 @@
__ZN3JSC4Heap25protectedObjectTypeCountsEv
__ZN3JSC4Heap26protectedGlobalObjectCountEv
__ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm
+__ZN3JSC4Heap4sizeEv
__ZN3JSC4Heap7destroyEv
__ZN3JSC4Heap7protectENS_7JSValueE
__ZN3JSC4Heap8allocateERNS_8NewSpace9SizeClassE
+__ZN3JSC4Heap8capacityEv
__ZN3JSC4Heap9unprotectENS_7JSValueE
__ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc
__ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE
@@ -535,9 +538,6 @@
__ZNK3JSC18PropertyDescriptor6setterEv
__ZNK3JSC18PropertyDescriptor8writableEv
__ZNK3JSC19SourceProviderCache8byteSizeEv
-__ZNK3JSC4Heap11objectCountEv
-__ZNK3JSC4Heap4sizeEv
-__ZNK3JSC4Heap8capacityEv
__ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
__ZNK3JSC6JSCell14isGetterSetterEv
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (88472 => 88473)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-06-09 19:44:37 UTC (rev 88473)
@@ -76,7 +76,7 @@
?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z
?cancelCallOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
- ?capacity@Heap@JSC@@QBEIXZ
+ ?capacity@Heap@JSC@@QAEIXZ
?changePrototypeTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VJSValue@2@@Z
?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@@Z
?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@@Z
@@ -253,7 +253,7 @@
?number@UString@JSC@@SA?AV12@I@Z
?number@UString@JSC@@SA?AV12@N@Z
?numberToString@WTF@@YAINQA_W@Z
- ?objectCount@Heap@JSC@@QBEIXZ
+ ?objectCount@Heap@JSC@@QAEIXZ
?objectProtoFuncToString@JSC@@YI_JPAVExecState@1@@Z
?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z
?preventExtensions@JSObject@JSC@@UAEXAAVJSGlobalData@2@@Z
@@ -312,7 +312,7 @@
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
?shrinkToFit@StringBuilder@WTF@@QAEXXZ
?signal@ThreadCondition@WTF@@QAEXXZ
- ?size@Heap@JSC@@QBEIXZ
+ ?size@Heap@JSC@@QAEIXZ
?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z
?slowValidateCell@JSC@@YAXPAVJSCell@1@@Z
?slowValidateCell@JSC@@YAXPAVJSGlobalObject@1@@Z
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (88472 => 88473)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2011-06-09 19:44:37 UTC (rev 88473)
@@ -33,7 +33,7 @@
using namespace JSC;
-class Recompiler {
+class Recompiler : public MarkedBlock::VoidFunctor {
public:
Recompiler(Debugger*);
~Recompiler();
@@ -118,7 +118,7 @@
return;
Recompiler recompiler(this);
- globalData->heap.forEach(recompiler);
+ globalData->heap.forEachCell(recompiler);
}
JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
Modified: trunk/Source/_javascript_Core/heap/HandleHeap.h (88472 => 88473)
--- trunk/Source/_javascript_Core/heap/HandleHeap.h 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/heap/HandleHeap.h 2011-06-09 19:44:37 UTC (rev 88473)
@@ -28,6 +28,7 @@
#include "BlockStack.h"
#include "Handle.h"
+#include "HashCountedSet.h"
#include "SentinelLinkedList.h"
#include "SinglyLinkedList.h"
@@ -38,7 +39,6 @@
class JSGlobalData;
class JSValue;
class MarkStack;
-class TypeCounter;
typedef MarkStack SlotVisitor;
class WeakHandleOwner {
@@ -74,8 +74,9 @@
#endif
unsigned protectedGlobalObjectCount();
- void protectedObjectTypeCounts(TypeCounter&);
+ template<typename Functor> void forEachStrongHandle(Functor&, const HashCountedSet<JSCell*>& skipSet);
+
private:
class Node {
public:
@@ -278,6 +279,19 @@
return reinterpret_cast<WeakHandleOwner*>(-1);
}
+template<typename Functor> void HandleHeap::forEachStrongHandle(Functor& functor, const HashCountedSet<JSCell*>& skipSet)
+{
+ Node* end = m_strongList.end();
+ for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
+ JSValue value = *node->slot();
+ if (!value || !value.isCell())
+ continue;
+ if (skipSet.contains(value.asCell()))
+ continue;
+ functor(value.asCell());
+ }
}
+}
+
#endif
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (88472 => 88473)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2011-06-09 19:44:37 UTC (rev 88473)
@@ -36,9 +36,12 @@
#define COLLECT_ON_EVERY_ALLOCATION 0
using namespace std;
+using namespace JSC;
namespace JSC {
+namespace {
+
const size_t minBytesPerCycle = 512 * 1024;
static inline bool isValidSharedInstanceThreadState()
@@ -63,6 +66,179 @@
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 ResetAllocator : MarkedBlock::VoidFunctor {
+ void operator()(MarkedBlock*);
+};
+
+inline void ResetAllocator::operator()(MarkedBlock* block)
+{
+ block->resetAllocator();
+}
+
+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*);
+};
+
+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*);
+};
+
+inline void CountIfGlobalObject::operator()(JSCell* cell)
+{
+ if (!cell->isObject())
+ return;
+ if (!asObject(cell)->isGlobalObject())
+ return;
+ count(1);
+}
+
+class TakeIfEmpty {
+public:
+ typedef MarkedBlock* ReturnType;
+
+ TakeIfEmpty(NewSpace*);
+ void operator()(MarkedBlock*);
+ ReturnType returnValue();
+
+private:
+ NewSpace* m_newSpace;
+ DoublyLinkedList<MarkedBlock> m_empties;
+};
+
+inline TakeIfEmpty::TakeIfEmpty(NewSpace* newSpace)
+ : m_newSpace(newSpace)
+{
+}
+
+inline void TakeIfEmpty::operator()(MarkedBlock* block)
+{
+ if (!block->isEmpty())
+ return;
+
+ m_newSpace->removeBlock(block);
+ m_empties.append(block);
+}
+
+inline TakeIfEmpty::ReturnType TakeIfEmpty::returnValue()
+{
+ return m_empties.head();
+}
+
+class RecordType {
+public:
+ typedef PassOwnPtr<TypeCountSet> ReturnType;
+
+ RecordType();
+ void operator()(JSCell*);
+ ReturnType returnValue();
+
+private:
+ const char* typeName(JSCell*);
+ OwnPtr<TypeCountSet> m_typeCountSet;
+};
+
+inline RecordType::RecordType()
+ : m_typeCountSet(adoptPtr(new TypeCountSet))
+{
+}
+
+inline const char* RecordType::typeName(JSCell* cell)
+{
+ const ClassInfo* info = cell->classInfo();
+ if (!info || !info->className)
+ return "[unknown]";
+ return info->className;
+}
+
+inline void RecordType::operator()(JSCell* cell)
+{
+ m_typeCountSet->add(typeName(cell));
+}
+
+inline PassOwnPtr<TypeCountSet> RecordType::returnValue()
+{
+ return m_typeCountSet.release();
+}
+
+} // anonymous namespace
+
Heap::Heap(JSGlobalData* globalData)
: m_operationInProgress(NoOperation)
, m_newSpace(this)
@@ -282,141 +458,52 @@
void Heap::clearMarks()
{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->clearMarks();
+ forEachBlock<ClearMarks>();
}
void Heap::sweep()
{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->sweep();
+ forEachBlock<Sweep>();
}
-size_t Heap::objectCount() const
+size_t Heap::objectCount()
{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->markCount();
- return result;
+ return forEachBlock<MarkCount>();
}
-size_t Heap::size() const
+size_t Heap::size()
{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->size();
- return result;
+ return forEachBlock<Size>();
}
-size_t Heap::capacity() const
+size_t Heap::capacity()
{
- size_t result = 0;
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- result += (*it)->capacity();
- return result;
+ return forEachBlock<Capacity>();
}
-size_t Heap::globalObjectCount()
+size_t Heap::protectedGlobalObjectCount()
{
- return m_globalData->globalObjectCount;
+ return forEachProtectedCell<CountIfGlobalObject>();
}
-size_t Heap::protectedGlobalObjectCount()
+size_t Heap::globalObjectCount()
{
- size_t count = m_handleHeap.protectedGlobalObjectCount();
-
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
- if (it->first->isObject() && asObject(it->first)->isGlobalObject())
- count++;
- }
-
- return count;
+ return forEachCell<CountIfGlobalObject>();
}
size_t Heap::protectedObjectCount()
{
- return m_protectedValues.size();
+ return forEachProtectedCell<Count>();
}
-class TypeCounter {
-public:
- TypeCounter();
- void operator()(JSCell*);
- PassOwnPtr<TypeCountSet> take();
-
-private:
- const char* typeName(JSCell*);
- OwnPtr<TypeCountSet> m_typeCountSet;
- HashSet<JSCell*> m_cells;
-};
-
-inline TypeCounter::TypeCounter()
- : m_typeCountSet(adoptPtr(new TypeCountSet))
-{
-}
-
-inline const char* TypeCounter::typeName(JSCell* cell)
-{
- if (cell->isString())
- return "string";
- if (cell->isGetterSetter())
- return "Getter-Setter";
- if (cell->isAPIValueWrapper())
- return "API wrapper";
- if (cell->isPropertyNameIterator())
- return "For-in iterator";
- if (const ClassInfo* info = cell->classInfo())
- return info->className;
- if (!cell->isObject())
- return "[empty cell]";
- return "Object";
-}
-
-inline void TypeCounter::operator()(JSCell* cell)
-{
- if (!m_cells.add(cell).second)
- return;
- m_typeCountSet->add(typeName(cell));
-}
-
-inline PassOwnPtr<TypeCountSet> TypeCounter::take()
-{
- return m_typeCountSet.release();
-}
-
PassOwnPtr<TypeCountSet> Heap::protectedObjectTypeCounts()
{
- TypeCounter typeCounter;
-
- ProtectCountSet::iterator end = m_protectedValues.end();
- for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
- typeCounter(it->first);
- m_handleHeap.protectedObjectTypeCounts(typeCounter);
-
- return typeCounter.take();
+ return forEachProtectedCell<RecordType>();
}
-void HandleHeap::protectedObjectTypeCounts(TypeCounter& typeCounter)
-{
- Node* end = m_strongList.end();
- for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
- JSValue value = *node->slot();
- if (value && value.isCell())
- typeCounter(value.asCell());
- }
-}
-
PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
{
- TypeCounter typeCounter;
- forEach(typeCounter);
- return typeCounter.take();
+ return forEachCell<RecordType>();
}
void Heap::collectAllGarbage()
@@ -463,13 +550,9 @@
void Heap::resetAllocator()
{
+ m_extraCost = 0;
m_newSpace.resetAllocator();
-
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->resetAllocator();
-
- m_extraCost = 0;
+ forEachBlock<ResetAllocator>();
}
void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
@@ -504,10 +587,10 @@
return block;
}
-void Heap::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
+void Heap::freeBlocks(MarkedBlock* head)
{
MarkedBlock* next;
- for (MarkedBlock* block = blocks.head(); block; block = next) {
+ for (MarkedBlock* block = head; block; block = next) {
next = block->next();
m_blocks.remove(block);
@@ -518,19 +601,8 @@
void Heap::shrink()
{
// We record a temporary list of empties to avoid modifying m_blocks while iterating it.
- DoublyLinkedList<MarkedBlock> empties;
-
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
- MarkedBlock* block = *it;
- if (!block->isEmpty())
- continue;
-
- m_newSpace.removeBlock(block);
- empties.append(block);
- }
-
- freeBlocks(empties);
+ TakeIfEmpty takeIfEmpty(&m_newSpace);
+ freeBlocks(forEachBlock(takeIfEmpty));
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/Heap.h (88472 => 88473)
--- trunk/Source/_javascript_Core/heap/Heap.h 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2011-06-09 19:44:37 UTC (rev 88473)
@@ -91,9 +91,9 @@
bool contains(const void*);
- size_t size() const;
- size_t capacity() const;
- size_t objectCount() const;
+ size_t size();
+ size_t capacity();
+ size_t objectCount();
size_t globalObjectCount();
size_t protectedObjectCount();
size_t protectedGlobalObjectCount();
@@ -105,7 +105,12 @@
HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
- template <typename Functor> void forEach(Functor&);
+ template<typename Functor> typename Functor::ReturnType forEachProtectedCell(Functor&);
+ template<typename Functor> typename Functor::ReturnType forEachProtectedCell();
+ template<typename Functor> typename Functor::ReturnType forEachCell(Functor&);
+ template<typename Functor> typename Functor::ReturnType forEachCell();
+ template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&);
+ template<typename Functor> typename Functor::ReturnType forEachBlock();
HandleSlot allocateGlobalHandle() { return m_handleHeap.allocate(); }
HandleSlot allocateLocalHandle() { return m_handleStack.push(); }
@@ -124,7 +129,7 @@
void resetAllocator();
MarkedBlock* allocateBlock(size_t cellSize);
- void freeBlocks(DoublyLinkedList<MarkedBlock>&);
+ void freeBlocks(MarkedBlock*);
void clearMarks();
void markRoots();
@@ -221,13 +226,50 @@
reportExtraMemoryCostSlowCase(cost);
}
- template <typename Functor> inline void Heap::forEach(Functor& functor)
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell(Functor& functor)
{
+ ProtectCountSet::iterator end = m_protectedValues.end();
+ for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
+ functor(it->first);
+ m_handleHeap.forEachStrongHandle(functor, m_protectedValues);
+
+ return functor.returnValue();
+ }
+
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell()
+ {
+ Functor functor;
+ return forEachProtectedCell(functor);
+ }
+
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachCell(Functor& functor)
+ {
BlockIterator end = m_blocks.end();
for (BlockIterator it = m_blocks.begin(); it != end; ++it)
- (*it)->forEach(functor);
+ (*it)->forEachCell(functor);
+ return functor.returnValue();
}
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachCell()
+ {
+ Functor functor;
+ return forEachCell(functor);
+ }
+
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachBlock(Functor& functor)
+ {
+ BlockIterator end = m_blocks.end();
+ for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+ functor(*it);
+ return functor.returnValue();
+ }
+
+ template<typename Functor> inline typename Functor::ReturnType Heap::forEachBlock()
+ {
+ Functor functor;
+ return forEachBlock(functor);
+ }
+
inline void* Heap::allocate(size_t bytes)
{
ASSERT(isValidAllocation(bytes));
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (88472 => 88473)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2011-06-09 19:44:37 UTC (rev 88473)
@@ -41,6 +41,11 @@
class MarkedBlock : public DoublyLinkedListNode<MarkedBlock> {
friend class WTF::DoublyLinkedListNode<MarkedBlock>;
public:
+ struct VoidFunctor {
+ typedef void ReturnType;
+ void returnValue() { }
+ };
+
static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
static MarkedBlock* create(Heap*, size_t cellSize);
@@ -72,7 +77,7 @@
bool testAndClearMarked(const void*);
void setMarked(const void*);
- template <typename Functor> void forEach(Functor&);
+ template <typename Functor> void forEachCell(Functor&);
private:
static const size_t blockSize = 16 * KB;
@@ -184,7 +189,7 @@
m_marks.set(atomNumber(p));
}
- template <typename Functor> inline void MarkedBlock::forEach(Functor& functor)
+ template <typename Functor> inline void MarkedBlock::forEachCell(Functor& functor)
{
for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
if (!m_marks.get(i))
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp (88472 => 88473)
--- trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalData.cpp 2011-06-09 19:44:37 UTC (rev 88473)
@@ -75,7 +75,7 @@
using namespace JSC;
-class Recompiler {
+class Recompiler : public MarkedBlock::VoidFunctor {
public:
void operator()(JSCell*);
};
@@ -186,7 +186,6 @@
, parser(new Parser)
, interpreter(0)
, heap(this)
- , globalObjectCount(0)
, dynamicGlobalObject(0)
, cachedUTCOffset(NaN)
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
@@ -448,8 +447,7 @@
// up throwing away code that is live on the stack.
ASSERT(!dynamicGlobalObject);
- Recompiler recompiler;
- heap.forEach(recompiler);
+ heap.forEachCell<Recompiler>();
}
void JSGlobalData::releaseExecutableMemory()
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalData.h (88472 => 88473)
--- trunk/Source/_javascript_Core/runtime/JSGlobalData.h 2011-06-09 19:41:10 UTC (rev 88472)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalData.h 2011-06-09 19:44:37 UTC (rev 88473)
@@ -238,7 +238,6 @@
HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- unsigned globalObjectCount;
JSGlobalObject* dynamicGlobalObject;
HashSet<JSObject*> stringRecursionCheckVisitedObjects;