Title: [265000] trunk
Revision
265000
Author
ca...@igalia.com
Date
2020-07-28 12:28:16 -0700 (Tue, 28 Jul 2020)

Log Message

[JSC] add IC support for op_get_private_name
https://bugs.webkit.org/show_bug.cgi?id=213545

Reviewed by Saam Barati.

JSTests:

Add a crashtest for a crash in an earlier edition of the GPN IC patch.

* stress/get-private-name-cache-failure.js: Added.

Source/_javascript_Core:

The baseline JIT now supports a fast path for op_private_name,
using a variant of GetByVal IC.

The generated AccessCase has the following qualities:
  - Always "direct", relying only on the current structure for cachebility
  - Never impure (DOM properties are not supported at this time, ProxyObjects are treated as JSObjects)

Based on the microbenchmark reviewed on https://bugs.webkit.org/show_bug.cgi?id=213544, this sees
an improvement of roughly 50% on average.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
* jit/ICStats.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITGetByValGenerator::JITGetByValGenerator):
* jit/JITInlineCacheGenerator.h:
* jit/JITOperations.cpp:
(JSC::getPrivateName):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emit_op_get_private_name):
(JSC::JIT::emitSlow_op_get_private_name):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emit_op_get_private_name):
(JSC::JIT::emitSlow_op_get_private_name):
* jit/Repatch.cpp:
(JSC::appropriateOptimizingGetByFunction):
(JSC::appropriateGetByFunction):
(JSC::tryCacheGetBy):
* jit/Repatch.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (264999 => 265000)


--- trunk/JSTests/ChangeLog	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/JSTests/ChangeLog	2020-07-28 19:28:16 UTC (rev 265000)
@@ -1,3 +1,14 @@
+2020-07-28  Caitlin Potter  <ca...@igalia.com>
+
+        [JSC] add IC support for op_get_private_name
+        https://bugs.webkit.org/show_bug.cgi?id=213545
+
+        Reviewed by Saam Barati.
+
+        Add a crashtest for a crash in an earlier edition of the GPN IC patch.
+
+        * stress/get-private-name-cache-failure.js: Added.
+
 2020-07-27  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC][wasm] Truncating slightly less than INT32_MIN is incorrect

Added: trunk/JSTests/stress/get-private-name-cache-failure.js (0 => 265000)


--- trunk/JSTests/stress/get-private-name-cache-failure.js	                        (rev 0)
+++ trunk/JSTests/stress/get-private-name-cache-failure.js	2020-07-28 19:28:16 UTC (rev 265000)
@@ -0,0 +1,42 @@
+//@requireOptions("--usePrivateClassFields=true", "--useLLInt=false", "--forceICFailure=true")
+// Regression test: Ensure that we don't crash when op_get_private_field caching results in
+// giving up on caching.`
+
+function assert(expr, message) {
+  if (!expr)
+    throw new Error(`Assertion Failed: ${message}`);
+}
+Object.assign(assert, {
+  equals(actual, expected) {
+    assert(actual === expected, `expected ${expected} but found ${actual}`);
+  },
+  throws(fn, errorType) {
+    try {
+      fn();
+    } catch (e) {
+      if (typeof errorType === "function")
+        assert(e instanceof errorType, `expected to throw ${errorType.name} but threw ${e}`);
+      return;
+    }
+    assert(false, `expected to throw, but no exception was thrown.`);
+  }
+});
+
+class C {
+  #x = 5;
+  get(o) { return o.#x; }
+}
+let get = C.prototype.get;
+function testAccess() {
+  assert.equals(get(new C), 5);
+}
+noInline(testAccess);
+function testThrows() {
+  assert.throws(() => get(globalThis), TypeError);
+}
+noInline(testThrows);
+
+for (var i = 0; i < 20; ++i) {
+  testAccess();
+  testThrows();
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (264999 => 265000)


--- trunk/Source/_javascript_Core/ChangeLog	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-07-28 19:28:16 UTC (rev 265000)
@@ -1,3 +1,56 @@
+2020-07-28  Caitlin Potter  <ca...@igalia.com>
+
+        [JSC] add IC support for op_get_private_name
+        https://bugs.webkit.org/show_bug.cgi?id=213545
+
+        Reviewed by Saam Barati.
+
+        The baseline JIT now supports a fast path for op_private_name,
+        using a variant of GetByVal IC.
+
+        The generated AccessCase has the following qualities:
+          - Always "direct", relying only on the current structure for cachebility
+          - Never impure (DOM properties are not supported at this time, ProxyObjects are treated as JSObjects)
+
+        Based on the microbenchmark reviewed on https://bugs.webkit.org/show_bug.cgi?id=213544, this sees
+        an improvement of roughly 50% on average.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finishCreation):
+        * bytecode/StructureStubInfo.cpp:
+        (JSC::StructureStubInfo::reset):
+        * bytecode/StructureStubInfo.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
+        * jit/ICStats.h:
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        * jit/JITInlineCacheGenerator.cpp:
+        (JSC::JITGetByValGenerator::JITGetByValGenerator):
+        * jit/JITInlineCacheGenerator.h:
+        * jit/JITOperations.cpp:
+        (JSC::getPrivateName):
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emit_op_get_private_name):
+        (JSC::JIT::emitSlow_op_get_private_name):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_get_by_val):
+        (JSC::JIT::emit_op_get_private_name):
+        (JSC::JIT::emitSlow_op_get_private_name):
+        * jit/Repatch.cpp:
+        (JSC::appropriateOptimizingGetByFunction):
+        (JSC::appropriateGetByFunction):
+        (JSC::tryCacheGetBy):
+        * jit/Repatch.h:
+
 2020-07-27  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC][wasm] Truncating slightly less than INT32_MIN is incorrect

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -509,6 +509,7 @@
         LINK(OpTailCallForwardArguments, profile)
         LINK(OpConstructVarargs, profile)
         LINK(OpGetByVal, profile)
+        LINK(OpGetPrivateName, profile)
 
         LINK(OpGetDirectPname, profile)
         LINK(OpGetByIdWithThis, profile)

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -265,6 +265,9 @@
     case AccessType::GetByVal:
         resetGetBy(codeBlock, *this, GetByKind::NormalByVal);
         break;
+    case AccessType::GetPrivateName:
+        resetGetBy(codeBlock, *this, GetByKind::PrivateName);
+        break;
     case AccessType::Put:
         resetPutByID(codeBlock, *this);
         break;

Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (264999 => 265000)


--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -57,7 +57,8 @@
     In,
     InstanceOf,
     DeleteByID,
-    DeleteByVal
+    DeleteByVal,
+    GetPrivateName,
 };
 
 enum class CacheType : int8_t {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -2326,7 +2326,7 @@
                 slowCases.append(m_jit.branchIfNotCell(baseRegs.tagGPR()));
 
             JITGetByValGenerator gen(
-                m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
+                m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetByVal, usedRegisters,
                 baseRegs, propertyRegs, resultRegs);
 
             if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString))

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -2695,7 +2695,7 @@
                 slowCases.append(m_jit.branchIfNotCell(baseGPR));
 
             JITGetByValGenerator gen(
-                m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
+                m_jit.codeBlock(), codeOrigin, callSite, AccessType::GetByVal, usedRegisters,
                 JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR));
 
             if (m_state.forNode(m_graph.varArgChild(node, 1)).isType(SpecString))

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -4897,8 +4897,8 @@
                 GPRReg propertyGPR = params[2].gpr();
 
                 auto generator = Box<JITGetByValGenerator>::create(
-                    jit.codeBlock(), node->origin.semantic, callSiteIndex, params.unavailableRegisters(),
-                    JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR));
+                    jit.codeBlock(), node->origin.semantic, callSiteIndex, AccessType::GetByVal,
+                    params.unavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(resultGPR));
 
                 generator->stubInfo()->propertyIsString = propertyIsString;
                 generator->stubInfo()->propertyIsInt32 = propertyIsInt32;

Modified: trunk/Source/_javascript_Core/jit/ICStats.h (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/ICStats.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/ICStats.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -74,7 +74,8 @@
     macro(PutByIdSelfPatch) \
     macro(InByIdSelfPatch) \
     macro(DelByReplaceWithJump) \
-    macro(DelByReplaceWithGeneric)
+    macro(DelByReplaceWithGeneric) \
+    macro(OperationGetPrivateNameOptimize)
 
 class ICEvent {
 public:

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -292,7 +292,6 @@
         DEFINE_SLOW_OP(push_with_scope)
         DEFINE_SLOW_OP(create_lexical_environment)
         DEFINE_SLOW_OP(get_by_val_with_this)
-        DEFINE_SLOW_OP(get_private_name)
         DEFINE_SLOW_OP(put_by_id_with_this)
         DEFINE_SLOW_OP(put_by_val_with_this)
         DEFINE_SLOW_OP(resolve_scope_for_hoisting_func_decl_in_eval)
@@ -357,6 +356,7 @@
         DEFINE_OP(op_get_by_id_with_this)
         DEFINE_OP(op_get_by_id_direct)
         DEFINE_OP(op_get_by_val)
+        DEFINE_OP(op_get_private_name)
         DEFINE_OP(op_get_prototype_of)
         DEFINE_OP(op_overrides_has_instance)
         DEFINE_OP(op_instanceof)
@@ -561,6 +561,7 @@
         DEFINE_SLOWCASE_OP(op_get_by_id_with_this)
         DEFINE_SLOWCASE_OP(op_get_by_id_direct)
         DEFINE_SLOWCASE_OP(op_get_by_val)
+        DEFINE_SLOWCASE_OP(op_get_private_name)
         DEFINE_SLOWCASE_OP(op_instanceof)
         DEFINE_SLOWCASE_OP(op_instanceof_custom)
         DEFINE_SLOWCASE_OP(op_jless)

Modified: trunk/Source/_javascript_Core/jit/JIT.h (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JIT.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -527,6 +527,7 @@
         void emit_op_get_by_id_with_this(const Instruction*);
         void emit_op_get_by_id_direct(const Instruction*);
         void emit_op_get_by_val(const Instruction*);
+        void emit_op_get_private_name(const Instruction*);
         void emit_op_get_argument_by_val(const Instruction*);
         void emit_op_get_prototype_of(const Instruction*);
         void emit_op_in_by_id(const Instruction*);
@@ -657,6 +658,7 @@
         void emitSlow_op_get_by_id_with_this(const Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_by_id_direct(const Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_get_private_name(const Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_get_argument_by_val(const Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_in_by_id(const Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_instanceof(const Instruction*, Vector<SlowCaseEntry>::iterator&);

Modified: trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -291,8 +291,8 @@
     fastPath.link(m_jump.m_jump, slowPath.locationOf<NoPtrTag>(m_slowPathBegin));
 }
 
-JITGetByValGenerator::JITGetByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result)
-    : Base(codeBlock, codeOrigin, callSiteIndex, AccessType::GetByVal, usedRegisters)
+JITGetByValGenerator::JITGetByValGenerator(CodeBlock* codeBlock, CodeOrigin codeOrigin, CallSiteIndex callSiteIndex, AccessType accessType, const RegisterSet& usedRegisters, JSValueRegs base, JSValueRegs property, JSValueRegs result)
+    : Base(codeBlock, codeOrigin, callSiteIndex, accessType, usedRegisters)
     , m_base(base)
     , m_result(result)
 {

Modified: trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITInlineCacheGenerator.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -232,7 +232,7 @@
     JITGetByValGenerator() { }
 
     JITGetByValGenerator(
-        CodeBlock*, CodeOrigin, CallSiteIndex, const RegisterSet& usedRegisters,
+        CodeBlock*, CodeOrigin, CallSiteIndex, AccessType, const RegisterSet& usedRegisters,
         JSValueRegs base, JSValueRegs property, JSValueRegs result);
 
     MacroAssembler::Jump slowPathJump() const

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -2192,7 +2192,79 @@
     RELEASE_AND_RETURN(scope, JSValue::encode(baseValue.get(globalObject, propertyName)));
 }
 
+} // extern "C"
 
+ALWAYS_INLINE static JSValue getPrivateName(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue baseValue, JSValue fieldNameValue)
+{
+    UNUSED_PARAM(callFrame);
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    baseValue.requireObjectCoercible(globalObject);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+    auto fieldName = fieldNameValue.toPropertyKey(globalObject);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
+    JSObject* base = baseValue.toObject(globalObject);
+    PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty);
+    base->getPrivateField(globalObject, fieldName, slot);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
+    return slot.getValue(globalObject, fieldName);
+}
+
+extern "C" {
+
+EncodedJSValue JIT_OPERATION operationGetPrivateNameOptimize(JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName)
+{
+    VM& vm = globalObject->vm();
+    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue baseValue = JSValue::decode(encodedBase);
+    JSValue fieldNameValue = JSValue::decode(encodedFieldName);
+    ASSERT(CacheableIdentifier::isCacheableIdentifierCell(fieldNameValue));
+
+    CodeBlock* codeBlock = callFrame->codeBlock();
+
+    if (baseValue.isObject()) {
+        const Identifier fieldName = fieldNameValue.toPropertyKey(globalObject);
+        EXCEPTION_ASSERT(!scope.exception());
+        ASSERT(fieldName.isSymbol());
+
+        JSObject* base = jsCast<JSObject*>(baseValue.asCell());
+        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+        PropertySlot slot(base, PropertySlot::InternalMethodType::GetOwnProperty);
+        base->getPrivateField(globalObject, fieldName, slot);
+        RETURN_IF_EXCEPTION(scope, encodedJSValue());
+
+        LOG_IC((ICEvent::OperationGetPrivateNameOptimize, baseValue.classInfoOrNull(vm), fieldName, true));
+
+        CacheableIdentifier identifier = CacheableIdentifier::createFromCell(fieldNameValue.asCell());
+        if (stubInfo->considerCachingBy(vm, codeBlock, baseValue.structureOrNull(), identifier))
+            repatchGetBy(globalObject, codeBlock, baseValue, identifier, slot, *stubInfo, GetByKind::PrivateName);
+        return JSValue::encode(slot.getValue(globalObject, fieldName));
+    }
+
+    RELEASE_AND_RETURN(scope, JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldNameValue)));
+}
+
+EncodedJSValue JIT_OPERATION operationGetPrivateName(JSGlobalObject* globalObject, StructureStubInfo* stubInfo, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName)
+{
+    VM& vm = globalObject->vm();
+    CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
+    JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
+
+    JSValue baseValue = JSValue::decode(encodedBase);
+    JSValue fieldNameValue = JSValue::decode(encodedFieldName);
+
+    stubInfo->tookSlowPath = true;
+
+    return JSValue::encode(getPrivateName(globalObject, callFrame, baseValue, fieldNameValue));
+}
+
 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)
 {
     VM& vm = globalObject->vm();

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -273,6 +273,9 @@
 CallFrame* JIT_OPERATION operationSetupForwardArgumentsFrame(JSGlobalObject*, CallFrame*, EncodedJSValue, int32_t, int32_t length) WTF_INTERNAL;
 CallFrame* JIT_OPERATION operationSetupVarargsFrame(JSGlobalObject*, CallFrame*, EncodedJSValue arguments, int32_t firstVarArgOffset, int32_t length) WTF_INTERNAL;
 
+EncodedJSValue JIT_OPERATION operationGetPrivateName(JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationGetPrivateNameOptimize(JSGlobalObject*, StructureStubInfo*, EncodedJSValue encodedBase, EncodedJSValue encodedFieldName) WTF_INTERNAL;
+
 char* JIT_OPERATION operationSwitchCharWithUnknownKeyType(JSGlobalObject*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
 char* JIT_OPERATION operationSwitchImmWithUnknownKeyType(VM*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;
 char* JIT_OPERATION operationSwitchStringWithUnknownKeyType(JSGlobalObject*, EncodedJSValue key, size_t tableIndex) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -64,7 +64,7 @@
         emitArrayProfilingSiteWithCell(regT0, regT2, profile);
 
         JITGetByValGenerator gen(
-            m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
+            m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(),
             JSValueRegs(regT0), JSValueRegs(regT1), JSValueRegs(regT0));
         if (isOperandConstantInt(property))
             gen.stubInfo()->propertyIsInt32 = true;
@@ -96,6 +96,47 @@
     }
 }
 
+void JIT::emit_op_get_private_name(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpGetPrivateName>();
+    VirtualRegister dst = bytecode.m_dst;
+    VirtualRegister base = bytecode.m_base;
+    VirtualRegister property = bytecode.m_property;
+    GPRReg baseGPR = regT0;
+    GPRReg propertyGPR = regT1;
+    emitGetVirtualRegister(base, baseGPR);
+    emitGetVirtualRegister(property, propertyGPR);
+
+    emitJumpSlowCaseIfNotJSCell(regT0, base);
+
+    JITGetByValGenerator gen(
+        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName,
+        RegisterSet::stubUnavailableRegisters(), JSValueRegs(baseGPR), JSValueRegs(propertyGPR), JSValueRegs(regT0));
+    gen.generateFastPath(*this);
+    addSlowCase(gen.slowPathJump());
+    m_getByVals.append(gen);
+
+    emitValueProfilingSite(bytecode.metadata(m_codeBlock));
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emitSlow_op_get_private_name(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    ASSERT(hasAnySlowCases(iter));
+    auto bytecode = currentInstruction->as<OpGetPrivateName>();
+    VirtualRegister dst = bytecode.m_dst;
+    GPRReg baseGPR = regT0;
+    GPRReg propertyGPR = regT1;
+
+    linkAllSlowCases(iter);
+
+    JITGetByValGenerator& gen = m_getByVals[m_getByValIndex];
+    ++m_getByValIndex;
+    Label coldPathBegin = label();
+    Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetPrivateNameOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseGPR, propertyGPR);
+    gen.reportSlowPathCall(coldPathBegin, call);
+}
+
 void JIT::emit_op_put_by_val_direct(const Instruction* currentInstruction)
 {
     emit_op_put_by_val<OpPutByValDirect>(currentInstruction);

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -255,7 +255,7 @@
         emitArrayProfilingSiteWithCell(regT0, regT4, profile);
 
         JITGetByValGenerator gen(
-            m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), RegisterSet::stubUnavailableRegisters(),
+            m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetByVal, RegisterSet::stubUnavailableRegisters(),
             JSValueRegs::payloadOnly(regT0), JSValueRegs(regT3, regT2), JSValueRegs(regT1, regT0));
         if (isOperandConstantInt(property))
             gen.stubInfo()->propertyIsInt32 = true;
@@ -287,6 +287,50 @@
     }
 }
 
+void JIT::emit_op_get_private_name(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpGetPrivateName>();
+    VirtualRegister dst = bytecode.m_dst;
+    VirtualRegister base = bytecode.m_base;
+    VirtualRegister property = bytecode.m_property;
+    auto baseGPR = JSValueRegs::payloadOnly(regT0);
+    auto propertyGPR = JSValueRegs(regT3, regT2);
+
+    emitLoad2(base, regT1, regT0, property, regT3, regT2);
+
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+
+    JITGetByValGenerator gen(
+        m_codeBlock, CodeOrigin(m_bytecodeIndex), CallSiteIndex(m_bytecodeIndex), AccessType::GetPrivateName,
+        RegisterSet::stubUnavailableRegisters(), baseGPR, propertyGPR, JSValueRegs(regT1, regT0));
+    gen.generateFastPath(*this);
+    addSlowCase(gen.slowPathJump());
+    m_getByVals.append(gen);
+
+    emitValueProfilingSite(bytecode.metadata(m_codeBlock));
+    emitStore(dst, regT1, regT0);
+}
+
+
+void JIT::emitSlow_op_get_private_name(const Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    ASSERT(hasAnySlowCases(iter));
+    auto bytecode = currentInstruction->as<OpGetPrivateName>();
+    VirtualRegister dst = bytecode.m_dst;
+
+    linkAllSlowCases(iter);
+
+    JITGetByValGenerator& gen = m_getByVals[m_getByValIndex];
+    ++m_getByValIndex;
+    Label coldPathBegin = label();
+
+    auto baseGPR = JSValueRegs(regT1, regT0);
+    auto propertyGPR = JSValueRegs(regT3, regT2);
+    Call call = callOperationWithProfile(bytecode.metadata(m_codeBlock), operationGetPrivateNameOptimize, dst, TrustedImmPtr(m_codeBlock->globalObject()), gen.stubInfo(), baseGPR, propertyGPR);
+    gen.reportSlowPathCall(coldPathBegin, call);
+}
+
+
 void JIT::emit_op_put_by_val_direct(const Instruction* currentInstruction)
 {
     emit_op_put_by_val<OpPutByValDirect>(currentInstruction);

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2020-07-28 19:28:16 UTC (rev 265000)
@@ -162,6 +162,8 @@
         return operationGetByIdDirectOptimize;
     case GetByKind::NormalByVal:
         return operationGetByValOptimize;
+    case GetByKind::PrivateName:
+        return operationGetPrivateNameOptimize;
     }
     RELEASE_ASSERT_NOT_REACHED();
 }
@@ -179,6 +181,8 @@
         return operationGetByIdDirect;
     case GetByKind::NormalByVal:
         return operationGetByValGeneric;
+    case GetByKind::PrivateName:
+        return operationGetPrivateName;
     }
     RELEASE_ASSERT_NOT_REACHED();
 }
@@ -198,6 +202,7 @@
         if (!baseValue.isCell())
             return GiveUpOnCache;
         JSCell* baseCell = baseValue.asCell();
+        const bool isPrivate = kind == GetByKind::PrivateName;
 
         std::unique_ptr<AccessCase> newCase;
 
@@ -253,6 +258,8 @@
 
             bool loadTargetFromProxy = false;
             if (baseCell->type() == PureForwardingProxyType) {
+                if (isPrivate)
+                    return GiveUpOnCache;
                 baseValue = jsCast<JSProxy*>(baseCell)->target();
                 baseCell = baseValue.asCell();
                 structure = baseCell->structure(vm);
@@ -308,9 +315,9 @@
                 if (slot.isUnset() && structure->typeInfo().getOwnPropertySlotIsImpureForPropertyAbsence())
                     return GiveUpOnCache;
 
-                // If a kind is GetByKind::Direct, we do not need to investigate prototype chains further.
+                // If a kind is GetByKind::Direct or GetByKind::PrivateName, we do not need to investigate prototype chains further.
                 // Cacheability just depends on the head structure.
-                if (kind != GetByKind::Direct) {
+                if (kind != GetByKind::Direct && !isPrivate) {
                     auto cacheStatus = prepareChainForCaching(globalObject, baseCell, slot);
                     if (!cacheStatus)
                         return GiveUpOnCache;
@@ -374,7 +381,14 @@
             } else if (!loadTargetFromProxy && getter && IntrinsicGetterAccessCase::canEmitIntrinsicGetter(getter, structure))
                 newCase = IntrinsicGetterAccessCase::create(vm, codeBlock, propertyName, slot.cachedOffset(), structure, conditionSet, getter, WTFMove(prototypeAccessChain));
             else {
-                if (slot.isCacheableValue() || slot.isUnset()) {
+                if (isPrivate) {
+                    RELEASE_ASSERT(!slot.isUnset());
+                    constexpr bool isProxy = false;
+                    if (!slot.isCacheable())
+                        return GiveUpOnCache;
+                    newCase = ProxyableAccessCase::create(vm, codeBlock, AccessCase::Load, propertyName, offset, structure,
+                        conditionSet, isProxy, slot.watchpointSet(), WTFMove(prototypeAccessChain));
+                } else if (slot.isCacheableValue() || slot.isUnset()) {
                     newCase = ProxyableAccessCase::create(vm, codeBlock, slot.isUnset() ? AccessCase::Miss : AccessCase::Load,
                         propertyName, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet(), WTFMove(prototypeAccessChain));
                 } else {

Modified: trunk/Source/_javascript_Core/jit/Repatch.h (264999 => 265000)


--- trunk/Source/_javascript_Core/jit/Repatch.h	2020-07-28 19:21:35 UTC (rev 264999)
+++ trunk/Source/_javascript_Core/jit/Repatch.h	2020-07-28 19:28:16 UTC (rev 265000)
@@ -38,7 +38,8 @@
     NormalByVal,
     Try,
     WithThis,
-    Direct
+    Direct,
+    PrivateName,
 };
 
 enum class DelByKind {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to