Changeset 130303 in webkit


Ignore:
Timestamp:
Oct 3, 2012 10:51:28 AM (12 years ago)
Author:
mhahnenberg@apple.com
Message:

Delayed structure sweep can leak structures without bound
https://bugs.webkit.org/show_bug.cgi?id=96546

Reviewed by Geoffrey Garen.

This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only
allocators. We now have separate allocators for our three types of objects: those objects with no destructors,
those objects with destructors and with immortal structures, and those objects with destructors that don't have
immortal structures. All of the objects of the third type (destructors without immortal structures) now
inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores
the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction.

Source/JavaScriptCore:

  • API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor.

(JSC):
(JSC::JSCallbackConstructor::JSCallbackConstructor):

  • API/JSCallbackConstructor.h:

(JSCallbackConstructor):

  • API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for

JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer.
(JSC):
(JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add
the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides
to subclass this. We use this same technique for many other subclasses of JSGlobalObject.
(JSC::::createStructure):

  • API/JSCallbackObject.h:

(JSCallbackObject):
(JSC):

  • API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead.

(OpaqueJSClass::prototype):

  • API/JSObjectRef.cpp: Ditto.

(JSObjectMake):
(JSObjectGetPrivate):
(JSObjectSetPrivate):
(JSObjectGetPrivateProperty):
(JSObjectSetPrivateProperty):
(JSObjectDeletePrivateProperty):

  • API/JSValueRef.cpp: Ditto.

(JSValueIsObjectOfClass):

  • API/JSWeakObjectMapRefPrivate.cpp: Ditto.
  • JSCTypedArrayStubs.h:

(JSC):

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG.

(JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
(JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):

  • heap/Heap.cpp:

(JSC):

  • heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function

since it's always safe to sweep Structures now.
(JSC::Heap::allocatorForObjectWithNormalDestructor):
(JSC::Heap::allocatorForObjectWithImmortalStructureDestructor):
(Heap):
(JSC::Heap::allocateWithNormalDestructor):
(JSC):
(JSC::Heap::allocateWithImmortalStructureDestructor):

  • heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the

IncrementalSweeper since it's always safe to sweep Structures now.
(JSC::IncrementalSweeper::IncrementalSweeper):
(JSC::IncrementalSweeper::sweepNextBlock):
(JSC::IncrementalSweeper::startSweeping):
(JSC::IncrementalSweeper::willFinishSweeping):
(JSC):

  • heap/IncrementalSweeper.h:

(IncrementalSweeper):

  • heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add

tracking of the specific destructor type of allocator.
(JSC::MarkedAllocator::tryAllocateHelper):
(JSC::MarkedAllocator::allocateBlock):

  • heap/MarkedAllocator.h:

(JSC::MarkedAllocator::destructorType):
(MarkedAllocator):
(JSC::MarkedAllocator::MarkedAllocator):
(JSC::MarkedAllocator::init):

  • heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping.

We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls.
(JSC::MarkedBlock::create):
(JSC::MarkedBlock::MarkedBlock):
(JSC):
(JSC::MarkedBlock::specializedSweep):
(JSC::MarkedBlock::sweep):
(JSC::MarkedBlock::sweepHelper):

  • heap/MarkedBlock.h:

(JSC):
(JSC::MarkedBlock::allocator):
(JSC::MarkedBlock::destructorType):

  • heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace.

(JSC::MarkedSpace::MarkedSpace):
(JSC::MarkedSpace::resetAllocators):
(JSC::MarkedSpace::canonicalizeCellLivenessData):
(JSC::MarkedSpace::isPagedOut):
(JSC::MarkedSpace::freeBlock):

  • heap/MarkedSpace.h:

(MarkedSpace):
(JSC::MarkedSpace::immortalStructureDestructorAllocatorFor):
(JSC::MarkedSpace::normalDestructorAllocatorFor):
(JSC::MarkedSpace::allocateWithImmortalStructureDestructor):
(JSC::MarkedSpace::allocateWithNormalDestructor):
(JSC::MarkedSpace::forEachBlock):

  • heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function.
  • jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT.
  • jit/JITInlineMethods.h:

(JSC::JIT::emitAllocateBasicJSObject):
(JSC::JIT::emitAllocateJSFinalObject):
(JSC::JIT::emitAllocateJSArray):

  • jsc.cpp:

(GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from
JSDestructibleObject.

  • runtime/Arguments.cpp: Inherit from JSDestructibleObject.

(JSC):

  • runtime/Arguments.h:

(Arguments):
(JSC::Arguments::Arguments):

  • runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor.

(JSC):

  • runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures.

(JSC):

  • runtime/InternalFunction.cpp: Inherit from JSDestructibleObject.

(JSC):
(JSC::InternalFunction::InternalFunction):

  • runtime/InternalFunction.h:

(InternalFunction):

  • runtime/JSCell.h: Added two static bools, needsDestruction and hasImmortalStructure, that classes can override

to indicate at compile time which part of the heap they should be allocated in.
(JSC::allocateCell): Use the appropriate allocator depending on the destructor type.

  • runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be

accessed safely when the object is being destroyed.
(JSC):
(JSDestructibleObject):
(JSC::JSDestructibleObject::classInfo):
(JSC::JSDestructibleObject::JSDestructibleObject):
(JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe.

  • runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all

of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well.
(JSC::JSGlobalObject::reset):

  • runtime/JSGlobalObject.h:

(JSGlobalObject):
(JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one
for the m_rareData field when it's created.
(JSC::JSGlobalObject::create):
(JSC):

  • runtime/JSGlobalThis.h: Inherit from JSDestructibleObject.

(JSGlobalThis):
(JSC::JSGlobalThis::JSGlobalThis):

  • runtime/JSPropertyNameIterator.h: Has an immortal Structure.

(JSC):

  • runtime/JSScope.cpp:

(JSC):

  • runtime/JSString.h: Has an immortal Structure.

(JSC):

  • runtime/JSWrapperObject.h: Inherit from JSDestructibleObject.

(JSWrapperObject):
(JSC::JSWrapperObject::JSWrapperObject):

  • runtime/MathObject.cpp: Cleaning up some of the inheritance stuff.

(JSC):

  • runtime/NameInstance.h: Inherit from JSDestructibleObject.

(NameInstance):

  • runtime/RegExp.h: Has immortal Structure.

(JSC):

  • runtime/RegExpObject.cpp: Inheritance cleanup.

(JSC):

  • runtime/SparseArrayValueMap.h: Has immortal Structure.

(JSC):

  • runtime/Structure.h: Has immortal Structure.

(JSC):

  • runtime/StructureChain.h: Ditto.

(JSC):

  • runtime/SymbolTable.h: Ditto.

(SharedSymbolTable):
(JSC):

Source/WebCore:

No new tests.

  • ForwardingHeaders/runtime/JSDestructableObject.h: Added.
  • bindings/js/JSDOMWrapper.h: Inherits from JSDestructibleObject.

(JSDOMWrapper):
(WebCore::JSDOMWrapper::JSDOMWrapper):

  • bindings/scripts/CodeGeneratorJS.pm: Add finalizers to anything that inherits from JSGlobalObject,

e.g. JSDOMWindow and JSWorkerContexts. For those classes we also need to define needsDestruction as true.
(GenerateHeader):

  • bridge/objc/objc_runtime.h: Inherit from JSDestructibleObject.

(ObjcFallbackObjectImp):

  • bridge/objc/objc_runtime.mm:

(Bindings):
(JSC::Bindings::ObjcFallbackObjectImp::ObjcFallbackObjectImp):

  • bridge/runtime_array.cpp: Use a finalizer so that JSArray isn't forced to inherit from JSDestructibleObject.

(JSC):
(JSC::RuntimeArray::destroy):

  • bridge/runtime_array.h:

(JSC::RuntimeArray::create):
(JSC):

  • bridge/runtime_object.cpp: Inherit from JSDestructibleObject.

(Bindings):
(JSC::Bindings::RuntimeObject::RuntimeObject):

  • bridge/runtime_object.h:

(RuntimeObject):

Location:
trunk/Source
Files:
2 added
62 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSCallbackConstructor.cpp

    r128851 r130303  
    3737namespace JSC {
    3838
    39 const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
     39const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) };
    4040
    4141JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
    42     : JSNonFinalObject(globalObject->globalData(), structure)
     42    : JSDestructibleObject(globalObject->globalData(), structure)
    4343    , m_class(jsClass)
    4444    , m_callback(callback)
  • trunk/Source/JavaScriptCore/API/JSCallbackConstructor.h

    r128851 r130303  
    2828
    2929#include "JSObjectRef.h"
    30 #include <runtime/JSObject.h>
     30#include "runtime/JSDestructibleObject.h"
    3131
    3232namespace JSC {
    3333
    34 class JSCallbackConstructor : public JSNonFinalObject {
     34class JSCallbackConstructor : public JSDestructibleObject {
    3535public:
    36     typedef JSNonFinalObject Base;
     36    typedef JSDestructibleObject Base;
    3737
    3838    static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback)
  • trunk/Source/JavaScriptCore/API/JSCallbackObject.cpp

    r128851 r130303  
    3333namespace JSC {
    3434
    35 ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSNonFinalObject>);
     35ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSDestructibleObject>);
    3636ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSGlobalObject>);
    3737
    3838// 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) };
     39template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
     40template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) };
     41
     42template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction = true;
     43template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false;
     44
     45template<>
     46JSCallbackObject<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}
    4153
    4254template <>
    43 Structure* JSCallbackObject<JSNonFinalObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
     55Structure* JSCallbackObject<JSDestructibleObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
    4456{
    4557    return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info);
  • trunk/Source/JavaScriptCore/API/JSCallbackObject.h

    r129281 r130303  
    134134        return callbackObject;
    135135    }
    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*);
    142140
    143141    void setPrivate(void* data);
     
    173171private:
    174172    static String className(const JSObject*);
    175 
    176     static void destroy(JSCell*);
    177173
    178174    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
  • trunk/Source/JavaScriptCore/API/JSClassRef.cpp

    r128851 r130303  
    200200
    201201    // Recursive, but should be good enough for our purposes
    202     JSObject* prototype = JSCallbackObject<JSNonFinalObject>::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
     202    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
    203203    if (parentClass) {
    204204        if (JSObject* parentPrototype = parentClass->prototype(exec))
  • trunk/Source/JavaScriptCore/API/JSObjectRef.cpp

    r128851 r130303  
    8484        return toRef(constructEmptyObject(exec));
    8585
    86     JSCallbackObject<JSNonFinalObject>* 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);
    8787    if (JSObject* prototype = jsClass->prototype(exec))
    8888        object->setPrototype(exec->globalData(), prototype);
     
    342342    if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
    343343        return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate();
    344     if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info))
    345         return jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivate();
     344    if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
     345        return jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivate();
    346346   
    347347    return 0;
     
    356356        return true;
    357357    }
    358     if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
    359         jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivate(data);
     358    if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
     359        jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data);
    360360        return true;
    361361    }
     
    373373    if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
    374374        result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
    375     else if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info))
    376         result = jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivateProperty(name);
     375    else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
     376        result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name);
    377377    return toRef(exec, result);
    378378}
     
    389389        return true;
    390390    }
    391     if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
    392         jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
     391    if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
     392        jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue);
    393393        return true;
    394394    }
     
    406406        return true;
    407407    }
    408     if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) {
    409         jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->deletePrivateProperty(name);
     408    if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) {
     409        jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name);
    410410        return true;
    411411    }
  • trunk/Source/JavaScriptCore/API/JSValueRef.cpp

    r129281 r130303  
    132132        if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info))
    133133            return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
    134         if (o->inherits(&JSCallbackObject<JSNonFinalObject>::s_info))
    135             return jsCast<JSCallbackObject<JSNonFinalObject>*>(o)->inherits(jsClass);
     134        if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info))
     135            return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass);
    136136    }
    137137    return false;
  • trunk/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp

    r128851 r130303  
    5858    if (!obj)
    5959        return;
    60     ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSNonFinalObject>::s_info));
     60    ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSDestructibleObject>::s_info));
    6161    map->map().set(exec->globalData(), key, obj);
    6262}
  • trunk/Source/JavaScriptCore/ChangeLog

    r130237 r130303  
     12012-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
    1173== Rolled over to ChangeLog-2012-10-02 ==
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r129713 r130303  
    536536        Source/JavaScriptCore/runtime/JSDateMath.cpp \
    537537        Source/JavaScriptCore/runtime/JSDateMath.h \
     538    Source/JavaScriptCore/runtime/JSDestructibleObject.h \
    538539        Source/JavaScriptCore/runtime/JSFunction.cpp \
    539540        Source/JavaScriptCore/runtime/JSFunction.h \
  • trunk/Source/JavaScriptCore/JSCTypedArrayStubs.h

    r128957 r130303  
    2727#define JSCTypedArrayStubs_h
    2828
    29 #include "JSObject.h"
     29#include "JSDestructibleObject.h"
    3030#include "ObjectPrototype.h"
    3131#include <wtf/Float32Array.h>
     
    4343   
    4444#define TYPED_ARRAY(name, type) \
    45 class JS##name##Array : public JSNonFinalObject { \
     45class JS##name##Array : public JSDestructibleObject { \
    4646public: \
    47     typedef JSNonFinalObject Base; \
     47    typedef JSDestructibleObject Base; \
    4848    static JS##name##Array* create(JSC::Structure* structure, JSGlobalObject* globalObject, PassRefPtr<name##Array> impl) \
    4949    { \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r129713 r130303  
    843843                        </File>
    844844                        <File
     845                                RelativePath="..\..\runtime\JSDestructibleObject.h"
     846                                >
     847                        </File>
     848                        <File
    845849                                RelativePath="..\..\runtime\JSFunction.cpp"
    846850                                >
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r129713 r130303  
    713713                C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; };
    714714                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, ); }; };
    715716                C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
    716717                C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */; };
     
    14881489                C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; };
    14891490                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>"; };
    14901492                C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocator.h; sourceTree = "<group>"; };
    14911493                C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedAllocator.cpp; sourceTree = "<group>"; };
     
    21312133                                9788FC221471AD0C0068CE2D /* JSDateMath.cpp */,
    21322134                                9788FC231471AD0C0068CE2D /* JSDateMath.h */,
     2135                                C2A7F687160432D400F76B98 /* JSDestructibleObject.h */,
    21332136                                A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */,
    21342137                                F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
     
    25702573                                C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
    25712574                                C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
     2575                                C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
    25722576                                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
    25732577                                C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */,
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r128957 r130303  
    21902190    // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will
    21912191    // get clobbered.
    2192     template <typename ClassType, bool destructor, typename StructureType>
     2192    template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType>
    21932193    void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
    21942194    {
    21952195        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));
    21982200        else
    21992201            allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType));
     
    22172219    void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
    22182220    {
    2219         return emitAllocateBasicJSObject<JSFinalObject, false>(structure, resultGPR, scratchGPR, slowPath);
     2221        return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, slowPath);
    22202222    }
    22212223
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r129586 r130303  
    943943}
    944944
    945 bool Heap::isSafeToSweepStructures()
    946 {
    947     return !m_sweeper || m_sweeper->structuresCanBeSwept();
    948 }
    949 
    950945void Heap::didStartVMShutdown()
    951946{
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r129586 r130303  
    113113        MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); }
    114114        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); }
    116117        CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); }
    117118        CheckedBoolean tryAllocateStorage(size_t, void**);
     
    170171
    171172        bool isPagedOut(double deadline);
    172         bool isSafeToSweepStructures();
    173173        void didStartVMShutdown();
    174174
     
    186186        template<typename T> friend void* allocateCell(Heap&, size_t);
    187187
    188         void* allocateWithDestructor(size_t);
    189         void* allocateWithoutDestructor(size_t);
    190         void* allocateStructure(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.
    191191
    192192        static const size_t minExtraCost = 256;
     
    364364    }
    365365
    366     inline void* Heap::allocateWithDestructor(size_t bytes)
     366    inline void* Heap::allocateWithNormalDestructor(size_t bytes)
    367367    {
    368368        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);
    370376    }
    371377   
     
    376382    }
    377383   
    378     inline void* Heap::allocateStructure(size_t bytes)
    379     {
    380         return m_objectSpace.allocateStructure(bytes);
    381     }
    382  
    383384    inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr)
    384385    {
  • trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp

    r128851 r130303  
    4949    : HeapTimer(heap->globalData(), runLoop)
    5050    , m_currentBlockToSweepIndex(0)
    51     , m_structuresCanBeSwept(false)
    5251{
    5352}
     
    7372    : HeapTimer(heap->globalData())
    7473    , m_currentBlockToSweepIndex(0)
    75     , m_structuresCanBeSwept(false)
    7674{
    7775}
     
    120118    while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
    121119        MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++];
    122         if (block->onlyContainsStructures())
    123             m_structuresCanBeSwept = true;
    124         else
    125             ASSERT(!m_structuresCanBeSwept);
    126120
    127121        if (!block->needsSweeping())
     
    140134    m_globalData->heap.objectSpace().forEachBlock(functor);
    141135    m_currentBlockToSweepIndex = 0;
    142     m_structuresCanBeSwept = false;
    143136    scheduleTimer();
    144137}
     
    147140{
    148141    m_currentBlockToSweepIndex = 0;
    149     m_structuresCanBeSwept = true;
    150142    m_blocksToSweep.clear();
    151143    if (m_globalData)
     
    157149IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData)
    158150    : HeapTimer(globalData)
    159     , m_structuresCanBeSwept(false)
    160151{
    161152}
     
    172163void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&)
    173164{
    174     m_structuresCanBeSwept = false;
    175165}
    176166
    177167void IncrementalSweeper::willFinishSweeping()
    178168{
    179     m_structuresCanBeSwept = true;
    180169}
    181170
     
    186175#endif
    187176
    188 bool IncrementalSweeper::structuresCanBeSwept()
    189 {
    190     return m_structuresCanBeSwept;
    191 }
    192 
    193177} // namespace JSC
  • trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h

    r128851 r130303  
    5757    virtual void doWork();
    5858    void sweepNextBlock();
    59     bool structuresCanBeSwept();
    6059    void willFinishSweeping();
    6160
     
    7978   
    8079#endif
    81     bool m_structuresCanBeSwept;
    8280};
    8381
  • trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp

    r128851 r130303  
    3131{
    3232    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 progress
    39             // toward being able to sweep Structures.
    40             m_heap->sweeper()->sweepNextBlock();
    41             return 0;
    42         }
    43 
    4433        for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) {
    4534            MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList);
     
    125114    if (blockSize == MarkedBlock::blockSize) {
    126115        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);
    128117    }
    129118
     
    131120    if (!static_cast<bool>(allocation))
    132121        CRASH();
    133     return MarkedBlock::create(allocation, m_heap, cellSize, m_cellsNeedDestruction, m_onlyContainsStructures);
     122    return MarkedBlock::create(allocation, this, cellSize, m_destructorType);
    134123}
    135124
  • trunk/Source/JavaScriptCore/heap/MarkedAllocator.h

    r128851 r130303  
    2424    void canonicalizeCellLivenessData();
    2525    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; }
    2827    void* allocate(size_t);
    2928    Heap* heap() { return m_heap; }
     
    3332    void addBlock(MarkedBlock*);
    3433    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);
    3635
    3736    bool isPagedOut(double deadline);
     
    5049    DoublyLinkedList<MarkedBlock> m_blockList;
    5150    size_t m_cellSize;
    52     bool m_cellsNeedDestruction;
    53     bool m_onlyContainsStructures;
     51    MarkedBlock::DestructorType m_destructorType;
    5452    Heap* m_heap;
    5553    MarkedSpace* m_markedSpace;
     
    6058    , m_blocksToSweep(0)
    6159    , m_cellSize(0)
    62     , m_cellsNeedDestruction(true)
    63     , m_onlyContainsStructures(false)
     60    , m_destructorType(MarkedBlock::None)
    6461    , m_heap(0)
    6562    , m_markedSpace(0)
     
    6764}
    6865
    69 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
     66inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType)
    7067{
    7168    m_heap = heap;
    7269    m_markedSpace = markedSpace;
    7370    m_cellSize = cellSize;
    74     m_cellsNeedDestruction = cellsNeedDestruction;
    75     m_onlyContainsStructures = onlyContainsStructures;
     71    m_destructorType = destructorType;
    7672}
    7773
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp

    r128851 r130303  
    2929#include "IncrementalSweeper.h"
    3030#include "JSCell.h"
    31 #include "JSObject.h"
     31#include "JSDestructibleObject.h"
    3232
    3333
    3434namespace JSC {
    3535
    36 MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
     36MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
    3737{
    38     return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures);
     38    return new (NotNull, allocation.base()) MarkedBlock(allocation, allocator, cellSize, destructorType);
    3939}
    4040
    41 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
     41MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
    4242    : HeapBlock<MarkedBlock>(allocation)
    4343    , m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
    4444    , m_endAtom(atomsPerBlock - m_atomsPerCell + 1)
    45     , m_cellsNeedDestruction(cellsNeedDestruction)
    46     , m_onlyContainsStructures(onlyContainsStructures)
     45    , m_destructorType(destructorType)
     46    , m_allocator(allocator)
    4747    , m_state(New) // All cells start out unmarked.
    48     , m_weakSet(heap->globalData())
     48    , m_weakSet(allocator->heap()->globalData())
    4949{
    50     ASSERT(heap);
     50    ASSERT(allocator);
    5151    HEAP_LOG_BLOCK_STATE_TRANSITION(this);
    5252}
     
    6666}
    6767
    68 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool destructorCallNeeded>
     68template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, MarkedBlock::DestructorType dtorType>
    6969MarkedBlock::FreeList MarkedBlock::specializedSweep()
    7070{
    7171    ASSERT(blockState != Allocated && blockState != FreeListed);
    72     ASSERT(destructorCallNeeded || sweepMode != SweepOnly);
     72    ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly));
    7373
    7474    // This produces a free list that is ordered in reverse through the block.
     
    8383        JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
    8484
    85         if (destructorCallNeeded && blockState != New)
     85        if (dtorType != MarkedBlock::None && blockState != New)
    8686            callDestructor(cell);
    8787
     
    104104    m_weakSet.sweep();
    105105
    106     if (sweepMode == SweepOnly && !m_cellsNeedDestruction)
     106    if (sweepMode == SweepOnly && m_destructorType == MarkedBlock::None)
    107107        return FreeList();
    108108
    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);
    112114}
    113115
    114 template<bool destructorCallNeeded>
     116template<MarkedBlock::DestructorType dtorType>
    115117MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
    116118{
     
    118120    case New:
    119121        ASSERT(sweepMode == SweepToFreeList);
    120         return specializedSweep<New, SweepToFreeList, destructorCallNeeded>();
     122        return specializedSweep<New, SweepToFreeList, dtorType>();
    121123    case FreeListed:
    122124        // Happens when a block transitions to fully allocated.
     
    127129        return FreeList();
    128130    case Marked:
    129         ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures());
    130131        return sweepMode == SweepToFreeList
    131             ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>()
    132             : specializedSweep<Marked, SweepOnly, destructorCallNeeded>();
     132            ? specializedSweep<Marked, SweepToFreeList, dtorType>()
     133            : specializedSweep<Marked, SweepOnly, dtorType>();
    133134    }
    134135
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.h

    r128851 r130303  
    5353    class Heap;
    5454    class JSCell;
     55    class MarkedAllocator;
    5556
    5657    typedef uintptr_t Bits;
     
    113114        };
    114115
    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);
    116118
    117119        static bool isAtomAligned(const void*);
     
    121123        void lastChanceToFinalize();
    122124
     125        MarkedAllocator* allocator() const;
    123126        Heap* heap() const;
    124127        JSGlobalData* globalData() const;
     
    144147
    145148        size_t cellSize();
    146         bool cellsNeedDestruction();
    147         bool onlyContainsStructures();
     149        DestructorType destructorType();
    148150
    149151        size_t size();
     
    195197
    196198        enum BlockState { New, FreeListed, Allocated, Marked };
    197         template<bool destructorCallNeeded> FreeList sweepHelper(SweepMode = SweepOnly);
     199        template<DestructorType> FreeList sweepHelper(SweepMode = SweepOnly);
    198200
    199201        typedef char Atom[atomSize];
    200202
    201         MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
     203        MarkedBlock(const PageAllocationAligned&, MarkedAllocator*, size_t cellSize, DestructorType);
    202204        Atom* atoms();
    203205        size_t atomNumber(const void*);
    204206        void callDestructor(JSCell*);
    205         template<BlockState, SweepMode, bool destructorCallNeeded> FreeList specializedSweep();
     207        template<BlockState, SweepMode, DestructorType> FreeList specializedSweep();
    206208       
    207209#if ENABLE(GGC)
     
    216218        WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks;
    217219#endif
    218         bool m_cellsNeedDestruction;
    219         bool m_onlyContainsStructures;
     220        DestructorType m_destructorType;
     221        MarkedAllocator* m_allocator;
    220222        BlockState m_state;
    221223        WeakSet m_weakSet;
     
    262264    }
    263265
     266    inline MarkedAllocator* MarkedBlock::allocator() const
     267    {
     268        return m_allocator;
     269    }
     270
    264271    inline Heap* MarkedBlock::heap() const
    265272    {
     
    327334    }
    328335
    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;
    337339    }
    338340
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp

    r128851 r130303  
    8282{
    8383    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);
    9598}
    9699
     
    121124    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
    122125        allocatorFor(cellSize).reset();
    123         destructorAllocatorFor(cellSize).reset();
     126        normalDestructorAllocatorFor(cellSize).reset();
     127        immortalStructureDestructorAllocatorFor(cellSize).reset();
    124128    }
    125129
    126130    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
    127131        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();
    133139}
    134140
     
    148154    for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
    149155        allocatorFor(cellSize).canonicalizeCellLivenessData();
    150         destructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
     156        normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
     157        immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData();
    151158    }
    152159
    153160    for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) {
    154161        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();
    160169}
    161170
     
    163172{
    164173    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))
    166177            return true;
    167178    }
    168179
    169180    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))
    171184            return true;
    172185    }
    173186
    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))
    175190        return true;
    176191
    177     if (m_structureAllocator.isPagedOut(deadline))
    178         return true;
    179 
    180192    return false;
    181193}
     
    183195void MarkedSpace::freeBlock(MarkedBlock* block)
    184196{
    185     allocatorFor(block).removeBlock(block);
     197    block->allocator()->removeBlock(block);
    186198    m_blocks.remove(block);
    187199    if (block->capacity() == MarkedBlock::blockSize) {
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.h

    r129586 r130303  
    7777    MarkedAllocator& firstAllocator();
    7878    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);
    8283    void* allocateWithoutDestructor(size_t);
    83     void* allocateStructure(size_t);
    8484 
    8585    void resetAllocators();
     
    132132        FixedArray<MarkedAllocator, preciseCount> preciseAllocators;
    133133        FixedArray<MarkedAllocator, impreciseCount> impreciseAllocators;
     134        MarkedAllocator largeAllocator;
    134135    };
    135136
    136     Subspace m_destructorSpace;
     137    Subspace m_normalDestructorSpace;
     138    Subspace m_immortalStructureDestructorSpace;
    137139    Subspace m_normalSpace;
    138     MarkedAllocator m_largeAllocator;
    139     MarkedAllocator m_structureAllocator;
    140140
    141141    Heap* m_heap;
     
    187187    if (bytes <= impreciseCutoff)
    188188        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
     192inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes)
    204193{
    205194    ASSERT(bytes);
    206195    if (bytes <= preciseCutoff)
    207         return m_destructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
     196        return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep];
    208197    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
     202inline 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;
    211210}
    212211
     
    216215}
    217216
    218 inline void* MarkedSpace::allocateWithDestructor(size_t bytes)
    219 {
    220     return destructorAllocatorFor(bytes).allocate(bytes);
    221 }
    222 
    223 inline void* MarkedSpace::allocateStructure(size_t bytes)
    224 {
    225     return m_structureAllocator.allocate(bytes);
     217inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes)
     218{
     219    return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes);
     220}
     221
     222inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes)
     223{
     224    return normalDestructorAllocatorFor(bytes).allocate(bytes);
    226225}
    227226
     
    230229    for (size_t i = 0; i < preciseCount; ++i) {
    231230        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);
    233233    }
    234234
    235235    for (size_t i = 0; i < impreciseCount; ++i) {
    236236        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);
    238239    }
    239240
    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);
    242244
    243245    return functor.returnValue();
  • trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp

    r128851 r130303  
    66#include "CopiedSpaceInlineMethods.h"
    77#include "JSArray.h"
     8#include "JSDestructibleObject.h"
    89#include "JSGlobalData.h"
    910#include "JSObject.h"
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r129045 r130303  
    435435        void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind);
    436436
    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);
    438438        void emitAllocateBasicStorage(size_t, ptrdiff_t offsetFromBase, RegisterID result);
    439439        template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
  • trunk/Source/JavaScriptCore/jit/JITInlineMethods.h

    r129281 r130303  
    406406}
    407407
    408 template <typename ClassType, bool destructor, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr)
     408template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr)
    409409{
    410410    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));
    413415    else
    414416        allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType));
     
    429431template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch)
    430432{
    431     emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch);
     433    emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None, T>(structure, result, scratch);
    432434}
    433435
     
    455457    // Allocate the cell for the array.
    456458    loadPtr(m_codeBlock->globalObject()->addressOfArrayStructure(), scratch);
    457     emitAllocateBasicJSObject<JSArray, false>(scratch, cellResult, storagePtr);
     459    emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(scratch, cellResult, storagePtr);
    458460
    459461    // Store all the necessary info in the ArrayStorage.
  • trunk/Source/JavaScriptCore/jsc.cpp

    r129719 r130303  
    178178        GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure);
    179179        object->finishCreation(globalData, arguments);
     180        globalData.heap.addFinalizer(object, destroy);
    180181        object->setGlobalThis(globalData, JSProxy::create(globalData, JSProxy::createStructure(globalData, object, object->prototype()), object));
    181182        return object;
    182183    }
     184
     185    static const bool needsDestruction = false;
    183186
    184187    static const ClassInfo s_info;
     
    246249    }
    247250};
     251
    248252COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
    249253ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r129297 r130303  
    3636ASSERT_CLASS_FITS_IN_CELL(Arguments);
    3737
    38 const ClassInfo Arguments::s_info = { "Arguments", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
     38const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
    3939
    4040void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r129297 r130303  
    2727#include "CodeOrigin.h"
    2828#include "JSActivation.h"
     29#include "JSDestructibleObject.h"
    2930#include "JSFunction.h"
    3031#include "JSGlobalObject.h"
     
    3435namespace JSC {
    3536
    36     class Arguments : public JSNonFinalObject {
     37    class Arguments : public JSDestructibleObject {
    3738        friend class JIT;
    3839        friend class DFG::SpeculativeJIT;
    3940    public:
    40         typedef JSNonFinalObject Base;
     41        typedef JSDestructibleObject Base;
    4142
    4243        static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame)
     
    148149
    149150    inline Arguments::Arguments(CallFrame* callFrame)
    150         : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
     151        : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
    151152    {
    152153    }
    153154
    154155    inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
    155         : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
     156        : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
    156157    {
    157158    }
  • trunk/Source/JavaScriptCore/runtime/ErrorPrototype.cpp

    r128851 r130303  
    3232
    3333ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
     34ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorPrototype);
    3435
    3536static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*);
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r129453 r130303  
    8282
    8383#if ENABLE(JIT)
     84        static const bool needsDestruction = true;
     85        static const bool hasImmortalStructure = true;
    8486        static void destroy(JSCell*);
    8587#endif
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp

    r128851 r130303  
    3333ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction);
    3434
    35 const ClassInfo InternalFunction::s_info = { "Function", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
     35const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) };
    3636
    3737InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure)
    38     : JSNonFinalObject(globalObject->globalData(), structure)
     38    : JSDestructibleObject(globalObject->globalData(), structure)
    3939{
    4040}
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.h

    r128851 r130303  
    2525#define InternalFunction_h
    2626
    27 #include "JSObject.h"
    2827#include "Identifier.h"
     28#include "JSDestructibleObject.h"
    2929
    3030namespace JSC {
     
    3232    class FunctionPrototype;
    3333
    34     class InternalFunction : public JSNonFinalObject {
     34    class InternalFunction : public JSDestructibleObject {
    3535    public:
    36         typedef JSNonFinalObject Base;
     36        typedef JSDestructibleObject Base;
    3737
    3838        static JS_EXPORTDATA const ClassInfo s_info;
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r129281 r130303  
    3838namespace JSC {
    3939
     40    class JSDestructibleObject;
    4041    class JSGlobalObject;
    4142    class LLIntOffsetsExtractor;
     
    7172        static const unsigned StructureFlags = 0;
    7273
     74        static const bool needsDestruction = false;
     75        static const bool hasImmortalStructure = false;
     76
    7377        enum CreatingEarlyCellTag { CreatingEarlyCell };
    7478        JSCell(CreatingEarlyCellTag);
     
    310314    }
    311315
    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 #endif
    324         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    
    335316    template<typename T>
    336317    void* allocateCell(Heap& heap, size_t size)
     
    342323#endif
    343324        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
    348330            result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
    349         }
    350331        result->clearStructure();
    351332        return result;
    352333    }
    353334   
     335    template<typename T>
     336    void* allocateCell(Heap& heap)
     337    {
     338        return allocateCell<T>(heap, sizeof(T));
     339    }
     340   
    354341    inline bool isZapped(const JSCell* cell)
    355342    {
     
    363350        return static_cast<To>(from);
    364351    }
    365 
     352   
    366353    template<typename To>
    367354    inline To jsCast(JSValue from)
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r129713 r130303  
    229229    m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), this, m_objectPrototype.get()));
    230230    m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), this, m_objectPrototype.get()));
    231     m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSNonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
     231    m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
    232232
    233233    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  
    7878    class JSGlobalObject : public JSSegmentedVariableObject {
    7979    private:
    80         typedef JSSegmentedVariableObject Base;
    8180        typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
    8281
     
    171170                return;
    172171            m_rareData = adoptPtr(new JSGlobalObjectRareData);
    173             Heap::heap(this)->addFinalizer(this, clearRareData);
    174172        }
    175173       
    176174    public:
     175        typedef JSSegmentedVariableObject Base;
     176
    177177        static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure)
    178178        {
    179179            JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure);
    180180            globalObject->finishCreation(globalData);
     181            globalData.heap.addFinalizer(globalObject, destroy);
    181182            return globalObject;
    182183        }
     
    206207        JS_EXPORT_PRIVATE ~JSGlobalObject();
    207208        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;
    208211
    209212        JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
  • trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h

    r128851 r130303  
    4949        static JSPropertyNameIterator* create(ExecState*, JSObject*);
    5050
     51        static const bool needsDestruction = true;
     52        static const bool hasImmortalStructure = true;
    5153        static void destroy(JSCell*);
    5254       
  • trunk/Source/JavaScriptCore/runtime/JSProxy.h

    r129719 r130303  
    2727#define JSProxy_h
    2828
    29 #include "JSObject.h"
     29#include "JSDestructibleObject.h"
    3030
    3131namespace JSC {
    3232
    33 class JSProxy : public JSNonFinalObject {
     33class JSProxy : public JSDestructibleObject {
    3434public:
    35     typedef JSNonFinalObject Base;
     35    typedef JSDestructibleObject Base;
    3636
    3737    static JSProxy* create(JSGlobalData& globalData, Structure* structure, JSObject* target)
     
    5353protected:
    5454    JSProxy(JSGlobalData& globalData, Structure* structure)
    55         : JSNonFinalObject(globalData, structure)
     55        : JSDestructibleObject(globalData, structure)
    5656    {
    5757    }
  • trunk/Source/JavaScriptCore/runtime/JSScope.cpp

    r128851 r130303  
    3535
    3636ASSERT_CLASS_FITS_IN_CELL(JSScope);
     37ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSScope);
    3738
    3839void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r128957 r130303  
    7272        typedef JSCell Base;
    7373
     74        static const bool needsDestruction = true;
     75        static const bool hasImmortalStructure = true;
    7476        static void destroy(JSCell*);
    7577
  • trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h

    r128851 r130303  
    2323#define JSWrapperObject_h
    2424
    25 #include "JSObject.h"
     25#include "JSDestructibleObject.h"
    2626
    2727namespace JSC {
     
    2929    // This class is used as a base for classes such as String,
    3030    // Number, Boolean and Date which are wrappers for primitive types.
    31     class JSWrapperObject : public JSNonFinalObject {
     31    class JSWrapperObject : public JSDestructibleObject {
    3232    public:
    33         typedef JSNonFinalObject Base;
     33        typedef JSDestructibleObject Base;
    3434
    3535        JSValue internalValue() const;
     
    4343    protected:
    4444        explicit JSWrapperObject(JSGlobalData&, Structure*);
    45         static const unsigned StructureFlags = OverridesVisitChildren | JSNonFinalObject::StructureFlags;
     45        static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
    4646
    4747        static void visitChildren(JSCell*, SlotVisitor&);
     
    5252
    5353    inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure)
    54         : JSNonFinalObject(globalData, structure)
     54        : JSDestructibleObject(globalData, structure)
    5555    {
    5656    }
  • trunk/Source/JavaScriptCore/runtime/MathObject.cpp

    r128851 r130303  
    3434
    3535ASSERT_CLASS_FITS_IN_CELL(MathObject);
     36ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject);
    3637
    3738static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*);
     
    6061namespace JSC {
    6162
    62 ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject);
    63 
    64 const ClassInfo MathObject::s_info = { "Math", &JSNonFinalObject::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) };
     63const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) };
    6564
    6665/* Source for MathObject.lut.h
  • trunk/Source/JavaScriptCore/runtime/NameInstance.h

    r128851 r130303  
    2727#define NameInstance_h
    2828
    29 #include "JSObject.h"
     29#include "JSDestructibleObject.h"
    3030#include "PrivateName.h"
    3131
    3232namespace JSC {
    3333
    34 class NameInstance : public JSNonFinalObject {
     34class NameInstance : public JSDestructibleObject {
    3535public:
    36     typedef JSNonFinalObject Base;
     36    typedef JSDestructibleObject Base;
    3737
    3838    static const ClassInfo s_info;
  • trunk/Source/JavaScriptCore/runtime/RegExp.h

    r128851 r130303  
    4848
    4949        JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags);
     50        static const bool needsDestruction = true;
     51        static const bool hasImmortalStructure = true;
    5052        static void destroy(JSCell*);
    5153
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r128851 r130303  
    5151
    5252ASSERT_CLASS_FITS_IN_CELL(RegExpObject);
    53 
    54 const ClassInfo RegExpObject::s_info = { "RegExp", &JSNonFinalObject::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) };
     53ASSERT_HAS_TRIVIAL_DESTRUCTOR(RegExpObject);
     54
     55const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) };
    5556
    5657/* Source for RegExpObject.lut.h
  • trunk/Source/JavaScriptCore/runtime/SparseArrayValueMap.h

    r128851 r130303  
    8282    static SparseArrayValueMap* create(JSGlobalData&);
    8383   
     84    static const bool needsDestruction = true;
     85    static const bool hasImmortalStructure = true;
    8486    static void destroy(JSCell*);
    8587   
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r128851 r130303  
    129129        Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
    130130
     131        static const bool needsDestruction = true;
     132        static const bool hasImmortalStructure = true;
    131133        static void destroy(JSCell*);
    132134
     
    474476    };
    475477
    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     }
    486 
    487478    inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType)
    488479    {
     
    629620    }
    630621
    631     inline const ClassInfo* JSCell::classInfo() const
    632     {
    633 #if ENABLE(GC_VALIDATION)
    634         return m_structure.unvalidatedGet()->classInfo();
    635 #else
    636         return m_structure->classInfo();
    637 #endif
    638     }
    639 
    640622} // namespace JSC
    641623
  • trunk/Source/JavaScriptCore/runtime/StructureChain.h

    r128851 r130303  
    6060        static ClassInfo s_info;
    6161
     62        static const bool needsDestruction = true;
     63        static const bool hasImmortalStructure = true;
     64        static void destroy(JSCell*);
     65
    6266    protected:
    6367        void finishCreation(JSGlobalData& globalData, Structure* head)
     
    7983       
    8084        StructureChain(JSGlobalData&, Structure*);
    81         static void destroy(JSCell*);
    8285        OwnArrayPtr<WriteBarrier<Structure> > m_vector;
    8386    };
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r129297 r130303  
    345345    class SharedSymbolTable : public JSCell, public SymbolTable {
    346346    public:
     347        typedef JSCell Base;
     348
    347349        static SharedSymbolTable* create(JSGlobalData& globalData)
    348350        {
     
    351353            return sharedSymbolTable;
    352354        }
     355        static const bool needsDestruction = true;
     356        static const bool hasImmortalStructure = true;
    353357        static void destroy(JSCell*);
    354358
     
    397401        OwnArrayPtr<SlowArgument> m_slowArguments;
    398402    };
     403
    399404} // namespace JSC
    400405
  • trunk/Source/JavaScriptCore/testRegExp.cpp

    r128851 r130303  
    116116    static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments)
    117117    {
    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;
    119121    }
    120122
    121123    static const ClassInfo s_info;
     124
     125    static const bool needsDestructor = false;
    122126
    123127    static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
  • trunk/Source/WebCore/ChangeLog

    r130302 r130303  
     12012-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
    1412012-10-02  Anders Carlsson  <andersca@apple.com>
    242
  • trunk/Source/WebCore/bindings/js/JSDOMWrapper.h

    r128851 r130303  
    2424
    2525#include "JSDOMGlobalObject.h"
    26 #include <runtime/JSObject.h>
     26#include <runtime/JSDestructibleObject.h>
    2727
    2828namespace WebCore {
     
    3030class ScriptExecutionContext;
    3131
    32 class JSDOMWrapper : public JSC::JSNonFinalObject {
     32class JSDOMWrapper : public JSC::JSDestructibleObject {
    3333public:
     34    typedef JSC::JSDestructibleObject Base;
     35
    3436    JSDOMGlobalObject* globalObject() const { return JSC::jsCast<JSDOMGlobalObject*>(JSC::JSNonFinalObject::globalObject()); }
    3537    ScriptExecutionContext* scriptExecutionContext() const { return globalObject()->scriptExecutionContext(); }
     
    3739protected:
    3840    JSDOMWrapper(JSC::Structure* structure, JSC::JSGlobalObject* globalObject)
    39         : JSNonFinalObject(globalObject->globalData(), structure)
     41        : JSDestructibleObject(globalObject->globalData(), structure)
    4042    {
    4143        ASSERT(scriptExecutionContext());
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r130255 r130303  
    743743        push(@headerContent, "        $className* ptr = new (NotNull, JSC::allocateCell<$className>(globalData.heap)) ${className}(globalData, structure, impl, windowShell);\n");
    744744        push(@headerContent, "        ptr->finishCreation(globalData, windowShell);\n");
     745        push(@headerContent, "        globalData.heap.addFinalizer(ptr, destroy);\n");
    745746        push(@headerContent, "        return ptr;\n");
    746747        push(@headerContent, "    }\n\n");
     
    750751        push(@headerContent, "        $className* ptr = new (NotNull, JSC::allocateCell<$className>(globalData.heap)) ${className}(globalData, structure, impl);\n");
    751752        push(@headerContent, "        ptr->finishCreation(globalData);\n");
     753        push(@headerContent, "        globalData.heap.addFinalizer(ptr, destroy);\n");
    752754        push(@headerContent, "        return ptr;\n");
    753755        push(@headerContent, "    }\n\n");
     
    769771        push(@headerContent, "        return ptr;\n");
    770772        push(@headerContent, "    }\n\n");
     773    }
     774
     775    if ($interfaceName eq "DOMWindow" || $dataNode->extendedAttributes->{"IsWorkerContext"}) {
     776        push(@headerContent, "    static const bool needsDestruction = false;\n\n");
    771777    }
    772778
  • trunk/Source/WebCore/bridge/objc/objc_runtime.h

    r128851 r130303  
    9191};
    9292
    93 class ObjcFallbackObjectImp : public JSNonFinalObject {
     93class ObjcFallbackObjectImp : public JSDestructibleObject {
    9494public:
    95     typedef JSNonFinalObject Base;
     95    typedef JSDestructibleObject Base;
    9696
    9797    static ObjcFallbackObjectImp* create(ExecState* exec, JSGlobalObject* globalObject, ObjcInstance* instance, const String& propertyName)
  • trunk/Source/WebCore/bridge/objc/objc_runtime.mm

    r128851 r130303  
    189189}
    190190
    191 const ClassInfo ObjcFallbackObjectImp::s_info = { "ObjcFallbackObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(ObjcFallbackObjectImp) };
     191const ClassInfo ObjcFallbackObjectImp::s_info = { "ObjcFallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ObjcFallbackObjectImp) };
    192192
    193193ObjcFallbackObjectImp::ObjcFallbackObjectImp(JSGlobalObject* globalObject, Structure* structure, ObjcInstance* i, const String& propertyName)
    194     : JSNonFinalObject(globalObject->globalData(), structure)
     194    : JSDestructibleObject(globalObject->globalData(), structure)
    195195    , _instance(i)
    196196    , m_item(propertyName)
  • trunk/Source/WebCore/bridge/runtime_array.cpp

    r128851 r130303  
    3636namespace JSC {
    3737
    38 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) };
     38const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeArray) };
    3939
    4040RuntimeArray::RuntimeArray(ExecState* exec, Structure* structure)
     
    5858void RuntimeArray::destroy(JSCell* cell)
    5959{
    60     static_cast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
     60    jsCast<RuntimeArray*>(cell)->RuntimeArray::~RuntimeArray();
    6161}
    6262
  • trunk/Source/WebCore/bridge/runtime_array.h

    r128851 r130303  
    4444        RuntimeArray* runtimeArray = new (NotNull, allocateCell<RuntimeArray>(*exec->heap())) RuntimeArray(exec, domStructure);
    4545        runtimeArray->finishCreation(exec->globalData(), array);
     46        exec->globalData().heap.addFinalizer(runtimeArray, destroy);
    4647        return runtimeArray;
    4748    }
     
    5051    ~RuntimeArray();
    5152    static void destroy(JSCell*);
     53    static const bool needsDestruction = false;
    5254
    5355    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     
    8991    BindingsArray* m_array;
    9092};
    91    
     93
    9294} // namespace JSC
    9395
  • trunk/Source/WebCore/bridge/runtime_object.cpp

    r129969 r130303  
    3636namespace Bindings {
    3737
    38 const ClassInfo RuntimeObject::s_info = { "RuntimeObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeObject) };
     38const ClassInfo RuntimeObject::s_info = { "RuntimeObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(RuntimeObject) };
    3939
    4040RuntimeObject::RuntimeObject(ExecState*, JSGlobalObject* globalObject, Structure* structure, PassRefPtr<Instance> instance)
    41     : JSNonFinalObject(globalObject->globalData(), structure)
     41    : JSDestructibleObject(globalObject->globalData(), structure)
    4242    , m_instance(instance)
    4343{
  • trunk/Source/WebCore/bridge/runtime_object.h

    r128851 r130303  
    3333namespace Bindings {
    3434
    35 class RuntimeObject : public JSNonFinalObject {
     35class RuntimeObject : public JSDestructibleObject {
    3636public:
    37     typedef JSNonFinalObject Base;
     37    typedef JSDestructibleObject Base;
    3838
    3939    static RuntimeObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, PassRefPtr<Instance> instance)
  • trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp

    r128851 r130303  
    5555}
    5656
    57 const ClassInfo JSNPObject::s_info = { "NPObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) };
     57const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) };
    5858
    5959JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject)
    60     : JSNonFinalObject(globalObject->globalData(), structure)
     60    : JSDestructibleObject(globalObject->globalData(), structure)
    6161    , m_objectMap(objectMap)
    6262    , m_npObject(npObject)
  • trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h

    r128851 r130303  
    4242// JSNPObject is a JSObject that wraps an NPObject.
    4343
    44 class JSNPObject : public JSC::JSNonFinalObject {
     44class JSNPObject : public JSC::JSDestructibleObject {
    4545public:
    46     typedef JSC::JSNonFinalObject Base;
     46    typedef JSC::JSDestructibleObject Base;
    4747
    4848    static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject)
Note: See TracChangeset for help on using the changeset viewer.