Bug 1313180 - Baldr: only allocate 4 bytes for float32 on the stack (r=bbouvier)
authorLuke Wagner <luke@mozilla.com>
Mon, 07 Nov 2016 14:47:05 -0600
changeset 351744 6dae0685c9d21b30fbe39ebb31254c733fd43900
parent 351743 c69a0c17a17d4948c66a1e3dae73a959836be628
child 351745 73a97f8ffebac71fb4b5d505e2aa0da35a013d8c
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1313180
milestone52.0a1
Bug 1313180 - Baldr: only allocate 4 bytes for float32 on the stack (r=bbouvier) MozReview-Commit-ID: 2n41Se7XJ6X
js/src/jit-test/tests/wasm/js-reexport.js
js/src/jit/arm/Assembler-arm.cpp
js/src/jit/x86/Assembler-x86.cpp
js/src/wasm/WasmStubs.cpp
--- a/js/src/jit-test/tests/wasm/js-reexport.js
+++ b/js/src/jit-test/tests/wasm/js-reexport.js
@@ -9,45 +9,55 @@ const Table = WebAssembly.Table;
 function accum(...args) {
     var sum = 0;
     for (var i = 0; i < args.length; i++)
         sum += args[i];
     return sum;
 }
 
 var e = wasmEvalText(`(module
-    (import $a "" "a" (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))
-    (import $b "" "b" (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32) (result f32))
-    (import $c "" "c" (param f64 f64 f64 f64 f64 f64 f64 f64 f64 f64) (result f64))
-    (import $d "" "d" (param i32 f32 f64 i32 f32 f64 i32 f32 f64 i32) (result f64))
+    (import $a "" "a" (param i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))
+    (import $b "" "b" (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32) (result f32))
+    (import $c "" "c" (param f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64) (result f64))
+    (import $d "" "d" (param i32 f32 f64 i32 f32 f64 i32 f32 f64 i32 f32 f64 i32 f32 f64 i32 f32 f64 i32 f32) (result f64))
     (func (export "a") (result i32)
         i32.const 1 i32.const 2 i32.const 3 i32.const 4 i32.const 5
         i32.const 6 i32.const 7 i32.const 8 i32.const 9 i32.const 10
+        i32.const 11 i32.const 12 i32.const 13 i32.const 14 i32.const 15
+        i32.const 16 i32.const 17 i32.const 18 i32.const 19 i32.const 20
         call $a
     )
     (func (export "b") (result f32)
         f32.const 1.1 f32.const 2.1 f32.const 3.1 f32.const 4.1 f32.const 5.1
         f32.const 6.1 f32.const 7.1 f32.const 8.1 f32.const 9.1 f32.const 10.1
+        f32.const 11.1 f32.const 12.1 f32.const 13.1 f32.const 14.1 f32.const 15.1
+        f32.const 16.1 f32.const 17.1 f32.const 18.1 f32.const 19.1 f32.const 20.1
         call $b
     )
     (func (export "c") (result f64)
         f64.const 1.2 f64.const 2.2 f64.const 3.2 f64.const 4.2 f64.const 5.2
         f64.const 6.2 f64.const 7.2 f64.const 8.2 f64.const 9.2 f64.const 10.2
+        f64.const 11.2 f64.const 12.2 f64.const 13.2 f64.const 14.2 f64.const 15.2
+        f64.const 16.2 f64.const 17.2 f64.const 18.2 f64.const 19.2 f64.const 20.2
         call $c
     )
     (func (export "d") (result f64)
-        i32.const 1 f32.const 2.1 f64.const 3.1 i32.const 4 f32.const 5.1
-        f64.const 6.1 i32.const 7 f32.const 8.3 f64.const 9.3 i32.const 10
+        i32.const 1 f32.const 2.3 f64.const 3.3 i32.const 4 f32.const 5.3
+        f64.const 6.3 i32.const 7 f32.const 8.3 f64.const 9.3 i32.const 10
+        f32.const 11.3 f64.const 12.3 i32.const 13 f32.const 14.3 f64.const 15.3
+        i32.const 16 f32.const 17.3 f64.const 18.3 i32.const 19 f32.const 20.3
         call $d
     )
 )`, {"":{a:accum, b:accum, c:accum, d:accum, e:accum}}).exports;
-assertEq(e.a(), 55);
-assertEq(e.b(), 56);
-assertEq(e.c(), 57);
-assertEq(e.d(), 56);
+
+const epsilon = .00001;
+assertEq(e.a(), 210);
+assertEq(Math.abs(e.b() - 212) < epsilon, true);
+assertEq(Math.abs(e.c() - 214) < epsilon, true);
+assertEq(Math.abs(e.d() - 213.9) < epsilon, true);
 
 setJitCompilerOption("baseline.warmup.trigger", 5);
 setJitCompilerOption("ion.warmup.trigger", 10);
 
 var e = wasmEvalText(`(module
     (import $a "" "a" (param i32 f64) (result f64))
     (export "a" $a)
 )`, {"":{a:(a,b)=>a+b}}).exports;
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -129,20 +129,18 @@ ABIArgGenerator::hardNext(MIRType type)
             stackOffset_ += sizeof(uint64_t);
             break;
         }
         current_ = ABIArg(Register::FromCode(intRegIndex_), Register::FromCode(intRegIndex_ + 1));
         intRegIndex_ += 2;
         break;
       case MIRType::Float32:
         if (floatRegIndex_ == NumFloatArgRegs) {
-            static const uint32_t align = sizeof(double) - 1;
-            stackOffset_ = (stackOffset_ + align) & ~align;
             current_ = ABIArg(stackOffset_);
-            stackOffset_ += sizeof(uint64_t);
+            stackOffset_ += sizeof(uint32_t);
             break;
         }
         current_ = ABIArg(VFPRegister(floatRegIndex_, VFPRegister::Single));
         floatRegIndex_++;
         break;
       case MIRType::Double:
         // Double register are composed of 2 float registers, thus we have to
         // skip any float register which cannot be used in a pair of float
--- a/js/src/jit/x86/Assembler-x86.cpp
+++ b/js/src/jit/x86/Assembler-x86.cpp
@@ -16,21 +16,21 @@ ABIArgGenerator::ABIArgGenerator()
     current_()
 {}
 
 ABIArg
 ABIArgGenerator::next(MIRType type)
 {
     switch (type) {
       case MIRType::Int32:
+      case MIRType::Float32:
       case MIRType::Pointer:
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint32_t);
         break;
-      case MIRType::Float32: // Float32 moves are actually double moves
       case MIRType::Double:
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint64_t);
         break;
       case MIRType::Int64:
         current_ = ABIArg(stackOffset_);
         stackOffset_ += sizeof(uint64_t);
         break;
--- a/js/src/wasm/WasmStubs.cpp
+++ b/js/src/wasm/WasmStubs.cpp
@@ -334,18 +334,21 @@ StackCopy(MacroAssembler& masm, MIRType 
         masm.store32(scratch, Address(dst.base, dst.offset + INT64LOW_OFFSET));
         masm.load32(Address(src.base, src.offset + INT64HIGH_OFFSET), scratch);
         masm.store32(scratch, Address(dst.base, dst.offset + INT64HIGH_OFFSET));
 #else
         Register64 scratch64(scratch);
         masm.load64(src, scratch64);
         masm.store64(scratch64, dst);
 #endif
+    } else if (type == MIRType::Float32) {
+        masm.loadFloat32(src, ScratchFloat32Reg);
+        masm.storeFloat32(ScratchFloat32Reg, dst);
     } else {
-        MOZ_ASSERT(IsFloatingPointType(type));
+        MOZ_ASSERT(type == MIRType::Double);
         masm.loadDouble(src, ScratchDoubleReg);
         masm.storeDouble(ScratchDoubleReg, dst);
     }
 }
 
 typedef bool ToValue;
 
 static void