Ignore:
Timestamp:
Mar 20, 2015, 11:08:29 AM (10 years ago)
Author:
[email protected]
Message:

JSCallbackObject<JSGlobalObject> should not destroy its JSCallbackObjectData before all its finalizers have been called.
<https://webkit.org/b/142846>

Reviewed by Geoffrey Garen.

Currently, JSCallbackObject<JSGlobalObject> registers weak finalizers via 2 mechanisms:

  1. JSCallbackObject<Parent>::init() registers a weak finalizer for all JSClassRef that a JSCallbackObject references.
  2. JSCallbackObject<JSGlobalObject>::create() registers a finalizer via vm.heap.addFinalizer() which destroys the JSCallbackObject.

The first finalizer is implemented as a virtual function of a JSCallbackObjectData
instance that will be destructed if the 2nd finalizer is called. Hence, if the
2nd finalizer if called first, the later invocation of the 1st finalizer will
result in a crash.

This patch fixes the issue by eliminating the finalizer registration in init().
Instead, we'll have the JSCallbackObject destructor call all the JSClassRef finalizers
if needed. This ensures that these finalizers are called before the JSCallbackObject
is destructor.

Also added assertions to a few Heap functions because JSCell::classInfo() expects
all objects that are allocated from MarkedBlock::Normal blocks to be derived from
JSDestructibleObject. These assertions will help us catch violations of this
expectation earlier.

  • API/JSCallbackObject.cpp:

(JSC::JSCallbackObjectData::finalize): Deleted.

  • API/JSCallbackObject.h:

(JSC::JSCallbackObjectData::~JSCallbackObjectData):

  • API/JSCallbackObjectFunctions.h:

(JSC::JSCallbackObject<Parent>::~JSCallbackObject):
(JSC::JSCallbackObject<Parent>::init):

  • API/tests/GlobalContextWithFinalizerTest.cpp: Added.

(finalize):
(testGlobalContextWithFinalizer):

  • API/tests/GlobalContextWithFinalizerTest.h: Added.
  • API/tests/testapi.c:

(main):

(JSC::Heap::allocateObjectOfType):
(JSC::Heap::subspaceForObjectOfType):
(JSC::Heap::allocatorForObjectOfType):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSCallbackObject.h

    r175651 r181806  
    3434namespace JSC {
    3535
    36 struct JSCallbackObjectData : WeakHandleOwner {
     36struct JSCallbackObjectData {
    3737    JSCallbackObjectData(void* privateData, JSClassRef jsClass)
    3838        : privateData(privateData)
     
    4242    }
    4343   
    44     virtual ~JSCallbackObjectData()
     44    ~JSCallbackObjectData()
    4545    {
    4646        JSClassRelease(jsClass);
     
    110110    };
    111111    std::unique_ptr<JSPrivatePropertyMap> m_privateProperties;
    112     virtual void finalize(Handle<Unknown>, void*) override;
    113112};
    114113
     
    125124public:
    126125    typedef Parent Base;
     126
     127    ~JSCallbackObject();
    127128
    128129    static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data)
Note: See TracChangeset for help on using the changeset viewer.