Bug 1279312 - Preserve TLS pointer register across calls. r=bbouvier
authorJakob Stoklund Olesen <jolesen@mozilla.com>
Mon, 25 Jul 2016 07:57:36 -0700
changeset 348665 6816fc6e9b61b38d2558e672fe9708bf1e4a6a9c
parent 348664 866d7307db91fd01cd26b50aba25b8396d716d93
child 348666 e3c513c3208856343feedd686a1997f9832f17fc
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1279312
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 1279312 - Preserve TLS pointer register across calls. r=bbouvier WebAssembly functions take a TLS pointer argument and now ensure that the WasmTlsReg register has the same value when they return. This is not yet exploited by the register allocator which still thinks that all registers are clobbered by function calls.
js/src/asmjs/WasmIonCompile.cpp
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/shared/LIR-shared.h
--- a/js/src/asmjs/WasmIonCompile.cpp
+++ b/js/src/asmjs/WasmIonCompile.cpp
@@ -952,26 +952,28 @@ class FunctionCompiler
     inline bool inDeadCode() const {
         return curBlock_ == nullptr;
     }
 
     void returnExpr(MDefinition* expr)
     {
         if (inDeadCode())
             return;
-        MAsmJSReturn* ins = MAsmJSReturn::New(alloc(), expr);
+
+        MAsmJSReturn* ins = MAsmJSReturn::New(alloc(), expr, tlsPointer_);
         curBlock_->end(ins);
         curBlock_ = nullptr;
     }
 
     void returnVoid()
     {
         if (inDeadCode())
             return;
-        MAsmJSVoidReturn* ins = MAsmJSVoidReturn::New(alloc());
+
+        MAsmJSVoidReturn* ins = MAsmJSVoidReturn::New(alloc(), tlsPointer_);
         curBlock_->end(ins);
         curBlock_ = nullptr;
     }
 
     void unreachableTrap()
     {
         if (inDeadCode())
             return;
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4130,23 +4130,34 @@ LIRGenerator::visitAsmJSReturn(MAsmJSRet
     else if (rval->type() == MIRType::Int32)
         lir->setOperand(0, useFixed(rval, ReturnReg));
 #if JS_BITS_PER_WORD == 64
     else if (rval->type() == MIRType::Int64)
         lir->setOperand(0, useFixed(rval, ReturnReg));
 #endif
     else
         MOZ_CRASH("Unexpected asm.js return type");
+
+    // Preserve the TLS pointer we were passed in `WasmTlsReg`.
+    MDefinition* tlsPtr = ins->getOperand(1);
+    lir->setOperand(1, useFixed(tlsPtr, WasmTlsReg));
+
     add(lir);
 }
 
 void
 LIRGenerator::visitAsmJSVoidReturn(MAsmJSVoidReturn* ins)
 {
-    add(new(alloc()) LAsmJSVoidReturn);
+    auto* lir = new(alloc()) LAsmJSVoidReturn;
+
+    // Preserve the TLS pointer we were passed in `WasmTlsReg`.
+    MDefinition* tlsPtr = ins->getOperand(0);
+    lir->setOperand(0, useFixed(tlsPtr, WasmTlsReg));
+
+    add(lir);
 }
 
 void
 LIRGenerator::visitAsmJSPassStackArg(MAsmJSPassStackArg* ins)
 {
     if (IsFloatingPointType(ins->arg()->type()) || IsSimdType(ins->arg()->type())) {
         MOZ_ASSERT(!ins->arg()->isEmittedAtUses());
         add(new(alloc()) LAsmJSPassStackArg(useRegisterAtStart(ins->arg())), ins);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -13417,32 +13417,37 @@ class MAsmJSParameter : public MNullaryI
   public:
     INSTRUCTION_HEADER(AsmJSParameter)
     TRIVIAL_NEW_WRAPPERS
 
     ABIArg abi() const { return abi_; }
 };
 
 class MAsmJSReturn
-  : public MAryControlInstruction<1, 0>,
+  : public MAryControlInstruction<2, 0>,
     public NoTypePolicy::Data
 {
-    explicit MAsmJSReturn(MDefinition* ins) {
+    explicit MAsmJSReturn(MDefinition* ins, MDefinition* tlsPtr) {
         initOperand(0, ins);
+        initOperand(1, tlsPtr);
     }
 
   public:
     INSTRUCTION_HEADER(AsmJSReturn)
     TRIVIAL_NEW_WRAPPERS
 };
 
 class MAsmJSVoidReturn
-  : public MAryControlInstruction<0, 0>,
+  : public MAryControlInstruction<1, 0>,
     public NoTypePolicy::Data
 {
+    explicit MAsmJSVoidReturn(MDefinition* tlsPtr) {
+        initOperand(0, tlsPtr);
+    }
+
   public:
     INSTRUCTION_HEADER(AsmJSVoidReturn)
     TRIVIAL_NEW_WRAPPERS
 };
 
 class MAsmJSPassStackArg
   : public MUnaryInstruction,
     public NoTypePolicy::Data
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -8102,23 +8102,23 @@ class LAsmJSLoadFFIFunc : public LInstru
 };
 
 class LAsmJSParameter : public LInstructionHelper<1, 0, 0>
 {
   public:
     LIR_HEADER(AsmJSParameter);
 };
 
-class LAsmJSReturn : public LInstructionHelper<0, 1, 0>
+class LAsmJSReturn : public LInstructionHelper<0, 2, 0>
 {
   public:
     LIR_HEADER(AsmJSReturn);
 };
 
-class LAsmJSVoidReturn : public LInstructionHelper<0, 0, 0>
+class LAsmJSVoidReturn : public LInstructionHelper<0, 1, 0>
 {
   public:
     LIR_HEADER(AsmJSVoidReturn);
 };
 
 class LAsmJSPassStackArg : public LInstructionHelper<0, 1, 0>
 {
   public: