Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (235516 => 235517)
--- trunk/Source/_javascript_Core/ChangeLog 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-08-30 19:46:56 UTC (rev 235517)
@@ -1,5 +1,47 @@
2018-08-30 Saam barati <[email protected]>
+ InlineAccess should do StringLength
+ https://bugs.webkit.org/show_bug.cgi?id=158911
+
+ Reviewed by Yusuke Suzuki.
+
+ This patch extends InlineAccess to support StringLength. This patch also
+ fixes AccessCase::fromStructureStubInfo to support ArrayLength and StringLength.
+ I forgot to implement this for ArrayLength in the initial InlineAccess
+ implementation. Supporting StringLength is a natural extension of the
+ InlineAccess machinery.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::patchableBranch8):
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::patchableBranch8):
+ * bytecode/AccessCase.cpp:
+ (JSC::AccessCase::fromStructureStubInfo):
+ * bytecode/BytecodeDumper.cpp:
+ (JSC::BytecodeDumper<Block>::printGetByIdCacheStatus):
+ * bytecode/InlineAccess.cpp:
+ (JSC::InlineAccess::dumpCacheSizesAndCrash):
+ (JSC::InlineAccess::generateSelfPropertyAccess):
+ (JSC::getScratchRegister):
+ (JSC::InlineAccess::generateSelfPropertyReplace):
+ (JSC::InlineAccess::generateArrayLength):
+ (JSC::InlineAccess::generateSelfInAccess):
+ (JSC::InlineAccess::generateStringLength):
+ * bytecode/InlineAccess.h:
+ * bytecode/PolymorphicAccess.cpp:
+ (JSC::PolymorphicAccess::regenerate):
+ * bytecode/StructureStubInfo.cpp:
+ (JSC::StructureStubInfo::initStringLength):
+ (JSC::StructureStubInfo::deref):
+ (JSC::StructureStubInfo::aboutToDie):
+ (JSC::StructureStubInfo::propagateTransitions):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::baseGPR const):
+ * jit/Repatch.cpp:
+ (JSC::tryCacheGetByID):
+
+2018-08-30 Saam barati <[email protected]>
+
CSE DataViewGet* DFG nodes
https://bugs.webkit.org/show_bug.cgi?id=188768
Modified: trunk/Source/_javascript_Core/assembler/MacroAssembler.h (235516 => 235517)
--- trunk/Source/_javascript_Core/assembler/MacroAssembler.h 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/assembler/MacroAssembler.h 2018-08-30 19:46:56 UTC (rev 235517)
@@ -450,6 +450,11 @@
return PatchableJump(branch32(cond, reg, imm));
}
+ PatchableJump patchableBranch8(RelationalCondition cond, Address address, TrustedImm32 imm)
+ {
+ return PatchableJump(branch8(cond, address, imm));
+ }
+
PatchableJump patchableBranch32(RelationalCondition cond, Address address, TrustedImm32 imm)
{
return PatchableJump(branch32(cond, address, imm));
Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (235516 => 235517)
--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-08-30 19:46:56 UTC (rev 235517)
@@ -3388,6 +3388,14 @@
return PatchableJump(result);
}
+ PatchableJump patchableBranch8(RelationalCondition cond, Address left, TrustedImm32 imm)
+ {
+ m_makeJumpPatchable = true;
+ Jump result = branch8(cond, left, imm);
+ m_makeJumpPatchable = false;
+ return PatchableJump(result);
+ }
+
PatchableJump patchableBranchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
m_makeJumpPatchable = true;
Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -121,6 +121,12 @@
case CacheType::InByIdSelf:
return AccessCase::create(vm, owner, InHit, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
+ case CacheType::ArrayLength:
+ return AccessCase::create(vm, owner, AccessCase::ArrayLength);
+
+ case CacheType::StringLength:
+ return AccessCase::create(vm, owner, AccessCase::StringLength);
+
default:
return nullptr;
}
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -447,6 +447,9 @@
case CacheType::ArrayLength:
out.printf("ArrayLength");
break;
+ case CacheType::StringLength:
+ out.printf("StringLength");
+ break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
Modified: trunk/Source/_javascript_Core/bytecode/InlineAccess.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/InlineAccess.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/InlineAccess.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -47,7 +47,19 @@
#else
JSValueRegs regs(base);
#endif
+ {
+ CCallHelpers jit;
+ jit.patchableBranch8(
+ CCallHelpers::NotEqual,
+ CCallHelpers::Address(base, JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(StringType));
+ jit.load32(CCallHelpers::Address(base, JSString::offsetOfLength()), regs.payloadGPR());
+ jit.boxInt32(regs.payloadGPR(), regs);
+
+ dataLog("string length size: ", jit.m_assembler.buffer().codeSize(), "\n");
+ }
+
{
CCallHelpers jit;
@@ -158,7 +170,7 @@
{
CCallHelpers jit;
- GPRReg base = static_cast<GPRReg>(stubInfo.patch.baseGPR);
+ GPRReg base = stubInfo.baseGPR();
JSValueRegs value = stubInfo.valueRegs();
auto branchToSlowPath = jit.patchableBranch32(
@@ -185,7 +197,7 @@
ALWAYS_INLINE static GPRReg getScratchRegister(StructureStubInfo& stubInfo)
{
ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
- allocator.lock(static_cast<GPRReg>(stubInfo.patch.baseGPR));
+ allocator.lock(stubInfo.baseGPR());
allocator.lock(static_cast<GPRReg>(stubInfo.patch.valueGPR));
#if USE(JSVALUE32_64)
allocator.lock(static_cast<GPRReg>(stubInfo.patch.baseTagGPR));
@@ -216,7 +228,7 @@
CCallHelpers jit;
- GPRReg base = static_cast<GPRReg>(stubInfo.patch.baseGPR);
+ GPRReg base = stubInfo.baseGPR();
JSValueRegs value = stubInfo.valueRegs();
auto branchToSlowPath = jit.patchableBranch32(
@@ -258,7 +270,7 @@
CCallHelpers jit;
- GPRReg base = static_cast<GPRReg>(stubInfo.patch.baseGPR);
+ GPRReg base = stubInfo.baseGPR();
JSValueRegs value = stubInfo.valueRegs();
GPRReg scratch = getScratchRegister(stubInfo);
@@ -276,11 +288,32 @@
return linkedCodeInline;
}
+bool InlineAccess::generateStringLength(StructureStubInfo& stubInfo)
+{
+ CCallHelpers jit;
+
+ GPRReg base = stubInfo.baseGPR();
+ JSValueRegs value = stubInfo.valueRegs();
+
+ auto branchToSlowPath = jit.patchableBranch8(
+ CCallHelpers::NotEqual,
+ CCallHelpers::Address(base, JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(StringType));
+ jit.load32(CCallHelpers::Address(base, JSString::offsetOfLength()), value.payloadGPR());
+ jit.boxInt32(value.payloadGPR(), value);
+
+ bool linkedCodeInline = linkCodeInline("string length", jit, stubInfo, [&] (LinkBuffer& linkBuffer) {
+ linkBuffer.link(branchToSlowPath, stubInfo.slowPathStartLocation());
+ });
+ return linkedCodeInline;
+}
+
+
bool InlineAccess::generateSelfInAccess(StructureStubInfo& stubInfo, Structure* structure)
{
CCallHelpers jit;
- GPRReg base = static_cast<GPRReg>(stubInfo.patch.baseGPR);
+ GPRReg base = stubInfo.baseGPR();
JSValueRegs value = stubInfo.valueRegs();
auto branchToSlowPath = jit.patchableBranch32(
Modified: trunk/Source/_javascript_Core/bytecode/InlineAccess.h (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/InlineAccess.h 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/InlineAccess.h 2018-08-30 19:46:56 UTC (rev 235517)
@@ -87,7 +87,7 @@
// FIXME: Make this constexpr when GCC is able to compile std::max() inside a constexpr function.
// https://bugs.webkit.org/show_bug.cgi?id=159436
//
- // This is the maximum between the size for array length access, and the size for regular self access.
+ // This is the maximum between array length, string length, and regular self access sizes.
ALWAYS_INLINE static size_t sizeForLengthAccess()
{
#if CPU(X86_64)
@@ -117,6 +117,7 @@
static bool generateArrayLength(StructureStubInfo&, JSArray*);
static void rewireStubAsJump(StructureStubInfo&, CodeLocationLabel<JITStubRoutinePtrTag>);
static bool generateSelfInAccess(StructureStubInfo&, Structure*);
+ static bool generateStringLength(StructureStubInfo&);
// This is helpful when determining the size of an IC on
// various platforms. When adding a new type of IC, implement
Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -381,7 +381,7 @@
state.stubInfo = &stubInfo;
state.ident = &ident;
- state.baseGPR = static_cast<GPRReg>(stubInfo.patch.baseGPR);
+ state.baseGPR = stubInfo.baseGPR();
state.thisGPR = static_cast<GPRReg>(stubInfo.patch.thisGPR);
state.valueRegs = stubInfo.valueRegs();
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -73,6 +73,11 @@
cacheType = CacheType::ArrayLength;
}
+void StructureStubInfo::initStringLength()
+{
+ cacheType = CacheType::StringLength;
+}
+
void StructureStubInfo::initPutByIdReplace(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset)
{
cacheType = CacheType::PutByIdReplace;
@@ -102,6 +107,7 @@
case CacheType::PutByIdReplace:
case CacheType::InByIdSelf:
case CacheType::ArrayLength:
+ case CacheType::StringLength:
return;
}
@@ -119,6 +125,7 @@
case CacheType::PutByIdReplace:
case CacheType::InByIdSelf:
case CacheType::ArrayLength:
+ case CacheType::StringLength:
return;
}
@@ -292,6 +299,7 @@
switch (cacheType) {
case CacheType::Unset:
case CacheType::ArrayLength:
+ case CacheType::StringLength:
return true;
case CacheType::GetByIdSelf:
case CacheType::PutByIdReplace:
Modified: trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h (235516 => 235517)
--- trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/bytecode/StructureStubInfo.h 2018-08-30 19:46:56 UTC (rev 235517)
@@ -61,7 +61,8 @@
PutByIdReplace,
InByIdSelf,
Stub,
- ArrayLength
+ ArrayLength,
+ StringLength
};
class StructureStubInfo {
@@ -73,6 +74,7 @@
void initGetByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
void initArrayLength();
+ void initStringLength();
void initPutByIdReplace(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
void initInByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
@@ -199,6 +201,11 @@
#endif
} patch;
+ GPRReg baseGPR() const
+ {
+ return static_cast<GPRReg>(patch.baseGPR);
+ }
+
CodeLocationCall<JSInternalPtrTag> slowPathCallLocation() { return patch.start.callAtOffset<JSInternalPtrTag>(patch.deltaFromStartToSlowPathCallLocation); }
CodeLocationLabel<JSInternalPtrTag> doneLocation() { return patch.start.labelAtOffset<JSInternalPtrTag>(patch.inlineSize); }
CodeLocationLabel<JITStubRoutinePtrTag> slowPathStartLocation() { return patch.start.labelAtOffset(patch.deltaFromStartToSlowPathStart); }
Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (235516 => 235517)
--- trunk/Source/_javascript_Core/jit/Repatch.cpp 2018-08-30 19:37:37 UTC (rev 235516)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp 2018-08-30 19:46:56 UTC (rev 235517)
@@ -215,8 +215,18 @@
}
newCase = AccessCase::create(vm, codeBlock, AccessCase::ArrayLength);
- } else if (isJSString(baseCell))
+ } else if (isJSString(baseCell)) {
+ if (stubInfo.cacheType == CacheType::Unset) {
+ bool generatedCodeInline = InlineAccess::generateStringLength(stubInfo);
+ if (generatedCodeInline) {
+ ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation(), appropriateOptimizingGetByIdFunction(kind));
+ stubInfo.initStringLength();
+ return RetryCacheLater;
+ }
+ }
+
newCase = AccessCase::create(vm, codeBlock, AccessCase::StringLength);
+ }
else if (DirectArguments* arguments = jsDynamicCast<DirectArguments*>(vm, baseCell)) {
// If there were overrides, then we can handle this as a normal property load! Guarding
// this with such a check enables us to add an IC case for that load if needed.