Bug 1281529 part 7 - Simplify GenerateJitExit a bit by using the context instead of the runtime. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 01 Jul 2016 18:44:02 +0200
changeset 303428 2c507a30066761d77392a3ca3e73ce62b081feb1
parent 303427 9f30d4101964f632a8f0c4cfe133fbfe337954c1
child 303429 fdadd7ef691eb0797103d95193d01c8483de3547
push id30388
push usercbook@mozilla.com
push dateSat, 02 Jul 2016 09:15:23 +0000
treeherdermozilla-central@39dffbba7642 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1281529
milestone50.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 1281529 part 7 - Simplify GenerateJitExit a bit by using the context instead of the runtime. r=luke
js/src/asmjs/WasmStubs.cpp
js/src/jit/arm/Assembler-arm.h
js/src/jit/arm64/Assembler-arm64.h
js/src/jit/mips-shared/Assembler-mips-shared.h
js/src/jit/none/MacroAssembler-none.h
js/src/jit/x64/Assembler-x64.h
js/src/jit/x86/Assembler-x86.h
js/src/jscntxt.h
js/src/vm/Runtime.h
--- a/js/src/asmjs/WasmStubs.cpp
+++ b/js/src/asmjs/WasmStubs.cpp
@@ -606,60 +606,58 @@ wasm::GenerateJitExit(MacroAssembler& ma
 #if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
     static_assert(MaybeSavedGlobalReg == sizeof(void*), "stack frame accounting");
     masm.storePtr(GlobalReg, Address(masm.getStackPointer(), jitFrameBytes));
 #endif
 
     {
         // Enable Activation.
         //
-        // This sequence requires four registers, and needs to preserve the 'callee'
-        // register, so there are five live registers.
+        // This sequence requires three registers, and needs to preserve the 'callee'
+        // register, so there are four live registers.
         MOZ_ASSERT(callee == AsmJSIonExitRegCallee);
         Register reg0 = AsmJSIonExitRegE0;
         Register reg1 = AsmJSIonExitRegE1;
         Register reg2 = AsmJSIonExitRegE2;
-        Register reg3 = AsmJSIonExitRegE3;
 
         // The following is inlined:
         //   JSContext* cx = activation->cx();
-        //   Activation* act = cx->runtime()->activation();
+        //   Activation* act = cx->activation();
         //   act.active_ = true;
-        //   act.prevJitTop_ = cx->runtime()->jitTop;
-        //   act.prevJitActivation_ = cx->runtime()->jitActivation;
-        //   cx->runtime()->jitActivation = act;
-        //   act.prevProfilingActivation_ = cx->runtime()->profilingActivation;
-        //   cx->runtime()->profilingActivation_ = act;
+        //   act.prevJitTop_ = cx->jitTop;
+        //   act.prevJitActivation_ = cx->jitActivation;
+        //   cx->jitActivation = act;
+        //   act.prevProfilingActivation_ = cx->profilingActivation;
+        //   cx->profilingActivation_ = act;
         // On the ARM store8() uses the secondScratchReg (lr) as a temp.
-        size_t offsetOfActivation = JSRuntime::offsetOfActivation();
-        size_t offsetOfJitTop = offsetof(JSRuntime, jitTop);
-        size_t offsetOfJitActivation = offsetof(JSRuntime, jitActivation);
-        size_t offsetOfProfilingActivation = JSRuntime::offsetOfProfilingActivation();
+        size_t offsetOfActivation = JSContext::offsetOfActivation();
+        size_t offsetOfJitTop = offsetof(JSContext, jitTop);
+        size_t offsetOfJitActivation = offsetof(JSContext, jitActivation);
+        size_t offsetOfProfilingActivation = JSContext::offsetOfProfilingActivation();
         masm.loadWasmActivation(reg0);
-        masm.loadPtr(Address(reg0, WasmActivation::offsetOfContext()), reg3);
-        masm.loadPtr(Address(reg3, JSContext::offsetOfRuntime()), reg0);
+        masm.loadPtr(Address(reg0, WasmActivation::offsetOfContext()), reg0);
         masm.loadPtr(Address(reg0, offsetOfActivation), reg1);
 
         //   act.active_ = true;
         masm.store8(Imm32(1), Address(reg1, JitActivation::offsetOfActiveUint8()));
 
-        //   act.prevJitTop_ = cx->runtime()->jitTop;
+        //   act.prevJitTop_ = cx->jitTop;
         masm.loadPtr(Address(reg0, offsetOfJitTop), reg2);
         masm.storePtr(reg2, Address(reg1, JitActivation::offsetOfPrevJitTop()));
 
-        //   act.prevJitActivation_ = cx->runtime()->jitActivation;
+        //   act.prevJitActivation_ = cx->jitActivation;
         masm.loadPtr(Address(reg0, offsetOfJitActivation), reg2);
         masm.storePtr(reg2, Address(reg1, JitActivation::offsetOfPrevJitActivation()));
-        //   cx->runtime()->jitActivation = act;
+        //   cx->jitActivation = act;
         masm.storePtr(reg1, Address(reg0, offsetOfJitActivation));
 
-        //   act.prevProfilingActivation_ = cx->runtime()->profilingActivation;
+        //   act.prevProfilingActivation_ = cx->profilingActivation;
         masm.loadPtr(Address(reg0, offsetOfProfilingActivation), reg2);
         masm.storePtr(reg2, Address(reg1, Activation::offsetOfPrevProfiling()));
-        //   cx->runtime()->profilingActivation_ = act;
+        //   cx->profilingActivation_ = act;
         masm.storePtr(reg1, Address(reg0, offsetOfProfilingActivation));
     }
 
     AssertStackAlignment(masm, JitStackAlignment, sizeOfRetAddr);
     masm.callJitNoProfiler(callee);
     AssertStackAlignment(masm, JitStackAlignment, sizeOfRetAddr);
 
     {
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -151,17 +151,16 @@ struct ScratchDoubleScope : public AutoF
 // accessed with a single instruction.
 static const int32_t AsmJSGlobalRegBias = 1024;
 
 // Registers used in the GenerateFFIIonExit Enable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = r4;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = r0;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE1 = r1;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE2 = r2;
-static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE3 = r3;
 
 // Registers used in the GenerateFFIIonExit Disable Activation block.
 // None of these may be the second scratch register (lr).
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnData = r2;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnType = r3;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD0 = r0;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD1 = r1;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = r4;
--- a/js/src/jit/arm64/Assembler-arm64.h
+++ b/js/src/jit/arm64/Assembler-arm64.h
@@ -119,17 +119,16 @@ REGISTER_CODE_LIST(IMPORT_VIXL_VREGISTER
 
 static constexpr ValueOperand JSReturnOperand = ValueOperand(JSReturnReg);
 
 // Registers used in the GenerateFFIIonExit Enable Activation block.
 static constexpr Register AsmJSIonExitRegCallee = r8;
 static constexpr Register AsmJSIonExitRegE0 = r0;
 static constexpr Register AsmJSIonExitRegE1 = r1;
 static constexpr Register AsmJSIonExitRegE2 = r2;
-static constexpr Register AsmJSIonExitRegE3 = r3;
 
 // Registers used in the GenerateFFIIonExit Disable Activation block.
 // None of these may be the second scratch register.
 static constexpr Register AsmJSIonExitRegReturnData = r2;
 static constexpr Register AsmJSIonExitRegReturnType = r3;
 static constexpr Register AsmJSIonExitRegD0 = r0;
 static constexpr Register AsmJSIonExitRegD1 = r1;
 static constexpr Register AsmJSIonExitRegD2 = r4;
--- a/js/src/jit/mips-shared/Assembler-mips-shared.h
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.h
@@ -112,17 +112,16 @@ static MOZ_CONSTEXPR_VAR FloatRegister S
 // accessed with a single instruction.
 static const int32_t AsmJSGlobalRegBias = 32768;
 
 // Registers used in the GenerateFFIIonExit Enable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = t0;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = a0;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE1 = a1;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE2 = a2;
-static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE3 = a3;
 
 // Registers used in the GenerateFFIIonExit Disable Activation block.
 // None of these may be the second scratch register (t8).
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD0 = a0;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD1 = a1;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = t0;
 
 // Registerd used in RegExpMatcher instruction (do not use JSReturnOperand).
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -42,17 +42,16 @@ static MOZ_CONSTEXPR_VAR Register IntArg
 static MOZ_CONSTEXPR_VAR Register IntArgReg3 = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register GlobalReg = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register HeapReg = { Registers::invalid_reg };
 
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE1 = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE2 = { Registers::invalid_reg };
-static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE3 = { Registers::invalid_reg };
 
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnData = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnType = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD0 = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD1 = { Registers::invalid_reg };
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = { Registers::invalid_reg };
 
 static MOZ_CONSTEXPR_VAR Register RegExpTesterRegExpReg = { Registers::invalid_reg };
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -149,17 +149,16 @@ static MOZ_CONSTEXPR_VAR uint32_t NumFlo
 static MOZ_CONSTEXPR_VAR FloatRegister FloatArgRegs[NumFloatArgRegs] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 };
 #endif
 
 // Registers used in the GenerateFFIIonExit Enable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = r10;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = rax;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE1 = rdi;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE2 = rbx;
-static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE3 = rsi;
 
 // Registers used in the GenerateFFIIonExit Disable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnData = ecx;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnType = ecx;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD0 = rax;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD1 = rdi;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = rbx;
 
--- a/js/src/jit/x86/Assembler-x86.h
+++ b/js/src/jit/x86/Assembler-x86.h
@@ -97,17 +97,16 @@ static MOZ_CONSTEXPR_VAR Register WasmTa
 static MOZ_CONSTEXPR_VAR Register OsrFrameReg = edx;
 static MOZ_CONSTEXPR_VAR Register PreBarrierReg = edx;
 
 // Registers used in the GenerateFFIIonExit Enable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegCallee = ecx;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE0 = edi;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE1 = eax;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE2 = ebx;
-static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegE3 = edx;
 
 // Registers used in the GenerateFFIIonExit Disable Activation block.
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnData = edx;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegReturnType = ecx;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD0 = edi;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD1 = eax;
 static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = esi;
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -98,16 +98,20 @@ class ExclusiveContext : public ContextF
     friend struct StackBaseShape;
     friend void JSScript::initCompartment(ExclusiveContext* cx);
     friend class jit::JitContext;
     friend class Activation;
 
     // The thread on which this context is running, if this is not a JSContext.
     HelperThread* helperThread_;
 
+    // Hide runtime_ from JSContext. JSContext inherits from JSRuntime, so it's
+    // more efficient to use |this|.
+    using ContextFriendFields::runtime_;
+
   public:
     enum ContextKind {
         Context_JS,
         Context_Exclusive
     };
 
   private:
     ContextKind contextKind_;
@@ -317,19 +321,22 @@ struct JSContext : public js::ExclusiveC
     using ExclusiveContext::pod_malloc;
     using ExclusiveContext::staticStrings;
     using ExclusiveContext::updateMallocCounter;
     using ExclusiveContext::wellKnownSymbols;
 
     JSRuntime* runtime() { return this; }
     js::PerThreadData& mainThread() { return this->JSRuntime::mainThread; }
 
-    static size_t offsetOfRuntime() {
-        return offsetof(JSContext, runtime_);
+    static size_t offsetOfActivation() {
+        return offsetof(JSContext, activation_);
     }
+    static size_t offsetOfProfilingActivation() {
+        return offsetof(JSContext, profilingActivation_);
+     }
     static size_t offsetOfCompartment() {
         return offsetof(JSContext, compartment_);
     }
 
     friend class js::ExclusiveContext;
     friend class JS::AutoSaveExceptionState;
     friend class js::jit::DebugModeOSRVolatileJitFrameIterator;
     friend void js::ReportOverRecursed(JSContext*, unsigned errorNumber);
@@ -383,26 +390,26 @@ struct JSContext : public js::ExclusiveC
     bool jitIsBroken;
 
     void updateJITEnabled();
 
     /* Whether this context has JS frames on the stack. */
     bool currentlyRunning() const;
 
     bool currentlyRunningInInterpreter() const {
-        return runtime_->activation()->isInterpreter();
+        return activation()->isInterpreter();
     }
     bool currentlyRunningInJit() const {
-        return runtime_->activation()->isJit();
+        return activation()->isJit();
     }
     js::InterpreterFrame* interpreterFrame() const {
-        return runtime_->activation()->asInterpreter()->current();
+        return activation()->asInterpreter()->current();
     }
     js::InterpreterRegs& interpreterRegs() const {
-        return runtime_->activation()->asInterpreter()->regs();
+        return activation()->asInterpreter()->regs();
     }
 
     /*
      * Get the topmost script and optional pc on the stack. By default, this
      * function only returns a JSScript in the current compartment, returning
      * nullptr if the current script is in a different compartment. This
      * behavior can be overridden by passing ALLOW_CROSS_COMPARTMENT.
      */
@@ -410,21 +417,21 @@ struct JSContext : public js::ExclusiveC
         DONT_ALLOW_CROSS_COMPARTMENT = false,
         ALLOW_CROSS_COMPARTMENT = true
     };
     inline JSScript* currentScript(jsbytecode** pc = nullptr,
                                    MaybeAllowCrossCompartment = DONT_ALLOW_CROSS_COMPARTMENT) const;
 
     // The generational GC nursery may only be used on the main thread.
     inline js::Nursery& nursery() {
-        return runtime_->gc.nursery;
+        return gc.nursery;
     }
 
     void minorGC(JS::gcreason::Reason reason) {
-        runtime_->gc.minorGC(this, reason);
+        gc.minorGC(this, reason);
     }
 
   public:
     bool isExceptionPending() {
         return throwing;
     }
 
     MOZ_MUST_USE
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -688,16 +688,17 @@ struct JSRuntime : public JS::shadow::Ru
     friend class js::ActivationIterator;
     friend class js::jit::JitActivation;
     friend class js::WasmActivation;
     friend class js::jit::CompileRuntime;
 #ifdef DEBUG
     friend void js::AssertCurrentThreadCanLock(js::RuntimeLock which);
 #endif
 
+  protected:
     /*
      * Points to the most recent activation running on the thread.
      * See Activation comment in vm/Stack.h.
      */
     js::Activation* activation_;
 
     /*
      * Points to the most recent profiling activation running on the