Changeset 128813 in webkit
- Timestamp:
- Sep 17, 2012 3:16:10 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 60 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSCallbackConstructor.cpp
r118616 r128813 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
r103243 r128813 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
r118616 r128813 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<> 43 JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) 44 { 45 JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(globalData.heap)) JSCallbackObject(globalData, classRef, structure); 46 callbackObject->finishCreation(globalData); 47 globalData.heap.addFinalizer(callbackObject, destroy); 48 return callbackObject; 49 } 41 50 42 51 template <> 43 Structure* JSCallbackObject<JS NonFinalObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)52 Structure* JSCallbackObject<JSDestructibleObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) 44 53 { 45 54 return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); -
trunk/Source/JavaScriptCore/API/JSCallbackObject.h
r128400 r128813 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 } 142 136 static JSCallbackObject<Parent>* create(JSGlobalData&, JSClassRef, Structure*); 143 137 void setPrivate(void* data); 144 138 void* getPrivate(); … … 218 212 }; 219 213 214 NEEDS_DESTRUCTOR(JSCallbackObject<JSGlobalObject>, false); 215 220 216 } // namespace JSC 221 217 -
trunk/Source/JavaScriptCore/API/JSClassRef.cpp
r127191 r128813 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
r128400 r128813 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
r127958 r128813 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
r118483 r128813 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
r128802 r128813 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 Gavin Barraclough. 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 the NEEDS_DESTRUCTOR macro to make it easier for classes to indicate that instead of being 125 allocated in a destructor MarkedAllocator that they will handle their destruction themselves through the 126 use of a finalizer. 127 (JSC): 128 (HasImmortalStructure): New template to help us determine at compile-time if a particular class 129 should be allocated in the immortal structure MarkedAllocator. The default value is false. In order 130 to be allocated in the immortal structure allocator, classes must specialize this template. Also added 131 a macro to make it easier for classes to specialize the template. 132 (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. 133 * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be 134 accessed safely when the object is being destroyed. 135 (JSC): 136 (JSDestructibleObject): 137 (JSC::JSDestructibleObject::classInfo): 138 (JSC::JSDestructibleObject::JSDestructibleObject): 139 (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. 140 * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all 141 of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. 142 (JSC::JSGlobalObject::reset): 143 * runtime/JSGlobalObject.h: 144 (JSGlobalObject): 145 (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one 146 for the m_rareData field when it's created. 147 (JSC::JSGlobalObject::create): 148 (JSC): 149 * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. 150 (JSGlobalThis): 151 (JSC::JSGlobalThis::JSGlobalThis): 152 * runtime/JSPropertyNameIterator.h: Has an immortal Structure. 153 (JSC): 154 * runtime/JSScope.cpp: 155 (JSC): 156 * runtime/JSString.h: Has an immortal Structure. 157 (JSC): 158 * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. 159 (JSWrapperObject): 160 (JSC::JSWrapperObject::JSWrapperObject): 161 * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. 162 (JSC): 163 * runtime/NameInstance.h: Inherit from JSDestructibleObject. 164 (NameInstance): 165 * runtime/RegExp.h: Has immortal Structure. 166 (JSC): 167 * runtime/RegExpObject.cpp: Inheritance cleanup. 168 (JSC): 169 * runtime/SparseArrayValueMap.h: Has immortal Structure. 170 (JSC): 171 * runtime/Structure.h: Has immortal Structure. 172 (JSC): 173 * runtime/StructureChain.h: Ditto. 174 (JSC): 175 * runtime/SymbolTable.h: Ditto. 176 (SharedSymbolTable): 177 (JSC): 178 179 <<<<<<< .mine 180 2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> 181 182 Delayed structure sweep can leak structures without bound 183 https://bugs.webkit.org/show_bug.cgi?id=96546 184 185 Reviewed by Gavin Barraclough. 186 187 This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only 188 allocators. We now have separate allocators for our three types of objects: those objects with no destructors, 189 those objects with destructors and with immortal structures, and those objects with destructors that don't have 190 immortal structures. All of the objects of the third type (destructors without immortal structures) now 191 inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores 192 the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. 193 194 * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor. 195 (JSC): 196 (JSC::JSCallbackConstructor::JSCallbackConstructor): 197 * API/JSCallbackConstructor.h: 198 (JSCallbackConstructor): 199 * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for 200 JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer. 201 (JSC): 202 (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add 203 the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides 204 to subclass this. We use this same technique for many other subclasses of JSGlobalObject. 205 (JSC::::createStructure): 206 * API/JSCallbackObject.h: 207 (JSCallbackObject): 208 (JSC): 209 * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead. 210 (OpaqueJSClass::prototype): 211 * API/JSObjectRef.cpp: Ditto. 212 (JSObjectMake): 213 (JSObjectGetPrivate): 214 (JSObjectSetPrivate): 215 (JSObjectGetPrivateProperty): 216 (JSObjectSetPrivateProperty): 217 (JSObjectDeletePrivateProperty): 218 * API/JSValueRef.cpp: Ditto. 219 (JSValueIsObjectOfClass): 220 * API/JSWeakObjectMapRefPrivate.cpp: Ditto. 221 * JSCTypedArrayStubs.h: 222 (JSC): 223 * JavaScriptCore.xcodeproj/project.pbxproj: 224 * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG. 225 (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): 226 (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): 227 * heap/Heap.cpp: 228 (JSC): 229 * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function 230 since it's always safe to sweep Structures now. 231 (JSC::Heap::allocatorForObjectWithNormalDestructor): 232 (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): 233 (Heap): 234 (JSC::Heap::allocateWithNormalDestructor): 235 (JSC): 236 (JSC::Heap::allocateWithImmortalStructureDestructor): 237 * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the 238 IncrementalSweeper since it's always safe to sweep Structures now. 239 (JSC::IncrementalSweeper::IncrementalSweeper): 240 (JSC::IncrementalSweeper::sweepNextBlock): 241 (JSC::IncrementalSweeper::startSweeping): 242 (JSC::IncrementalSweeper::willFinishSweeping): 243 (JSC): 244 * heap/IncrementalSweeper.h: 245 (IncrementalSweeper): 246 * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add 247 tracking of the specific destructor type of allocator. 248 (JSC::MarkedAllocator::tryAllocateHelper): 249 (JSC::MarkedAllocator::allocateBlock): 250 * heap/MarkedAllocator.h: 251 (JSC::MarkedAllocator::destructorType): 252 (MarkedAllocator): 253 (JSC::MarkedAllocator::MarkedAllocator): 254 (JSC::MarkedAllocator::init): 255 * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping. 256 We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls. 257 (JSC::MarkedBlock::create): 258 (JSC::MarkedBlock::MarkedBlock): 259 (JSC): 260 (JSC::MarkedBlock::specializedSweep): 261 (JSC::MarkedBlock::sweep): 262 (JSC::MarkedBlock::sweepHelper): 263 * heap/MarkedBlock.h: 264 (JSC): 265 (JSC::MarkedBlock::allocator): 266 (JSC::MarkedBlock::destructorType): 267 * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace. 268 (JSC::MarkedSpace::MarkedSpace): 269 (JSC::MarkedSpace::resetAllocators): 270 (JSC::MarkedSpace::canonicalizeCellLivenessData): 271 (JSC::MarkedSpace::isPagedOut): 272 (JSC::MarkedSpace::freeBlock): 273 * heap/MarkedSpace.h: 274 (MarkedSpace): 275 (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): 276 (JSC::MarkedSpace::normalDestructorAllocatorFor): 277 (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): 278 (JSC::MarkedSpace::allocateWithNormalDestructor): 279 (JSC::MarkedSpace::forEachBlock): 280 * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function. 281 * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT. 282 * jit/JITInlineMethods.h: 283 (JSC::JIT::emitAllocateBasicJSObject): 284 (JSC::JIT::emitAllocateJSFinalObject): 285 (JSC::JIT::emitAllocateJSArray): 286 * jsc.cpp: 287 (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from 288 JSDestructibleObject. 289 * runtime/Arguments.cpp: Inherit from JSDestructibleObject. 290 (JSC): 291 * runtime/Arguments.h: 292 (Arguments): 293 (JSC::Arguments::Arguments): 294 * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor. 295 (JSC): 296 * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures. 297 (JSC): 298 * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject. 299 (JSC): 300 (JSC::InternalFunction::InternalFunction): 301 * runtime/InternalFunction.h: 302 (InternalFunction): 303 * runtime/JSCell.h: Added the NEEDS_DESTRUCTOR macro to make it easier for classes to indicate that instead of being 304 allocated in a destructor MarkedAllocator that they will handle their destruction themselves through the 305 use of a finalizer. 306 (JSC): 307 (HasImmortalStructure): New template to help us determine at compile-time if a particular class 308 should be allocated in the immortal structure MarkedAllocator. The default value is false. In order 309 to be allocated in the immortal structure allocator, classes must specialize this template. Also added 310 a macro to make it easier for classes to specialize the template. 311 (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. 312 * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be 313 accessed safely when the object is being destroyed. 314 (JSC): 315 (JSDestructibleObject): 316 (JSC::JSDestructibleObject::classInfo): 317 (JSC::JSDestructibleObject::JSDestructibleObject): 318 (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. 319 * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all 320 of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. 321 (JSC::JSGlobalObject::reset): 322 * runtime/JSGlobalObject.h: 323 (JSGlobalObject): 324 (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one 325 for the m_rareData field when it's created. 326 (JSC::JSGlobalObject::create): 327 (JSC): 328 * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. 329 (JSGlobalThis): 330 (JSC::JSGlobalThis::JSGlobalThis): 331 * runtime/JSPropertyNameIterator.h: Has an immortal Structure. 332 (JSC): 333 * runtime/JSScope.cpp: 334 (JSC): 335 * runtime/JSString.h: Has an immortal Structure. 336 (JSC): 337 * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. 338 (JSWrapperObject): 339 (JSC::JSWrapperObject::JSWrapperObject): 340 * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. 341 (JSC): 342 * runtime/NameInstance.h: Inherit from JSDestructibleObject. 343 (NameInstance): 344 * runtime/RegExp.h: Has immortal Structure. 345 (JSC): 346 * runtime/RegExpObject.cpp: Inheritance cleanup. 347 (JSC): 348 * runtime/SparseArrayValueMap.h: Has immortal Structure. 349 (JSC): 350 * runtime/Structure.h: Has immortal Structure. 351 (JSC): 352 * runtime/StructureChain.h: Ditto. 353 (JSC): 354 * runtime/SymbolTable.h: Ditto. 355 (SharedSymbolTable): 356 (JSC): 357 358 ======= 1 359 2012-09-17 Filip Pizlo <fpizlo@apple.com> 2 360 … … 234 592 * llint/LowLevelInterpreter64.asm: 235 593 594 >>>>>>> .r128811 236 595 2012-09-17 Mark Lam <mark.lam@apple.com> 237 596 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r128680 r128813 534 534 Source/JavaScriptCore/runtime/JSDateMath.cpp \ 535 535 Source/JavaScriptCore/runtime/JSDateMath.h \ 536 Source/JavaScriptCore/runtime/JSDestructibleObject.h \ 536 537 Source/JavaScriptCore/runtime/JSFunction.cpp \ 537 538 Source/JavaScriptCore/runtime/JSFunction.h \ -
trunk/Source/JavaScriptCore/JSCTypedArrayStubs.h
r116828 r128813 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
r128771 r128813 842 842 > 843 843 </File> 844 <File 845 RelativePath="..\..\runtime\JSDestructibleObject.h" 846 > 847 </File> 844 848 <File 845 849 RelativePath="..\..\runtime\JSFunction.cpp" -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r128680 r128813 709 709 C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; }; 710 710 C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C240305314B404C90079EB64 /* CopiedSpace.cpp */; }; 711 C25177F81607D0A6000A233C /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C25177F71607D0A6000A233C /* JSDestructibleObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; 711 712 C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; }; 712 713 C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */ = {isa = PBXBuildFile; fileRef = C25F8BCC157544A900245B71 /* IncrementalSweeper.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1482 1483 C225494215F7DBAA0065E898 /* SlotVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotVisitor.cpp; sourceTree = "<group>"; }; 1483 1484 C240305314B404C90079EB64 /* CopiedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopiedSpace.cpp; sourceTree = "<group>"; }; 1485 C25177F71607D0A6000A233C /* JSDestructibleObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObject.h; sourceTree = "<group>"; }; 1484 1486 C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; }; 1485 1487 C25F8BCC157544A900245B71 /* IncrementalSweeper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncrementalSweeper.h; sourceTree = "<group>"; }; … … 2044 2046 isa = PBXGroup; 2045 2047 children = ( 2048 C25177F71607D0A6000A233C /* JSDestructibleObject.h */, 2046 2049 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */, 2047 2050 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */, … … 2564 2567 C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */, 2565 2568 C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */, 2569 C25177F81607D0A6000A233C /* JSDestructibleObject.h in Headers */, 2566 2570 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */, 2567 2571 C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r128400 r128813 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
r128498 r128813 831 831 } 832 832 833 bool Heap::isSafeToSweepStructures()834 {835 return !m_sweeper || m_sweeper->structuresCanBeSwept();836 }837 838 833 void Heap::didStartVMShutdown() 839 834 { -
trunk/Source/JavaScriptCore/heap/Heap.h
r128260 r128813 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**); … … 169 170 170 171 bool isPagedOut(double deadline); 171 bool isSafeToSweepStructures();172 172 void didStartVMShutdown(); 173 173 … … 185 185 template<typename T> friend void* allocateCell(Heap&, size_t); 186 186 187 void* allocateWith Destructor(size_t);188 void* allocateWith outDestructor(size_t);189 void* allocate Structure(size_t);187 void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die. 188 void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject. 189 void* allocateWithoutDestructor(size_t); // For use with objects without destructors. 190 190 191 191 static const size_t minExtraCost = 256; … … 362 362 } 363 363 364 inline void* Heap::allocateWith Destructor(size_t bytes)364 inline void* Heap::allocateWithNormalDestructor(size_t bytes) 365 365 { 366 366 ASSERT(isValidAllocation(bytes)); 367 return m_objectSpace.allocateWithDestructor(bytes); 367 return m_objectSpace.allocateWithNormalDestructor(bytes); 368 } 369 370 inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes) 371 { 372 ASSERT(isValidAllocation(bytes)); 373 return m_objectSpace.allocateWithImmortalStructureDestructor(bytes); 368 374 } 369 375 … … 374 380 } 375 381 376 inline void* Heap::allocateStructure(size_t bytes)377 {378 return m_objectSpace.allocateStructure(bytes);379 }380 381 382 inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr) 382 383 { -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
r127202 r128813 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
r127185 r128813 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
r128563 r128813 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
r128563 r128813 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
r128563 r128813 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
r128563 r128813 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
r128563 r128813 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
r128498 r128813 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(); … … 130 130 FixedArray<MarkedAllocator, preciseCount> preciseAllocators; 131 131 FixedArray<MarkedAllocator, impreciseCount> impreciseAllocators; 132 MarkedAllocator largeAllocator; 132 133 }; 133 134 134 Subspace m_destructorSpace; 135 Subspace m_normalDestructorSpace; 136 Subspace m_immortalStructureDestructorSpace; 135 137 Subspace m_normalSpace; 136 MarkedAllocator m_largeAllocator;137 MarkedAllocator m_structureAllocator;138 138 139 139 Heap* m_heap; … … 169 169 if (bytes <= impreciseCutoff) 170 170 return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 171 return m_largeAllocator; 172 } 173 174 inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block) 175 { 176 if (block->onlyContainsStructures()) 177 return m_structureAllocator; 178 179 if (block->cellsNeedDestruction()) 180 return destructorAllocatorFor(block->cellSize()); 181 182 return allocatorFor(block->cellSize()); 183 } 184 185 inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes) 171 return m_normalSpace.largeAllocator; 172 } 173 174 inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes) 186 175 { 187 176 ASSERT(bytes); 188 177 if (bytes <= preciseCutoff) 189 return m_ destructorSpace.preciseAllocators[(bytes - 1) / preciseStep];178 return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; 190 179 if (bytes <= impreciseCutoff) 191 return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 192 return m_largeAllocator; 180 return m_immortalStructureDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 181 return m_immortalStructureDestructorSpace.largeAllocator; 182 } 183 184 inline MarkedAllocator& MarkedSpace::normalDestructorAllocatorFor(size_t bytes) 185 { 186 ASSERT(bytes); 187 if (bytes <= preciseCutoff) 188 return m_normalDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; 189 if (bytes <= impreciseCutoff) 190 return m_normalDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; 191 return m_normalDestructorSpace.largeAllocator; 193 192 } 194 193 … … 198 197 } 199 198 200 inline void* MarkedSpace::allocateWith Destructor(size_t bytes)201 { 202 return destructorAllocatorFor(bytes).allocate(bytes);203 } 204 205 inline void* MarkedSpace::allocate Structure(size_t bytes)206 { 207 return m_structureAllocator.allocate(bytes);199 inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes) 200 { 201 return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes); 202 } 203 204 inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes) 205 { 206 return normalDestructorAllocatorFor(bytes).allocate(bytes); 208 207 } 209 208 … … 212 211 for (size_t i = 0; i < preciseCount; ++i) { 213 212 m_normalSpace.preciseAllocators[i].forEachBlock(functor); 214 m_destructorSpace.preciseAllocators[i].forEachBlock(functor); 213 m_normalDestructorSpace.preciseAllocators[i].forEachBlock(functor); 214 m_immortalStructureDestructorSpace.preciseAllocators[i].forEachBlock(functor); 215 215 } 216 216 217 217 for (size_t i = 0; i < impreciseCount; ++i) { 218 218 m_normalSpace.impreciseAllocators[i].forEachBlock(functor); 219 m_destructorSpace.impreciseAllocators[i].forEachBlock(functor); 219 m_normalDestructorSpace.impreciseAllocators[i].forEachBlock(functor); 220 m_immortalStructureDestructorSpace.impreciseAllocators[i].forEachBlock(functor); 220 221 } 221 222 222 m_largeAllocator.forEachBlock(functor); 223 m_structureAllocator.forEachBlock(functor); 223 m_normalSpace.largeAllocator.forEachBlock(functor); 224 m_normalDestructorSpace.largeAllocator.forEachBlock(functor); 225 m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor); 224 226 225 227 return functor.returnValue(); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r128084 r128813 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
r128802 r128813 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
r128802 r128813 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
r128400 r128813 177 177 GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure); 178 178 object->finishCreation(globalData, arguments); 179 globalData.heap.addFinalizer(object, destroy); 179 180 return object; 180 181 } … … 244 245 } 245 246 }; 247 248 249 namespace JSC { 250 NEEDS_DESTRUCTOR(GlobalObject, false); 251 }; 252 246 253 COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false); 247 254 ASSERT_CLASS_FITS_IN_CELL(GlobalObject); -
trunk/Source/JavaScriptCore/runtime/Arguments.cpp
r128400 r128813 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
r128260 r128813 27 27 #include "CodeOrigin.h" 28 28 #include "JSActivation.h" 29 #include "JSDestructibleObject.h" 29 30 #include "JSFunction.h" 30 31 #include "JSGlobalObject.h" … … 58 59 }; 59 60 60 class Arguments : public JS NonFinalObject {61 class Arguments : public JSDestructibleObject { 61 62 public: 62 typedef JS NonFinalObject Base;63 typedef JSDestructibleObject Base; 63 64 64 65 static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame) … … 155 156 156 157 inline Arguments::Arguments(CallFrame* callFrame) 157 : JS NonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())158 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 158 159 , d(adoptPtr(new ArgumentsData)) 159 160 { … … 161 162 162 163 inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) 163 : JS NonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())164 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 164 165 , d(adoptPtr(new ArgumentsData)) 165 166 { -
trunk/Source/JavaScriptCore/runtime/ErrorPrototype.cpp
r127505 r128813 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
r128265 r128813 258 258 }; 259 259 260 HAS_IMMORTAL_STRUCTURE(ExecutableBase); 261 260 262 class NativeExecutable : public ExecutableBase { 261 263 friend class JIT; … … 340 342 }; 341 343 344 HAS_IMMORTAL_STRUCTURE(NativeExecutable); 345 342 346 class ScriptExecutable : public ExecutableBase { 343 347 public: … … 468 472 }; 469 473 474 HAS_IMMORTAL_STRUCTURE(EvalExecutable); 475 470 476 class ProgramExecutable : public ScriptExecutable { 471 477 friend class LLIntOffsetsExtractor; … … 534 540 OwnPtr<ProgramCodeBlock> m_programCodeBlock; 535 541 }; 542 543 HAS_IMMORTAL_STRUCTURE(ProgramExecutable); 536 544 537 545 class FunctionExecutable : public ScriptExecutable { … … 755 763 WriteBarrier<SharedSymbolTable> m_symbolTable; 756 764 }; 765 766 HAS_IMMORTAL_STRUCTURE(FunctionExecutable); 757 767 758 768 inline JSFunction::JSFunction(JSGlobalData& globalData, FunctionExecutable* executable, JSScope* scope) -
trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp
r127505 r128813 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
r127191 r128813 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
r128400 r128813 37 37 namespace JSC { 38 38 39 class JSDestructibleObject; 39 40 class JSGlobalObject; 40 41 class LLIntOffsetsExtractor; … … 322 323 #endif 323 324 325 template<class T> 326 struct HasImmortalStructure { 327 static const bool value = false; 328 }; 329 330 #define HAS_IMMORTAL_STRUCTURE(klass) \ 331 template <> \ 332 struct HasImmortalStructure<klass> {\ 333 static const bool value = true;\ 334 } 335 336 #define NEEDS_DESTRUCTOR(klass, v) \ 337 template <> \ 338 struct NeedsDestructor<klass> {\ 339 static const bool value = v;\ 340 } 341 324 342 template<typename T> 325 343 void* allocateCell(Heap& heap) … … 330 348 #endif 331 349 JSCell* result = 0; 332 if (NeedsDestructor<T>::value) 333 result = static_cast<JSCell*>(heap.allocateWithDestructor(sizeof(T))); 334 else { 335 ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); 350 if (NeedsDestructor<T>::value && HasImmortalStructure<T>::value) 351 result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(sizeof(T))); 352 else if (NeedsDestructor<T>::value && !HasImmortalStructure<T>::value) 353 result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(sizeof(T))); 354 else 336 355 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(sizeof(T))); 337 }338 356 result->clearStructure(); 339 357 return result; … … 349 367 #endif 350 368 JSCell* result = 0; 351 if (NeedsDestructor<T>::value) 352 result = static_cast<JSCell*>(heap.allocateWithDestructor(size)); 369 if (NeedsDestructor<T>::value && HasImmortalStructure<T>::value) 370 result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size)); 371 else if (NeedsDestructor<T>::value && !HasImmortalStructure<T>::value) 372 result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size)); 353 373 else { 354 374 ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); … … 370 390 return static_cast<To>(from); 371 391 } 372 392 373 393 template<typename To> 374 394 inline To jsCast(JSValue from) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r128802 r128813 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
r128802 r128813 78 78 class JSGlobalObject : public JSSegmentedVariableObject { 79 79 private: 80 typedef JSSegmentedVariableObject Base;81 80 typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; 82 81 … … 169 168 return; 170 169 m_rareData = adoptPtr(new JSGlobalObjectRareData); 171 Heap::heap(this)->addFinalizer(this, clearRareData);172 170 } 173 171 174 172 public: 173 typedef JSSegmentedVariableObject Base; 174 175 175 static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure) 176 176 { 177 177 JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure); 178 178 globalObject->finishCreation(globalData); 179 globalData.heap.addFinalizer(globalObject, destroy); 179 180 return globalObject; 180 181 } … … 380 381 }; 381 382 383 // We don't need to be allocated in the destructor space because we use a finalizer instead. 384 NEEDS_DESTRUCTOR(JSGlobalObject, false); 385 382 386 JSGlobalObject* asGlobalObject(JSValue); 383 387 -
trunk/Source/JavaScriptCore/runtime/JSGlobalThis.h
r114457 r128813 27 27 #define JSGlobalThis_h 28 28 29 #include "JS Object.h"29 #include "JSDestructibleObject.h" 30 30 31 31 namespace JSC { 32 32 33 class JSGlobalThis : public JS NonFinalObject {33 class JSGlobalThis : public JSDestructibleObject { 34 34 public: 35 typedef JS NonFinalObject Base;35 typedef JSDestructibleObject Base; 36 36 37 37 static JSGlobalThis* create(JSGlobalData& globalData, Structure* structure) … … 53 53 protected: 54 54 JSGlobalThis(JSGlobalData& globalData, Structure* structure) 55 : JS NonFinalObject(globalData, structure)55 : JSDestructibleObject(globalData, structure) 56 56 { 57 57 } -
trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h
r127958 r128813 105 105 }; 106 106 107 HAS_IMMORTAL_STRUCTURE(JSPropertyNameIterator); 108 107 109 inline void Structure::setEnumerationCache(JSGlobalData& globalData, JSPropertyNameIterator* enumerationCache) 108 110 { -
trunk/Source/JavaScriptCore/runtime/JSScope.cpp
r127958 r128813 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
r127958 r128813 60 60 JSRopeString* jsStringBuilder(JSGlobalData*); 61 61 62 HAS_IMMORTAL_STRUCTURE(JSString); 63 62 64 class JSString : public JSCell { 63 65 public: … … 321 323 mutable FixedArray<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers; 322 324 }; 325 326 HAS_IMMORTAL_STRUCTURE(JSRopeString); 323 327 324 328 JSString* asString(JSValue); -
trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h
r103083 r128813 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; … … 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
r119775 r128813 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
r117859 r128813 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
r127191 r128813 124 124 }; 125 125 126 HAS_IMMORTAL_STRUCTURE(RegExp); 127 126 128 } // namespace JSC 127 129 -
trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp
r128400 r128813 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
r128802 r128813 132 132 }; 133 133 134 HAS_IMMORTAL_STRUCTURE(SparseArrayValueMap); 135 134 136 } // namespace JSC 135 137 -
trunk/Source/JavaScriptCore/runtime/Structure.h
r128802 r128813 474 474 }; 475 475 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 #endif 482 JSCell* result = static_cast<JSCell*>(heap.allocateStructure(sizeof(Structure))); 483 result->clearStructure(); 484 return result; 485 } 476 HAS_IMMORTAL_STRUCTURE(Structure); 486 477 487 478 inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType) … … 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
r108444 r128813 83 83 }; 84 84 85 HAS_IMMORTAL_STRUCTURE(StructureChain); 86 85 87 } // namespace JSC 86 88 -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r128260 r128813 328 328 class SharedSymbolTable : public JSCell, public SymbolTable { 329 329 public: 330 typedef JSCell Base; 331 330 332 static SharedSymbolTable* create(JSGlobalData& globalData) 331 333 { … … 381 383 int m_captureEnd; 382 384 }; 383 385 386 HAS_IMMORTAL_STRUCTURE(SharedSymbolTable); 387 384 388 } // namespace JSC 385 389 -
trunk/Source/JavaScriptCore/testRegExp.cpp
r127191 r128813 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 … … 133 135 } 134 136 }; 137 138 namespace JSC { 139 NEEDS_DESTRUCTOR(GlobalObject, false); 140 } 135 141 136 142 COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false); -
trunk/Source/WebCore/ChangeLog
r128812 r128813 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 Gavin Barraclough. 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 use the NEEDS_DESTRUCTOR macro. 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 41 <<<<<<< .mine 42 2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> 43 44 Delayed structure sweep can leak structures without bound 45 https://bugs.webkit.org/show_bug.cgi?id=96546 46 47 Reviewed by Gavin Barraclough. 48 49 This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only 50 allocators. We now have separate allocators for our three types of objects: those objects with no destructors, 51 those objects with destructors and with immortal structures, and those objects with destructors that don't have 52 immortal structures. All of the objects of the third type (destructors without immortal structures) now 53 inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores 54 the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. 55 56 No new tests. 57 58 * ForwardingHeaders/runtime/JSDestructableObject.h: Added. 59 * bindings/js/JSDOMWrapper.h: Inherits from JSDestructibleObject. 60 (JSDOMWrapper): 61 (WebCore::JSDOMWrapper::JSDOMWrapper): 62 * bindings/scripts/CodeGeneratorJS.pm: Add finalizers to anything that inherits from JSGlobalObject, 63 e.g. JSDOMWindow and JSWorkerContexts. For those classes we also need to use the NEEDS_DESTRUCTOR macro. 64 (GenerateHeader): 65 * bridge/objc/objc_runtime.h: Inherit from JSDestructibleObject. 66 (ObjcFallbackObjectImp): 67 * bridge/objc/objc_runtime.mm: 68 (Bindings): 69 (JSC::Bindings::ObjcFallbackObjectImp::ObjcFallbackObjectImp): 70 * bridge/runtime_array.cpp: Use a finalizer so that JSArray isn't forced to inherit from JSDestructibleObject. 71 (JSC): 72 (JSC::RuntimeArray::destroy): 73 * bridge/runtime_array.h: 74 (JSC::RuntimeArray::create): 75 (JSC): 76 * bridge/runtime_object.cpp: Inherit from JSDestructibleObject. 77 (Bindings): 78 (JSC::Bindings::RuntimeObject::RuntimeObject): 79 * bridge/runtime_object.h: 80 (RuntimeObject): 81 82 ======= 1 83 2012-09-17 Sheriff Bot <webkit.review.bot@gmail.com> 2 84 … … 362 444 (.css-named-flow-collections-view .split-view-contents .named-flow-element): 363 445 446 >>>>>>> .r128811 364 447 2012-09-17 Zan Dobersek <zandobersek@gmail.com> 365 448 -
trunk/Source/WebCore/bindings/js/JSDOMWrapper.h
r125688 r128813 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
r128655 r128813 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"); … … 1008 1010 1009 1011 push(@headerContent, "};\n\n"); 1012 1013 if ($interfaceName eq "DOMWindow" || $dataNode->extendedAttributes->{"IsWorkerContext"}) { 1014 push(@headerContent, "} // namespace WebCore\n\n"); 1015 push(@headerContent, "namespace JSC {\n"); 1016 push(@headerContent, "NEEDS_DESTRUCTOR(WebCore::${className}, false);\n\n"); 1017 push(@headerContent, "} // namespace JSC\n\n"); 1018 push(@headerContent, "namespace WebCore {\n\n"); 1019 } 1010 1020 1011 1021 if ($dataNode->extendedAttributes->{"JSInlineGetOwnPropertySlot"} && !$dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) { -
trunk/Source/WebCore/bridge/objc/objc_runtime.h
r127191 r128813 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
r127191 r128813 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
r128400 r128813 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
r128428 r128813 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 } … … 89 90 BindingsArray* m_array; 90 91 }; 92 93 NEEDS_DESTRUCTOR(RuntimeArray, false); 91 94 92 95 } // namespace JSC -
trunk/Source/WebCore/bridge/runtime_object.cpp
r121316 r128813 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
r116828 r128813 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)
Note: See TracChangeset
for help on using the changeset viewer.