[JSC] Use branchIfString/branchIfNotString instead of structure checkings
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 May 2018 04:44:44 +0000 (04:44 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 May 2018 04:44:44 +0000 (04:44 +0000)
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:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232105 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
Source/JavaScriptCore/jit/JSInterfaceJIT.h
Source/JavaScriptCore/jit/SpecializedThunkJIT.h
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/runtime/JSString.h

index 1216ee1..e352587 100644 (file)
@@ -1,3 +1,41 @@
+2018-05-22  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [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  <mark.lam@apple.com>
 
         BytecodeGeneratorification shouldn't add a ValueProfile if the JIT is disabled.
index c385222..c004d72 100644 (file)
@@ -797,8 +797,6 @@ namespace JSC {
 
         void emitRightShiftFastPath(Instruction* currentInstruction, OpcodeID);
 
-        Jump checkStructure(RegisterID reg, Structure* structure);
-
         void updateTopCallFrame();
 
         Call emitNakedCall(CodePtr<NoPtrTag> function = CodePtr<NoPtrTag>());
index db7993b..a800a74 100644 (file)
@@ -99,9 +99,9 @@ ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, int entry)
 
 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 @@ ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckSetJSValueRe
     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))
index 9133abc..eee9d28 100644 (file)
@@ -461,8 +461,8 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
     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 @@ void JIT::compileOpEqJumpSlow(Vector<SlowCaseEntry>::iterator& iter, CompileOpEq
     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 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
     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);
index ec792f4..51c276b 100644 (file)
@@ -55,14 +55,11 @@ JIT::CodeRef<JITThunkPtrTag> JIT::stringGetByValStubGenerator(VM* vm)
     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 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
         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 @@ void JIT::emitByValIdentifierCheck(ByValInfo* byValInfo, RegisterID cell, Regist
     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())));
     }
index a70a155..3c6adf0 100644 (file)
@@ -132,11 +132,11 @@ JIT::CodeRef<JITThunkPtrTag> JIT::stringGetByValStubGenerator(VM* vm)
 {
     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 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
 
     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);
index 416b5f6..5c3e323 100644 (file)
@@ -62,11 +62,6 @@ namespace JSC {
         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)
     {
index 2ddaa5a..70666fa 100644 (file)
@@ -65,12 +65,10 @@ namespace JSC {
             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)
index f59a4ff..e91b9d7 100644 (file)
@@ -612,14 +612,14 @@ MacroAssemblerCodeRef<JITThunkPtrTag> unreachableGenerator(VM* vm)
     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 @@ static void charToString(SpecializedThunkJIT& jit, VM* vm, MacroAssembler::Regis
 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> charCodeAtThunkGenerator(VM* vm)
 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");
index 4f65f63..c755911 100644 (file)
@@ -80,7 +80,6 @@ public:
     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;