Bug 654190 - Optimize calls to GetIndexFromString in CacheIR. r=jandem
authorTom Schuster <evilpies@gmail.com>
Mon, 24 Apr 2017 19:09:17 +0200
changeset 354675 18c3c29e52b4cb97e62a762a99a7b672b6e79495
parent 354674 a139ec75777a1263c8d09ddffcda40d65f0c6413
child 354676 6477b1b7808857c3df4be01c13eb2fbe984eb185
push id31709
push userihsiao@mozilla.com
push dateTue, 25 Apr 2017 03:21:59 +0000
treeherdermozilla-central@85932a5027c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs654190
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 654190 - Optimize calls to GetIndexFromString in CacheIR. r=jandem
js/src/jit/CacheIRCompiler.cpp
js/src/jit/MacroAssembler.cpp
js/src/jit/MacroAssembler.h
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -1517,30 +1517,39 @@ CacheIRCompiler::emitGuardAndGetIndexFro
 {
     Register str = allocator.useRegister(masm, reader.stringOperandId());
     Register output = allocator.defineRegister(masm, reader.int32OperandId());
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
 
-    LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
-    masm.PushRegsInMask(save);
+    Label vmCall, done;
+    masm.loadStringIndexValue(str, output, &vmCall);
+    masm.jump(&done);
+
+    {
+        masm.bind(&vmCall);
+        LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
+        masm.PushRegsInMask(save);
 
-    masm.setupUnalignedABICall(output);
-    masm.passABIArg(str);
-    masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetIndexFromString));
-    masm.mov(ReturnReg, output);
+        masm.setupUnalignedABICall(output);
+        masm.passABIArg(str);
+        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetIndexFromString));
+        masm.mov(ReturnReg, output);
 
-    LiveRegisterSet ignore;
-    ignore.add(output);
-    masm.PopRegsInMaskIgnore(save, ignore);
+        LiveRegisterSet ignore;
+        ignore.add(output);
+        masm.PopRegsInMaskIgnore(save, ignore);
 
-    // GetIndexFromString returns a negative value on failure.
-    masm.branchTest32(Assembler::Signed, output, output, failure->label());
+        // GetIndexFromString returns a negative value on failure.
+        masm.branchTest32(Assembler::Signed, output, output, failure->label());
+    }
+
+    masm.bind(&done);
     return true;
 }
 
 bool
 CacheIRCompiler::emitLoadProto()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     Register reg = allocator.defineRegister(masm, reader.objOperandId());
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -1418,16 +1418,30 @@ MacroAssembler::loadStringChar(Register 
     bind(&isLatin1);
     loadStringChars(output, output);
     load8ZeroExtend(BaseIndex(output, index, TimesOne), output);
 
     bind(&done);
 }
 
 void
+MacroAssembler::loadStringIndexValue(Register str, Register dest, Label* fail)
+{
+    MOZ_ASSERT(str != dest);
+
+    load32(Address(str, JSString::offsetOfFlags()), dest);
+
+    // Does not have a cached index value.
+    branchTest32(Assembler::Zero, dest, Imm32(JSString::INDEX_VALUE_BIT), fail);
+
+    // Extract the index.
+    rshift32(Imm32(JSString::INDEX_VALUE_SHIFT), dest);
+}
+
+void
 MacroAssembler::loadJSContext(Register dest)
 {
     CompileCompartment* compartment = GetJitContext()->compartment;
     if (compartment->zone()->isAtomsZone()) {
         // If we are in the atoms zone then we are generating a runtime wide
         // trampoline which can run in any zone. Load the context which is
         // currently running using cooperative scheduling in the runtime.
         // (This will need to be fixed when we have preemptive scheduling,
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -1523,16 +1523,18 @@ class MacroAssembler : public MacroAssem
 
     void loadStringLength(Register str, Register dest) {
         load32(Address(str, JSString::offsetOfLength()), dest);
     }
 
     void loadStringChars(Register str, Register dest);
     void loadStringChar(Register str, Register index, Register output, Label* fail);
 
+    void loadStringIndexValue(Register str, Register dest, Label* fail);
+
     void loadJSContext(Register dest);
     void loadJitActivation(Register dest) {
         loadJSContext(dest);
         loadPtr(Address(dest, offsetof(JSContext, activation_)), dest);
     }
 
     void guardGroupHasUnanalyzedNewScript(Register group, Register scratch, Label* fail);