Changeset 130303 in webkit
- Timestamp:
- Oct 3, 2012 10:51:28 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 62 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
r128851 r130303 37 37 namespace JSC { 38 38 39 const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };39 const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) }; 40 40 41 41 JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback) 42 : JS NonFinalObject(globalObject->globalData(), structure)42 : JSDestructibleObject(globalObject->globalData(), structure) 43 43 , m_class(jsClass) 44 44 , m_callback(callback) -
trunk/Source/JavaScriptCore/API/JSCallbackConstructor.h
r128851 r130303 28 28 29 29 #include "JSObjectRef.h" 30 #include <runtime/JSObject.h>30 #include "runtime/JSDestructibleObject.h" 31 31 32 32 namespace JSC { 33 33 34 class JSCallbackConstructor : public JS NonFinalObject {34 class JSCallbackConstructor : public JSDestructibleObject { 35 35 public: 36 typedef JS NonFinalObject Base;36 typedef JSDestructibleObject Base; 37 37 38 38 static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback) -
trunk/Source/JavaScriptCore/API/JSCallbackObject.cpp
r128851 r130303 33 33 namespace JSC { 34 34 35 ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JS NonFinalObject>);35 ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSDestructibleObject>); 36 36 ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSGlobalObject>); 37 37 38 38 // Define the two types of JSCallbackObjects we support. 39 template <> const ClassInfo JSCallbackObject<JSNonFinalObject>::s_info = { "CallbackObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; 40 template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &JSGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; 39 template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; 40 template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; 41 42 template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction = true; 43 template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false; 44 45 template<> 46 JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) 47 { 48 JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(globalData.heap)) JSCallbackObject(globalData, classRef, structure); 49 callbackObject->finishCreation(globalData); 50 globalData.heap.addFinalizer(callbackObject, destroy); 51 return callbackObject; 52 } 41 53 42 54 template <> 43 Structure* JSCallbackObject<JS NonFinalObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)55 Structure* JSCallbackObject<JSDestructibleObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) 44 56 { 45 57 return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); -
trunk/Source/JavaScriptCore/API/JSCallbackObject.h
r129281 r130303 134 134 return callbackObject; 135 135 } 136 static JSCallbackObject* create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) 137 { 138 JSCallbackObject* callbackObject = new (NotNull, allocateCell<JSCallbackObject>(globalData.heap)) JSCallbackObject(globalData, classRef, structure); 139 callbackObject->finishCreation(globalData); 140 return callbackObject; 141 } 136 static JSCallbackObject<Parent>* create(JSGlobalData&, JSClassRef, Structure*); 137 138 static const bool needsDestruction; 139 static void destroy(JSCell*); 142 140 143 141 void setPrivate(void* data); … … 173 171 private: 174 172 static String className(const JSObject*); 175 176 static void destroy(JSCell*);177 173 178 174 static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); -
trunk/Source/JavaScriptCore/API/JSClassRef.cpp
r128851 r130303 200 200 201 201 // Recursive, but should be good enough for our purposes 202 JSObject* prototype = JSCallbackObject<JS NonFinalObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction202 JSObject* prototype = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction 203 203 if (parentClass) { 204 204 if (JSObject* parentPrototype = parentClass->prototype(exec)) -
trunk/Source/JavaScriptCore/API/JSObjectRef.cpp
r128851 r130303 84 84 return toRef(constructEmptyObject(exec)); 85 85 86 JSCallbackObject<JS NonFinalObject>* object = JSCallbackObject<JSNonFinalObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data);86 JSCallbackObject<JSDestructibleObject>* object = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data); 87 87 if (JSObject* prototype = jsClass->prototype(exec)) 88 88 object->setPrototype(exec->globalData(), prototype); … … 342 342 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) 343 343 return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate(); 344 if (jsObject->inherits(&JSCallbackObject<JS NonFinalObject>::s_info))345 return jsCast<JSCallbackObject<JS NonFinalObject>*>(jsObject)->getPrivate();344 if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) 345 return jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivate(); 346 346 347 347 return 0; … … 356 356 return true; 357 357 } 358 if (jsObject->inherits(&JSCallbackObject<JS NonFinalObject>::s_info)) {359 jsCast<JSCallbackObject<JS NonFinalObject>*>(jsObject)->setPrivate(data);358 if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { 359 jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data); 360 360 return true; 361 361 } … … 373 373 if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) 374 374 result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name); 375 else if (jsObject->inherits(&JSCallbackObject<JS NonFinalObject>::s_info))376 result = jsCast<JSCallbackObject<JS NonFinalObject>*>(jsObject)->getPrivateProperty(name);375 else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) 376 result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name); 377 377 return toRef(exec, result); 378 378 } … … 389 389 return true; 390 390 } 391 if (jsObject->inherits(&JSCallbackObject<JS NonFinalObject>::s_info)) {392 jsCast<JSCallbackObject<JS NonFinalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);391 if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { 392 jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); 393 393 return true; 394 394 } … … 406 406 return true; 407 407 } 408 if (jsObject->inherits(&JSCallbackObject<JS NonFinalObject>::s_info)) {409 jsCast<JSCallbackObject<JS NonFinalObject>*>(jsObject)->deletePrivateProperty(name);408 if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { 409 jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name); 410 410 return true; 411 411 } -
trunk/Source/JavaScriptCore/API/JSValueRef.cpp
r129281 r130303 132 132 if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) 133 133 return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass); 134 if (o->inherits(&JSCallbackObject<JS NonFinalObject>::s_info))135 return jsCast<JSCallbackObject<JS NonFinalObject>*>(o)->inherits(jsClass);134 if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) 135 return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass); 136 136 } 137 137 return false; -
trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
r128851 r130303 58 58 if (!obj) 59 59 return; 60 ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JS NonFinalObject>::s_info));60 ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)); 61 61 map->map().set(exec->globalData(), key, obj); 62 62 } -
trunk/Source/JavaScriptCore/ChangeLog
r130237 r130303 1 2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Delayed structure sweep can leak structures without bound 4 https://bugs.webkit.org/show_bug.cgi?id=96546 5 6 Reviewed by Geoffrey Garen. 7 8 This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only 9 allocators. We now have separate allocators for our three types of objects: those objects with no destructors, 10 those objects with destructors and with immortal structures, and those objects with destructors that don't have 11 immortal structures. All of the objects of the third type (destructors without immortal structures) now 12 inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores 13 the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. 14 15 * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor. 16 (JSC): 17 (JSC::JSCallbackConstructor::JSCallbackConstructor): 18 * API/JSCallbackConstructor.h: 19 (JSCallbackConstructor): 20 * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for 21 JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer. 22 (JSC): 23 (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add 24 the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides 25 to subclass this. We use this same technique for many other subclasses of JSGlobalObject. 26 (JSC::::createStructure): 27 * API/JSCallbackObject.h: 28 (JSCallbackObject): 29 (JSC): 30 * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead. 31 (OpaqueJSClass::prototype): 32 * API/JSObjectRef.cpp: Ditto. 33 (JSObjectMake): 34 (JSObjectGetPrivate): 35 (JSObjectSetPrivate): 36 (JSObjectGetPrivateProperty): 37 (JSObjectSetPrivateProperty): 38 (JSObjectDeletePrivateProperty): 39 * API/JSValueRef.cpp: Ditto. 40 (JSValueIsObjectOfClass): 41 * API/JSWeakObjectMapRefPrivate.cpp: Ditto. 42 * JSCTypedArrayStubs.h: 43 (JSC): 44 * JavaScriptCore.xcodeproj/project.pbxproj: 45 * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG. 46 (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): 47 (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): 48 * heap/Heap.cpp: 49 (JSC): 50 * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function 51 since it's always safe to sweep Structures now. 52 (JSC::Heap::allocatorForObjectWithNormalDestructor): 53 (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): 54 (Heap): 55 (JSC::Heap::allocateWithNormalDestructor): 56 (JSC): 57 (JSC::Heap::allocateWithImmortalStructureDestructor): 58 * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the 59 IncrementalSweeper since it's always safe to sweep Structures now. 60 (JSC::IncrementalSweeper::IncrementalSweeper): 61 (JSC::IncrementalSweeper::sweepNextBlock): 62 (JSC::IncrementalSweeper::startSweeping): 63 (JSC::IncrementalSweeper::willFinishSweeping): 64 (JSC): 65 * heap/IncrementalSweeper.h: 66 (IncrementalSweeper): 67 * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add 68 tracking of the specific destructor type of allocator. 69 (JSC::MarkedAllocator::tryAllocateHelper): 70 (JSC::MarkedAllocator::allocateBlock): 71 * heap/MarkedAllocator.h: 72 (JSC::MarkedAllocator::destructorType): 73 (MarkedAllocator): 74 (JSC::MarkedAllocator::MarkedAllocator): 75 (JSC::MarkedAllocator::init): 76 * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping. 77 We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls. 78 (JSC::MarkedBlock::create): 79 (JSC::MarkedBlock::MarkedBlock): 80 (JSC): 81 (JSC::MarkedBlock::specializedSweep): 82 (JSC::MarkedBlock::sweep): 83 (JSC::MarkedBlock::sweepHelper): 84 * heap/MarkedBlock.h: 85 (JSC): 86 (JSC::MarkedBlock::allocator): 87 (JSC::MarkedBlock::destructorType): 88 * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace. 89 (JSC::MarkedSpace::MarkedSpace): 90 (JSC::MarkedSpace::resetAllocators): 91 (JSC::MarkedSpace::canonicalizeCellLivenessData): 92 (JSC::MarkedSpace::isPagedOut): 93 (JSC::MarkedSpace::freeBlock): 94 * heap/MarkedSpace.h: 95 (MarkedSpace): 96 (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): 97 (JSC::MarkedSpace::normalDestructorAllocatorFor): 98 (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): 99 (JSC::MarkedSpace::allocateWithNormalDestructor): 100 (JSC::MarkedSpace::forEachBlock): 101 * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function. 102 * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT. 103 * jit/JITInlineMethods.h: 104 (JSC::JIT::emitAllocateBasicJSObject): 105 (JSC::JIT::emitAllocateJSFinalObject): 106 (JSC::JIT::emitAllocateJSArray): 107 * jsc.cpp: 108 (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from 109 JSDestructibleObject. 110 * runtime/Arguments.cpp: Inherit from JSDestructibleObject. 111 (JSC): 112 * runtime/Arguments.h: 113 (Arguments): 114 (JSC::Arguments::Arguments): 115 * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor. 116 (JSC): 117 * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures. 118 (JSC): 119 * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject. 120 (JSC): 121 (JSC::InternalFunction::InternalFunction): 122 * runtime/InternalFunction.h: 123 (InternalFunction): 124 * runtime/JSCell.h: Added two static bools, needsDestruction and hasImmortalStructure, that classes can override 125 to indicate at compile time which part of the heap they should be allocated in. 126 (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. 127 * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be 128 accessed safely when the object is being destroyed. 129 (JSC): 130 (JSDestructibleObject): 131 (JSC::JSDestructibleObject::classInfo): 132 (JSC::JSDestructibleObject::JSDestructibleObject): 133 (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. 134 * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all 135 of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. 136 (JSC::JSGlobalObject::reset): 137 * runtime/JSGlobalObject.h: 138 (JSGlobalObject): 139 (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one 140 for the m_rareData field when it's created. 141 (JSC::JSGlobalObject::create): 142 (JSC): 143 * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. 144 (JSGlobalThis): 145 (JSC::JSGlobalThis::JSGlobalThis): 146 * runtime/JSPropertyNameIterator.h: Has an immortal Structure. 147 (JSC): 148 * runtime/JSScope.cpp: 149 (JSC): 150 * runtime/JSString.h: Has an immortal Structure. 151 (JSC): 152 * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. 153 (JSWrapperObject): 154 (JSC::JSWrapperObject::JSWrapperObject): 155 * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. 156 (JSC): 157 * runtime/NameInstance.h: Inherit from JSDestructibleObject. 158 (NameInstance): 159 * runtime/RegExp.h: Has immortal Structure. 160 (JSC): 161 * runtime/RegExpObject.cpp: Inheritance cleanup. 162 (JSC): 163 * runtime/SparseArrayValueMap.h: Has immortal Structure. 164 (JSC): 165 * runtime/Structure.h: Has immortal Structure. 166 (JSC): 167 * runtime/StructureChain.h: Ditto. 168 (JSC): 169 * runtime/SymbolTable.h: Ditto. 170 (SharedSymbolTable): 171 (JSC): 172 1 173 == Rolled over to ChangeLog-2012-10-02 == -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r129713 r130303 536 536 Source/JavaScriptCore/runtime/JSDateMath.cpp \ 537 537 Source/JavaScriptCore/runtime/JSDateMath.h \ 538 Source/JavaScriptCore/runtime/JSDestructibleObject.h \ 538 539 Source/JavaScriptCore/runtime/JSFunction.cpp \ 539 540 Source/JavaScriptCore/runtime/JSFunction.h \ -
trunk/Source/JavaScriptCore/JSCTypedArrayStubs.h
r128957 r130303 27 27 #define JSCTypedArrayStubs_h 28 28 29 #include "JS Object.h"29 #include "JSDestructibleObject.h" 30 30 #include "ObjectPrototype.h" 31 31 #include <wtf/Float32Array.h> … … 43 43 44 44 #define TYPED_ARRAY(name, type) \ 45 class JS##name##Array : public JS NonFinalObject { \45 class JS##name##Array : public JSDestructibleObject { \ 46 46 public: \ 47 typedef JS NonFinalObject Base; \47 typedef JSDestructibleObject Base; \ 48 48 static JS##name##Array* create(JSC::Structure* structure, JSGlobalObject* globalObject, PassRefPtr<name##Array> impl) \ 49 49 { \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
r129713 r130303 843 843 </File> 844 844 <File 845 RelativePath="..\..\runtime\JSDestructibleObject.h" 846 > 847 </File> 848 <File 845 849 RelativePath="..\..\runtime\JSFunction.cpp" 846 850 > -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r129713 r130303 713 713 C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; }; 714 714 C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */ = {isa = PBXBuildFile; fileRef = C25F8BCC157544A900245B71 /* IncrementalSweeper.h */; settings = {ATTRIBUTES = (Private, ); }; }; 715 C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A7F687160432D400F76B98 /* JSDestructibleObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; 715 716 C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 716 717 C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */; }; … … 1488 1489 C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; }; 1489 1490 C25F8BCC157544A900245B71 /* IncrementalSweeper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncrementalSweeper.h; sourceTree = "<group>"; }; 1491 C2A7F687160432D400F76B98 /* JSDestructibleObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObject.h; sourceTree = "<group>"; }; 1490 1492 C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocator.h; sourceTree = "<group>"; }; 1491 1493 C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedAllocator.cpp; sourceTree = "<group>"; }; … … 2131 2133 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */, 2132 2134 9788FC231471AD0C0068CE2D /* JSDateMath.h */, 2135 C2A7F687160432D400F76B98 /* JSDestructibleObject.h */, 2133 2136 A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */, 2134 2137 F692A85E0255597D01FF60F7 /* JSFunction.cpp */, … … 2570 2573 C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */, 2571 2574 C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */, 2575 C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */, 2572 2576 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */, 2573 2577 C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r128957 r130303 2190 2190 // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will 2191 2191 // get clobbered. 2192 template <typename ClassType, bool destructor, typename StructureType>2192 template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> 2193 2193 void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) 2194 2194 { 2195 2195 MarkedAllocator* allocator = 0; 2196 if (destructor) 2197 allocator = &m_jit.globalData()->heap.allocatorForObjectWithDestructor(sizeof(ClassType)); 2196 if (destructorType == MarkedBlock::Normal) 2197 allocator = &m_jit.globalData()->heap.allocatorForObjectWithNormalDestructor(sizeof(ClassType)); 2198 else if (destructorType == MarkedBlock::ImmortalStructure) 2199 allocator = &m_jit.globalData()->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(ClassType)); 2198 2200 else 2199 2201 allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType)); … … 2217 2219 void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) 2218 2220 { 2219 return emitAllocateBasicJSObject<JSFinalObject, false>(structure, resultGPR, scratchGPR, slowPath);2221 return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, slowPath); 2220 2222 } 2221 2223 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r129586 r130303 943 943 } 944 944 945 bool Heap::isSafeToSweepStructures()946 {947 return !m_sweeper || m_sweeper->structuresCanBeSwept();948 }949 950 945 void Heap::didStartVMShutdown() 951 946 { -
trunk/Source/JavaScriptCore/heap/Heap.h
r129586 r130303 113 113 MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); } 114 114 MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } 115 MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); } 115 MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); } 116 MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); } 116 117 CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); } 117 118 CheckedBoolean tryAllocateStorage(size_t, void**); … … 170 171 171 172 bool isPagedOut(double deadline); 172 bool isSafeToSweepStructures();173 173 void didStartVMShutdown(); 174 174 … … 186 186 template<typename T> friend void* allocateCell(Heap&, size_t); 187 187 188 void* allocateWith Destructor(size_t);189 void* allocateWith outDestructor(size_t);190 void* allocate Structure(size_t);188 void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die. 189 void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject. 190 void* allocateWithoutDestructor(size_t); // For use with objects without destructors. 191 191 192 192 static const size_t minExtraCost = 256; … … 364 364 } 365 365 366 inline void* Heap::allocateWith Destructor(size_t bytes)366 inline void* Heap::allocateWithNormalDestructor(size_t bytes) 367 367 { 368 368 ASSERT(isValidAllocation(bytes)); 369 return m_objectSpace.allocateWithDestructor(bytes); 369 return m_objectSpace.allocateWithNormalDestructor(bytes); 370 } 371 372 inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes) 373 { 374 ASSERT(isValidAllocation(bytes)); 375 return m_objectSpace.allocateWithImmortalStructureDestructor(bytes); 370 376 } 371 377 … … 376 382 } 377 383 378 inline void* Heap::allocateStructure(size_t bytes)379 {380 return m_objectSpace.allocateStructure(bytes);381 }382 383 384 inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr) 384 385 { -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
r128851 r130303 49 49 : HeapTimer(heap->globalData(), runLoop) 50 50 , m_currentBlockToSweepIndex(0) 51 , m_structuresCanBeSwept(false)52 51 { 53 52 } … … 73 72 : HeapTimer(heap->globalData()) 74 73 , m_currentBlockToSweepIndex(0) 75 , m_structuresCanBeSwept(false)76 74 { 77 75 } … … 120 118 while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { 121 119 MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; 122 if (block->onlyContainsStructures())123 m_structuresCanBeSwept = true;124 else125 ASSERT(!m_structuresCanBeSwept);126 120 127 121 if (!block->needsSweeping()) … … 140 134 m_globalData->heap.objectSpace().forEachBlock(functor); 141 135 m_currentBlockToSweepIndex = 0; 142 m_structuresCanBeSwept = false;143 136 scheduleTimer(); 144 137 } … … 147 140 { 148 141 m_currentBlockToSweepIndex = 0; 149 m_structuresCanBeSwept = true;150 142 m_blocksToSweep.clear(); 151 143 if (m_globalData) … … 157 149 IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) 158 150 : HeapTimer(globalData) 159 , m_structuresCanBeSwept(false)160 151 { 161 152 } … … 172 163 void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&) 173 164 { 174 m_structuresCanBeSwept = false;175 165 } 176 166 177 167 void IncrementalSweeper::willFinishSweeping() 178 168 { 179 m_structuresCanBeSwept = true;180 169 } 181 170 … … 186 175 #endif 187 176 188 bool IncrementalSweeper::structuresCanBeSwept()189 {190 return m_structuresCanBeSwept;191 }192 193 177 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h
r128851 r130303 57 57 virtual void doWork(); 58 58 void sweepNextBlock(); 59 bool structuresCanBeSwept();60 59 void willFinishSweeping(); 61 60 … … 79 78 80 79 #endif 81 bool m_structuresCanBeSwept;82 80 }; 83 81 -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp
r128851 r130303 31 31 { 32 32 if (!m_freeList.head) { 33 if (m_onlyContainsStructures && !m_heap->isSafeToSweepStructures()) {34 if (m_currentBlock) {35 m_currentBlock->didConsumeFreeList();36 m_currentBlock = 0;37 }38 // We sweep another random block here so that we can make progress39 // toward being able to sweep Structures.40 m_heap->sweeper()->sweepNextBlock();41 return 0;42 }43 44 33 for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) { 45 34 MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList); … … 125 114 if (blockSize == MarkedBlock::blockSize) { 126 115 PageAllocationAligned allocation = m_heap->blockAllocator().allocate(); 127 return MarkedBlock::create(allocation, m_heap, cellSize, m_cellsNeedDestruction, m_onlyContainsStructures);116 return MarkedBlock::create(allocation, this, cellSize, m_destructorType); 128 117 } 129 118 … … 131 120 if (!static_cast<bool>(allocation)) 132 121 CRASH(); 133 return MarkedBlock::create(allocation, m_heap, cellSize, m_cellsNeedDestruction, m_onlyContainsStructures);122 return MarkedBlock::create(allocation, this, cellSize, m_destructorType); 134 123 } 135 124 -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r128851 r130303 24 24 void canonicalizeCellLivenessData(); 25 25 size_t cellSize() { return m_cellSize; } 26 bool cellsNeedDestruction() { return m_cellsNeedDestruction; } 27 bool onlyContainsStructures() { return m_onlyContainsStructures; } 26 MarkedBlock::DestructorType destructorType() { return m_destructorType; } 28 27 void* allocate(size_t); 29 28 Heap* heap() { return m_heap; } … … 33 32 void addBlock(MarkedBlock*); 34 33 void removeBlock(MarkedBlock*); 35 void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);34 void init(Heap*, MarkedSpace*, size_t cellSize, MarkedBlock::DestructorType); 36 35 37 36 bool isPagedOut(double deadline); … … 50 49 DoublyLinkedList<MarkedBlock> m_blockList; 51 50 size_t m_cellSize; 52 bool m_cellsNeedDestruction; 53 bool m_onlyContainsStructures; 51 MarkedBlock::DestructorType m_destructorType; 54 52 Heap* m_heap; 55 53 MarkedSpace* m_markedSpace; … … 60 58 , m_blocksToSweep(0) 61 59 , m_cellSize(0) 62 , m_cellsNeedDestruction(true) 63 , m_onlyContainsStructures(false) 60 , m_destructorType(MarkedBlock::None) 64 61 , m_heap(0) 65 62 , m_markedSpace(0) … … 67 64 } 68 65 69 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)66 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType) 70 67 { 71 68 m_heap = heap; 72 69 m_markedSpace = markedSpace; 73 70 m_cellSize = cellSize; 74 m_cellsNeedDestruction = cellsNeedDestruction; 75 m_onlyContainsStructures = onlyContainsStructures; 71 m_destructorType = destructorType; 76 72 } 77 73 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r128851 r130303 29 29 #include "IncrementalSweeper.h" 30 30 #include "JSCell.h" 31 #include "JS Object.h"31 #include "JSDestructibleObject.h" 32 32 33 33 34 34 namespace JSC { 35 35 36 MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)36 MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType) 37 37 { 38 return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures);38 return new (NotNull, allocation.base()) MarkedBlock(allocation, allocator, cellSize, destructorType); 39 39 } 40 40 41 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)41 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType) 42 42 : HeapBlock<MarkedBlock>(allocation) 43 43 , m_atomsPerCell((cellSize + atomSize - 1) / atomSize) 44 44 , m_endAtom(atomsPerBlock - m_atomsPerCell + 1) 45 , m_ cellsNeedDestruction(cellsNeedDestruction)46 , m_ onlyContainsStructures(onlyContainsStructures)45 , m_destructorType(destructorType) 46 , m_allocator(allocator) 47 47 , m_state(New) // All cells start out unmarked. 48 , m_weakSet( heap->globalData())48 , m_weakSet(allocator->heap()->globalData()) 49 49 { 50 ASSERT( heap);50 ASSERT(allocator); 51 51 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 52 52 } … … 66 66 } 67 67 68 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool destructorCallNeeded>68 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, MarkedBlock::DestructorType dtorType> 69 69 MarkedBlock::FreeList MarkedBlock::specializedSweep() 70 70 { 71 71 ASSERT(blockState != Allocated && blockState != FreeListed); 72 ASSERT( destructorCallNeeded || sweepMode != SweepOnly);72 ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly)); 73 73 74 74 // This produces a free list that is ordered in reverse through the block. … … 83 83 JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); 84 84 85 if (d estructorCallNeeded&& blockState != New)85 if (dtorType != MarkedBlock::None && blockState != New) 86 86 callDestructor(cell); 87 87 … … 104 104 m_weakSet.sweep(); 105 105 106 if (sweepMode == SweepOnly && !m_cellsNeedDestruction)106 if (sweepMode == SweepOnly && m_destructorType == MarkedBlock::None) 107 107 return FreeList(); 108 108 109 if (m_cellsNeedDestruction) 110 return sweepHelper<true>(sweepMode); 111 return sweepHelper<false>(sweepMode); 109 if (m_destructorType == MarkedBlock::ImmortalStructure) 110 return sweepHelper<MarkedBlock::ImmortalStructure>(sweepMode); 111 if (m_destructorType == MarkedBlock::Normal) 112 return sweepHelper<MarkedBlock::Normal>(sweepMode); 113 return sweepHelper<MarkedBlock::None>(sweepMode); 112 114 } 113 115 114 template< bool destructorCallNeeded>116 template<MarkedBlock::DestructorType dtorType> 115 117 MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode) 116 118 { … … 118 120 case New: 119 121 ASSERT(sweepMode == SweepToFreeList); 120 return specializedSweep<New, SweepToFreeList, d estructorCallNeeded>();122 return specializedSweep<New, SweepToFreeList, dtorType>(); 121 123 case FreeListed: 122 124 // Happens when a block transitions to fully allocated. … … 127 129 return FreeList(); 128 130 case Marked: 129 ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures());130 131 return sweepMode == SweepToFreeList 131 ? specializedSweep<Marked, SweepToFreeList, d estructorCallNeeded>()132 : specializedSweep<Marked, SweepOnly, d estructorCallNeeded>();132 ? specializedSweep<Marked, SweepToFreeList, dtorType>() 133 : specializedSweep<Marked, SweepOnly, dtorType>(); 133 134 } 134 135 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r128851 r130303 53 53 class Heap; 54 54 class JSCell; 55 class MarkedAllocator; 55 56 56 57 typedef uintptr_t Bits; … … 113 114 }; 114 115 115 static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures); 116 enum DestructorType { None, ImmortalStructure, Normal }; 117 static MarkedBlock* create(const PageAllocationAligned&, MarkedAllocator*, size_t cellSize, DestructorType); 116 118 117 119 static bool isAtomAligned(const void*); … … 121 123 void lastChanceToFinalize(); 122 124 125 MarkedAllocator* allocator() const; 123 126 Heap* heap() const; 124 127 JSGlobalData* globalData() const; … … 144 147 145 148 size_t cellSize(); 146 bool cellsNeedDestruction(); 147 bool onlyContainsStructures(); 149 DestructorType destructorType(); 148 150 149 151 size_t size(); … … 195 197 196 198 enum BlockState { New, FreeListed, Allocated, Marked }; 197 template< bool destructorCallNeeded> FreeList sweepHelper(SweepMode = SweepOnly);199 template<DestructorType> FreeList sweepHelper(SweepMode = SweepOnly); 198 200 199 201 typedef char Atom[atomSize]; 200 202 201 MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);203 MarkedBlock(const PageAllocationAligned&, MarkedAllocator*, size_t cellSize, DestructorType); 202 204 Atom* atoms(); 203 205 size_t atomNumber(const void*); 204 206 void callDestructor(JSCell*); 205 template<BlockState, SweepMode, bool destructorCallNeeded> FreeList specializedSweep();207 template<BlockState, SweepMode, DestructorType> FreeList specializedSweep(); 206 208 207 209 #if ENABLE(GGC) … … 216 218 WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks; 217 219 #endif 218 bool m_cellsNeedDestruction;219 bool m_onlyContainsStructures;220 DestructorType m_destructorType; 221 MarkedAllocator* m_allocator; 220 222 BlockState m_state; 221 223 WeakSet m_weakSet; … … 262 264 } 263 265 266 inline MarkedAllocator* MarkedBlock::allocator() const 267 { 268 return m_allocator; 269 } 270 264 271 inline Heap* MarkedBlock::heap() const 265 272 { … … 327 334 } 328 335 329 inline bool MarkedBlock::cellsNeedDestruction() 330 { 331 return m_cellsNeedDestruction; 332 } 333 334 inline bool MarkedBlock::onlyContainsStructures() 335 { 336 return m_onlyContainsStructures; 336 inline MarkedBlock::DestructorType MarkedBlock::destructorType() 337 { 338 return m_destructorType; 337 339 } 338 340 -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r128851 r130303 82 82 { 83 83 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 84 allocatorFor(cellSize).init(heap, this, cellSize, false, false); 85 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false); 86 } 87 88 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 89 allocatorFor(cellSize).init(heap, this, cellSize, false, false); 90 destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false); 91 } 92 93 m_largeAllocator.init(heap, this, 0, true, false); 94 m_structureAllocator.init(heap, this, WTF::roundUpToMultipleOf(32, sizeof(Structure)), true, true); 84 allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None); 85 normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal); 86 immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure); 87 } 88 89 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 90 allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None); 91 normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal); 92 immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure); 93 } 94 95 m_normalSpace.largeAllocator.init(heap, this, 0, MarkedBlock::None); 96 m_normalDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::Normal); 97 m_immortalStructureDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::ImmortalStructure); 95 98 } 96 99 … … 121 124 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 122 125 allocatorFor(cellSize).reset(); 123 destructorAllocatorFor(cellSize).reset(); 126 normalDestructorAllocatorFor(cellSize).reset(); 127 immortalStructureDestructorAllocatorFor(cellSize).reset(); 124 128 } 125 129 126 130 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 127 131 allocatorFor(cellSize).reset(); 128 destructorAllocatorFor(cellSize).reset(); 129 } 130 131 m_largeAllocator.reset(); 132 m_structureAllocator.reset(); 132 normalDestructorAllocatorFor(cellSize).reset(); 133 immortalStructureDestructorAllocatorFor(cellSize).reset(); 134 } 135 136 m_normalSpace.largeAllocator.reset(); 137 m_normalDestructorSpace.largeAllocator.reset(); 138 m_immortalStructureDestructorSpace.largeAllocator.reset(); 133 139 } 134 140 … … 148 154 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 149 155 allocatorFor(cellSize).canonicalizeCellLivenessData(); 150 destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 156 normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 157 immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 151 158 } 152 159 153 160 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 154 161 allocatorFor(cellSize).canonicalizeCellLivenessData(); 155 destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 156 } 157 158 m_largeAllocator.canonicalizeCellLivenessData(); 159 m_structureAllocator.canonicalizeCellLivenessData(); 162 normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 163 immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); 164 } 165 166 m_normalSpace.largeAllocator.canonicalizeCellLivenessData(); 167 m_normalDestructorSpace.largeAllocator.canonicalizeCellLivenessData(); 168 m_immortalStructureDestructorSpace.largeAllocator.canonicalizeCellLivenessData(); 160 169 } 161 170 … … 163 172 { 164 173 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 165 if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline)) 174 if (allocatorFor(cellSize).isPagedOut(deadline) 175 || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 176 || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline)) 166 177 return true; 167 178 } 168 179 169 180 for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 170 if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline)) 181 if (allocatorFor(cellSize).isPagedOut(deadline) 182 || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) 183 || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline)) 171 184 return true; 172 185 } 173 186 174 if (m_largeAllocator.isPagedOut(deadline)) 187 if (m_normalSpace.largeAllocator.isPagedOut(deadline) 188 || m_normalDestructorSpace.largeAllocator.isPagedOut(deadline) 189 || m_immortalStructureDestructorSpace.largeAllocator.isPagedOut(deadline)) 175 190 return true; 176 191 177 if (m_structureAllocator.isPagedOut(deadline))178 return true;179 180 192 return false; 181 193 } … … 183 195 void MarkedSpace::freeBlock(MarkedBlock* block) 184 196 { 185 allocatorFor(block).removeBlock(block);197 block->allocator()->removeBlock(block); 186 198 m_blocks.remove(block); 187 199 if (block->capacity() == MarkedBlock::blockSize) { -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r129586 r130303 77 77 MarkedAllocator& firstAllocator(); 78 78 MarkedAllocator& allocatorFor(size_t); 79 MarkedAllocator& allocatorFor(MarkedBlock*); 80 MarkedAllocator& destructorAllocatorFor(size_t); 81 void* allocateWithDestructor(size_t); 79 MarkedAllocator& immortalStructureDestructorAllocatorFor(size_t); 80 MarkedAllocator& normalDestructorAllocatorFor(size_t); 81 void* allocateWithNormalDestructor(size_t); 82 void* allocateWithImmortalStructureDestructor(size_t); 82 83 void* allocateWithoutDestructor(size_t); 83 void* allocateStructure(size_t);84 84 85 85 void resetAllocators(); … … 132 132 FixedArray<MarkedAllocator, preciseCount> preciseAllocators; 133 133 FixedArray<MarkedAllocator, impreciseCount> impreciseAllocators; 134 MarkedAllocator largeAllocator; 134 135 }; 135 136 136 Subspace m_destructorSpace; 137 Subspace m_normalDestructorSpace; 138 Subspace m_immortalStructureDestructorSpace; 137 139 Subspace m_normalSpace; 138 MarkedAllocator m_largeAllocator;139 MarkedAllocator m_structureAllocator;140 140 141 141 Heap* m_heap; … … 187 187 if (bytes <= impreciseCutoff) 188 188 return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 189 return m_largeAllocator; 190 } 191 192 inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block) 193 { 194 if (block->onlyContainsStructures()) 195 return m_structureAllocator; 196 197 if (block->cellsNeedDestruction()) 198 return destructorAllocatorFor(block->cellSize()); 199 200 return allocatorFor(block->cellSize()); 201 } 202 203 inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes) 189 return m_normalSpace.largeAllocator; 190 } 191 192 inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes) 204 193 { 205 194 ASSERT(bytes); 206 195 if (bytes <= preciseCutoff) 207 return m_ destructorSpace.preciseAllocators[(bytes - 1) / preciseStep];196 return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; 208 197 if (bytes <= impreciseCutoff) 209 return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 210 return m_largeAllocator; 198 return m_immortalStructureDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 199 return m_immortalStructureDestructorSpace.largeAllocator; 200 } 201 202 inline MarkedAllocator& MarkedSpace::normalDestructorAllocatorFor(size_t bytes) 203 { 204 ASSERT(bytes); 205 if (bytes <= preciseCutoff) 206 return m_normalDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; 207 if (bytes <= impreciseCutoff) 208 return m_normalDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 209 return m_normalDestructorSpace.largeAllocator; 211 210 } 212 211 … … 216 215 } 217 216 218 inline void* MarkedSpace::allocateWith Destructor(size_t bytes)219 { 220 return destructorAllocatorFor(bytes).allocate(bytes);221 } 222 223 inline void* MarkedSpace::allocate Structure(size_t bytes)224 { 225 return m_structureAllocator.allocate(bytes);217 inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes) 218 { 219 return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes); 220 } 221 222 inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes) 223 { 224 return normalDestructorAllocatorFor(bytes).allocate(bytes); 226 225 } 227 226 … … 230 229 for (size_t i = 0; i < preciseCount; ++i) { 231 230 m_normalSpace.preciseAllocators[i].forEachBlock(functor); 232 m_destructorSpace.preciseAllocators[i].forEachBlock(functor); 231 m_normalDestructorSpace.preciseAllocators[i].forEachBlock(functor); 232 m_immortalStructureDestructorSpace.preciseAllocators[i].forEachBlock(functor); 233 233 } 234 234 235 235 for (size_t i = 0; i < impreciseCount; ++i) { 236 236 m_normalSpace.impreciseAllocators[i].forEachBlock(functor); 237 m_destructorSpace.impreciseAllocators[i].forEachBlock(functor); 237 m_normalDestructorSpace.impreciseAllocators[i].forEachBlock(functor); 238 m_immortalStructureDestructorSpace.impreciseAllocators[i].forEachBlock(functor); 238 239 } 239 240 240 m_largeAllocator.forEachBlock(functor); 241 m_structureAllocator.forEachBlock(functor); 241 m_normalSpace.largeAllocator.forEachBlock(functor); 242 m_normalDestructorSpace.largeAllocator.forEachBlock(functor); 243 m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor); 242 244 243 245 return functor.returnValue(); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r128851 r130303 6 6 #include "CopiedSpaceInlineMethods.h" 7 7 #include "JSArray.h" 8 #include "JSDestructibleObject.h" 8 9 #include "JSGlobalData.h" 9 10 #include "JSObject.h" -
trunk/Source/JavaScriptCore/jit/JIT.h
r129045 r130303 435 435 void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind); 436 436 437 template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);437 template<typename ClassType, MarkedBlock::DestructorType, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr); 438 438 void emitAllocateBasicStorage(size_t, ptrdiff_t offsetFromBase, RegisterID result); 439 439 template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); -
trunk/Source/JavaScriptCore/jit/JITInlineMethods.h
r129281 r130303 406 406 } 407 407 408 template <typename ClassType, bool destructor, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr)408 template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr) 409 409 { 410 410 MarkedAllocator* allocator = 0; 411 if (destructor) 412 allocator = &m_globalData->heap.allocatorForObjectWithDestructor(sizeof(ClassType)); 411 if (destructorType == MarkedBlock::Normal) 412 allocator = &m_globalData->heap.allocatorForObjectWithNormalDestructor(sizeof(ClassType)); 413 else if (destructorType == MarkedBlock::ImmortalStructure) 414 allocator = &m_globalData->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(ClassType)); 413 415 else 414 416 allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType)); … … 429 431 template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch) 430 432 { 431 emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch);433 emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None, T>(structure, result, scratch); 432 434 } 433 435 … … 455 457 // Allocate the cell for the array. 456 458 loadPtr(m_codeBlock->globalObject()->addressOfArrayStructure(), scratch); 457 emitAllocateBasicJSObject<JSArray, false>(scratch, cellResult, storagePtr);459 emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(scratch, cellResult, storagePtr); 458 460 459 461 // Store all the necessary info in the ArrayStorage. -
trunk/Source/JavaScriptCore/jsc.cpp
r129719 r130303 178 178 GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure); 179 179 object->finishCreation(globalData, arguments); 180 globalData.heap.addFinalizer(object, destroy); 180 181 object->setGlobalThis(globalData, JSProxy::create(globalData, JSProxy::createStructure(globalData, object, object->prototype()), object)); 181 182 return object; 182 183 } 184 185 static const bool needsDestruction = false; 183 186 184 187 static const ClassInfo s_info; … … 246 249 } 247 250 }; 251 248 252 COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false); 249 253 ASSERT_CLASS_FITS_IN_CELL(GlobalObject); -
trunk/Source/JavaScriptCore/runtime/Arguments.cpp
r129297 r130303 36 36 ASSERT_CLASS_FITS_IN_CELL(Arguments); 37 37 38 const ClassInfo Arguments::s_info = { "Arguments", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };38 const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; 39 39 40 40 void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) -
trunk/Source/JavaScriptCore/runtime/Arguments.h
r129297 r130303 27 27 #include "CodeOrigin.h" 28 28 #include "JSActivation.h" 29 #include "JSDestructibleObject.h" 29 30 #include "JSFunction.h" 30 31 #include "JSGlobalObject.h" … … 34 35 namespace JSC { 35 36 36 class Arguments : public JS NonFinalObject {37 class Arguments : public JSDestructibleObject { 37 38 friend class JIT; 38 39 friend class DFG::SpeculativeJIT; 39 40 public: 40 typedef JS NonFinalObject Base;41 typedef JSDestructibleObject Base; 41 42 42 43 static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame) … … 148 149 149 150 inline Arguments::Arguments(CallFrame* callFrame) 150 : JS NonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())151 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 151 152 { 152 153 } 153 154 154 155 inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) 155 : JS NonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())156 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 156 157 { 157 158 } -
trunk/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
r128851 r130303 32 32 33 33 ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype); 34 ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorPrototype); 34 35 35 36 static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*); -
trunk/Source/JavaScriptCore/runtime/Executable.h
r129453 r130303 82 82 83 83 #if ENABLE(JIT) 84 static const bool needsDestruction = true; 85 static const bool hasImmortalStructure = true; 84 86 static void destroy(JSCell*); 85 87 #endif -
trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp
r128851 r130303 33 33 ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction); 34 34 35 const ClassInfo InternalFunction::s_info = { "Function", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };35 const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) }; 36 36 37 37 InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure) 38 : JS NonFinalObject(globalObject->globalData(), structure)38 : JSDestructibleObject(globalObject->globalData(), structure) 39 39 { 40 40 } -
trunk/Source/JavaScriptCore/runtime/InternalFunction.h
r128851 r130303 25 25 #define InternalFunction_h 26 26 27 #include "JSObject.h"28 27 #include "Identifier.h" 28 #include "JSDestructibleObject.h" 29 29 30 30 namespace JSC { … … 32 32 class FunctionPrototype; 33 33 34 class InternalFunction : public JS NonFinalObject {34 class InternalFunction : public JSDestructibleObject { 35 35 public: 36 typedef JS NonFinalObject Base;36 typedef JSDestructibleObject Base; 37 37 38 38 static JS_EXPORTDATA const ClassInfo s_info; -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r129281 r130303 38 38 namespace JSC { 39 39 40 class JSDestructibleObject; 40 41 class JSGlobalObject; 41 42 class LLIntOffsetsExtractor; … … 71 72 static const unsigned StructureFlags = 0; 72 73 74 static const bool needsDestruction = false; 75 static const bool hasImmortalStructure = false; 76 73 77 enum CreatingEarlyCellTag { CreatingEarlyCell }; 74 78 JSCell(CreatingEarlyCellTag); … … 310 314 } 311 315 312 template<class T>313 struct NeedsDestructor {314 static const bool value = !WTF::HasTrivialDestructor<T>::value;315 };316 317 template<typename T>318 void* allocateCell(Heap& heap)319 {320 #if ENABLE(GC_VALIDATION)321 ASSERT(!heap.globalData()->isInitializingObject());322 heap.globalData()->setInitializingObjectClass(&T::s_info);323 #endif324 JSCell* result = 0;325 if (NeedsDestructor<T>::value)326 result = static_cast<JSCell*>(heap.allocateWithDestructor(sizeof(T)));327 else {328 ASSERT(T::s_info.methodTable.destroy == JSCell::destroy);329 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(sizeof(T)));330 }331 result->clearStructure();332 return result;333 }334 335 316 template<typename T> 336 317 void* allocateCell(Heap& heap, size_t size) … … 342 323 #endif 343 324 JSCell* result = 0; 344 if (NeedsDestructor<T>::value) 345 result = static_cast<JSCell*>(heap.allocateWithDestructor(size)); 346 else { 347 ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); 325 if (T::needsDestruction && T::hasImmortalStructure) 326 result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size)); 327 else if (T::needsDestruction && !T::hasImmortalStructure) 328 result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size)); 329 else 348 330 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size)); 349 }350 331 result->clearStructure(); 351 332 return result; 352 333 } 353 334 335 template<typename T> 336 void* allocateCell(Heap& heap) 337 { 338 return allocateCell<T>(heap, sizeof(T)); 339 } 340 354 341 inline bool isZapped(const JSCell* cell) 355 342 { … … 363 350 return static_cast<To>(from); 364 351 } 365 352 366 353 template<typename To> 367 354 inline To jsCast(JSValue from) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r129713 r130303 229 229 m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), this, m_objectPrototype.get())); 230 230 m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), this, m_objectPrototype.get())); 231 m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JS NonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));231 m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get())); 232 232 233 233 m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()))); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r129713 r130303 78 78 class JSGlobalObject : public JSSegmentedVariableObject { 79 79 private: 80 typedef JSSegmentedVariableObject Base;81 80 typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; 82 81 … … 171 170 return; 172 171 m_rareData = adoptPtr(new JSGlobalObjectRareData); 173 Heap::heap(this)->addFinalizer(this, clearRareData);174 172 } 175 173 176 174 public: 175 typedef JSSegmentedVariableObject Base; 176 177 177 static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure) 178 178 { 179 179 JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure); 180 180 globalObject->finishCreation(globalData); 181 globalData.heap.addFinalizer(globalObject, destroy); 181 182 return globalObject; 182 183 } … … 206 207 JS_EXPORT_PRIVATE ~JSGlobalObject(); 207 208 JS_EXPORT_PRIVATE static void destroy(JSCell*); 209 // We don't need a destructor because we use a finalizer instead. 210 static const bool needsDestruction = false; 208 211 209 212 JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
r128851 r130303 49 49 static JSPropertyNameIterator* create(ExecState*, JSObject*); 50 50 51 static const bool needsDestruction = true; 52 static const bool hasImmortalStructure = true; 51 53 static void destroy(JSCell*); 52 54 -
trunk/Source/JavaScriptCore/runtime/JSProxy.h
r129719 r130303 27 27 #define JSProxy_h 28 28 29 #include "JS Object.h"29 #include "JSDestructibleObject.h" 30 30 31 31 namespace JSC { 32 32 33 class JSProxy : public JS NonFinalObject {33 class JSProxy : public JSDestructibleObject { 34 34 public: 35 typedef JS NonFinalObject Base;35 typedef JSDestructibleObject Base; 36 36 37 37 static JSProxy* create(JSGlobalData& globalData, Structure* structure, JSObject* target) … … 53 53 protected: 54 54 JSProxy(JSGlobalData& globalData, Structure* structure) 55 : JS NonFinalObject(globalData, structure)55 : JSDestructibleObject(globalData, structure) 56 56 { 57 57 } -
trunk/Source/JavaScriptCore/runtime/JSScope.cpp
r128851 r130303 35 35 36 36 ASSERT_CLASS_FITS_IN_CELL(JSScope); 37 ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSScope); 37 38 38 39 void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor) -
trunk/Source/JavaScriptCore/runtime/JSString.h
r128957 r130303 72 72 typedef JSCell Base; 73 73 74 static const bool needsDestruction = true; 75 static const bool hasImmortalStructure = true; 74 76 static void destroy(JSCell*); 75 77 -
trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h
r128851 r130303 23 23 #define JSWrapperObject_h 24 24 25 #include "JS Object.h"25 #include "JSDestructibleObject.h" 26 26 27 27 namespace JSC { … … 29 29 // This class is used as a base for classes such as String, 30 30 // Number, Boolean and Date which are wrappers for primitive types. 31 class JSWrapperObject : public JS NonFinalObject {31 class JSWrapperObject : public JSDestructibleObject { 32 32 public: 33 typedef JS NonFinalObject Base;33 typedef JSDestructibleObject Base; 34 34 35 35 JSValue internalValue() const; … … 43 43 protected: 44 44 explicit JSWrapperObject(JSGlobalData&, Structure*); 45 static const unsigned StructureFlags = OverridesVisitChildren | JSNonFinalObject::StructureFlags;45 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; 46 46 47 47 static void visitChildren(JSCell*, SlotVisitor&); … … 52 52 53 53 inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure) 54 : JS NonFinalObject(globalData, structure)54 : JSDestructibleObject(globalData, structure) 55 55 { 56 56 } -
trunk/Source/JavaScriptCore/runtime/MathObject.cpp
r128851 r130303 34 34 35 35 ASSERT_CLASS_FITS_IN_CELL(MathObject); 36 ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject); 36 37 37 38 static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*); … … 60 61 namespace JSC { 61 62 62 ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject); 63 64 const ClassInfo MathObject::s_info = { "Math", &JSNonFinalObject::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) }; 63 const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) }; 65 64 66 65 /* Source for MathObject.lut.h -
trunk/Source/JavaScriptCore/runtime/NameInstance.h
r128851 r130303 27 27 #define NameInstance_h 28 28 29 #include "JS Object.h"29 #include "JSDestructibleObject.h" 30 30 #include "PrivateName.h" 31 31 32 32 namespace JSC { 33 33 34 class NameInstance : public JS NonFinalObject {34 class NameInstance : public JSDestructibleObject { 35 35 public: 36 typedef JS NonFinalObject Base;36 typedef JSDestructibleObject Base; 37 37 38 38 static const ClassInfo s_info; -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r128851 r130303 48 48 49 49 JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags); 50 static const bool needsDestruction = true; 51 static const bool hasImmortalStructure = true; 50 52 static void destroy(JSCell*); 51 53 -
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r128851 r130303 51 51 52 52 ASSERT_CLASS_FITS_IN_CELL(RegExpObject); 53 54 const ClassInfo RegExpObject::s_info = { "RegExp", &JSNonFinalObject::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) }; 53 ASSERT_HAS_TRIVIAL_DESTRUCTOR(RegExpObject); 54 55 const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) }; 55 56 56 57 /* Source for RegExpObject.lut.h -
trunk/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
r128851 r130303 82 82 static SparseArrayValueMap* create(JSGlobalData&); 83 83 84 static const bool needsDestruction = true; 85 static const bool hasImmortalStructure = true; 84 86 static void destroy(JSCell*); 85 87 -
trunk/Source/JavaScriptCore/runtime/Structure.h
r128851 r130303 129 129 Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*); 130 130 131 static const bool needsDestruction = true; 132 static const bool hasImmortalStructure = true; 131 133 static void destroy(JSCell*); 132 134 … … 474 476 }; 475 477 476 template <> inline void* allocateCell<Structure>(Heap& heap)477 {478 #if ENABLE(GC_VALIDATION)479 ASSERT(!heap.globalData()->isInitializingObject());480 heap.globalData()->setInitializingObjectClass(&Structure::s_info);481 #endif482 JSCell* result = static_cast<JSCell*>(heap.allocateStructure(sizeof(Structure)));483 result->clearStructure();484 return result;485 }486 487 478 inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType) 488 479 { … … 629 620 } 630 621 631 inline const ClassInfo* JSCell::classInfo() const632 {633 #if ENABLE(GC_VALIDATION)634 return m_structure.unvalidatedGet()->classInfo();635 #else636 return m_structure->classInfo();637 #endif638 }639 640 622 } // namespace JSC 641 623 -
trunk/Source/JavaScriptCore/runtime/StructureChain.h
r128851 r130303 60 60 static ClassInfo s_info; 61 61 62 static const bool needsDestruction = true; 63 static const bool hasImmortalStructure = true; 64 static void destroy(JSCell*); 65 62 66 protected: 63 67 void finishCreation(JSGlobalData& globalData, Structure* head) … … 79 83 80 84 StructureChain(JSGlobalData&, Structure*); 81 static void destroy(JSCell*);82 85 OwnArrayPtr<WriteBarrier<Structure> > m_vector; 83 86 }; -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r129297 r130303 345 345 class SharedSymbolTable : public JSCell, public SymbolTable { 346 346 public: 347 typedef JSCell Base; 348 347 349 static SharedSymbolTable* create(JSGlobalData& globalData) 348 350 { … … 351 353 return sharedSymbolTable; 352 354 } 355 static const bool needsDestruction = true; 356 static const bool hasImmortalStructure = true; 353 357 static void destroy(JSCell*); 354 358 … … 397 401 OwnArrayPtr<SlowArgument> m_slowArguments; 398 402 }; 403 399 404 } // namespace JSC 400 405 -
trunk/Source/JavaScriptCore/testRegExp.cpp
r128851 r130303 116 116 static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments) 117 117 { 118 return new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments); 118 GlobalObject* globalObject = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments); 119 globalData.heap.addFinalizer(globalObject, destroy); 120 return globalObject; 119 121 } 120 122 121 123 static const ClassInfo s_info; 124 125 static const bool needsDestructor = false; 122 126 123 127 static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) -
trunk/Source/WebCore/ChangeLog
r130302 r130303 1 2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 Delayed structure sweep can leak structures without bound 4 https://bugs.webkit.org/show_bug.cgi?id=96546 5 6 Reviewed by Geoffrey Garen. 7 8 This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only 9 allocators. We now have separate allocators for our three types of objects: those objects with no destructors, 10 those objects with destructors and with immortal structures, and those objects with destructors that don't have 11 immortal structures. All of the objects of the third type (destructors without immortal structures) now 12 inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores 13 the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. 14 15 No new tests. 16 17 * ForwardingHeaders/runtime/JSDestructableObject.h: Added. 18 * bindings/js/JSDOMWrapper.h: Inherits from JSDestructibleObject. 19 (JSDOMWrapper): 20 (WebCore::JSDOMWrapper::JSDOMWrapper): 21 * bindings/scripts/CodeGeneratorJS.pm: Add finalizers to anything that inherits from JSGlobalObject, 22 e.g. JSDOMWindow and JSWorkerContexts. For those classes we also need to define needsDestruction as true. 23 (GenerateHeader): 24 * bridge/objc/objc_runtime.h: Inherit from JSDestructibleObject. 25 (ObjcFallbackObjectImp): 26 * bridge/objc/objc_runtime.mm: 27 (Bindings): 28 (JSC::Bindings::ObjcFallbackObjectImp::ObjcFallbackObjectImp): 29 * bridge/runtime_array.cpp: Use a finalizer so that JSArray isn't forced to inherit from JSDestructibleObject. 30 (JSC): 31 (JSC::RuntimeArray::destroy): 32 * bridge/runtime_array.h: 33 (JSC::RuntimeArray::create): 34 (JSC): 35 * bridge/runtime_object.cpp: Inherit from JSDestructibleObject. 36 (Bindings): 37 (JSC::Bindings::RuntimeObject::RuntimeObject): 38 * bridge/runtime_object.h: 39 (RuntimeObject): 40 1 41 2012-10-02 Anders Carlsson <andersca@apple.com> 2 42 -
trunk/Source/WebCore/bindings/js/JSDOMWrapper.h
r128851 r130303 24 24 25 25 #include "JSDOMGlobalObject.h" 26 #include <runtime/JS Object.h>26 #include <runtime/JSDestructibleObject.h> 27 27 28 28 namespace WebCore { … … 30 30 class ScriptExecutionContext; 31 31 32 class JSDOMWrapper : public JSC::JS NonFinalObject {32 class JSDOMWrapper : public JSC::JSDestructibleObject { 33 33 public: 34 typedef JSC::JSDestructibleObject Base; 35 34 36 JSDOMGlobalObject* globalObject() const { return JSC::jsCast<JSDOMGlobalObject*>(JSC::JSNonFinalObject::globalObject()); } 35 37 ScriptExecutionContext* scriptExecutionContext() const { return globalObject()->scriptExecutionContext(); } … … 37 39 protected: 38 40 JSDOMWrapper(JSC::Structure* structure, JSC::JSGlobalObject* globalObject) 39 : JS NonFinalObject(globalObject->globalData(), structure)41 : JSDestructibleObject(globalObject->globalData(), structure) 40 42 { 41 43 ASSERT(scriptExecutionContext()); -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r130255 r130303 743 743 push(@headerContent, " $className* ptr = new (NotNull, JSC::allocateCell<$className>(globalData.heap)) ${className}(globalData, structure, impl, windowShell);\n"); 744 744 push(@headerContent, " ptr->finishCreation(globalData, windowShell);\n"); 745 push(@headerContent, " globalData.heap.addFinalizer(ptr, destroy);\n"); 745 746 push(@headerContent, " return ptr;\n"); 746 747 push(@headerContent, " }\n\n"); … … 750 751 push(@headerContent, " $className* ptr = new (NotNull, JSC::allocateCell<$className>(globalData.heap)) ${className}(globalData, structure, impl);\n"); 751 752 push(@headerContent, " ptr->finishCreation(globalData);\n"); 753 push(@headerContent, " globalData.heap.addFinalizer(ptr, destroy);\n"); 752 754 push(@headerContent, " return ptr;\n"); 753 755 push(@headerContent, " }\n\n"); … … 769 771 push(@headerContent, " return ptr;\n"); 770 772 push(@headerContent, " }\n\n"); 773 } 774 775 if ($interfaceName eq "DOMWindow" || $dataNode->extendedAttributes->{"IsWorkerContext"}) { 776 push(@headerContent, " static const bool needsDestruction = false;\n\n"); 771 777 } 772 778 -
trunk/Source/WebCore/bridge/objc/objc_runtime.h
r128851 r130303 91 91 }; 92 92 93 class ObjcFallbackObjectImp : public JS NonFinalObject {93 class ObjcFallbackObjectImp : public JSDestructibleObject { 94 94 public: 95 typedef JS NonFinalObject Base;95 typedef JSDestructibleObject Base; 96 96 97 97 static ObjcFallbackObjectImp* create(ExecState* exec, JSGlobalObject* globalObject, ObjcInstance* instance, const String& propertyName) -
trunk/Source/WebCore/bridge/objc/objc_runtime.mm
r128851 r130303 189 189 } 190 190 191 const ClassInfo ObjcFallbackObjectImp::s_info = { "ObjcFallbackObject", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ObjcFallbackObjectImp) };191 const ClassInfo ObjcFallbackObjectImp::s_info = { "ObjcFallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjcFallbackObjectImp) }; 192 192 193 193 ObjcFallbackObjectImp::ObjcFallbackObjectImp(JSGlobalObject* globalObject, Structure* structure, ObjcInstance* i, const String& propertyName) 194 : JS NonFinalObject(globalObject->globalData(), structure)194 : JSDestructibleObject(globalObject->globalData(), structure) 195 195 , _instance(i) 196 196 , m_item(propertyName) -
trunk/Source/WebCore/bridge/runtime_array.cpp
r128851 r130303 36 36 namespace JSC { 37 37 38 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", & JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) };38 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) }; 39 39 40 40 RuntimeArray::RuntimeArray(ExecState* exec, Structure* structure) … … 58 58 void RuntimeArray::destroy(JSCell* cell) 59 59 { 60 static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();60 jsCast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray(); 61 61 } 62 62 -
trunk/Source/WebCore/bridge/runtime_array.h
r128851 r130303 44 44 RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(*exec->heap())) RuntimeArray(exec, domStructure); 45 45 runtimeArray->finishCreation(exec->globalData(), array); 46 exec->globalData().heap.addFinalizer(runtimeArray, destroy); 46 47 return runtimeArray; 47 48 } … … 50 51 ~RuntimeArray(); 51 52 static void destroy(JSCell*); 53 static const bool needsDestruction = false; 52 54 53 55 static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); … … 89 91 BindingsArray* m_array; 90 92 }; 91 93 92 94 } // namespace JSC 93 95 -
trunk/Source/WebCore/bridge/runtime_object.cpp
r129969 r130303 36 36 namespace Bindings { 37 37 38 const ClassInfo RuntimeObject::s_info = { "RuntimeObject", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeObject) };38 const ClassInfo RuntimeObject::s_info = { "RuntimeObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeObject) }; 39 39 40 40 RuntimeObject::RuntimeObject(ExecState*, JSGlobalObject* globalObject, Structure* structure, PassRefPtr<Instance> instance) 41 : JS NonFinalObject(globalObject->globalData(), structure)41 : JSDestructibleObject(globalObject->globalData(), structure) 42 42 , m_instance(instance) 43 43 { -
trunk/Source/WebCore/bridge/runtime_object.h
r128851 r130303 33 33 namespace Bindings { 34 34 35 class RuntimeObject : public JS NonFinalObject {35 class RuntimeObject : public JSDestructibleObject { 36 36 public: 37 typedef JS NonFinalObject Base;37 typedef JSDestructibleObject Base; 38 38 39 39 static RuntimeObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, PassRefPtr<Instance> instance) -
trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
r128851 r130303 55 55 } 56 56 57 const ClassInfo JSNPObject::s_info = { "NPObject", & JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) };57 const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) }; 58 58 59 59 JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject) 60 : JS NonFinalObject(globalObject->globalData(), structure)60 : JSDestructibleObject(globalObject->globalData(), structure) 61 61 , m_objectMap(objectMap) 62 62 , m_npObject(npObject) -
trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h
r128851 r130303 42 42 // JSNPObject is a JSObject that wraps an NPObject. 43 43 44 class JSNPObject : public JSC::JS NonFinalObject {44 class JSNPObject : public JSC::JSDestructibleObject { 45 45 public: 46 typedef JSC::JS NonFinalObject Base;46 typedef JSC::JSDestructibleObject Base; 47 47 48 48 static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject)
Note: See TracChangeset
for help on using the changeset viewer.