Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (232104 => 232105)
--- trunk/Source/_javascript_Core/ChangeLog 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-05-23 04:44:44 UTC (rev 232105)
@@ -1,3 +1,41 @@
+2018-05-22 Yusuke Suzuki <[email protected]>
+
+ [JSC] Use branchIfString/branchIfNotString instead of structure checkings
+ https://bugs.webkit.org/show_bug.cgi?id=185810
+
+ Reviewed by Saam Barati.
+
+ Let's use branchIfString/branchIfNotString helper functions instead of
+ checking structure with jsString's structure. It's easy to read. And
+ it emits less code since we do not need to embed string structure's
+ raw pointer in 32bit environment.
+
+ * jit/JIT.h:
+ * jit/JITInlines.h:
+ (JSC::JIT::emitLoadCharacterString):
+ (JSC::JIT::checkStructure): Deleted.
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emitSlow_op_eq):
+ (JSC::JIT::compileOpEqJumpSlow):
+ (JSC::JIT::emitSlow_op_neq):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ (JSC::JIT::emitByValIdentifierCheck):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ * jit/JSInterfaceJIT.h:
+ (JSC::ThunkHelpers::jsStringLengthOffset): Deleted.
+ (JSC::ThunkHelpers::jsStringValueOffset): Deleted.
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::loadJSStringArgument):
+ * jit/ThunkGenerators.cpp:
+ (JSC::stringCharLoad):
+ (JSC::charCodeAtThunkGenerator):
+ (JSC::charAtThunkGenerator):
+ * runtime/JSString.h:
+
2018-05-22 Mark Lam <[email protected]>
BytecodeGeneratorification shouldn't add a ValueProfile if the JIT is disabled.
Modified: trunk/Source/_javascript_Core/jit/JIT.h (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JIT.h 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2018-05-23 04:44:44 UTC (rev 232105)
@@ -797,8 +797,6 @@
void emitRightShiftFastPath(Instruction* currentInstruction, OpcodeID);
- Jump checkStructure(RegisterID reg, Structure* structure);
-
void updateTopCallFrame();
Call emitNakedCall(CodePtr<NoPtrTag> function = CodePtr<NoPtrTag>());
Modified: trunk/Source/_javascript_Core/jit/JITInlines.h (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JITInlines.h 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JITInlines.h 2018-05-23 04:44:44 UTC (rev 232105)
@@ -99,9 +99,9 @@
ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
{
- failures.append(branchStructure(NotEqual, Address(src, JSCell::structureIDOffset()), m_vm->stringStructure.get()));
- failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
- loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
+ failures.append(branchIfNotString(src));
+ failures.append(branch32(NotEqual, MacroAssembler::Address(src, JSString::offsetOfLength()), TrustedImm32(1)));
+ loadPtr(MacroAssembler::Address(src, JSString::offsetOfValue()), dst);
failures.append(branchTest32(Zero, dst));
loadPtr(MacroAssembler::Address(dst, StringImpl::flagsOffset()), regT1);
loadPtr(MacroAssembler::Address(dst, StringImpl::dataOffset()), dst);
@@ -198,11 +198,6 @@
return call;
}
-ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
-{
- return branchStructure(NotEqual, Address(reg, JSCell::structureIDOffset()), structure);
-}
-
ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
{
if (!m_codeBlock->isKnownNotImmediate(vReg))
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2018-05-23 04:44:44 UTC (rev 232105)
@@ -461,8 +461,8 @@
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+ genericCase.append(branchIfNotString(regT0));
+ genericCase.append(branchIfNotString(regT2));
// String case.
callOperation(operationCompareStringEq, regT0, regT2);
@@ -499,8 +499,8 @@
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+ genericCase.append(branchIfNotString(regT0));
+ genericCase.append(branchIfNotString(regT2));
// String case.
callOperation(operationCompareStringEq, regT0, regT2);
@@ -547,8 +547,8 @@
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
+ genericCase.append(branchIfNotString(regT0));
+ genericCase.append(branchIfNotString(regT2));
// String case.
callOperation(operationCompareStringEq, regT0, regT2);
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp 2018-05-23 04:44:44 UTC (rev 232105)
@@ -55,14 +55,11 @@
JSInterfaceJIT jit(vm);
JumpList failures;
jit.tagReturnAddress();
- failures.append(jit.branchStructure(
- NotEqual,
- Address(regT0, JSCell::structureIDOffset()),
- vm->stringStructure.get()));
+ failures.append(jit.branchIfNotString(regT0));
// Load string length to regT2, and start the process of loading the data pointer into regT0
- jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
- jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
+ jit.load32(Address(regT0, JSString::offsetOfLength()), regT2);
+ jit.loadPtr(Address(regT0, JSString::offsetOfValue()), regT0);
failures.append(jit.branchTest32(Zero, regT0));
// Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
@@ -252,9 +249,7 @@
linkSlowCase(iter); // property int32 check
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchStructure(NotEqual,
- Address(regT0, JSCell::structureIDOffset()),
- m_vm->stringStructure.get());
+ Jump notString = branchIfNotString(regT0);
emitNakedCall(CodeLocationLabel<NoPtrTag>(m_vm->getCTIStub(stringGetByValStubGenerator).retaggedCode<NoPtrTag>()));
Jump failed = branchTest64(Zero, regT0);
emitPutVirtualRegister(dst, regT0);
@@ -1257,7 +1252,7 @@
if (propertyName.isSymbol())
slowCases.append(branchPtr(NotEqual, cell, TrustedImmPtr(byValInfo->cachedSymbol.get())));
else {
- slowCases.append(branchStructure(NotEqual, Address(cell, JSCell::structureIDOffset()), m_vm->stringStructure.get()));
+ slowCases.append(branchIfNotString(cell));
loadPtr(Address(cell, JSString::offsetOfValue()), scratch);
slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(propertyName.impl())));
}
Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp 2018-05-23 04:44:44 UTC (rev 232105)
@@ -132,11 +132,11 @@
{
JSInterfaceJIT jit(vm);
JumpList failures;
- failures.append(jit.branchStructure(NotEqual, Address(regT0, JSCell::structureIDOffset()), vm->stringStructure.get()));
+ failures.append(jit.branchIfNotString(regT0));
// Load string length to regT1, and start the process of loading the data pointer into regT0
- jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
- jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
+ jit.load32(Address(regT0, JSString::offsetOfLength()), regT1);
+ jit.loadPtr(Address(regT0, JSString::offsetOfValue()), regT0);
failures.append(jit.branchTest32(Zero, regT0));
// Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
@@ -308,7 +308,7 @@
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchStructure(NotEqual, Address(regT0, JSCell::structureIDOffset()), m_vm->stringStructure.get());
+ Jump notString = branchIfNotString(regT0);
emitNakedCall(CodeLocationLabel<NoPtrTag>(m_vm->getCTIStub(stringGetByValStubGenerator).retaggedCode<NoPtrTag>()));
Jump failed = branchTestPtr(Zero, regT0);
emitStore(dst, regT1, regT0);
Modified: trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h 2018-05-23 04:44:44 UTC (rev 232105)
@@ -62,11 +62,6 @@
VM* m_vm;
};
- struct ThunkHelpers {
- static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
- static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
- };
-
#if USE(JSVALUE32_64)
inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload)
{
Modified: trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/SpecializedThunkJIT.h 2018-05-23 04:44:44 UTC (rev 232105)
@@ -65,12 +65,10 @@
m_failures.append(emitLoadJSCell(src, dst));
}
- void loadJSStringArgument(VM& vm, int argument, RegisterID dst)
+ void loadJSStringArgument(int argument, RegisterID dst)
{
loadCellArgument(argument, dst);
- m_failures.append(branchStructure(NotEqual,
- Address(dst, JSCell::structureIDOffset()),
- vm.stringStructure.get()));
+ m_failures.append(branchIfNotString(dst));
}
void loadArgumentWithSpecificClass(const ClassInfo* classInfo, int argument, RegisterID dst, RegisterID scratch)
Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (232104 => 232105)
--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2018-05-23 04:44:44 UTC (rev 232105)
@@ -612,14 +612,14 @@
return FINALIZE_CODE(patchBuffer, JITThunkPtrTag, "unreachable thunk");
}
-static void stringCharLoad(SpecializedThunkJIT& jit, VM* vm)
+static void stringCharLoad(SpecializedThunkJIT& jit)
{
// load string
- jit.loadJSStringArgument(*vm, SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
+ jit.loadJSStringArgument(SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
// Load string length to regT2, and start the process of loading the data pointer into regT0
- jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2);
- jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringValueOffset()), SpecializedThunkJIT::regT0);
+ jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, JSString::offsetOfLength()), SpecializedThunkJIT::regT2);
+ jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, JSString::offsetOfValue()), SpecializedThunkJIT::regT0);
jit.appendFailure(jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0));
// load index
@@ -653,7 +653,7 @@
MacroAssemblerCodeRef<JITThunkPtrTag> charCodeAtThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(vm, 1);
- stringCharLoad(jit, vm);
+ stringCharLoad(jit);
jit.returnInt32(SpecializedThunkJIT::regT0);
return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "charCodeAt");
}
@@ -661,7 +661,7 @@
MacroAssemblerCodeRef<JITThunkPtrTag> charAtThunkGenerator(VM* vm)
{
SpecializedThunkJIT jit(vm, 1);
- stringCharLoad(jit, vm);
+ stringCharLoad(jit);
charToString(jit, vm, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
return jit.finalize(vm->jitStubs->ctiNativeTailCall(vm), "charAt");
Modified: trunk/Source/_javascript_Core/runtime/JSString.h (232104 => 232105)
--- trunk/Source/_javascript_Core/runtime/JSString.h 2018-05-23 04:04:35 UTC (rev 232104)
+++ trunk/Source/_javascript_Core/runtime/JSString.h 2018-05-23 04:44:44 UTC (rev 232105)
@@ -80,7 +80,6 @@
friend class JSRopeString;
friend class MarkStack;
friend class SlotVisitor;
- friend struct ThunkHelpers;
typedef JSCell Base;
static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal | OverridesToThis;