Bug 1320956 - wasm baseline, read operands also when calling out to i64 division. r=bbouvier
authorLars T Hansen <lhansen@mozilla.com>
Wed, 30 Nov 2016 21:13:56 +0100
changeset 325001 df0d879c4b7c6b301a829994aca72630289bdb95
parent 325000 5b14585f3efcd201d4552591d2bbe3acc42cc4ba
child 325002 ba552ddb7a28f1f770d7360d53717b292a6d6b23
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersbbouvier
bugs1320956
milestone53.0a1
Bug 1320956 - wasm baseline, read operands also when calling out to i64 division. r=bbouvier
js/src/wasm/WasmBaselineCompile.cpp
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -3811,19 +3811,16 @@ class BaseCompiler
     MOZ_MUST_USE bool emitReturn();
     MOZ_MUST_USE bool emitCallArgs(const ValTypeVector& args, FunctionCall& baselineCall);
     MOZ_MUST_USE bool emitCall();
     MOZ_MUST_USE bool emitCallIndirect(bool oldStyle);
     MOZ_MUST_USE bool emitCommonMathCall(uint32_t lineOrBytecode, SymbolicAddress callee,
                                          ValTypeVector& signature, ExprType retType);
     MOZ_MUST_USE bool emitUnaryMathBuiltinCall(SymbolicAddress callee, ValType operandType);
     MOZ_MUST_USE bool emitBinaryMathBuiltinCall(SymbolicAddress callee, ValType operandType);
-#ifdef INT_DIV_I64_CALLOUT
-    MOZ_MUST_USE bool emitDivOrModI64BuiltinCall(SymbolicAddress callee, ValType operandType);
-#endif
     MOZ_MUST_USE bool emitGetLocal();
     MOZ_MUST_USE bool emitSetLocal();
     MOZ_MUST_USE bool emitTeeLocal();
     MOZ_MUST_USE bool emitGetGlobal();
     MOZ_MUST_USE bool emitSetGlobal();
     MOZ_MUST_USE bool emitTeeGlobal();
     MOZ_MUST_USE bool emitLoad(ValType type, Scalar::Type viewType);
     MOZ_MUST_USE bool emitStore(ValType resultType, Scalar::Type viewType);
@@ -3865,17 +3862,19 @@ class BaseCompiler
     void emitMultiplyI32();
     void emitMultiplyI64();
     void emitMultiplyF32();
     void emitMultiplyF64();
     void emitQuotientI32();
     void emitQuotientU32();
     void emitRemainderI32();
     void emitRemainderU32();
-#ifndef INT_DIV_I64_CALLOUT
+#ifdef INT_DIV_I64_CALLOUT
+    void emitDivOrModI64BuiltinCall(SymbolicAddress callee, ValType operandType);
+#else
     void emitQuotientI64();
     void emitQuotientU64();
     void emitRemainderI64();
     void emitRemainderU64();
 #endif
     void emitDivideF32();
     void emitDivideF64();
     void emitMinI32();
@@ -5875,23 +5874,21 @@ BaseCompiler::emitBinaryMathBuiltinCall(
 
     if (deadCode_)
         return true;
 
     return emitCommonMathCall(lineOrBytecode, callee, SigDD_, ExprType::F64);
 }
 
 #ifdef INT_DIV_I64_CALLOUT
-bool
+void
 BaseCompiler::emitDivOrModI64BuiltinCall(SymbolicAddress callee, ValType operandType)
 {
     MOZ_ASSERT(operandType == ValType::I64);
-
-    if (deadCode_)
-        return true;
+    MOZ_ASSERT(!deadCode_);
 
     sync();
 
     needI64(abiReturnRegI64);
 
     RegI32 temp = needI32();
     RegI64 rhs = popI64();
     RegI64 srcDest = popI64ToSpecific(abiReturnRegI64);
@@ -5912,18 +5909,16 @@ BaseCompiler::emitDivOrModI64BuiltinCall
     masm.passABIArg(rhs.low);
     masm.callWithABI(callee);
 
     masm.bind(&done);
 
     freeI32(temp);
     freeI64(rhs);
     pushI64(srcDest);
-
-    return true;
 }
 #endif // INT_DIV_I64_CALLOUT
 
 #ifdef I64_TO_FLOAT_CALLOUT
 bool
 BaseCompiler::emitConvertInt64ToFloatingCallout(SymbolicAddress callee, ValType operandType,
                                                 ValType resultType)
 {
@@ -6704,16 +6699,19 @@ BaseCompiler::emitBody()
 
 #define emitConversionOOM(doEmit, inType, outType) \
         iter_.readConversion(inType, outType, &unused_a) && (deadCode_ || doEmit())
 
 #define emitCalloutConversionOOM(doEmit, symbol, inType, outType) \
         iter_.readConversion(inType, outType, &unused_a) && \
             (deadCode_ || doEmit(symbol, inType, outType))
 
+#define emitIntDivCallout(doEmit, symbol, type) \
+        iter_.readBinary(type, &unused_a, &unused_b) && (deadCode_ || (doEmit(symbol, type), true))
+
 #define CHECK(E)      if (!(E)) goto done
 #define NEXT()        continue
 #define CHECK_NEXT(E) if (!(E)) goto done; continue
 
         // TODO / EVALUATE (bug 1316845): Not obvious that this attempt at
         // reducing overhead is really paying off relative to making the check
         // every iteration.
 
@@ -6900,35 +6898,39 @@ BaseCompiler::emitBody()
           case uint16_t(Op::I64Add):
             CHECK_NEXT(emitBinary(emitAddI64, ValType::I64));
           case uint16_t(Op::I64Sub):
             CHECK_NEXT(emitBinary(emitSubtractI64, ValType::I64));
           case uint16_t(Op::I64Mul):
             CHECK_NEXT(emitBinary(emitMultiplyI64, ValType::I64));
           case uint16_t(Op::I64DivS):
 #ifdef INT_DIV_I64_CALLOUT
-            CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::DivI64, ValType::I64));
+            CHECK_NEXT(emitIntDivCallout(emitDivOrModI64BuiltinCall, SymbolicAddress::DivI64,
+                                         ValType::I64));
 #else
             CHECK_NEXT(emitBinary(emitQuotientI64, ValType::I64));
 #endif
           case uint16_t(Op::I64DivU):
 #ifdef INT_DIV_I64_CALLOUT
-            CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::UDivI64, ValType::I64));
+            CHECK_NEXT(emitIntDivCallout(emitDivOrModI64BuiltinCall, SymbolicAddress::UDivI64,
+                                         ValType::I64));
 #else
             CHECK_NEXT(emitBinary(emitQuotientU64, ValType::I64));
 #endif
           case uint16_t(Op::I64RemS):
 #ifdef INT_DIV_I64_CALLOUT
-            CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::ModI64, ValType::I64));
+            CHECK_NEXT(emitIntDivCallout(emitDivOrModI64BuiltinCall, SymbolicAddress::ModI64,
+                                         ValType::I64));
 #else
             CHECK_NEXT(emitBinary(emitRemainderI64, ValType::I64));
 #endif
           case uint16_t(Op::I64RemU):
 #ifdef INT_DIV_I64_CALLOUT
-            CHECK_NEXT(emitDivOrModI64BuiltinCall(SymbolicAddress::UModI64, ValType::I64));
+            CHECK_NEXT(emitIntDivCallout(emitDivOrModI64BuiltinCall, SymbolicAddress::UModI64,
+                                         ValType::I64));
 #else
             CHECK_NEXT(emitBinary(emitRemainderU64, ValType::I64));
 #endif
           case uint16_t(Op::I64TruncSF32):
 #ifdef FLOAT_TO_I64_CALLOUT
             CHECK_NEXT(emitCalloutConversionOOM(emitConvertFloatingToInt64Callout,
                                                 SymbolicAddress::TruncateDoubleToInt64,
                                                 ValType::F32, ValType::I64));