Ignore:
Timestamp:
Jan 26, 2007, 8:50:17 PM (18 years ago)
Author:
ggaren
Message:

JavaScriptCore:

Reviewed by Maciej Stachowiak.


Fixed <rdar://problem/4608404> WebScriptObject's _rootObject lack
of ownership policy causes crashes (e.g., in Dashcode)


The old model for RootObject ownership was either to (1) leak them or (2) assign
them to a single owner -- the WebCore::Frame -- which would destroy them
when it believed that all of its plug-ins had unloaded.


This model was broken because of (1) and also because plug-ins are not the only
RootObject clients. All Bindings clients are RootObjects clients, including
applications, which outlive any particular WebCore::Frame.


The new model for RootObject ownership is to reference-count them, with a
throw-back to the old model: The WebCore::Frame tracks the RootObjects
it creates, and invalidates them when it believes that all of its plug-ins
have unloaded.


We maintain this throw-back to avoid plug-in leaks, particularly from Java.
Java is completely broken when it comes to releasing JavaScript objects.
Comments in our code allege that Java does not always call finalize when
collecting objects. Moreoever, my own testing reveals that, when Java does
notify JavaScript of a finalize, the data it provides is totally bogus.


This setup is far from ideal, but I don't think we can do better without
completely rewriting the bindings code, and possibly part of the Java
plug-in / VM.


Layout tests pass. No additional leaks reported. WebCore/manual-tests/*liveconnect*
and a few LiveConnect demos on the web also run without a hitch.


const RootObject* => RootObject*, since we need to ref/deref


  • bindings/NP_jsobject.cpp: (jsDeallocate): deref our RootObjects. Also unprotect or JSObject, instead of just relying on the RootObject to do it for us when it's invalidated. (_isSafeScript): Check RootObject validity. (_NPN_CreateScriptObject): ditto (_NPN_Invoke): ditto (_NPN_Evaluate): ditto (_NPN_GetProperty): ditto (_NPN_SetProperty): ditto (_NPN_RemoveProperty): ditto (_NPN_HasProperty): ditto (_NPN_HasMethod): ditto (_NPN_SetException): ditto
  • bindings/runtime_root.cpp: Revived bit-rotted LIAR LIAR LIAR comment.


LOOK: Added support for invalidating RootObjects without deleting them,
which is the main goal of this patch.

Moved protect counting into the RootObject class, to emphasize that
the RootObject protects the JSObject, and unprotects it upon being invalidated.

addNativeReference => RootObject::gcProtect
removeNativeReference => RootObject::gcUnprotect
ProtectCountSet::contains => RootObject::gcIsProtected


I know we'll all be sad to see the word "native" go.


  • bindings/runtime_root.h: Added ref-counting support to RootObject, with all the standard accoutrements.
  • bindings/c/c_utility.cpp: (KJS::Bindings::convertValueToNPVariant): If we can't find a valid RootObject, return void instead of just leaking.
  • bindings/jni/jni_instance.cpp: (JavaInstance::JavaInstance): Don't take a RootObject in our constructor; be like other Instances and require the caller to call setRootObject. This reduces the number of ownership code paths. (JavaInstance::invokeMethod): Check RootObject for validity.
  • bindings/jni/jni_instance.h: Removed private no-arg constructor. Having an arg constructor accomplishes the same thing.
  • bindings/jni/jni_jsobject.cpp: (JavaJSObject::invoke): No need to call findProtectCountSet, because finalize() checks for RootObject validity. (JavaJSObject::JavaJSObject): check RootObject for validity (JavaJSObject::call): ditto (JavaJSObject::eval): ditto (JavaJSObject::getMember): ditto (JavaJSObject::setMember): ditto (JavaJSObject::removeMember): ditto (JavaJSObject::getSlot): ditto (JavaJSObject::setSlot): ditto (JavaJSObject::toString): ditto (JavaJSObject::finalize): ditto (JavaJSObject::createNative): No need to tell the RootObject to protect the global object, since the RootObject already owns the interpreter.
  • bindings/jni/jni_runtime.cpp: (JavaArray::JavaArray): Removed copy construcutor becaue it was unused. Dead code is dangerous code.
  • bindings/objc/objc_runtime.mm: Added WebUndefined protocol. Previous use of WebScriptObject was bogus, because WebUndefined is not a subclass of WebScriptObject. (convertValueToObjcObject): If we can't find a valid RootObject, return nil instead of just leaking.
  • bindings/objc/objc_utility.mm: (KJS::Bindings::convertValueToObjcValue): If we can't find a valid RootObject, return nil instead of just leaking.

LayoutTests:

Reviewed by Maciej Stachowiak.


Added test for <rdar://problem/4608404> WebScriptObject's _rootObject lack
of ownership policy causes crashes (e.g., in Dashcode)


No test for Java or NPP versions of this bug because there's no reliable way to
make Java and NPP objects outlive their RootObjects (although Java objects
sometimes do).

  • plugins/root-object-premature-delete-crash-expected.txt: Added.
  • plugins/root-object-premature-delete-crash.html: Added.

WebCore:

Reviewed by Maciej Stachowiak.


Fixed <rdar://problem/4608404> WebScriptObject's _executionContext lack
of ownership policy causes crashes (e.g., in Dashcode)

Added RootObject ref-counting goodness.

  • page/mac/FrameMac.h:
  • page/mac/FrameMac.mm: (WebCore::FrameMac::cleanupPluginObjects): Invalidate our RootObjects instead of detroying them. Track _bindingRootObject separately from the rest of our RootObjects, since it has its own variable.
  • page/mac/WebCoreFrameBridge.mm: (createRootObject): Use the Frame's new, more encapsulated function to create a RootObject.
  • bindings/objc/WebScriptObject.mm: Nixed rootObject setters, since they were unused and they complicated reference-counting.

WebKitTools:

Reviewed by Maciej Stachowiak.


Added support for test for <rdar://problem/4608404> WebScriptObject's
_rootObject lack of ownership policy causes crashes (e.g., in Dashcode)


  • DumpRenderTree/DumpRenderTree.m: (+[LayoutTestController isSelectorExcludedFromWebScript:]): (+[LayoutTestController webScriptNameForSelector:]): (-[LayoutTestController storeWebScriptObject:]): (-[LayoutTestController accessStoredWebScriptObject]): (-[LayoutTestController dealloc]):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r18837 r19183  
    101101__NPN_SetProperty
    102102__NPN_UTF8FromIdentifier
    103 __Z23_NPN_CreateScriptObjectP4_NPPPN3KJS8JSObjectEPKNS1_8Bindings10RootObjectES7_
     103__Z23_NPN_CreateScriptObjectP4_NPPPN3KJS8JSObjectEN3WTF10PassRefPtrINS1_8Bindings10RootObjectEEES8_
    104104__Z25_NPN_CreateNoScriptObjectv
    105105__ZN3KJS10Identifier3addEPKNS_5UCharEi
     
    180180__ZN3KJS7UStringC1ERKS0_S2_
    181181__ZN3KJS7UStringaSEPKc
     182__ZN3KJS8Bindings10RootObject10invalidateEv
     183__ZN3KJS8Bindings10RootObject11gcUnprotectEPNS_8JSObjectE
    182184__ZN3KJS8Bindings10RootObject17_createRootObjectE
    183 __ZN3KJS8Bindings10RootObject19setCreateRootObjectEPFPS1_PvE
    184 __ZN3KJS8Bindings10RootObject7destroyEv
     185__ZN3KJS8Bindings10RootObject19setCreateRootObjectEPFN3WTF10PassRefPtrIS1_EEPvE
     186__ZN3KJS8Bindings10RootObject6createEPKvN3WTF10PassRefPtrINS_11InterpreterEEE
     187__ZN3KJS8Bindings10RootObject9gcProtectEPNS_8JSObjectE
     188__ZN3KJS8Bindings10RootObjectD1Ev
    185189__ZN3KJS8Bindings10throwErrorEPNS_9ExecStateENS_9ErrorTypeEP8NSString
    186 __ZN3KJS8Bindings18addNativeReferenceEPKNS0_10RootObjectEPNS_8JSObjectE
    187 __ZN3KJS8Bindings21removeNativeReferenceEPNS_8JSObjectE
    188190__ZN3KJS8Bindings23convertObjcValueToValueEPNS_9ExecStateEPvNS0_13ObjcValueTypeE
    189191__ZN3KJS8Bindings23convertValueToObjcValueEPNS_9ExecStateEPNS_7JSValueENS0_13ObjcValueTypeE
    190192__ZN3KJS8Bindings8Instance18didExecuteFunctionEv
    191193__ZN3KJS8Bindings8Instance21setDidExecuteFunctionEPFvPNS_9ExecStateEPNS_8JSObjectEE
    192 __ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvPKNS0_10RootObjectE
     194__ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
    193195__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEi
    194196__ZN3KJS8Debugger6attachEPNS_11InterpreterE
     
    255257__ZNK3KJS7UString6is8BitEv
    256258__ZNK3KJS7UString8toUInt32EPb
     259__ZNK3KJS8Bindings10RootObject11interpreterEv
    257260__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
    258261__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
Note: See TracChangeset for help on using the changeset viewer.