ENH: Add 8 bit string support to JSC JIT
https://bugs.webkit.org/show_bug.cgi?id=71073
Changed the JIT String character access generation to create code
to check the character size and load8() or load16() as approriate.
Reviewed by Gavin Barraclough.
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::load8):
* assembler/X86Assembler.h:
(JSC::X86Assembler::movzbl_mr):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetCharCodeAt):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
* jit/JITInlineMethods.h:
(JSC::JIT::emitLoadCharacterString):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::stringGetByValStubGenerator):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::stringGetByValStubGenerator):
* jit/JSInterfaceJIT.h:
(JSC::ThunkHelpers::stringImplFlagsOffset):
(JSC::ThunkHelpers::stringImpl8BitFlag):
* jit/ThunkGenerators.cpp:
(JSC::stringCharLoad):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@98674 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 30e6309..cdb9859 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -88,8 +88,17 @@
failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
failures.append(branchTest32(Zero, dst));
+ loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplFlagsOffset()), regT1);
loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplDataOffset()), dst);
+
+ JumpList is16Bit;
+ JumpList cont8Bit;
+ is16Bit.append(branchTest32(Zero, regT1, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ load8(MacroAssembler::Address(dst, 0), dst);
+ cont8Bit.append(jump());
+ is16Bit.link(this);
load16(MacroAssembler::Address(dst, 0), dst);
+ cont8Bit.link(this);
}
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 5f389fe..41c2ae3 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -60,14 +60,23 @@
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
failures.append(jit.branchTest32(Zero, regT0));
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
-
+
// Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
failures.append(jit.branch32(AboveOrEqual, regT1, regT2));
// Load the character
+ JumpList is16Bit;
+ JumpList cont8Bit;
+ // Load the string flags
+ jit.loadPtr(Address(regT0, ThunkHelpers::stringImplFlagsOffset()), regT2);
+ jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
+ is16Bit.append(jit.branchTest32(Zero, regT2, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.load8(BaseIndex(regT0, regT1, TimesOne, 0), regT0);
+ cont8Bit.append(jit.jump());
+ is16Bit.link(&jit);
jit.load16(BaseIndex(regT0, regT1, TimesTwo, 0), regT0);
-
+ cont8Bit.link(&jit);
+
failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 0d80935..23019a8 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -176,13 +176,23 @@
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
failures.append(jit.branchTest32(Zero, regT0));
- jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
// Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
failures.append(jit.branch32(AboveOrEqual, regT2, regT1));
// Load the character
+ JumpList is16Bit;
+ JumpList cont8Bit;
+ // Load the string flags
+ jit.loadPtr(Address(regT0, ThunkHelpers::stringImplFlagsOffset()), regT1);
+ jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
+ is16Bit.append(jit.branchTest32(Zero, regT1, TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.load8(BaseIndex(regT0, regT2, TimesOne, 0), regT0);
+ cont8Bit.append(jit.jump());
+ is16Bit.link(&jit);
jit.load16(BaseIndex(regT0, regT2, TimesTwo, 0), regT0);
+
+ cont8Bit.link(&jit);
failures.append(jit.branch32(AboveOrEqual, regT0, TrustedImm32(0x100)));
jit.move(TrustedImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
index a5c94ed..3909a0d 100644
--- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -215,6 +215,8 @@
};
struct ThunkHelpers {
+ static unsigned stringImplFlagsOffset() { return StringImpl::flagsOffset(); }
+ static unsigned stringImpl8BitFlag() { return StringImpl::flagIs8Bit(); }
static unsigned stringImplDataOffset() { return StringImpl::dataOffset(); }
static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index 90d4364..d7f9923 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -43,7 +43,6 @@
jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2);
jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringValueOffset()), SpecializedThunkJIT::regT0);
jit.appendFailure(jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0));
- jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplDataOffset()), SpecializedThunkJIT::regT0);
// load index
jit.loadInt32Argument(0, SpecializedThunkJIT::regT1); // regT1 contains the index
@@ -52,7 +51,17 @@
jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT2));
// Load the character
+ SpecializedThunkJIT::JumpList is16Bit;
+ SpecializedThunkJIT::JumpList cont8Bit;
+ // Load the string flags
+ jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplFlagsOffset()), SpecializedThunkJIT::regT2);
+ jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplDataOffset()), SpecializedThunkJIT::regT0);
+ is16Bit.append(jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT2, MacroAssembler::TrustedImm32(ThunkHelpers::stringImpl8BitFlag())));
+ jit.load8(MacroAssembler::BaseIndex(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1, MacroAssembler::TimesOne, 0), SpecializedThunkJIT::regT0);
+ cont8Bit.append(jit.jump());
+ is16Bit.link(&jit);
jit.load16(MacroAssembler::BaseIndex(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1, MacroAssembler::TimesTwo, 0), SpecializedThunkJIT::regT0);
+ cont8Bit.link(&jit);
}
static void charToString(SpecializedThunkJIT& jit, JSGlobalData* globalData, MacroAssembler::RegisterID src, MacroAssembler::RegisterID dst, MacroAssembler::RegisterID scratch)