Changeset 107445 in webkit
- Timestamp:
- Feb 10, 2012 2:44:09 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r107421 r107445 1 2012-02-10 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Split MarkedSpace into destructor and destructor-free subspaces 4 https://bugs.webkit.org/show_bug.cgi?id=77761 5 6 Reviewed by Geoffrey Garen. 7 8 * dfg/DFGSpeculativeJIT.h: 9 (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): Switched over to use destructor-free space. 10 * heap/Heap.h: 11 (JSC::Heap::allocatorForObjectWithoutDestructor): Added to give clients (e.g. the JIT) the ability to 12 pick which subspace they want to allocate out of. 13 (JSC::Heap::allocatorForObjectWithDestructor): Ditto. 14 (Heap): 15 (JSC::Heap::allocateWithDestructor): Added private function for CellAllocator to use. 16 (JSC): 17 (JSC::Heap::allocateWithoutDestructor): Ditto. 18 * heap/MarkedAllocator.cpp: Added the cellsNeedDestruction flag to allocators so that they can allocate 19 their MarkedBlocks correctly. 20 (JSC::MarkedAllocator::allocateBlock): 21 * heap/MarkedAllocator.h: 22 (JSC::MarkedAllocator::cellsNeedDestruction): 23 (MarkedAllocator): 24 (JSC::MarkedAllocator::MarkedAllocator): 25 (JSC): 26 (JSC::MarkedAllocator::init): Replaced custom set functions, which were only used upon initialization, with 27 an init function that does all of that stuff in fewer lines. 28 * heap/MarkedBlock.cpp: 29 (JSC::MarkedBlock::create): 30 (JSC::MarkedBlock::recycle): 31 (JSC::MarkedBlock::MarkedBlock): 32 (JSC::MarkedBlock::callDestructor): Templatized, along with specializedSweep and sweepHelper, to make 33 checking the m_cellsNeedDestructor flag faster and cleaner looking. 34 (JSC): 35 (JSC::MarkedBlock::specializedSweep): 36 (JSC::MarkedBlock::sweep): 37 (JSC::MarkedBlock::sweepHelper): 38 * heap/MarkedBlock.h: 39 (MarkedBlock): 40 (JSC::MarkedBlock::cellsNeedDestruction): 41 (JSC): 42 * heap/MarkedSpace.cpp: 43 (JSC::MarkedSpace::MarkedSpace): 44 (JSC::MarkedSpace::resetAllocators): 45 (JSC::MarkedSpace::canonicalizeCellLivenessData): 46 (JSC::TakeIfUnmarked::operator()): 47 * heap/MarkedSpace.h: 48 (MarkedSpace): 49 (Subspace): 50 (JSC::MarkedSpace::allocatorFor): Needed function to differentiate between the two broad subspaces of 51 allocators. 52 (JSC): 53 (JSC::MarkedSpace::destructorAllocatorFor): Ditto. 54 (JSC::MarkedSpace::allocateWithoutDestructor): Ditto. 55 (JSC::MarkedSpace::allocateWithDestructor): Ditto. 56 (JSC::MarkedSpace::forEachBlock): 57 * jit/JIT.h: 58 * jit/JITInlineMethods.h: Modified to use the proper allocator for JSFinalObjects and others. 59 (JSC::JIT::emitAllocateBasicJSObject): 60 (JSC::JIT::emitAllocateJSFinalObject): 61 (JSC::JIT::emitAllocateJSFunction): 62 * runtime/JSArray.cpp: 63 (JSC): 64 * runtime/JSArray.h: 65 (JSArray): 66 (JSC::JSArray::create): 67 (JSC): 68 (JSC::JSArray::tryCreateUninitialized): 69 * runtime/JSCell.h: 70 (JSCell): 71 (JSC): 72 (NeedsDestructor): Template struct that calculates at compile time whether the class in question requires 73 destruction or not using the compiler type trait __has_trivial_destructor. allocateCell then checks this 74 constant to decide whether to allocate in the destructor or destructor-free parts of the heap. 75 (JSC::allocateCell): 76 * runtime/JSFunction.cpp: 77 (JSC): 78 * runtime/JSFunction.h: 79 (JSFunction): 80 * runtime/JSObject.cpp: 81 (JSC): 82 * runtime/JSObject.h: 83 (JSNonFinalObject): 84 (JSC): 85 (JSFinalObject): 86 (JSC::JSFinalObject::create): 87 1 88 2012-02-10 Adrienne Walker <enne@google.com> 2 89 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r106775 r107445 1566 1566 void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) 1567 1567 { 1568 MarkedAllocator* allocator = &m_jit.globalData()->heap.allocatorForObject (sizeof(JSFinalObject));1568 MarkedAllocator* allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)); 1569 1569 1570 1570 m_jit.loadPtr(&allocator->m_firstFreeCell, resultGPR); -
trunk/Source/JavaScriptCore/heap/Heap.h
r106676 r107445 96 96 inline bool isBusy(); 97 97 98 MarkedAllocator& allocatorForObject (size_t bytes) { return m_objectSpace.allocatorFor(bytes); }99 void* allocate(size_t);98 MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } 99 MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); } 100 100 CheckedBoolean tryAllocateStorage(size_t, void**); 101 101 CheckedBoolean tryReallocateStorage(void**, size_t, size_t); … … 143 143 friend class SlotVisitor; 144 144 friend class CodeBlock; 145 template<typename T> friend void* allocateCell(Heap&); 146 147 void* allocateWithDestructor(size_t); 148 void* allocateWithoutDestructor(size_t); 145 149 146 150 size_t waterMark(); … … 335 339 } 336 340 337 inline void* Heap::allocate (size_t bytes)341 inline void* Heap::allocateWithDestructor(size_t bytes) 338 342 { 339 343 ASSERT(isValidAllocation(bytes)); 340 return m_objectSpace.allocate(bytes); 344 return m_objectSpace.allocateWithDestructor(bytes); 345 } 346 347 inline void* Heap::allocateWithoutDestructor(size_t bytes) 348 { 349 ASSERT(isValidAllocation(bytes)); 350 return m_objectSpace.allocateWithoutDestructor(bytes); 341 351 } 342 352 -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp
r106677 r107445 98 98 } 99 99 if (block) 100 block = MarkedBlock::recycle(block, m_heap, m_cellSize );100 block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction); 101 101 else if (allocationEffort == AllocationCanFail) 102 102 return 0; 103 103 else 104 block = MarkedBlock::create(m_heap, m_cellSize );104 block = MarkedBlock::create(m_heap, m_cellSize, m_cellsNeedDestruction); 105 105 106 106 m_markedSpace->didAddBlock(block); -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r106677 r107445 23 23 void zapFreeList(); 24 24 size_t cellSize() { return m_cellSize; } 25 bool cellsNeedDestruction() { return m_cellsNeedDestruction; } 25 26 void* allocate(); 26 27 Heap* heap() { return m_heap; } … … 30 31 void addBlock(MarkedBlock*); 31 32 void removeBlock(MarkedBlock*); 32 void setHeap(Heap* heap) { m_heap = heap; } 33 void setCellSize(size_t cellSize) { m_cellSize = cellSize; } 34 void setMarkedSpace(MarkedSpace* space) { m_markedSpace = space; } 33 void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction); 35 34 36 35 private: … … 44 43 DoublyLinkedList<HeapBlock> m_blockList; 45 44 size_t m_cellSize; 45 bool m_cellsNeedDestruction; 46 46 Heap* m_heap; 47 47 MarkedSpace* m_markedSpace; … … 52 52 , m_currentBlock(0) 53 53 , m_cellSize(0) 54 , m_cellsNeedDestruction(true) 54 55 , m_heap(0) 55 56 , m_markedSpace(0) 56 57 { 57 58 } 58 59 60 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction) 61 { 62 m_heap = heap; 63 m_markedSpace = markedSpace; 64 m_cellSize = cellSize; 65 m_cellsNeedDestruction = cellsNeedDestruction; 66 } 67 59 68 inline void* MarkedAllocator::allocate() 60 69 { -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r106686 r107445 33 33 namespace JSC { 34 34 35 MarkedBlock* MarkedBlock::create(Heap* heap, size_t cellSize )35 MarkedBlock* MarkedBlock::create(Heap* heap, size_t cellSize, bool cellsNeedDestruction) 36 36 { 37 37 PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockSize, OSAllocator::JSGCHeapPages); 38 38 if (!static_cast<bool>(allocation)) 39 39 CRASH(); 40 return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize );41 } 42 43 MarkedBlock* MarkedBlock::recycle(MarkedBlock* block, Heap* heap, size_t cellSize )44 { 45 return new (NotNull, block) MarkedBlock(block->m_allocation, heap, cellSize );40 return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction); 41 } 42 43 MarkedBlock* MarkedBlock::recycle(MarkedBlock* block, Heap* heap, size_t cellSize, bool cellsNeedDestruction) 44 { 45 return new (NotNull, block) MarkedBlock(block->m_allocation, heap, cellSize, cellsNeedDestruction); 46 46 } 47 47 … … 51 51 } 52 52 53 MarkedBlock::MarkedBlock(PageAllocationAligned& allocation, Heap* heap, size_t cellSize )53 MarkedBlock::MarkedBlock(PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction) 54 54 : HeapBlock(allocation) 55 55 , m_atomsPerCell((cellSize + atomSize - 1) / atomSize) 56 56 , m_endAtom(atomsPerBlock - m_atomsPerCell + 1) 57 , m_cellsNeedDestruction(cellsNeedDestruction) 57 58 , m_state(New) // All cells start out unmarked. 58 59 , m_heap(heap) … … 71 72 m_heap->m_destroyedTypeCounts.countVPtr(vptr); 72 73 #endif 73 if (cell->classInfo() != &JSFinalObject::s_info)74 74 ASSERT(cell->classInfo() != &JSFinalObject::s_info); 75 cell->methodTable()->destroy(cell); 75 76 76 77 cell->zap(); 77 78 } 78 79 79 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode >80 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool destructorCallNeeded> 80 81 MarkedBlock::FreeCell* MarkedBlock::specializedSweep() 81 82 { 82 83 ASSERT(blockState != Allocated && blockState != FreeListed); 84 ASSERT(destructorCallNeeded || sweepMode != SweepOnly); 83 85 84 86 // This produces a free list that is ordered in reverse through the block. … … 94 96 continue; 95 97 96 if ( blockState != New)98 if (destructorCallNeeded && blockState != New) 97 99 callDestructor(cell); 98 100 … … 112 114 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 113 115 116 if (sweepMode == SweepOnly && !m_cellsNeedDestruction) 117 return 0; 118 119 if (m_cellsNeedDestruction) 120 return sweepHelper<true>(sweepMode); 121 return sweepHelper<false>(sweepMode); 122 } 123 124 template<bool destructorCallNeeded> 125 MarkedBlock::FreeCell* MarkedBlock::sweepHelper(SweepMode sweepMode) 126 { 114 127 switch (m_state) { 115 128 case New: 116 129 ASSERT(sweepMode == SweepToFreeList); 117 return specializedSweep<New, SweepToFreeList >();130 return specializedSweep<New, SweepToFreeList, destructorCallNeeded>(); 118 131 case FreeListed: 119 132 // Happens when a block transitions to fully allocated. … … 125 138 case Marked: 126 139 return sweepMode == SweepToFreeList 127 ? specializedSweep<Marked, SweepToFreeList >()128 : specializedSweep<Marked, SweepOnly >();140 ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>() 141 : specializedSweep<Marked, SweepOnly, destructorCallNeeded>(); 129 142 case Zapped: 130 143 return sweepMode == SweepToFreeList 131 ? specializedSweep<Zapped, SweepToFreeList >()132 : specializedSweep<Zapped, SweepOnly >();144 ? specializedSweep<Zapped, SweepToFreeList, destructorCallNeeded>() 145 : specializedSweep<Zapped, SweepOnly, destructorCallNeeded>(); 133 146 } 134 147 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r106686 r107445 90 90 }; 91 91 92 static MarkedBlock* create(Heap*, size_t cellSize );93 static MarkedBlock* recycle(MarkedBlock*, Heap*, size_t cellSize );92 static MarkedBlock* create(Heap*, size_t cellSize, bool cellsNeedDestruction); 93 static MarkedBlock* recycle(MarkedBlock*, Heap*, size_t cellSize, bool cellsNeedDestruction); 94 94 static void destroy(MarkedBlock*); 95 95 … … 116 116 117 117 size_t cellSize(); 118 bool cellsNeedDestruction(); 118 119 119 120 size_t size(); … … 160 161 161 162 enum BlockState { New, FreeListed, Allocated, Marked, Zapped }; 163 template<bool destructorCallNeeded> FreeCell* sweepHelper(SweepMode = SweepOnly); 162 164 163 165 typedef char Atom[atomSize]; 164 166 165 MarkedBlock(PageAllocationAligned&, Heap*, size_t cellSize );167 MarkedBlock(PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction); 166 168 Atom* atoms(); 167 169 size_t atomNumber(const void*); 168 170 void callDestructor(JSCell*); 169 template<BlockState, SweepMode > FreeCell* specializedSweep();171 template<BlockState, SweepMode, bool destructorCallNeeded> FreeCell* specializedSweep(); 170 172 171 173 #if ENABLE(GGC) … … 180 182 WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks; 181 183 #endif 184 bool m_cellsNeedDestruction; 182 185 BlockState m_state; 183 186 Heap* m_heap; … … 242 245 { 243 246 return m_atomsPerCell * atomSize; 247 } 248 249 inline bool MarkedBlock::cellsNeedDestruction() 250 { 251 return m_cellsNeedDestruction; 244 252 } 245 253 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r106676 r107445 37 37 { 38 38 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 39 allocatorFor(cellSize).setCellSize(cellSize); 40 allocatorFor(cellSize).setHeap(heap); 41 allocatorFor(cellSize).setMarkedSpace(this); 39 allocatorFor(cellSize).init(heap, this, cellSize, false); 40 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true); 42 41 } 43 42 44 43 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 45 allocatorFor(cellSize).setCellSize(cellSize); 46 allocatorFor(cellSize).setHeap(heap); 47 allocatorFor(cellSize).setMarkedSpace(this); 44 allocatorFor(cellSize).init(heap, this, cellSize, false); 45 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true); 48 46 } 49 47 } … … 54 52 m_nurseryWaterMark = 0; 55 53 56 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) 54 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 57 55 allocatorFor(cellSize).reset(); 56 destructorAllocatorFor(cellSize).reset(); 57 } 58 58 59 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) 59 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 60 60 allocatorFor(cellSize).reset(); 61 destructorAllocatorFor(cellSize).reset(); 62 } 61 63 } 62 64 63 65 void MarkedSpace::canonicalizeCellLivenessData() 64 66 { 65 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) 67 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 66 68 allocatorFor(cellSize).zapFreeList(); 69 destructorAllocatorFor(cellSize).zapFreeList(); 70 } 67 71 68 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) 72 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 69 73 allocatorFor(cellSize).zapFreeList(); 74 destructorAllocatorFor(cellSize).zapFreeList(); 75 } 70 76 } 71 77 … … 108 114 return; 109 115 110 m_markedSpace->allocatorFor(block ->cellSize()).removeBlock(block);116 m_markedSpace->allocatorFor(block).removeBlock(block); 111 117 m_empties.append(block); 112 118 } -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r106676 r107445 53 53 54 54 MarkedAllocator& allocatorFor(size_t); 55 void* allocate(size_t); 55 MarkedAllocator& allocatorFor(MarkedBlock*); 56 MarkedAllocator& destructorAllocatorFor(size_t); 57 void* allocateWithDestructor(size_t); 58 void* allocateWithoutDestructor(size_t); 56 59 57 60 void resetAllocators(); … … 87 90 static const size_t impreciseCount = impreciseCutoff / impreciseStep; 88 91 89 FixedArray<MarkedAllocator, preciseCount> m_preciseSizeClasses; 90 FixedArray<MarkedAllocator, impreciseCount> m_impreciseSizeClasses; 92 struct Subspace { 93 FixedArray<MarkedAllocator, preciseCount> preciseAllocators; 94 FixedArray<MarkedAllocator, impreciseCount> impreciseAllocators; 95 }; 96 97 Subspace m_destructorSpace; 98 Subspace m_normalSpace; 99 91 100 size_t m_waterMark; 92 101 size_t m_nurseryWaterMark; … … 125 134 ASSERT(bytes && bytes <= maxCellSize); 126 135 if (bytes <= preciseCutoff) 127 return m_ preciseSizeClasses[(bytes - 1) / preciseStep];128 return m_ impreciseSizeClasses[(bytes - 1) / impreciseStep];136 return m_normalSpace.preciseAllocators[(bytes - 1) / preciseStep]; 137 return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 129 138 } 130 139 131 inline void* MarkedSpace::allocate(size_t bytes) 140 inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block) 141 { 142 if (block->cellsNeedDestruction()) 143 return destructorAllocatorFor(block->cellSize()); 144 return allocatorFor(block->cellSize()); 145 } 146 147 inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes) 148 { 149 ASSERT(bytes && bytes <= maxCellSize); 150 if (bytes <= preciseCutoff) 151 return m_destructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; 152 return m_destructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 153 } 154 155 inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes) 132 156 { 133 157 return allocatorFor(bytes).allocate(); 158 } 159 160 inline void* MarkedSpace::allocateWithDestructor(size_t bytes) 161 { 162 return destructorAllocatorFor(bytes).allocate(); 134 163 } 135 164 … … 137 166 { 138 167 for (size_t i = 0; i < preciseCount; ++i) { 139 m_preciseSizeClasses[i].forEachBlock(functor); 168 m_normalSpace.preciseAllocators[i].forEachBlock(functor); 169 m_destructorSpace.preciseAllocators[i].forEachBlock(functor); 140 170 } 141 171 142 172 for (size_t i = 0; i < impreciseCount; ++i) { 143 m_impreciseSizeClasses[i].forEachBlock(functor); 173 m_normalSpace.impreciseAllocators[i].forEachBlock(functor); 174 m_destructorSpace.impreciseAllocators[i].forEachBlock(functor); 144 175 } 145 176 -
trunk/Source/JavaScriptCore/jit/JIT.h
r107126 r107445 336 336 void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind); 337 337 338 template<typename ClassType, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);338 template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr); 339 339 template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); 340 340 void emitAllocateJSFunction(FunctionExecutable*, RegisterID scopeChain, RegisterID result, RegisterID storagePtr); -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r107126 r107445 403 403 } 404 404 405 template <typename ClassType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr) 406 { 407 MarkedAllocator* allocator = &m_globalData->heap.allocatorForObject(sizeof(ClassType)); 405 template <typename ClassType, bool destructor, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr) 406 { 407 MarkedAllocator* allocator = 0; 408 if (destructor) 409 allocator = &m_globalData->heap.allocatorForObjectWithDestructor(sizeof(ClassType)); 410 else 411 allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType)); 408 412 loadPtr(&allocator->m_firstFreeCell, result); 409 413 addSlowCase(branchTestPtr(Zero, result)); … … 429 433 template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch) 430 434 { 431 emitAllocateBasicJSObject<JSFinalObject >(structure, result, scratch);435 emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch); 432 436 } 433 437 434 438 inline void JIT::emitAllocateJSFunction(FunctionExecutable* executable, RegisterID scopeChain, RegisterID result, RegisterID storagePtr) 435 439 { 436 emitAllocateBasicJSObject<JSFunction >(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), result, storagePtr);440 emitAllocateBasicJSObject<JSFunction, true>(TrustedImmPtr(m_codeBlock->globalObject()->namedFunctionStructure()), result, storagePtr); 437 441 438 442 // store the function's scope chain -
trunk/Source/JavaScriptCore/runtime/JSArray.cpp
r106496 r107445 43 43 44 44 ASSERT_CLASS_FITS_IN_CELL(JSArray); 45 ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSArray); 45 46 46 47 // Overview of JSArray -
trunk/Source/JavaScriptCore/runtime/JSArray.h
r106496 r107445 136 136 static void finalize(JSCell*); 137 137 138 static JSArray* create(JSGlobalData& globalData, Structure* structure, unsigned initialLength = 0) 139 { 140 JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure); 141 array->finishCreation(globalData, initialLength); 142 return array; 143 } 138 static JSArray* create(JSGlobalData&, Structure*, unsigned initialLength = 0); 144 139 145 140 // tryCreateUninitialized is used for fast construction of arrays whose size and … … 148 143 // - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength. 149 144 // - called 'completeInitialization' after all properties have been initialized. 150 static JSArray* tryCreateUninitialized(JSGlobalData& globalData, Structure* structure, unsigned initialLength) 151 { 152 JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure); 153 return array->tryFinishCreationUninitialized(globalData, initialLength); 154 } 145 static JSArray* tryCreateUninitialized(JSGlobalData&, Structure*, unsigned initialLength); 155 146 156 147 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&, bool throwException); … … 300 291 }; 301 292 293 inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength) 294 { 295 JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure); 296 array->finishCreation(globalData, initialLength); 297 return array; 298 } 299 300 inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Structure* structure, unsigned initialLength) 301 { 302 JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure); 303 return array->tryFinishCreationUninitialized(globalData, initialLength); 304 } 305 302 306 JSArray* asArray(JSValue); 303 307 -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r106783 r107445 62 62 friend class JSValue; 63 63 friend class MarkedBlock; 64 template<typename T> friend void* allocateCell(Heap&); 64 65 65 66 public: … … 308 309 } 309 310 310 template <typename T> void* allocateCell(Heap& heap) 311 #if COMPILER(CLANG) 312 template<class T> 313 struct NeedsDestructor { 314 static const bool value = !__has_trivial_destructor(T); 315 }; 316 #else 317 // Write manual specializations for this struct template if you care about non-clang compilers. 318 template<class T> 319 struct NeedsDestructor { 320 static const bool value = true; 321 }; 322 #endif 323 324 template<typename T> 325 void* allocateCell(Heap& heap) 311 326 { 312 327 #if ENABLE(GC_VALIDATION) … … 315 330 heap.globalData()->setInitializingObject(true); 316 331 #endif 317 JSCell* result = static_cast<JSCell*>(heap.allocate(sizeof(T))); 332 JSCell* result = 0; 333 if (NeedsDestructor<T>::value) 334 result = static_cast<JSCell*>(heap.allocateWithDestructor(sizeof(T))); 335 else { 336 ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); 337 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(sizeof(T))); 338 } 318 339 result->clearStructure(); 319 340 return result; -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r107128 r107445 51 51 52 52 ASSERT_CLASS_FITS_IN_CELL(JSFunction); 53 ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFunction); 53 54 54 55 const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) }; … … 107 108 setStructure(exec->globalData(), scopeChainNode->globalObject->namedFunctionStructure()); 108 109 putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue()); 109 }110 111 void JSFunction::destroy(JSCell* cell)112 {113 JSFunction* thisObject = jsCast<JSFunction*>(cell);114 ASSERT(thisObject->classInfo()->isSubClassOf(&JSFunction::s_info));115 thisObject->JSFunction::~JSFunction();116 110 } 117 111 -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r106504 r107445 65 65 } 66 66 67 static void destroy(JSCell*);68 69 67 JS_EXPORT_PRIVATE const UString& name(ExecState*); 70 68 JS_EXPORT_PRIVATE const UString displayName(ExecState*); -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r106783 r107445 49 49 50 50 ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSObject); 51 ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFinalObject); 51 52 52 53 const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property."; … … 55 56 56 57 const ClassInfo JSFinalObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFinalObject) }; 57 58 void JSFinalObject::destroy(JSCell* cell)59 {60 jsCast<JSFinalObject*>(cell)->JSFinalObject::~JSFinalObject();61 }62 63 void JSNonFinalObject::destroy(JSCell* cell)64 {65 jsCast<JSNonFinalObject*>(cell)->JSNonFinalObject::~JSNonFinalObject();66 }67 58 68 59 static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode) … … 83 74 } 84 75 } 85 }86 87 void JSObject::destroy(JSCell* cell)88 {89 jsCast<JSObject*>(cell)->JSObject::~JSObject();90 76 } 91 77 -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r106783 r107445 85 85 typedef JSCell Base; 86 86 87 JS_EXPORT_PRIVATE static void destroy(JSCell*);88 89 87 JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); 90 88 … … 324 322 } 325 323 326 JS_EXPORT_PRIVATE static void destroy(JSCell*);327 328 324 protected: 329 325 explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure) … … 344 340 }; 345 341 342 class JSFinalObject; 343 346 344 // JSFinalObject is a type of JSObject that contains sufficent internal 347 345 // storage to fully make use of the colloctor cell containing it. … … 352 350 typedef JSObject Base; 353 351 354 static JSFinalObject* create(ExecState* exec, Structure* structure) 355 { 356 JSFinalObject* finalObject = new (NotNull, allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure); 357 finalObject->finishCreation(exec->globalData()); 358 return finalObject; 359 } 360 352 static JSFinalObject* create(ExecState*, Structure*); 361 353 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) 362 354 { … … 375 367 } 376 368 377 static void destroy(JSCell*);378 379 369 private: 380 370 explicit JSFinalObject(JSGlobalData& globalData, Structure* structure) … … 387 377 WriteBarrierBase<Unknown> m_inlineStorage[JSFinalObject_inlineStorageCapacity]; 388 378 }; 379 380 inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure) 381 { 382 JSFinalObject* finalObject = new (NotNull, allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure); 383 finalObject->finishCreation(exec->globalData()); 384 return finalObject; 385 } 389 386 390 387 inline bool isJSFinalObject(JSCell* cell) -
trunk/Source/WebCore/ChangeLog
r107443 r107445 1 2012-02-10 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Split MarkedSpace into destructor and destructor-free subspaces 4 https://bugs.webkit.org/show_bug.cgi?id=77761 5 6 Reviewed by Geoffrey Garen. 7 8 No new tests. 9 10 * bindings/js/JSDOMWindowShell.cpp: Removed old operator new, which was just used in the create 11 function so that we can use allocateCell instead. 12 (WebCore): 13 * bindings/js/JSDOMWindowShell.h: 14 (WebCore::JSDOMWindowShell::create): 15 (JSDOMWindowShell): 16 * bindings/scripts/CodeGeneratorJS.pm: Added destructor back to root JS DOM nodes (e.g. JSNode, etc) 17 because their destroy functions need to be called, so we don't want the NeedsDestructor struct to 18 think they don't need destruction due to having empty/trivial destructors. 19 Removed ASSERT_HAS_TRIVIAL_DESTRUCTOR from all JS DOM wrapper auto-generated objects because their 20 ancestors now have non-trivial destructors. 21 (GenerateHeader): 22 (GenerateImplementation): 23 (GenerateConstructorDefinition): 24 1 25 2012-02-10 Anders Carlsson <andersca@apple.com> 2 26 -
trunk/Source/WebCore/bindings/js/JSDOMWindowShell.cpp
r106783 r107445 150 150 } 151 151 152 void* JSDOMWindowShell::operator new(size_t size)153 {154 Heap& heap = JSDOMWindow::commonJSGlobalData()->heap;155 #if ENABLE(GC_VALIDATION)156 ASSERT(!heap.globalData()->isInitializingObject());157 heap.globalData()->setInitializingObject(true);158 #endif159 return heap.allocate(size);160 }161 162 152 // ---- 163 153 // Conversion methods -
trunk/Source/WebCore/bindings/js/JSDOMWindowShell.h
r106783 r107445 59 59 static JSDOMWindowShell* create(PassRefPtr<DOMWindow> window, JSC::Structure* structure, DOMWrapperWorld* world) 60 60 { 61 JSDOMWindowShell* shell = new JSDOMWindowShell(structure, world); 61 JSC::Heap& heap = JSDOMWindow::commonJSGlobalData()->heap; 62 JSDOMWindowShell* shell = new (NotNull, JSC::allocateCell<JSDOMWindowShell>(heap)) JSDOMWindowShell(structure, world); 62 63 shell->finishCreation(*world->globalData(), window); 63 64 return shell; … … 76 77 77 78 private: 78 void* operator new(size_t);79 79 static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags; 80 80 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r107436 r107445 795 795 if (!$hasParent) { 796 796 push(@headerContent, " static void destroy(JSC::JSCell*);\n"); 797 push(@headerContent, " ~${className}();\n"); 797 798 } 798 799 … … 1341 1342 1342 1343 push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className);\n"); 1343 if ($interfaceName ne "DOMWindow" && !$dataNode->extendedAttributes->{"IsWorkerContext"}) {1344 push(@implContent, "ASSERT_HAS_TRIVIAL_DESTRUCTOR($className);\n\n");1345 }1346 1344 1347 1345 my $numAttributes = GenerateAttributesHashTable($object, $dataNode); … … 1616 1614 push(@implContent, "{\n"); 1617 1615 push(@implContent, " ${className}* thisObject = jsCast<${className}*>(cell);\n"); 1618 push(@implContent, " thisObject->releaseImplIfNotNull();\n"); 1616 push(@implContent, " thisObject->${className}::~${className}();\n"); 1617 push(@implContent, "}\n\n"); 1618 1619 # We also need a destructor for the allocateCell to work properly with the destructor-free part of the heap. 1620 # Otherwise, these destroy functions/destructors won't get called. 1621 push(@implContent, "${className}::~${className}()\n"); 1622 push(@implContent, "{\n"); 1623 push(@implContent, " releaseImplIfNotNull();\n"); 1619 1624 push(@implContent, "}\n\n"); 1620 1625 } … … 3371 3376 push(@$outputArray, "}\n\n"); 3372 3377 } else { 3373 push(@$outputArray, "ASSERT_HAS_TRIVIAL_DESTRUCTOR(${constructorClassName});\n\n");3374 3375 3378 push(@$outputArray, "const ClassInfo ${constructorClassName}::s_info = { \"${visibleClassName}Constructor\", &Base::s_info, &${constructorClassName}Table, 0, CREATE_METHOD_TABLE($constructorClassName) };\n\n"); 3376 3379 push(@$outputArray, "${constructorClassName}::${constructorClassName}(Structure* structure, JSDOMGlobalObject* globalObject)\n");
Note: See TracChangeset
for help on using the changeset viewer.