Optimize accesses to how we get the direct prototype
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 07:50:08 +0000 (07:50 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Oct 2017 07:50:08 +0000 (07:50 +0000)
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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223746 268f45cc-cd09-0410-ab3c-d52691b4dbfc

34 files changed:
Source/JavaScriptCore/API/JSObjectRef.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/ErrorInstance.cpp
Source/JavaScriptCore/runtime/JSArray.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h
Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp
Source/JavaScriptCore/runtime/JSMap.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSObjectInlines.h
Source/JavaScriptCore/runtime/JSProxy.cpp
Source/JavaScriptCore/runtime/JSSet.cpp
Source/JavaScriptCore/runtime/ProgramExecutable.cpp
Source/JavaScriptCore/runtime/StructureInlines.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMAbstractOperations.h
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bindings/js/JSDOMWindowProperties.cpp
Source/WebCore/bindings/js/JSPluginElementFunctions.cpp
Source/WebCore/bindings/js/WorkerScriptController.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp

index 0d0fff3..03c7243 100644 (file)
@@ -261,7 +261,7 @@ JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
     JSLockHolder locker(exec);
 
     JSObject* jsObject = toJS(object); 
-    return toRef(exec, jsObject->getPrototypeDirect());
+    return toRef(exec, jsObject->getPrototypeDirect(exec->vm()));
 }
 
 void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
index cab14f8..5d5d613 100644 (file)
@@ -1,3 +1,65 @@
+2017-10-20  Saam Barati  <sbarati@apple.com>
+
+        Optimize accesses to how we get the direct prototype
+        https://bugs.webkit.org/show_bug.cgi?id=178548
+
+        Reviewed by Yusuke Suzuki.
+
+        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):
+
 2017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [ARM64] static_cast<int32_t>() in BinaryOpNode::emitBytecode() prevents op_unsigned emission
index 6581f93..977b9f2 100644 (file)
@@ -996,7 +996,7 @@ public:
             VM& vm = exec->vm();
             NativeCallFrameTracer tracer(&vm, exec);
             JSObject* object = static_cast<JSObject*>(pointer);
-            return JSValue::encode(object->getPrototypeDirect());
+            return JSValue::encode(object->getPrototypeDirect(vm));
         }
 
         static Ref<DOMJIT::CallDOMGetterSnippet> callDOMGetter()
@@ -1023,7 +1023,7 @@ private:
         VM& vm = exec->vm();
         JSObject* thisObject = jsDynamicCast<JSObject*>(vm, JSValue::decode(thisValue));
         RELEASE_ASSERT(thisObject);
-        return JSValue::encode(thisObject->getPrototypeDirect());
+        return JSValue::encode(thisObject->getPrototypeDirect(vm));
     }
 };
 
@@ -2211,7 +2211,7 @@ EncodedJSValue JSC_HOST_CALL functionCreateProxy(ExecState* exec)
     if (!target.isObject())
         return JSValue::encode(jsUndefined());
     JSObject* jsTarget = asObject(target.asCell());
-    Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(), ImpureProxyType);
+    Structure* structure = JSProxy::createStructure(vm, exec->lexicalGlobalObject(), jsTarget->getPrototypeDirect(vm), ImpureProxyType);
     JSProxy* proxy = JSProxy::create(vm, structure, jsTarget);
     return JSValue::encode(proxy);
 }
index a3ea8d6..234a4e3 100644 (file)
@@ -202,7 +202,7 @@ ALWAYS_INLINE bool speciesWatchpointIsValid(ExecState* exec, JSObject* thisObjec
     }
 
     return !thisObject->hasCustomProperties()
-        && arrayPrototype == thisObject->getPrototypeDirect()
+        && arrayPrototype == thisObject->getPrototypeDirect(globalObject->vm())
         && globalObject->arraySpeciesWatchpoint().stateOnJSThread() == IsWatched;
 }
 
index ae30f28..4e711aa 100644 (file)
@@ -162,7 +162,7 @@ String ErrorInstance::sanitizedToString(ExecState* exec)
             nameValue = nameSlot.getValue(exec, namePropertName);
             break;
         }
-        currentObj = obj->getPrototypeDirect();
+        currentObj = obj->getPrototypeDirect(vm);
     }
     scope.assertNoException();
 
index 76e3705..cd37da6 100644 (file)
@@ -1292,10 +1292,10 @@ bool JSArray::isIteratorProtocolFastAndNonObservable()
     if (structure->mayInterceptIndexedAccesses())
         return false;
 
-    if (getPrototypeDirect() != globalObject->arrayPrototype())
+    VM& vm = globalObject->vm();
+    if (getPrototypeDirect(vm) != globalObject->arrayPrototype())
         return false;
 
-    VM& vm = globalObject->vm();
     if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
         return false;
 
index 8b08ec6..5c5f2ab 100644 (file)
@@ -1026,7 +1026,7 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
         }
     }
 
-    resetPrototype(vm, getPrototypeDirect());
+    resetPrototype(vm, getPrototypeDirect(vm));
 }
 
 bool JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
@@ -1096,11 +1096,11 @@ void JSGlobalObject::clearGlobalScopeExtension()
     m_globalScopeExtension.clear();
 }
 
-static inline JSObject* lastInPrototypeChain(JSObject* object)
+static inline JSObject* lastInPrototypeChain(VM& vm, JSObject* object)
 {
     JSObject* o = object;
-    while (o->getPrototypeDirect().isObject())
-        o = asObject(o->getPrototypeDirect());
+    while (o->getPrototypeDirect(vm).isObject())
+        o = asObject(o->getPrototypeDirect(vm));
     return o;
 }
 
@@ -1150,13 +1150,14 @@ inline void ObjectsWithBrokenIndexingFinder::visit(JSCell* cell)
     // VM. But we have to be careful, since there may be objects that claim to belong to
     // a different global object that have prototypes from our global object.
     bool foundGlobalObject = false;
+    VM& vm = m_globalObject->vm();
     for (JSObject* current = object; ;) {
         if (current->globalObject() == m_globalObject) {
             foundGlobalObject = true;
             break;
         }
         
-        JSValue prototypeValue = current->getPrototypeDirect();
+        JSValue prototypeValue = current->getPrototypeDirect(vm);
         if (prototypeValue.isNull())
             break;
         current = asObject(prototypeValue);
@@ -1227,7 +1228,7 @@ void JSGlobalObject::resetPrototype(VM& vm, JSValue prototype)
 {
     setPrototypeDirect(vm, prototype);
 
-    JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
+    JSObject* oldLastInPrototypeChain = lastInPrototypeChain(vm, this);
     JSObject* objectPrototype = m_objectPrototype.get();
     if (oldLastInPrototypeChain != objectPrototype)
         oldLastInPrototypeChain->setPrototypeDirect(vm, objectPrototype);
@@ -1526,7 +1527,7 @@ void JSGlobalObject::finishCreation(VM& vm)
     structure()->setGlobalObject(vm, this);
     m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
     init(vm);
-    setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(), PureForwardingProxyType), this));
+    setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(vm), PureForwardingProxyType), this));
 }
 
 void JSGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
index 52e9376..6f4ebc0 100644 (file)
@@ -35,20 +35,20 @@ namespace JSC {
 ALWAYS_INLINE bool JSGlobalObject::objectPrototypeIsSane()
 {
     return !hasIndexedProperties(m_objectPrototype->indexingType())
-        && m_objectPrototype->getPrototypeDirect().isNull();
+        && m_objectPrototype->getPrototypeDirect(vm()).isNull();
 }
 
 ALWAYS_INLINE bool JSGlobalObject::arrayPrototypeChainIsSane()
 {
     return !hasIndexedProperties(m_arrayPrototype->indexingType())
-        && m_arrayPrototype->getPrototypeDirect() == m_objectPrototype.get()
+        && m_arrayPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
         && objectPrototypeIsSane();
 }
 
 ALWAYS_INLINE bool JSGlobalObject::stringPrototypeChainIsSane()
 {
     return !hasIndexedProperties(m_stringPrototype->indexingType())
-        && m_stringPrototype->getPrototypeDirect() == m_objectPrototype.get()
+        && m_stringPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
         && objectPrototypeIsSane();
 }
 
index 02b4784..d801d5a 100644 (file)
@@ -105,7 +105,7 @@ bool JSLexicalEnvironment::getOwnPropertySlot(JSObject* object, ExecState* exec,
     // We don't call through to JSObject because there's no way to give a 
     // lexical environment object getter properties or a prototype.
     ASSERT(!thisObject->hasGetterSetterProperties());
-    ASSERT(thisObject->getPrototypeDirect().isNull());
+    ASSERT(thisObject->getPrototypeDirect(exec->vm()).isNull());
     return false;
 }
 
index 0da1a77..96ae55f 100644 (file)
@@ -56,10 +56,10 @@ bool JSMap::isIteratorProtocolFastAndNonObservable()
     if (structure == globalObject->mapStructure())
         return true;
 
-    if (getPrototypeDirect() != globalObject->mapPrototype())
+    VM& vm = globalObject->vm();
+    if (getPrototypeDirect(vm) != globalObject->mapPrototype())
         return false;
 
-    VM& vm = globalObject->vm();
     if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
         return false;
 
index 7bec396..c9cb22d 100644 (file)
@@ -531,7 +531,7 @@ String JSObject::calculatedClassName(JSObject* object)
     auto scope = DECLARE_CATCH_SCOPE(vm);
 
     ExecState* exec = globalObject->globalExec();
-    PropertySlot slot(object->getPrototypeDirect(), PropertySlot::InternalMethodType::VMInquiry);
+    PropertySlot slot(object->getPrototypeDirect(vm), PropertySlot::InternalMethodType::VMInquiry);
     PropertyName constructor(vm.propertyNames->constructor);
     if (object->getPropertySlot(exec, constructor, slot)) {
         EXCEPTION_ASSERT(!scope.exception());
@@ -1671,7 +1671,7 @@ bool JSObject::setPrototypeWithCycleCheck(VM& vm, ExecState* exec, JSValue proto
 
     ASSERT(methodTable(vm)->toThis(this, exec, NotStrictMode) == this);
 
-    if (this->getPrototypeDirect() == prototype)
+    if (this->getPrototypeDirect(vm) == prototype)
         return true;
 
     bool isExtensible = this->isExtensible(exec);
@@ -1690,7 +1690,7 @@ bool JSObject::setPrototypeWithCycleCheck(VM& vm, ExecState* exec, JSValue proto
         // https://bugs.webkit.org/show_bug.cgi?id=161534
         if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType))
             break; // We're done. Set the prototype.
-        nextPrototype = asObject(nextPrototype)->getPrototypeDirect();
+        nextPrototype = asObject(nextPrototype)->getPrototypeDirect(vm);
     }
     setPrototypeDirect(vm, prototype);
     return true;
@@ -1701,9 +1701,9 @@ bool JSObject::setPrototype(JSObject* object, ExecState* exec, JSValue prototype
     return object->setPrototypeWithCycleCheck(exec->vm(), exec, prototype, shouldThrowIfCantSet);
 }
 
-JSValue JSObject::getPrototype(JSObject* object, ExecState*)
+JSValue JSObject::getPrototype(JSObject* object, ExecState* exec)
 {
-    return object->getPrototypeDirect();
+    return object->getPrototypeDirect(exec->vm());
 }
 
 bool JSObject::setPrototype(VM& vm, ExecState* exec, JSValue prototype, bool shouldThrowIfCantSet)
@@ -2538,6 +2538,7 @@ void JSObject::deallocateSparseIndexMap()
 
 bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, JSValue thisValue, unsigned i, JSValue value, bool shouldThrow, bool& putResult)
 {
+    VM& vm = exec->vm();
     for (JSObject* current = this; ;) {
         // This has the same behavior with respect to prototypes as JSObject::put(). It only
         // allows a prototype to intercept a put if (a) the prototype declares the property
@@ -2559,7 +2560,7 @@ bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, J
             return true;
         }
         
-        JSValue prototypeValue = current->getPrototypeDirect();
+        JSValue prototypeValue = current->getPrototypeDirect(vm);
         if (prototypeValue.isNull())
             return false;
         
@@ -2569,7 +2570,7 @@ bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, J
 
 bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, bool& putResult)
 {
-    JSValue prototypeValue = getPrototypeDirect();
+    JSValue prototypeValue = getPrototypeDirect(exec->vm());
     if (prototypeValue.isNull())
         return false;
     
@@ -3680,7 +3681,7 @@ bool JSObject::anyObjectInChainMayInterceptIndexedAccesses() const
         if (current->structure(vm)->mayInterceptIndexedAccesses())
             return true;
         
-        JSValue prototype = current->getPrototypeDirect();
+        JSValue prototype = current->getPrototypeDirect(vm);
         if (prototype.isNull())
             return false;
         
@@ -3694,7 +3695,7 @@ bool JSObject::prototypeChainMayInterceptStoreTo(VM& vm, PropertyName propertyNa
         return anyObjectInChainMayInterceptIndexedAccesses();
     
     for (JSObject* current = this; ;) {
-        JSValue prototype = current->getPrototypeDirect();
+        JSValue prototype = current->getPrototypeDirect(vm);
         if (prototype.isNull())
             return false;
         
index 83d4275..edd5ab9 100644 (file)
@@ -132,7 +132,7 @@ public:
     // It is valid to use though when you know that you want to directly get it
     // without consulting the method table. This is akin to getting the [[Prototype]]
     // internal field directly as described in the specification.
-    JSValue getPrototypeDirect() const;
+    JSValue getPrototypeDirect(VM&) const;
 
     // This sets the prototype without checking for cycles and without
     // doing dynamic dispatch on [[SetPrototypeOf]] operation in the specification.
@@ -873,7 +873,7 @@ protected:
     {
         Base::finishCreation(vm);
         ASSERT(inherits(vm, info()));
-        ASSERT(structure()->hasPolyProto() || getPrototypeDirect().isNull() || Heap::heap(this) == Heap::heap(getPrototypeDirect()));
+        ASSERT(structure()->hasPolyProto() || getPrototypeDirect(vm).isNull() || Heap::heap(this) == Heap::heap(getPrototypeDirect(vm)));
         ASSERT(structure()->isObject());
         ASSERT(classInfo(vm));
     }
@@ -1303,9 +1303,9 @@ inline JSObject::JSObject(VM& vm, Structure* structure, Butterfly* butterfly)
 {
 }
 
-inline JSValue JSObject::getPrototypeDirect() const
+inline JSValue JSObject::getPrototypeDirect(VM& vm) const
 {
-    return structure()->storedPrototype(this);
+    return structure(vm)->storedPrototype(this);
 }
 
 inline JSValue JSObject::getPrototype(VM& vm, ExecState* exec)
@@ -1313,7 +1313,7 @@ inline JSValue JSObject::getPrototype(VM& vm, ExecState* exec)
     auto getPrototypeMethod = methodTable(vm)->getPrototype;
     MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
     if (LIKELY(getPrototypeMethod == defaultGetPrototype))
-        return getPrototypeDirect();
+        return getPrototypeDirect(vm);
     return getPrototypeMethod(this, exec);
 }
 
index 2e0b609..89811c9 100644 (file)
@@ -73,7 +73,7 @@ ALWAYS_INLINE bool JSObject::canPerformFastPutInline(VM& vm, PropertyName proper
         if (obj->structure(vm)->hasReadOnlyOrGetterSetterPropertiesExcludingProto() || obj->methodTable(vm)->getPrototype != defaultGetPrototype)
             return false;
 
-        prototype = obj->getPrototypeDirect();
+        prototype = obj->getPrototypeDirect(vm);
         if (prototype.isNull())
             return true;
 
@@ -116,7 +116,7 @@ ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyN
             return true;
         JSValue prototype;
         if (LIKELY(structure->classInfo()->methodTable.getPrototype == defaultGetPrototype || slot.internalMethodType() == PropertySlot::InternalMethodType::VMInquiry))
-            prototype = object->getPrototypeDirect();
+            prototype = object->getPrototypeDirect(vm);
         else {
             prototype = object->getPrototype(vm, exec);
             RETURN_IF_EXCEPTION(scope, false);
@@ -150,7 +150,7 @@ ALWAYS_INLINE bool JSObject::getNonIndexPropertySlot(ExecState* exec, PropertyNa
         }
         JSValue prototype;
         if (LIKELY(structure->classInfo()->methodTable.getPrototype == defaultGetPrototype || slot.internalMethodType() == PropertySlot::InternalMethodType::VMInquiry))
-            prototype = object->getPrototypeDirect();
+            prototype = object->getPrototypeDirect(vm);
         else {
             prototype = object->getPrototype(vm, exec);
             RETURN_IF_EXCEPTION(scope, false);
index cf8a678..df136fb 100644 (file)
@@ -46,7 +46,7 @@ void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor)
 void JSProxy::setTarget(VM& vm, JSGlobalObject* globalObject)
 {
     m_target.set(vm, this, globalObject);
-    setPrototypeDirect(vm, globalObject->getPrototypeDirect());
+    setPrototypeDirect(vm, globalObject->getPrototypeDirect(vm));
 }
 
 String JSProxy::className(const JSObject* object)
index b5f6b5c..4b6879b 100644 (file)
@@ -56,10 +56,10 @@ bool JSSet::isIteratorProtocolFastAndNonObservable()
     if (structure == globalObject->setStructure())
         return true;
 
-    if (getPrototypeDirect() != globalObject->jsSetPrototype())
+    VM& vm = globalObject->vm();
+    if (getPrototypeDirect(vm) != globalObject->jsSetPrototype())
         return false;
 
-    VM& vm = globalObject->vm();
     if (getDirectOffset(vm, vm.propertyNames->iteratorSymbol) != invalidOffset)
         return false;
 
index c8953aa..0e4034c 100644 (file)
@@ -104,13 +104,13 @@ JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callF
     if (error.isValid())
         return error.toErrorObject(globalObject, source());
 
-    JSValue nextPrototype = globalObject->getPrototypeDirect();
+    JSValue nextPrototype = globalObject->getPrototypeDirect(vm);
     while (nextPrototype && nextPrototype.isObject()) {
         if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType)) {
             ExecState* exec = globalObject->globalExec();
             return createTypeError(exec, ASCIILiteral("Proxy is not allowed in the global prototype chain."));
         }
-        nextPrototype = asObject(nextPrototype)->getPrototypeDirect();
+        nextPrototype = asObject(nextPrototype)->getPrototypeDirect(vm);
     }
     
     JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment();
index f1643b1..ae52107 100644 (file)
@@ -243,13 +243,14 @@ inline bool Structure::isValid(JSGlobalObject* globalObject, StructureChain* cac
     if (!cachedPrototypeChain)
         return false;
 
+    VM& vm = globalObject->vm();
     JSValue prototype = prototypeForLookup(globalObject, base);
     WriteBarrier<Structure>* cachedStructure = cachedPrototypeChain->head();
     while (*cachedStructure && !prototype.isNull()) {
-        if (asObject(prototype)->structure() != cachedStructure->get())
+        if (asObject(prototype)->structure(vm) != cachedStructure->get())
             return false;
         ++cachedStructure;
-        prototype = asObject(prototype)->getPrototypeDirect();
+        prototype = asObject(prototype)->getPrototypeDirect(vm);
     }
     return prototype.isNull() && !*cachedStructure;
 }
index 90d87af..ff8ebb7 100644 (file)
@@ -1,3 +1,57 @@
+2017-10-20  Saam Barati  <sbarati@apple.com>
+
+        Optimize accesses to how we get the direct prototype
+        https://bugs.webkit.org/show_bug.cgi?id=178548
+
+        Reviewed by Yusuke Suzuki.
+
+        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):
+
 2017-10-20  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [JSC] ScriptFetcher should be notified directly from module pipeline
index 1bccc91..3f8114f 100644 (file)
@@ -72,7 +72,7 @@ static bool isVisibleNamedProperty(JSC::ExecState& state, JSClass& thisObject, J
     //    1. If prototype is not a named properties object, and prototype has an own property named P, then return false.
     // FIXME: Implement checking for 'named properties object'.
     //    2. Set prototype to be the value of the internal [[Prototype]] property of prototype.
-    auto prototype = thisObject.getPrototypeDirect();
+    auto prototype = thisObject.getPrototypeDirect(state.vm());
     if (prototype.isObject() && JSC::asObject(prototype)->getPropertySlot(&state, propertyName, slot))
         return false;
 
@@ -112,7 +112,7 @@ static auto accessVisibleNamedProperty(JSC::ExecState& state, JSClass& thisObjec
     //    1. If prototype is not a named properties object, and prototype has an own property named P, then return false.
     // FIXME: Implement checking for 'named properties object'.
     //    2. Set prototype to be the value of the internal [[Prototype]] property of prototype.
-    auto prototype = thisObject.getPrototypeDirect();
+    auto prototype = thisObject.getPrototypeDirect(state.vm());
     if (prototype.isObject() && JSC::asObject(prototype)->getPropertySlot(&state, propertyName, slot))
         return std::nullopt;
 
index 9827d40..9406247 100644 (file)
@@ -282,7 +282,7 @@ JSDOMWindow* toJSDOMWindow(JSC::VM& vm, JSValue value)
             return jsCast<JSDOMWindow*>(object);
         if (classInfo == JSDOMWindowProxy::info())
             return jsCast<JSDOMWindowProxy*>(object)->window();
-        value = object->getPrototypeDirect();
+        value = object->getPrototypeDirect(vm);
     }
     return nullptr;
 }
index a4833d4..8098eff 100644 (file)
@@ -85,7 +85,7 @@ bool JSDOMWindowProperties::getOwnPropertySlot(JSObject* object, ExecState* stat
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     if (Base::getOwnPropertySlot(thisObject, state, propertyName, slot))
         return true;
-    JSValue proto = thisObject->getPrototypeDirect();
+    JSValue proto = thisObject->getPrototypeDirect(state->vm());
     if (proto.isObject() && jsCast<JSObject*>(proto)->hasProperty(state, propertyName))
         return false;
 
index 4ddc590..cab5919 100644 (file)
@@ -112,7 +112,7 @@ static EncodedJSValue pluginElementPropertyGetter(ExecState* exec, EncodedJSValu
 bool pluginElementCustomGetOwnPropertySlot(JSHTMLElement* element, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     if (!element->globalObject()->world().isNormal()) {
-        JSC::JSValue proto = element->getPrototypeDirect();
+        JSC::JSValue proto = element->getPrototypeDirect(exec->vm());
         if (proto.isObject() && JSC::jsCast<JSC::JSObject*>(asObject(proto))->hasProperty(exec, propertyName))
             return false;
     }
index 049e7e0..9f32811 100644 (file)
@@ -114,7 +114,7 @@ void WorkerScriptController::initScript()
     }
     
     ASSERT(m_workerGlobalScopeWrapper->globalObject() == m_workerGlobalScopeWrapper);
-    ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect())->globalObject() == m_workerGlobalScopeWrapper);
+    ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect(*m_vm))->globalObject() == m_workerGlobalScopeWrapper);
 
     m_consoleClient = std::make_unique<WorkerConsoleClient>(*m_workerGlobalScope);
     m_workerGlobalScopeWrapper->setConsoleClient(m_consoleClient.get());
index ffbf5ed..ddadfc1 100644 (file)
@@ -954,7 +954,7 @@ sub GeneratePut
         my $overrideBuiltins = $codeGenerator->InheritsExtendedAttribute($interface, "OverrideBuiltins");
         if (!$overrideBuiltins) {
             push(@$outputArray, "        PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };\n");
-            push(@$outputArray, "        JSValue prototype = thisObject->getPrototypeDirect();\n");
+            push(@$outputArray, "        JSValue prototype = thisObject->getPrototypeDirect(state->vm());\n");
             push(@$outputArray, "        if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
             $additionalIndent .= "    ";
         }
@@ -1023,7 +1023,7 @@ sub GeneratePutByIndex
         my $additionalIndent = "";
         if (!$overrideBuiltins) {
             push(@$outputArray, "    PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };\n");
-            push(@$outputArray, "    JSValue prototype = thisObject->getPrototypeDirect();\n");
+            push(@$outputArray, "    JSValue prototype = thisObject->getPrototypeDirect(state->vm());\n");
             push(@$outputArray, "    if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {\n");
             $additionalIndent .= "    ";
         }
@@ -7114,7 +7114,7 @@ sub GenerateConstructorHelperMethods
     # of whether the interface was declared with the [NoInterfaceObject] extended attribute.
     # https://heycam.github.io/webidl/#interface-prototype-object
     if (ShouldUseGlobalObjectPrototype($interface)) {
-        push(@$outputArray, "    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n");
+        push(@$outputArray, "    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(vm), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);\n");
     } elsif ($interface->isCallback) {
         push(@$outputArray, "    UNUSED_PARAM(globalObject);\n");
     } else {
index dc89813..d6c7007 100644 (file)
@@ -127,7 +127,7 @@ template<> JSValue JSTestGlobalObjectConstructor::prototypeForStructure(JSC::VM&
 
 template<> void JSTestGlobalObjectConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
 {
-    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
+    putDirect(vm, vm.propertyNames->prototype, globalObject.getPrototypeDirect(vm), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
     putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("TestGlobalObject"))), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
     putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
 }
index 53cf077..62f08f1 100644 (file)
@@ -215,7 +215,7 @@ bool JSTestNamedAndIndexedSetterNoIdentifier::put(JSCell* cell, ExecState* state
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -243,7 +243,7 @@ bool JSTestNamedAndIndexedSetterNoIdentifier::putByIndex(JSCell* cell, ExecState
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index e97892f..ff2dd16 100644 (file)
@@ -215,7 +215,7 @@ bool JSTestNamedAndIndexedSetterThrowingException::put(JSCell* cell, ExecState*
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -243,7 +243,7 @@ bool JSTestNamedAndIndexedSetterThrowingException::putByIndex(JSCell* cell, Exec
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index a29b341..eed8d88 100644 (file)
@@ -224,7 +224,7 @@ bool JSTestNamedAndIndexedSetterWithIdentifier::put(JSCell* cell, ExecState* sta
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -252,7 +252,7 @@ bool JSTestNamedAndIndexedSetterWithIdentifier::putByIndex(JSCell* cell, ExecSta
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index f5bac28..fc53a85 100644 (file)
@@ -187,7 +187,7 @@ bool JSTestNamedSetterNoIdentifier::put(JSCell* cell, ExecState* state, Property
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -207,7 +207,7 @@ bool JSTestNamedSetterNoIdentifier::putByIndex(JSCell* cell, ExecState* state, u
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index 05f7a78..1a3ad17 100644 (file)
@@ -187,7 +187,7 @@ bool JSTestNamedSetterThrowingException::put(JSCell* cell, ExecState* state, Pro
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -207,7 +207,7 @@ bool JSTestNamedSetterThrowingException::putByIndex(JSCell* cell, ExecState* sta
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index ec63e82..4e5eaa7 100644 (file)
@@ -193,7 +193,7 @@ bool JSTestNamedSetterWithIdentifier::put(JSCell* cell, ExecState* state, Proper
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -213,7 +213,7 @@ bool JSTestNamedSetterWithIdentifier::putByIndex(JSCell* cell, ExecState* state,
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index 6dd740d..89c7d95 100644 (file)
@@ -216,7 +216,7 @@ bool JSTestNamedSetterWithIndexedGetter::put(JSCell* cell, ExecState* state, Pro
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -236,7 +236,7 @@ bool JSTestNamedSetterWithIndexedGetter::putByIndex(JSCell* cell, ExecState* sta
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index a236867..7afd0c7 100644 (file)
@@ -224,7 +224,7 @@ bool JSTestNamedSetterWithIndexedGetterAndSetter::put(JSCell* cell, ExecState* s
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -252,7 +252,7 @@ bool JSTestNamedSetterWithIndexedGetterAndSetter::putByIndex(JSCell* cell, ExecS
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);
index b8f3c5a..d168cb6 100644 (file)
@@ -211,7 +211,7 @@ bool JSTestNamedSetterWithUnforgableProperties::put(JSCell* cell, ExecState* sta
 
     if (!propertyName.isSymbol()) {
         PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-        JSValue prototype = thisObject->getPrototypeDirect();
+        JSValue prototype = thisObject->getPrototypeDirect(state->vm());
         if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
             auto throwScope = DECLARE_THROW_SCOPE(state->vm());
             auto nativeValue = convert<IDLDOMString>(*state, value);
@@ -231,7 +231,7 @@ bool JSTestNamedSetterWithUnforgableProperties::putByIndex(JSCell* cell, ExecSta
 
     auto propertyName = Identifier::from(state, index);
     PropertySlot slot { thisObject, PropertySlot::InternalMethodType::VMInquiry };
-    JSValue prototype = thisObject->getPrototypeDirect();
+    JSValue prototype = thisObject->getPrototypeDirect(state->vm());
     if (!(prototype.isObject() && asObject(prototype)->getPropertySlot(state, propertyName, slot))) {
         auto throwScope = DECLARE_THROW_SCOPE(state->vm());
         auto nativeValue = convert<IDLDOMString>(*state, value);