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 {