Changeset 36016 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Sep 1, 2008, 2:22:54 PM (17 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.


SunSpider says 4% faster. Tests heavy on dictionary-like access have
regressed a bit -- we have a lot of room to improve in this area,
but this patch is over-ripe as-is.


JSCells now have a StructureID that uniquely identifies their layout,
and holds their prototype.


JSValue::put takes a PropertySlot& argument, so it can fill in details
about where it put a value, for the sake of caching.

  • VM/CodeGenerator.cpp: (KJS::CodeGenerator::CodeGenerator): Avoid calling removeDirect if we can, since it disables inline caching in the global object. This can probably improve in the future.
  • kjs/JSGlobalObject.cpp: Nixed reset(), since it complicates caching, and wasn't really necessary.
  • kjs/JSObject.cpp: Tweaked getter / setter behavior not to rely on the IsGetterSetter flag, since the flag was buggy. This is necessary in order to avoid accidentally accessing a getter / setter as a normal property.


Also changed getter / setter creation to honor ReadOnly, matching Mozilla.


  • kjs/PropertyMap.cpp: Nixed clear(), since it complicates caching and isn't necessary.
  • kjs/Shell.cpp: Moved SamplingTool dumping outside the loop. This allows you to aggregate sampling of multiple files (or the same file repeatedly), which helped me track down regressions.
  • kjs/ustring.h: Moved IdentifierRepHash here to share it.

WebCore:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.

Updated for JavaScriptCore changes. Mostly mechanical addition of StructureIDs
to WebCore classes, and PutPropertySlot& arguments to put functions.

(WebCore::JSCSSStyleDeclaration::customPut): Be sure to play nice with
inline caching for global properties, so global assignment can be optimized.

  • ForwardingHeaders/kjs/StructureID.h: Added.
  • bindings/js/JSDOMBinding.h: (WebCore::DOMObject::DOMObject):
  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::put):
  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/JSDOMWindowCustom.h: (WebCore::JSDOMWindow::customPut):
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::JSDOMWindowShell): (WebCore::JSDOMWindowShell::put):
  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSEventTargetBase.h: (WebCore::JSEventTargetBase::put):
  • bindings/js/JSEventTargetNode.h: (WebCore::JSEventTargetNode::put):
  • bindings/js/JSHTMLAppletElementCustom.cpp: (WebCore::JSHTMLAppletElement::customPut):
  • bindings/js/JSHTMLEmbedElementCustom.cpp: (WebCore::JSHTMLEmbedElement::customPut):
  • bindings/js/JSHTMLInputElementBase.cpp: (WebCore::JSHTMLInputElementBase::put):
  • bindings/js/JSHTMLInputElementBase.h:
  • bindings/js/JSHTMLObjectElementCustom.cpp: (WebCore::JSHTMLObjectElement::customPut):
  • bindings/js/JSHistoryCustom.cpp: (WebCore::JSHistory::customPut):
  • bindings/js/JSInspectedObjectWrapper.cpp: (WebCore::JSInspectedObjectWrapper::wrap): (WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper):
  • bindings/js/JSInspectedObjectWrapper.h:
  • bindings/js/JSInspectorCallbackWrapper.cpp: (WebCore::JSInspectorCallbackWrapper::wrap): (WebCore::JSInspectorCallbackWrapper::JSInspectorCallbackWrapper):
  • bindings/js/JSInspectorCallbackWrapper.h:
  • bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::customPut):
  • bindings/js/JSPluginElementFunctions.cpp: (WebCore::runtimeObjectCustomPut):
  • bindings/js/JSPluginElementFunctions.h:
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper): (WebCore::JSQuarantinedObjectWrapper::put):
  • bindings/js/JSQuarantinedObjectWrapper.h:
  • bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::customPut):
  • bindings/objc/WebScriptObject.mm: (-[WebScriptObject setValue:forKey:]):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp: (_NPN_SetProperty):
  • bridge/jni/jni_jsobject.mm: (JavaJSObject::setMember):
  • bridge/objc/objc_class.mm: (KJS::Bindings::ObjcClass::fallbackObject):
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm: (ObjcFallbackObjectImp::ObjcFallbackObjectImp): (ObjcFallbackObjectImp::put):
  • bridge/runtime.cpp: (KJS::Bindings::Instance::createRuntimeObject):
  • bridge/runtime_array.cpp: (RuntimeArray::put):
  • bridge/runtime_array.h:
  • bridge/runtime_object.cpp: (RuntimeObjectImp::RuntimeObjectImp): (RuntimeObjectImp::put):
  • bridge/runtime_object.h:

LayoutTests:

2008-09-01 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.

First cut at inline caching for access to vanilla JavaScript properties.


Tests for things I broke along the way.


  • fast/dom/getter-on-window-object2-expected.txt:
  • fast/js/pic: Added.
  • fast/js/pic/cached-deleted-properties-expected.txt: Added.
  • fast/js/pic/cached-deleted-properties.html: Added.
  • fast/js/pic/cached-getter-dictionary-and-proto-expected.txt: Added.
  • fast/js/pic/cached-getter-dictionary-and-proto.html: Added.
  • fast/js/pic/cached-getter-setter-expected.txt: Added.
  • fast/js/pic/cached-getter-setter.html: Added.
  • fast/js/pic/cached-prototype-setter-expected.txt: Added.
  • fast/js/pic/cached-prototype-setter.html: Added.
  • fast/js/pic/cached-single-entry-transition-expected.txt: Added.
  • fast/js/pic/cached-single-entry-transition.html: Added.
  • fast/js/pic/get-empty-string-expected.txt: Added.
  • fast/js/pic/get-empty-string.html: Added.
  • fast/js/pic/get-set-proxy-object-expected.txt: Added.
  • fast/js/pic/get-set-proxy-object.html: Added.
  • fast/js/pic/rehash-poisons-structure-expected.txt: Added.
  • fast/js/pic/rehash-poisons-structure.html: Added.
Location:
trunk/JavaScriptCore/API
Files:
4 edited

Legend:

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

    r35900 r36016  
    3737class JSCallbackObject : public Base {
    3838public:
    39     JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype, void* data);
    40     JSCallbackObject(JSClassRef);
     39    JSCallbackObject(ExecState*, JSClassRef, JSObject* prototype, void* data);
     40    JSCallbackObject(JSGlobalData*, JSClassRef);
    4141    virtual ~JSCallbackObject();
    4242
     
    5555    virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
    5656   
    57     virtual void put(ExecState*, const Identifier&, JSValue*);
    58     virtual void put(ExecState*, unsigned, JSValue*);
     57    virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
    5958
    6059    virtual bool deleteProperty(ExecState*, const Identifier&);
  • trunk/JavaScriptCore/API/JSCallbackObjectFunctions.h

    r35900 r36016  
    4141
    4242template <class Base>
    43 JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
     43JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSObject* prototype, void* data)
    4444    : Base(prototype)
    4545    , m_callbackObjectData(new JSCallbackObjectData(data, jsClass))
     
    5151// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
    5252template <class Base>
    53 JSCallbackObject<Base>::JSCallbackObject(JSClassRef jsClass)
    54     : m_callbackObjectData(new JSCallbackObjectData(0, jsClass))
     53JSCallbackObject<Base>::JSCallbackObject(JSGlobalData* globalData, JSClassRef jsClass)
     54    : Base(globalData)
     55    , m_callbackObjectData(new JSCallbackObjectData(0, jsClass))
    5556{
    5657    ASSERT(Base::isGlobalObject());
     
    153154
    154155template <class Base>
    155 void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
     156void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
    156157{
    157158    JSContextRef ctx = toRef(exec);
     
    194195    }
    195196   
    196     return Base::put(exec, propertyName, value);
    197 }
    198 
    199 template <class Base>
    200 void JSCallbackObject<Base>::put(ExecState* exec, unsigned propertyName, JSValue* value)
    201 {
    202     return put(exec, Identifier::from(exec, propertyName), value);
     197    return Base::put(exec, propertyName, value, slot);
    203198}
    204199
  • trunk/JavaScriptCore/API/JSContextRef.cpp

    r35917 r36016  
    6868
    6969    if (!globalObjectClass) {
    70         JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject;
     70        JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject(globalData.get());
    7171        return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
    7272    }
    7373
    74     JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass);
     74    JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalData.get(), globalObjectClass);
    7575    ExecState* exec = globalObject->globalExec();
    7676    JSValue* prototype = globalObjectClass->prototype(exec);
    7777    if (!prototype)
    7878        prototype = jsNull();
    79     globalObject->reset(prototype);
     79    globalObject->resetPrototype(prototype);
    8080    return JSGlobalContextRetain(toGlobalRef(exec));
    8181}
  • trunk/JavaScriptCore/API/JSObjectRef.cpp

    r36006 r36016  
    7575        return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
    7676
    77     JSValue* jsPrototype = jsClass->prototype(exec);
     77    JSObject* jsPrototype = jsClass->prototype(exec);
    7878    if (!jsPrototype)
    7979        jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
     
    142142    JSValue* jsValue = toJS(value);
    143143
    144     jsObject->setPrototype(jsValue);
     144    jsObject->setPrototype(jsValue->isObject() ? jsValue : jsNull());
    145145}
    146146
     
    185185    if (attributes && !jsObject->hasProperty(exec, name))
    186186        jsObject->putWithAttributes(exec, name, jsValue, attributes);
    187     else
    188         jsObject->put(exec, name, jsValue);
     187    else {
     188        PutPropertySlot slot;
     189        jsObject->put(exec, name, jsValue, slot);
     190    }
    189191
    190192    if (exec->hadException()) {
Note: See TracChangeset for help on using the changeset viewer.