Title: [123813] trunk/Source/_javascript_Core
Revision
123813
Author
[email protected]
Date
2012-07-26 16:27:53 -0700 (Thu, 26 Jul 2012)

Log Message

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):

Modified Paths

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);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to