Changeset 223746 in webkit


Ignore:
Timestamp:
Oct 20, 2017 12:50:08 AM (6 years ago)
Author:
sbarati@apple.com
Message:

Optimize accesses to how we get the direct prototype
https://bugs.webkit.org/show_bug.cgi?id=178548

Reviewed by Yusuke Suzuki.

Source/JavaScriptCore:

This patch makes JSObject::getPrototypeDirect take VM& as a parameter
so it can use the faster version of the structure accessor function.
The reason for making this change is that JSObjet::getPrototypeDirect
is called on the hot path in property lookup.

  • API/JSObjectRef.cpp:

(JSObjectGetPrototype):

  • jsc.cpp:

(WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::slowCall):
(WTF::DOMJITGetterBaseJSObject::customGetter):
(functionCreateProxy):

  • runtime/ArrayPrototype.cpp:

(JSC::speciesWatchpointIsValid):

  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::sanitizedToString):

  • runtime/JSArray.cpp:

(JSC::JSArray::isIteratorProtocolFastAndNonObservable):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::lastInPrototypeChain):
(JSC::JSGlobalObject::resetPrototype):
(JSC::JSGlobalObject::finishCreation):

  • runtime/JSGlobalObjectInlines.h:

(JSC::JSGlobalObject::objectPrototypeIsSane):
(JSC::JSGlobalObject::arrayPrototypeChainIsSane):
(JSC::JSGlobalObject::stringPrototypeChainIsSane):

  • runtime/JSLexicalEnvironment.cpp:

(JSC::JSLexicalEnvironment::getOwnPropertySlot):

  • runtime/JSMap.cpp:

(JSC::JSMap::isIteratorProtocolFastAndNonObservable):

  • runtime/JSObject.cpp:

(JSC::JSObject::calculatedClassName):
(JSC::JSObject::setPrototypeWithCycleCheck):
(JSC::JSObject::getPrototype):
(JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
(JSC::JSObject::attemptToInterceptPutByIndexOnHole):
(JSC::JSObject::anyObjectInChainMayInterceptIndexedAccesses const):
(JSC::JSObject::prototypeChainMayInterceptStoreTo):

  • runtime/JSObject.h:

(JSC::JSObject::finishCreation):
(JSC::JSObject::getPrototypeDirect const):
(JSC::JSObject::getPrototype):

  • runtime/JSObjectInlines.h:

(JSC::JSObject::canPerformFastPutInline):
(JSC::JSObject::getPropertySlot):
(JSC::JSObject::getNonIndexPropertySlot):

  • runtime/JSProxy.cpp:

(JSC::JSProxy::setTarget):

  • runtime/JSSet.cpp:

(JSC::JSSet::isIteratorProtocolFastAndNonObservable):

  • runtime/ProgramExecutable.cpp:

(JSC::ProgramExecutable::initializeGlobalProperties):

  • runtime/StructureInlines.h:

(JSC::Structure::isValid const):

Source/WebCore:

No new tests: no functionality change.

  • bindings/js/JSDOMAbstractOperations.h:

(WebCore::isVisibleNamedProperty):
(WebCore::accessVisibleNamedProperty):

  • bindings/js/JSDOMWindowBase.cpp:

(WebCore::toJSDOMWindow):

  • bindings/js/JSDOMWindowProperties.cpp:

(WebCore::JSDOMWindowProperties::getOwnPropertySlot):

  • bindings/js/JSPluginElementFunctions.cpp:

(WebCore::pluginElementCustomGetOwnPropertySlot):

  • bindings/js/WorkerScriptController.cpp:

(WebCore::WorkerScriptController::initScript):

  • bindings/scripts/CodeGeneratorJS.pm:

(GeneratePut):
(GeneratePutByIndex):
(GenerateConstructorHelperMethods):

  • bindings/scripts/test/JS/JSTestGlobalObject.cpp:

(WebCore::JSTestGlobalObjectConstructor::initializeProperties):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:

(WebCore::JSTestNamedAndIndexedSetterNoIdentifier::put):
(WebCore::JSTestNamedAndIndexedSetterNoIdentifier::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:

(WebCore::JSTestNamedAndIndexedSetterThrowingException::put):
(WebCore::JSTestNamedAndIndexedSetterThrowingException::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:

(WebCore::JSTestNamedAndIndexedSetterWithIdentifier::put):
(WebCore::JSTestNamedAndIndexedSetterWithIdentifier::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:

(WebCore::JSTestNamedSetterNoIdentifier::put):
(WebCore::JSTestNamedSetterNoIdentifier::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:

(WebCore::JSTestNamedSetterThrowingException::put):
(WebCore::JSTestNamedSetterThrowingException::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:

(WebCore::JSTestNamedSetterWithIdentifier::put):
(WebCore::JSTestNamedSetterWithIdentifier::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:

(WebCore::JSTestNamedSetterWithIndexedGetter::put):
(WebCore::JSTestNamedSetterWithIndexedGetter::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:

(WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::put):
(WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::putByIndex):

  • bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp:

(WebCore::JSTestNamedSetterWithUnforgableProperties::put):
(WebCore::JSTestNamedSetterWithUnforgableProperties::putByIndex):

Location:
trunk/Source
Files:
34 edited

Legend:

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

    r222617 r223746  
    262262
    263263    JSObject* jsObject = toJS(object);
    264     return toRef(exec, jsObject->getPrototypeDirect());
     264    return toRef(exec, jsObject->getPrototypeDirect(exec->vm()));
    265265}
    266266
  • trunk/Source/JavaScriptCore/ChangeLog

    r223745 r223746  
     12017-10-20  Saam Barati  <sbarati@apple.com>
     2
     3        Optimize accesses to how we get the direct prototype
     4        https://bugs.webkit.org/show_bug.cgi?id=178548
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch makes JSObject::getPrototypeDirect take VM& as a parameter
     9        so it can use the faster version of the structure accessor function.
     10        The reason for making this change is that JSObjet::getPrototypeDirect
     11        is called on the hot path in property lookup.
     12
     13        * API/JSObjectRef.cpp:
     14        (JSObjectGetPrototype):
     15        * jsc.cpp:
     16        (WTF::DOMJITGetterBaseJSObject::DOMJITAttribute::slowCall):
     17        (WTF::DOMJITGetterBaseJSObject::customGetter):
     18        (functionCreateProxy):
     19        * runtime/ArrayPrototype.cpp:
     20        (JSC::speciesWatchpointIsValid):
     21        * runtime/ErrorInstance.cpp:
     22        (JSC::ErrorInstance::sanitizedToString):
     23        * runtime/JSArray.cpp:
     24        (JSC::JSArray::isIteratorProtocolFastAndNonObservable):
     25        * runtime/JSGlobalObject.cpp:
     26        (JSC::JSGlobalObject::init):
     27        (JSC::lastInPrototypeChain):
     28        (JSC::JSGlobalObject::resetPrototype):
     29        (JSC::JSGlobalObject::finishCreation):
     30        * runtime/JSGlobalObjectInlines.h:
     31        (JSC::JSGlobalObject::objectPrototypeIsSane):
     32        (JSC::JSGlobalObject::arrayPrototypeChainIsSane):
     33        (JSC::JSGlobalObject::stringPrototypeChainIsSane):
     34        * runtime/JSLexicalEnvironment.cpp:
     35        (JSC::JSLexicalEnvironment::getOwnPropertySlot):
     36        * runtime/JSMap.cpp:
     37        (JSC::JSMap::isIteratorProtocolFastAndNonObservable):
     38        * runtime/JSObject.cpp:
     39        (JSC::JSObject::calculatedClassName):
     40        (JSC::JSObject::setPrototypeWithCycleCheck):
     41        (JSC::JSObject::getPrototype):
     42        (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
     43        (JSC::JSObject::attemptToInterceptPutByIndexOnHole):
     44        (JSC::JSObject::anyObjectInChainMayInterceptIndexedAccesses const):
     45        (JSC::JSObject::prototypeChainMayInterceptStoreTo):
     46        * runtime/JSObject.h:
     47        (JSC::JSObject::finishCreation):
     48        (JSC::JSObject::getPrototypeDirect const):
     49        (JSC::JSObject::getPrototype):
     50        * runtime/JSObjectInlines.h:
     51        (JSC::JSObject::canPerformFastPutInline):
     52        (JSC::JSObject::getPropertySlot):
     53        (JSC::JSObject::getNonIndexPropertySlot):
     54        * runtime/JSProxy.cpp:
     55        (JSC::JSProxy::setTarget):
     56        * runtime/JSSet.cpp:
     57        (JSC::JSSet::isIteratorProtocolFastAndNonObservable):
     58        * runtime/ProgramExecutable.cpp:
     59        (JSC::ProgramExecutable::initializeGlobalProperties):
     60        * runtime/StructureInlines.h:
     61        (JSC::Structure::isValid const):
     62
    1632017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
    264
  • trunk/Source/JavaScriptCore/jsc.cpp

    r223738 r223746  
    997997            NativeCallFrameTracer tracer(&vm, exec);
    998998            JSObject* object = static_cast<JSObject*>(pointer);
    999             return JSValue::encode(object->getPrototypeDirect());
     999            return JSValue::encode(object->getPrototypeDirect(vm));
    10001000        }
    10011001
     
    10241024        JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
    10251025        RELEASE_ASSERT(thisObject);
    1026         return JSValue::encode(thisObject->getPrototypeDirect());
     1026        return JSValue::encode(thisObject->getPrototypeDirect(vm));
    10271027    }
    10281028};
     
    22122212        return JSValue::encode(jsUndefined());
    22132213    JSObject* jsTarget = asObject(target.asCell());
    2214     Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(), ImpureProxyType);
     2214    Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(vm), ImpureProxyType);
    22152215    JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
    22162216    return JSValue::encode(proxy);
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r223027 r223746  
    203203
    204204    return !thisObject->hasCustomProperties()
    205         && arrayPrototype == thisObject->getPrototypeDirect()
     205        && arrayPrototype == thisObject->getPrototypeDirect(globalObject->vm())
    206206        && globalObject->arraySpeciesWatchpoint().stateOnJSThread() == IsWatched;
    207207}
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp

    r222473 r223746  
    163163            break;
    164164        }
    165         currentObj = obj->getPrototypeDirect();
     165        currentObj = obj->getPrototypeDirect(vm);
    166166    }
    167167    scope.assertNoException();
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r222827 r223746  
    12931293        return false;
    12941294
    1295     if (getPrototypeDirect() != globalObject->arrayPrototype())
    1296         return false;
    1297 
    12981295    VM& vm = globalObject->vm();
     1296    if (getPrototypeDirect(vm) != globalObject->arrayPrototype())
     1297        return false;
     1298
    12991299    if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
    13001300        return false;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r223594 r223746  
    10271027    }
    10281028
    1029     resetPrototype(vm, getPrototypeDirect());
     1029    resetPrototype(vm, getPrototypeDirect(vm));
    10301030}
    10311031
     
    10971097}
    10981098
    1099 static inline JSObject* lastInPrototypeChain(JSObject* object)
     1099static inline JSObject* lastInPrototypeChain(VM& vm, JSObject* object)
    11001100{
    11011101    JSObject* o = object;
    1102     while (o->getPrototypeDirect().isObject())
    1103         o = asObject(o->getPrototypeDirect());
     1102    while (o->getPrototypeDirect(vm).isObject())
     1103        o = asObject(o->getPrototypeDirect(vm));
    11041104    return o;
    11051105}
     
    11511151    // a different global object that have prototypes from our global object.
    11521152    bool foundGlobalObject = false;
     1153    VM& vm = m_globalObject->vm();
    11531154    for (JSObject* current = object; ;) {
    11541155        if (current->globalObject() == m_globalObject) {
     
    11571158        }
    11581159       
    1159         JSValue prototypeValue = current->getPrototypeDirect();
     1160        JSValue prototypeValue = current->getPrototypeDirect(vm);
    11601161        if (prototypeValue.isNull())
    11611162            break;
     
    12281229    setPrototypeDirect(vm, prototype);
    12291230
    1230     JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
     1231    JSObject* oldLastInPrototypeChain = lastInPrototypeChain(vm, this);
    12311232    JSObject* objectPrototype = m_objectPrototype.get();
    12321233    if (oldLastInPrototypeChain != objectPrototype)
     
    15271528    m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
    15281529    init(vm);
    1529     setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(), PureForwardingProxyType), this));
     1530    setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(vm), PureForwardingProxyType), this));
    15301531}
    15311532
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h

    r218836 r223746  
    3636{
    3737    return !hasIndexedProperties(m_objectPrototype->indexingType())
    38         && m_objectPrototype->getPrototypeDirect().isNull();
     38        && m_objectPrototype->getPrototypeDirect(vm()).isNull();
    3939}
    4040
     
    4242{
    4343    return !hasIndexedProperties(m_arrayPrototype->indexingType())
    44         && m_arrayPrototype->getPrototypeDirect() == m_objectPrototype.get()
     44        && m_arrayPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
    4545        && objectPrototypeIsSane();
    4646}
     
    4949{
    5050    return !hasIndexedProperties(m_stringPrototype->indexingType())
    51         && m_stringPrototype->getPrototypeDirect() == m_objectPrototype.get()
     51        && m_stringPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
    5252        && objectPrototypeIsSane();
    5353}
  • trunk/Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp

    r222473 r223746  
    106106    // lexical environment object getter properties or a prototype.
    107107    ASSERT(!thisObject->hasGetterSetterProperties());
    108     ASSERT(thisObject->getPrototypeDirect().isNull());
     108    ASSERT(thisObject->getPrototypeDirect(exec->vm()).isNull());
    109109    return false;
    110110}
  • trunk/Source/JavaScriptCore/runtime/JSMap.cpp

    r222827 r223746  
    5757        return true;
    5858
    59     if (getPrototypeDirect() != globalObject->mapPrototype())
     59    VM& vm = globalObject->vm();
     60    if (getPrototypeDirect(vm) != globalObject->mapPrototype())
    6061        return false;
    6162
    62     VM& vm = globalObject->vm();
    6363    if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
    6464        return false;
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r223715 r223746  
    532532
    533533    ExecState* exec = globalObject->globalExec();
    534     PropertySlot slot(object->getPrototypeDirect(), PropertySlot::InternalMethodType::VMInquiry);
     534    PropertySlot slot(object->getPrototypeDirect(vm), PropertySlot::InternalMethodType::VMInquiry);
    535535    PropertyName constructor(vm.propertyNames->constructor);
    536536    if (object->getPropertySlot(exec, constructor, slot)) {
     
    16721672    ASSERT(methodTable(vm)->toThis(this, exec, NotStrictMode) == this);
    16731673
    1674     if (this->getPrototypeDirect() == prototype)
     1674    if (this->getPrototypeDirect(vm) == prototype)
    16751675        return true;
    16761676
     
    16911691        if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType))
    16921692            break; // We're done. Set the prototype.
    1693         nextPrototype = asObject(nextPrototype)->getPrototypeDirect();
     1693        nextPrototype = asObject(nextPrototype)->getPrototypeDirect(vm);
    16941694    }
    16951695    setPrototypeDirect(vm, prototype);
     
    17021702}
    17031703
    1704 JSValue JSObject::getPrototype(JSObject* object, ExecState*)
    1705 {
    1706     return object->getPrototypeDirect();
     1704JSValue JSObject::getPrototype(JSObject* object, ExecState* exec)
     1705{
     1706    return object->getPrototypeDirect(exec->vm());
    17071707}
    17081708
     
    25392539bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, JSValue thisValue, unsigned i, JSValue value, bool shouldThrow, bool& putResult)
    25402540{
     2541    VM& vm = exec->vm();
    25412542    for (JSObject* current = this; ;) {
    25422543        // This has the same behavior with respect to prototypes as JSObject::put(). It only
     
    25602561        }
    25612562       
    2562         JSValue prototypeValue = current->getPrototypeDirect();
     2563        JSValue prototypeValue = current->getPrototypeDirect(vm);
    25632564        if (prototypeValue.isNull())
    25642565            return false;
     
    25702571bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, bool& putResult)
    25712572{
    2572     JSValue prototypeValue = getPrototypeDirect();
     2573    JSValue prototypeValue = getPrototypeDirect(exec->vm());
    25732574    if (prototypeValue.isNull())
    25742575        return false;
     
    36813682            return true;
    36823683       
    3683         JSValue prototype = current->getPrototypeDirect();
     3684        JSValue prototype = current->getPrototypeDirect(vm);
    36843685        if (prototype.isNull())
    36853686            return false;
     
    36953696   
    36963697    for (JSObject* current = this; ;) {
    3697         JSValue prototype = current->getPrototypeDirect();
     3698        JSValue prototype = current->getPrototypeDirect(vm);
    36983699        if (prototype.isNull())
    36993700            return false;
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r223715 r223746  
    133133    // without consulting the method table. This is akin to getting the [[Prototype]]
    134134    // internal field directly as described in the specification.
    135     JSValue getPrototypeDirect() const;
     135    JSValue getPrototypeDirect(VM&) const;
    136136
    137137    // This sets the prototype without checking for cycles and without
     
    874874        Base::finishCreation(vm);
    875875        ASSERT(inherits(vm, info()));
    876         ASSERT(structure()->hasPolyProto() || getPrototypeDirect().isNull() || Heap::heap(this) == Heap::heap(getPrototypeDirect()));
     876        ASSERT(structure()->hasPolyProto() || getPrototypeDirect(vm).isNull() || Heap::heap(this) == Heap::heap(getPrototypeDirect(vm)));
    877877        ASSERT(structure()->isObject());
    878878        ASSERT(classInfo(vm));
     
    13041304}
    13051305
    1306 inline JSValue JSObject::getPrototypeDirect() const
    1307 {
    1308     return structure()->storedPrototype(this);
     1306inline JSValue JSObject::getPrototypeDirect(VM& vm) const
     1307{
     1308    return structure(vm)->storedPrototype(this);
    13091309}
    13101310
     
    13141314    MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
    13151315    if (LIKELY(getPrototypeMethod == defaultGetPrototype))
    1316         return getPrototypeDirect();
     1316        return getPrototypeDirect(vm);
    13171317    return getPrototypeMethod(this, exec);
    13181318}
  • trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h

    r222827 r223746  
    7474            return false;
    7575
    76         prototype = obj->getPrototypeDirect();
     76        prototype = obj->getPrototypeDirect(vm);
    7777        if (prototype.isNull())
    7878            return true;
     
    117117        JSValue prototype;
    118118        if (LIKELY(structure->classInfo()->methodTable.getPrototype == defaultGetPrototype || slot.internalMethodType() == PropertySlot::InternalMethodType::VMInquiry))
    119             prototype = object->getPrototypeDirect();
     119            prototype = object->getPrototypeDirect(vm);
    120120        else {
    121121            prototype = object->getPrototype(vm, exec);
     
    151151        JSValue prototype;
    152152        if (LIKELY(structure->classInfo()->methodTable.getPrototype == defaultGetPrototype || slot.internalMethodType() == PropertySlot::InternalMethodType::VMInquiry))
    153             prototype = object->getPrototypeDirect();
     153            prototype = object->getPrototypeDirect(vm);
    154154        else {
    155155            prototype = object->getPrototype(vm, exec);
  • trunk/Source/JavaScriptCore/runtime/JSProxy.cpp

    r223123 r223746  
    4747{
    4848    m_target.set(vm, this, globalObject);
    49     setPrototypeDirect(vm, globalObject->getPrototypeDirect());
     49    setPrototypeDirect(vm, globalObject->getPrototypeDirect(vm));
    5050}
    5151
  • trunk/Source/JavaScriptCore/runtime/JSSet.cpp

    r222827 r223746  
    5757        return true;
    5858
    59     if (getPrototypeDirect() != globalObject->jsSetPrototype())
     59    VM& vm = globalObject->vm();
     60    if (getPrototypeDirect(vm) != globalObject->jsSetPrototype())
    6061        return false;
    6162
    62     VM& vm = globalObject->vm();
    6363    if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
    6464        return false;
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp

    r222617 r223746  
    105105        return error.toErrorObject(globalObject, source());
    106106
    107     JSValue nextPrototype = globalObject->getPrototypeDirect();
     107    JSValue nextPrototype = globalObject->getPrototypeDirect(vm);
    108108    while (nextPrototype && nextPrototype.isObject()) {
    109109        if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType)) {
     
    111111            return createTypeError(exec, ASCIILiteral("Proxy is not allowed in the global prototype chain."));
    112112        }
    113         nextPrototype = asObject(nextPrototype)->getPrototypeDirect();
     113        nextPrototype = asObject(nextPrototype)->getPrototypeDirect(vm);
    114114    }
    115115   
  • trunk/Source/JavaScriptCore/runtime/StructureInlines.h

    r223715 r223746  
    244244        return false;
    245245
     246    VM& vm = globalObject->vm();
    246247    JSValue prototype = prototypeForLookup(globalObject, base);
    247248    WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
    248249    while (*cachedStructure && !prototype.isNull()) {
    249         if (asObject(prototype)->structure() != cachedStructure->get())
     250        if (asObject(prototype)->structure(vm) != cachedStructure->get())
    250251            return false;
    251252        ++cachedStructure;
    252         prototype = asObject(prototype)->getPrototypeDirect();
     253        prototype = asObject(prototype)->getPrototypeDirect(vm);
    253254    }
    254255    return prototype.isNull() && !*cachedStructure;
  • trunk/Source/WebCore/ChangeLog

    r223744 r223746  
     12017-10-20  Saam Barati  <sbarati@apple.com>
     2
     3        Optimize accesses to how we get the direct prototype
     4        https://bugs.webkit.org/show_bug.cgi?id=178548
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        No new tests: no functionality change.
     9
     10        * bindings/js/JSDOMAbstractOperations.h:
     11        (WebCore::isVisibleNamedProperty):
     12        (WebCore::accessVisibleNamedProperty):
     13        * bindings/js/JSDOMWindowBase.cpp:
     14        (WebCore::toJSDOMWindow):
     15        * bindings/js/JSDOMWindowProperties.cpp:
     16        (WebCore::JSDOMWindowProperties::getOwnPropertySlot):
     17        * bindings/js/JSPluginElementFunctions.cpp:
     18        (WebCore::pluginElementCustomGetOwnPropertySlot):
     19        * bindings/js/WorkerScriptController.cpp:
     20        (WebCore::WorkerScriptController::initScript):
     21        * bindings/scripts/CodeGeneratorJS.pm:
     22        (GeneratePut):
     23        (GeneratePutByIndex):
     24        (GenerateConstructorHelperMethods):
     25        * bindings/scripts/test/JS/JSTestGlobalObject.cpp:
     26        (WebCore::JSTestGlobalObjectConstructor::initializeProperties):
     27        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:
     28        (WebCore::JSTestNamedAndIndexedSetterNoIdentifier::put):
     29        (WebCore::JSTestNamedAndIndexedSetterNoIdentifier::putByIndex):
     30        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:
     31        (WebCore::JSTestNamedAndIndexedSetterThrowingException::put):
     32        (WebCore::JSTestNamedAndIndexedSetterThrowingException::putByIndex):
     33        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:
     34        (WebCore::JSTestNamedAndIndexedSetterWithIdentifier::put):
     35        (WebCore::JSTestNamedAndIndexedSetterWithIdentifier::putByIndex):
     36        * bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:
     37        (WebCore::JSTestNamedSetterNoIdentifier::put):
     38        (WebCore::JSTestNamedSetterNoIdentifier::putByIndex):
     39        * bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:
     40        (WebCore::JSTestNamedSetterThrowingException::put):
     41        (WebCore::JSTestNamedSetterThrowingException::putByIndex):
     42        * bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:
     43        (WebCore::JSTestNamedSetterWithIdentifier::put):
     44        (WebCore::JSTestNamedSetterWithIdentifier::putByIndex):
     45        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:
     46        (WebCore::JSTestNamedSetterWithIndexedGetter::put):
     47        (WebCore::JSTestNamedSetterWithIndexedGetter::putByIndex):
     48        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:
     49        (WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::put):
     50        (WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::putByIndex):
     51        * bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp:
     52        (WebCore::JSTestNamedSetterWithUnforgableProperties::put):
     53        (WebCore::JSTestNamedSetterWithUnforgableProperties::putByIndex):
     54
    1552017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
    256
  • trunk/Source/WebCore/bindings/js/JSDOMAbstractOperations.h

    r218126 r223746  
    7373    // FIXME: Implement checking for 'named properties object'.
    7474    //    2. Set prototype to be the value of the internal [[Prototype]] property of prototype.
    75     auto prototype = thisObject.getPrototypeDirect();
     75    auto prototype = thisObject.getPrototypeDirect(state.vm());
    7676    if (prototype.isObject() && JSC::asObject(prototype)->getPropertySlot(&state, propertyName, slot))
    7777        return false;
     
    113113    // FIXME: Implement checking for 'named properties object'.
    114114    //    2. Set prototype to be the value of the internal [[Prototype]] property of prototype.
    115     auto prototype = thisObject.getPrototypeDirect();
     115    auto prototype = thisObject.getPrototypeDirect(state.vm());
    116116    if (prototype.isObject() && JSC::asObject(prototype)->getPropertySlot(&state, propertyName, slot))
    117117        return std::nullopt;
  • trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp

    r223476 r223746  
    283283        if (classInfo == JSDOMWindowProxy::info())
    284284            return jsCast<JSDOMWindowProxy*>(object)->window();
    285         value = object->getPrototypeDirect();
     285        value = object->getPrototypeDirect(vm);
    286286    }
    287287    return nullptr;
  • trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp

    r222473 r223746  
    8686    if (Base::getOwnPropertySlot(thisObject, state, propertyName, slot))
    8787        return true;
    88     JSValue proto = thisObject->getPrototypeDirect();
     88    JSValue proto = thisObject->getPrototypeDirect(state->vm());
    8989    if (proto.isObject() && jsCast<JSObject*>(proto)->hasProperty(state, propertyName))
    9090        return false;
  • trunk/Source/WebCore/bindings/js/JSPluginElementFunctions.cpp

    r223476 r223746  
    113113{
    114114    if (!element->globalObject()->world().isNormal()) {
    115         JSC::JSValue proto = element->getPrototypeDirect();
     115        JSC::JSValue proto = element->getPrototypeDirect(exec->vm());
    116116        if (proto.isObject() && JSC::jsCast<JSC::JSObject*>(asObject(proto))->hasProperty(exec, propertyName))
    117117            return false;
  • trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp

    r223476 r223746  
    115115   
    116116    ASSERT(m_workerGlobalScopeWrapper->globalObject() == m_workerGlobalScopeWrapper);
    117     ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect())->globalObject() == m_workerGlobalScopeWrapper);
     117    ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect(*m_vm))->globalObject() == m_workerGlobalScopeWrapper);
    118118
    119119    m_consoleClient = std::make_unique<WorkerConsoleClient>(*m_workerGlobalScope);
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r223725 r223746  
    955955        if (!$overrideBuiltins) {
    956956            push(@$outputArray, "        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };\n");
    957             push(@$outputArray, "        JSValue prototype = thisObject->getPrototypeDirect();\n");
     957            push(@$outputArray, "        JSValue prototype = thisObject->getPrototypeDirect(state->vm());\n");
    958958            push(@$outputArray, "        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
    959959            $additionalIndent .= "    ";
     
    10241024        if (!$overrideBuiltins) {
    10251025            push(@$outputArray, "    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };\n");
    1026             push(@$outputArray, "    JSValue prototype = thisObject->getPrototypeDirect();\n");
     1026            push(@$outputArray, "    JSValue prototype = thisObject->getPrototypeDirect(state->vm());\n");
    10271027            push(@$outputArray, "    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
    10281028            $additionalIndent .= "    ";
     
    71157115    # https://heycam.github.io/webidl/#interface-prototype-object
    71167116    if (ShouldUseGlobalObjectPrototype($interface)) {
    7117         push(@$outputArray, "    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n");
     7117        push(@$outputArray, "    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(vm), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n");
    71187118    } elsif ($interface->isCallback) {
    71197119        push(@$outputArray, "    UNUSED_PARAM(globalObject);\n");
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp

    r223476 r223746  
    128128template<> void JSTestGlobalObjectConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
    129129{
    130     putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
     130    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(vm), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
    131131    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestGlobalObject"))), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
    132132    putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp

    r223476 r223746  
    216216    if (!propertyName.isSymbol()) {
    217217        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    218         JSValue prototype = thisObject->getPrototypeDirect();
     218        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    219219        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    220220            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    244244    auto propertyName = Identifier::from(state, index);
    245245    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    246     JSValue prototype = thisObject->getPrototypeDirect();
     246    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    247247    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    248248        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp

    r223476 r223746  
    216216    if (!propertyName.isSymbol()) {
    217217        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    218         JSValue prototype = thisObject->getPrototypeDirect();
     218        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    219219        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    220220            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    244244    auto propertyName = Identifier::from(state, index);
    245245    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    246     JSValue prototype = thisObject->getPrototypeDirect();
     246    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    247247    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    248248        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp

    r223476 r223746  
    225225    if (!propertyName.isSymbol()) {
    226226        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    227         JSValue prototype = thisObject->getPrototypeDirect();
     227        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    228228        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    229229            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    253253    auto propertyName = Identifier::from(state, index);
    254254    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    255     JSValue prototype = thisObject->getPrototypeDirect();
     255    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    256256    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    257257        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp

    r223476 r223746  
    188188    if (!propertyName.isSymbol()) {
    189189        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    190         JSValue prototype = thisObject->getPrototypeDirect();
     190        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    191191        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    192192            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    208208    auto propertyName = Identifier::from(state, index);
    209209    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    210     JSValue prototype = thisObject->getPrototypeDirect();
     210    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    211211    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    212212        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp

    r223476 r223746  
    188188    if (!propertyName.isSymbol()) {
    189189        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    190         JSValue prototype = thisObject->getPrototypeDirect();
     190        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    191191        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    192192            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    208208    auto propertyName = Identifier::from(state, index);
    209209    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    210     JSValue prototype = thisObject->getPrototypeDirect();
     210    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    211211    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    212212        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp

    r223476 r223746  
    194194    if (!propertyName.isSymbol()) {
    195195        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    196         JSValue prototype = thisObject->getPrototypeDirect();
     196        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    197197        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    198198            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    214214    auto propertyName = Identifier::from(state, index);
    215215    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    216     JSValue prototype = thisObject->getPrototypeDirect();
     216    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    217217    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    218218        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp

    r223476 r223746  
    217217    if (!propertyName.isSymbol()) {
    218218        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    219         JSValue prototype = thisObject->getPrototypeDirect();
     219        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    220220        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    221221            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    237237    auto propertyName = Identifier::from(state, index);
    238238    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    239     JSValue prototype = thisObject->getPrototypeDirect();
     239    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    240240    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    241241        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp

    r223476 r223746  
    225225    if (!propertyName.isSymbol()) {
    226226        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    227         JSValue prototype = thisObject->getPrototypeDirect();
     227        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    228228        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    229229            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    253253    auto propertyName = Identifier::from(state, index);
    254254    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    255     JSValue prototype = thisObject->getPrototypeDirect();
     255    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    256256    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    257257        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp

    r223476 r223746  
    212212    if (!propertyName.isSymbol()) {
    213213        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    214         JSValue prototype = thisObject->getPrototypeDirect();
     214        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    215215        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    216216            auto throwScope = DECLARE_THROW_SCOPE(state->vm());
     
    232232    auto propertyName = Identifier::from(state, index);
    233233    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
    234     JSValue prototype = thisObject->getPrototypeDirect();
     234    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
    235235    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
    236236        auto throwScope = DECLARE_THROW_SCOPE(state->vm());
Note: See TracChangeset for help on using the changeset viewer.