Title: [98674] trunk/Source/_javascript_Core
Revision
98674
Author
msab...@apple.com
Date
2011-10-27 18:09:53 -0700 (Thu, 27 Oct 2011)

Log Message

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):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (98673 => 98674)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-28 01:09:53 UTC (rev 98674)
@@ -1,3 +1,32 @@
+2011-10-27  Michael Saboff  <msab...@apple.com>
+
+        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):
+
 2011-10-27  Filip Pizlo  <fpi...@apple.com>
 
         If the bytecode generator emits code after the return in the first basic block,

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (98673 => 98674)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2011-10-28 01:09:53 UTC (rev 98674)
@@ -481,6 +481,11 @@
         m_assembler.movzbl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
 
+    void load8(ImplicitAddress address, RegisterID dest)
+    {
+        m_assembler.movzbl_mr(address.offset, address.base, dest);
+    }
+    
     void load16(BaseIndex address, RegisterID dest)
     {
         m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);

Modified: trunk/Source/_javascript_Core/assembler/X86Assembler.h (98673 => 98674)


--- trunk/Source/_javascript_Core/assembler/X86Assembler.h	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/assembler/X86Assembler.h	2011-10-28 01:09:53 UTC (rev 98674)
@@ -1231,6 +1231,11 @@
         m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
     }
 
+    void movzbl_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
+    }
+    
     void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     {
         m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (98673 => 98674)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-10-28 01:09:53 UTC (rev 98674)
@@ -581,28 +581,38 @@
     ASSERT(node.child3() == NoNode);
     SpeculateCellOperand string(this, node.child1());
     SpeculateStrictInt32Operand index(this, node.child2());
-    
+
     GPRReg stringReg = string.gpr();
     GPRReg indexReg = index.gpr();
-    
+
     if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
         speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(stringReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
-    
+
     // unsigned comparison so we can filter out negative indices and indices that are too large
     speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
-    
+
     GPRTemporary scratch(this);
     GPRReg scratchReg = scratch.gpr();
 
     m_jit.loadPtr(MacroAssembler::Address(stringReg, JSString::offsetOfValue()), scratchReg);
-    
+
     // Speculate that we're not accessing a rope
     speculationCheck(m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
-    
+
     // Load the character into scratchReg
+    JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
+
     m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load8(MacroAssembler::BaseIndex(scratchReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
+    JITCompiler::Jump cont8Bit = m_jit.jump();
+
+    is16Bit.link(&m_jit);
+
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
     m_jit.load16(MacroAssembler::BaseIndex(scratchReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
 
+    cont8Bit.link(&m_jit);
+
     integerResult(scratchReg, m_compileIndex);
 }
 
@@ -611,7 +621,7 @@
     ASSERT(node.child3() == NoNode);
     SpeculateCellOperand base(this, node.child1());
     SpeculateStrictInt32Operand property(this, node.child2());
-    
+
     GPRReg baseReg = base.gpr();
     GPRReg propertyReg = property.gpr();
 
@@ -623,18 +633,30 @@
 
     GPRTemporary scratch(this);
     GPRReg scratchReg = scratch.gpr();
-    
+
     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), scratchReg);
 
     // Speculate that we're not accessing a rope
     speculationCheck(m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
-    
+
     // Load the character into scratchReg
+    JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
+
     m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+    m_jit.load8(MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
+    JITCompiler::Jump cont8Bit = m_jit.jump();
+
+    is16Bit.link(&m_jit);
+
+    m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
     m_jit.load16(MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
 
     // We only support ascii characters
     speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
+
+    // 8 bit string values don't need the isASCII check.
+    cont8Bit.link(&m_jit);
+
     GPRTemporary smallStrings(this);
     GPRReg smallStringsReg = smallStrings.gpr();
     m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);

Modified: trunk/Source/_javascript_Core/jit/JITInlineMethods.h (98673 => 98674)


--- trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/jit/JITInlineMethods.h	2011-10-28 01:09:53 UTC (rev 98674)
@@ -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)

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (98673 => 98674)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2011-10-28 01:09:53 UTC (rev 98674)
@@ -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);

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp (98673 => 98674)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess32_64.cpp	2011-10-28 01:09:53 UTC (rev 98674)
@@ -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);

Modified: trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h (98673 => 98674)


--- trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/jit/JSInterfaceJIT.h	2011-10-28 01:09:53 UTC (rev 98674)
@@ -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); }

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (98673 => 98674)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2011-10-28 01:01:45 UTC (rev 98673)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2011-10-28 01:09:53 UTC (rev 98674)
@@ -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)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to