Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (123812 => 123813)
--- trunk/Source/_javascript_Core/ChangeLog 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-07-26 23:27:53 UTC (rev 123813)
@@ -1,3 +1,53 @@
+2012-07-26 Mark Hahnenberg <[email protected]>
+
+ Allocate Structures in a separate part of the Heap
+ https://bugs.webkit.org/show_bug.cgi?id=92420
+
+ Reviewed by Filip Pizlo.
+
+ To fix our issue with destruction/finalization of Structures before their objects, we can move Structures to a separate
+ part of the Heap that will be swept after all other objects. This first patch will just be separating Structures
+ out into their own separate MarkedAllocator. Everything else will behave identically.
+
+ * heap/Heap.h: New function to allocate Structures in the Heap.
+ (Heap):
+ (JSC):
+ (JSC::Heap::allocateStructure):
+ * heap/MarkedAllocator.cpp: Pass whether or not we're allocated Structures to the MarkedBlock.
+ (JSC::MarkedAllocator::allocateBlock):
+ * heap/MarkedAllocator.h: Add tracking for whether or not we're allocating only Structures.
+ (JSC::MarkedAllocator::onlyContainsStructures):
+ (MarkedAllocator):
+ (JSC::MarkedAllocator::MarkedAllocator):
+ (JSC::MarkedAllocator::init):
+ * heap/MarkedBlock.cpp: Add tracking for whether or not we're allocating only Structures. We need this to be able to
+ distinguish the various MarkedBlock types in MarkedSpace::allocatorFor(MarkedBlock*).
+ (JSC::MarkedBlock::create):
+ (JSC::MarkedBlock::MarkedBlock):
+ * heap/MarkedBlock.h:
+ (MarkedBlock):
+ (JSC::MarkedBlock::onlyContainsStructures):
+ (JSC):
+ * heap/MarkedSpace.cpp: Include the new Structure allocator in all the places that all the other allocators are used/modified.
+ (JSC::MarkedSpace::MarkedSpace):
+ (JSC::MarkedSpace::resetAllocators):
+ (JSC::MarkedSpace::canonicalizeCellLivenessData):
+ (JSC::MarkedSpace::isPagedOut):
+ * heap/MarkedSpace.h: Add new MarkedAllocator just for Structures.
+ (MarkedSpace):
+ (JSC::MarkedSpace::allocatorFor):
+ (JSC::MarkedSpace::allocateStructure):
+ (JSC):
+ (JSC::MarkedSpace::forEachBlock):
+ * runtime/Structure.h: Move all of the functions that call allocateCell<Structure> down below the explicit template specialization
+ for allocateCell<Structure>. The new inline specialization for allocateCell directly calls the allocateStructure() function in the
+ Heap.
+ (Structure):
+ (JSC::Structure):
+ (JSC):
+ (JSC::Structure::create):
+ (JSC::Structure::createStructure):
+
2012-07-26 Filip Pizlo <[email protected]>
JSArray has methods that are neither used nor defined
Modified: trunk/Source/_javascript_Core/heap/Heap.h (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/Heap.h 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2012-07-26 23:27:53 UTC (rev 123813)
@@ -183,6 +183,7 @@
void* allocateWithDestructor(size_t);
void* allocateWithoutDestructor(size_t);
+ void* allocateStructure();
static const size_t minExtraCost = 256;
static const size_t maxExtraCost = 1024 * 1024;
@@ -367,7 +368,12 @@
ASSERT(isValidAllocation(bytes));
return m_objectSpace.allocateWithoutDestructor(bytes);
}
-
+
+ inline void* Heap::allocateStructure()
+ {
+ return m_objectSpace.allocateStructure();
+ }
+
inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr)
{
return m_storageSpace.tryAllocate(bytes, outPtr);
Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2012-07-26 23:27:53 UTC (rev 123813)
@@ -92,7 +92,7 @@
MarkedBlock* MarkedAllocator::allocateBlock()
{
- MarkedBlock* block = MarkedBlock::create(m_heap->blockAllocator().allocate(), m_heap, m_cellSize, m_cellsNeedDestruction);
+ MarkedBlock* block = MarkedBlock::create(m_heap->blockAllocator().allocate(), m_heap, m_cellSize, m_cellsNeedDestruction, m_onlyContainsStructures);
m_markedSpace->didAddBlock(block);
return block;
}
Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.h (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedAllocator.h 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.h 2012-07-26 23:27:53 UTC (rev 123813)
@@ -24,6 +24,7 @@
void zapFreeList();
size_t cellSize() { return m_cellSize; }
bool cellsNeedDestruction() { return m_cellsNeedDestruction; }
+ bool onlyContainsStructures() { return m_onlyContainsStructures; }
void* allocate();
Heap* heap() { return m_heap; }
@@ -31,7 +32,7 @@
void addBlock(MarkedBlock*);
void removeBlock(MarkedBlock*);
- void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction);
+ void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
bool isPagedOut(double deadline);
@@ -48,6 +49,7 @@
DoublyLinkedList<HeapBlock> m_blockList;
size_t m_cellSize;
bool m_cellsNeedDestruction;
+ bool m_onlyContainsStructures;
Heap* m_heap;
MarkedSpace* m_markedSpace;
};
@@ -56,17 +58,19 @@
: m_currentBlock(0)
, m_cellSize(0)
, m_cellsNeedDestruction(true)
+ , m_onlyContainsStructures(false)
, m_heap(0)
, m_markedSpace(0)
{
}
-inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction)
+inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
{
m_heap = heap;
m_markedSpace = markedSpace;
m_cellSize = cellSize;
m_cellsNeedDestruction = cellsNeedDestruction;
+ m_onlyContainsStructures = onlyContainsStructures;
}
inline void* MarkedAllocator::allocate()
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2012-07-26 23:27:53 UTC (rev 123813)
@@ -32,9 +32,9 @@
namespace JSC {
-MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction)
+MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
{
- return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction);
+ return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures);
}
PageAllocationAligned MarkedBlock::destroy(MarkedBlock* block)
@@ -46,11 +46,12 @@
return allocation;
}
-MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction)
+MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
: HeapBlock(allocation)
, m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
, m_endAtom(atomsPerBlock - m_atomsPerCell + 1)
, m_cellsNeedDestruction(cellsNeedDestruction)
+ , m_onlyContainsStructures(onlyContainsStructures)
, m_state(New) // All cells start out unmarked.
, m_weakSet(heap)
{
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2012-07-26 23:27:53 UTC (rev 123813)
@@ -113,7 +113,7 @@
ReturnType m_count;
};
- static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction);
+ static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
static PageAllocationAligned destroy(MarkedBlock*);
static bool isAtomAligned(const void*);
@@ -145,6 +145,7 @@
size_t cellSize();
bool cellsNeedDestruction();
+ bool onlyContainsStructures();
size_t size();
size_t capacity();
@@ -195,7 +196,7 @@
typedef char Atom[atomSize];
- MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction);
+ MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
Atom* atoms();
size_t atomNumber(const void*);
void callDestructor(JSCell*);
@@ -213,6 +214,7 @@
WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks;
#endif
bool m_cellsNeedDestruction;
+ bool m_onlyContainsStructures;
BlockState m_state;
WeakSet m_weakSet;
};
@@ -322,6 +324,11 @@
return m_cellsNeedDestruction;
}
+ inline bool MarkedBlock::onlyContainsStructures()
+ {
+ return m_onlyContainsStructures;
+ }
+
inline size_t MarkedBlock::size()
{
return markCount() * cellSize();
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.cpp (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.cpp 2012-07-26 23:27:53 UTC (rev 123813)
@@ -80,14 +80,16 @@
: m_heap(heap)
{
for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
- allocatorFor(cellSize).init(heap, this, cellSize, false);
- destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+ allocatorFor(cellSize).init(heap, this, cellSize, false, false);
+ destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false);
}
for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
- allocatorFor(cellSize).init(heap, this, cellSize, false);
- destructorAllocatorFor(cellSize).init(heap, this, cellSize, true);
+ allocatorFor(cellSize).init(heap, this, cellSize, false, false);
+ destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false);
}
+
+ m_structureAllocator.init(heap, this, WTF::roundUpToMultipleOf(32, sizeof(Structure)), true, true);
}
MarkedSpace::~MarkedSpace()
@@ -117,6 +119,8 @@
allocatorFor(cellSize).reset();
destructorAllocatorFor(cellSize).reset();
}
+
+ m_structureAllocator.reset();
}
void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor)
@@ -141,6 +145,8 @@
allocatorFor(cellSize).zapFreeList();
destructorAllocatorFor(cellSize).zapFreeList();
}
+
+ m_structureAllocator.zapFreeList();
}
bool MarkedSpace::isPagedOut(double deadline)
@@ -155,6 +161,9 @@
return true;
}
+ if (m_structureAllocator.isPagedOut(deadline))
+ return true;
+
return false;
}
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.h (123812 => 123813)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.h 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.h 2012-07-26 23:27:53 UTC (rev 123813)
@@ -80,7 +80,8 @@
MarkedAllocator& destructorAllocatorFor(size_t);
void* allocateWithDestructor(size_t);
void* allocateWithoutDestructor(size_t);
-
+ void* allocateStructure();
+
void resetAllocators();
void visitWeakSets(HeapRootVisitor&);
@@ -132,6 +133,7 @@
Subspace m_destructorSpace;
Subspace m_normalSpace;
+ MarkedAllocator m_structureAllocator;
Heap* m_heap;
MarkedBlockSet m_blocks;
@@ -168,8 +170,12 @@
inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block)
{
+ if (block->onlyContainsStructures())
+ return m_structureAllocator;
+
if (block->cellsNeedDestruction())
return destructorAllocatorFor(block->cellSize());
+
return allocatorFor(block->cellSize());
}
@@ -191,6 +197,11 @@
return destructorAllocatorFor(bytes).allocate();
}
+inline void* MarkedSpace::allocateStructure()
+{
+ return m_structureAllocator.allocate();
+}
+
template <typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachBlock(Functor& functor)
{
for (size_t i = 0; i < preciseCount; ++i) {
@@ -203,6 +214,8 @@
m_destructorSpace.impreciseAllocators[i].forEachBlock(functor);
}
+ m_structureAllocator.forEachBlock(functor);
+
return functor.returnValue();
}
Modified: trunk/Source/_javascript_Core/runtime/Structure.h (123812 => 123813)
--- trunk/Source/_javascript_Core/runtime/Structure.h 2012-07-26 23:10:19 UTC (rev 123812)
+++ trunk/Source/_javascript_Core/runtime/Structure.h 2012-07-26 23:27:53 UTC (rev 123813)
@@ -68,14 +68,7 @@
typedef JSCell Base;
- static Structure* create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo)
- {
- ASSERT(globalData.structureStructure);
- ASSERT(classInfo);
- Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo);
- structure->finishCreation(globalData);
- return structure;
- }
+ static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*);
protected:
void finishCreation(JSGlobalData& globalData)
@@ -330,13 +323,7 @@
return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
}
- static Structure* createStructure(JSGlobalData& globalData)
- {
- ASSERT(!globalData.structureStructure);
- Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData);
- structure->finishCreation(globalData, CreatingEarlyCell);
- return structure;
- }
+ static Structure* createStructure(JSGlobalData&);
bool transitionWatchpointSetHasBeenInvalidated() const
{
@@ -368,13 +355,7 @@
Structure(JSGlobalData&);
Structure(JSGlobalData&, const Structure*);
- static Structure* create(JSGlobalData& globalData, const Structure* structure)
- {
- ASSERT(globalData.structureStructure);
- Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure);
- newStructure->finishCreation(globalData);
- return newStructure;
- }
+ static Structure* create(JSGlobalData&, const Structure*);
typedef enum {
NoneDictionaryKind = 0,
@@ -461,6 +442,42 @@
unsigned m_staticFunctionReified;
};
+ template <> inline void* allocateCell<Structure>(Heap& heap)
+ {
+#if ENABLE(GC_VALIDATION)
+ ASSERT(!heap.globalData()->isInitializingObject());
+ heap.globalData()->setInitializingObjectClass(&Structure::s_info);
+#endif
+ JSCell* result = static_cast<JSCell*>(heap.allocateStructure());
+ result->clearStructure();
+ return result;
+ }
+
+ inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo)
+ {
+ ASSERT(globalData.structureStructure);
+ ASSERT(classInfo);
+ Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo);
+ structure->finishCreation(globalData);
+ return structure;
+ }
+
+ inline Structure* Structure::createStructure(JSGlobalData& globalData)
+ {
+ ASSERT(!globalData.structureStructure);
+ Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData);
+ structure->finishCreation(globalData, CreatingEarlyCell);
+ return structure;
+ }
+
+ inline Structure* Structure::create(JSGlobalData& globalData, const Structure* structure)
+ {
+ ASSERT(globalData.structureStructure);
+ Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure);
+ newStructure->finishCreation(globalData);
+ return newStructure;
+ }
+
inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName)
{
ASSERT(structure()->classInfo() == &s_info);