Bug 1559072: MIPS fixes r=djvj
authorIain Ireland <iireland@mozilla.com>
Tue, 25 Jun 2019 15:58:59 +0000
changeset 542996 01dd4bf87d24ac6492bddbbd28bb00021a6e6d23
parent 542995 eecb579563f7ab63376d5fd72ebf16ca0b672fc7
child 542997 f3cec09ec91b9c0f715d19cd3c7a588cfcd0d9b1
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1559072
milestone69.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 1559072: MIPS fixes r=djvj Depends on D35549 Differential Revision: https://phabricator.services.mozilla.com/D35550
js/src/jit/mips-shared/Assembler-mips-shared.h
js/src/jit/mips64/Assembler-mips64.cpp
js/src/jit/mips64/CodeGenerator-mips64.cpp
js/src/jit/mips64/MacroAssembler-mips64.cpp
js/src/jit/mips64/MacroAssembler-mips64.h
--- a/js/src/jit/mips-shared/Assembler-mips-shared.h
+++ b/js/src/jit/mips-shared/Assembler-mips-shared.h
@@ -791,16 +791,18 @@ class AssemblerMIPSShared : public Assem
 
   void writeRelocation(BufferOffset src) {
     jumpRelocations_.writeUnsigned(src.getOffset());
   }
 
   // As opposed to x86/x64 version, the data relocation has to be executed
   // before to recover the pointer, and not after.
   void writeDataRelocation(ImmGCPtr ptr) {
+    // Raw GC pointer relocations and Value relocations both end up in
+    // TraceOneDataRelocation.
     if (ptr.value) {
       if (gc::IsInsideNursery(ptr.value)) {
         embedsNurseryPointers_ = true;
       }
       dataRelocations_.writeUnsigned(nextOffset().getOffset());
     }
   }
 
--- a/js/src/jit/mips64/Assembler-mips64.cpp
+++ b/js/src/jit/mips64/Assembler-mips64.cpp
@@ -111,24 +111,28 @@ void Assembler::TraceJumpRelocations(JST
     TraceManuallyBarrieredEdge(trc, &child, "rel32");
   }
 }
 
 static void TraceOneDataRelocation(JSTracer* trc, Instruction* inst) {
   void* ptr = (void*)Assembler::ExtractLoad64Value(inst);
   void* prior = ptr;
 
-  // All pointers on MIPS64 will have the top bits cleared. If those bits
-  // are not cleared, this must be a Value.
+  // Data relocations can be for Values or for raw pointers. If a Value is
+  // zero-tagged, we can trace it as if it were a raw pointer. If a Value
+  // is not zero-tagged, we have to interpret it as a Value to ensure that the
+  // tag bits are masked off to recover the actual pointer.
   uintptr_t word = reinterpret_cast<uintptr_t>(ptr);
   if (word >> JSVAL_TAG_SHIFT) {
+    // This relocation is a Value with a non-zero tag.
     Value v = Value::fromRawBits(word);
     TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value");
     ptr = (void*)v.bitsAsPunboxPointer();
   } else {
+    // This relocation is a raw pointer or a Value with a zero tag.
     // No barrier needed since these are constants.
     TraceManuallyBarrieredGenericPointerEdge(
         trc, reinterpret_cast<gc::Cell**>(&ptr), "ion-masm-ptr");
   }
 
   if (ptr != prior) {
     Assembler::UpdateLoad64Value(inst, uint64_t(ptr));
     AutoFlushICache::flush(uintptr_t(inst), 6 * sizeof(uint32_t));
--- a/js/src/jit/mips64/CodeGenerator-mips64.cpp
+++ b/js/src/jit/mips64/CodeGenerator-mips64.cpp
@@ -28,29 +28,19 @@ ValueOperand CodeGeneratorMIPS64::ToValu
 }
 
 ValueOperand CodeGeneratorMIPS64::ToTempValue(LInstruction* ins, size_t pos) {
   return ValueOperand(ToRegister(ins->getTemp(pos)));
 }
 
 void CodeGenerator::visitBox(LBox* box) {
   const LAllocation* in = box->getOperand(0);
-  const LDefinition* result = box->getDef(0);
+  ValueOperand result = ToOutValue(box);
 
-  if (IsFloatingPointType(box->type())) {
-    FloatRegister reg = ToFloatRegister(in);
-    if (box->type() == MIRType::Float32) {
-      masm.convertFloat32ToDouble(reg, ScratchDoubleReg);
-      reg = ScratchDoubleReg;
-    }
-    masm.moveFromDouble(reg, ToRegister(result));
-  } else {
-    masm.boxValue(ValueTypeFromMIRType(box->type()), ToRegister(in),
-                  ToRegister(result));
-  }
+  masm.moveValue(TypedOrValueRegister(box->type(), ToAnyRegister(in)), result);
 }
 
 void CodeGenerator::visitUnbox(LUnbox* unbox) {
   MUnbox* mir = unbox->mir();
 
   if (mir->fallible()) {
     const ValueOperand value = ToValue(unbox, LUnbox::Input);
     masm.splitTag(value, SecondScratchReg);
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -1232,16 +1232,22 @@ void MacroAssemblerMIPS64Compat::unboxDo
                                              FloatRegister dest) {
   as_dmtc1(operand.valueReg(), dest);
 }
 
 void MacroAssemblerMIPS64Compat::unboxDouble(const Address& src,
                                              FloatRegister dest) {
   ma_ld(dest, Address(src.base, src.offset));
 }
+void MacroAssemblerMIPS64Compat::unboxDouble(const BaseIndex& src,
+                                             FloatRegister dest) {
+  SecondScratchRegisterScope scratch(asMasm());
+  loadPtr(src, scratch);
+  unboxDouble(ValueOperand(scratch), dest);
+}
 
 void MacroAssemblerMIPS64Compat::unboxString(const ValueOperand& operand,
                                              Register dest) {
   unboxNonDouble(operand, dest, JSVAL_TYPE_STRING);
 }
 
 void MacroAssemblerMIPS64Compat::unboxString(Register src, Register dest) {
   unboxNonDouble(src, dest, JSVAL_TYPE_STRING);
@@ -1362,17 +1368,17 @@ void MacroAssemblerMIPS64Compat::loadInt
   ma_dsrl(SecondScratchReg, ScratchRegister, Imm32(JSVAL_TAG_SHIFT));
   asMasm().branchTestInt32(Assembler::NotEqual, SecondScratchReg, &notInt32);
   loadPtr(Address(src.base, src.offset), SecondScratchReg);
   convertInt32ToDouble(SecondScratchReg, dest);
   ma_b(&end, ShortJump);
 
   // Not an int, just load as double.
   bind(&notInt32);
-  ma_ld(dest, src);
+  unboxDouble(src, dest);
   bind(&end);
 }
 
 void MacroAssemblerMIPS64Compat::loadInt32OrDouble(const BaseIndex& addr,
                                                    FloatRegister dest) {
   Label notInt32, end;
 
   // If it's an int, convert it to double.
@@ -1387,17 +1393,17 @@ void MacroAssemblerMIPS64Compat::loadInt
   convertInt32ToDouble(SecondScratchReg, dest);
   ma_b(&end, ShortJump);
 
   // Not an int, just load as double.
   bind(&notInt32);
   // First, recompute the offset that had been stored in the scratch register
   // since the scratch register was overwritten loading in the type.
   computeScaledAddress(addr, SecondScratchReg);
-  loadDouble(Address(SecondScratchReg, 0), dest);
+  unboxDouble(Address(SecondScratchReg, 0), dest);
   bind(&end);
 }
 
 void MacroAssemblerMIPS64Compat::loadConstantDouble(double dp,
                                                     FloatRegister dest) {
   ma_lid(dest, dp);
 }
 
@@ -2029,17 +2035,17 @@ void MacroAssembler::branchTestValue(Con
 
 // ========================================================================
 // Memory access primitives.
 template <typename T>
 void MacroAssembler::storeUnboxedValue(const ConstantOrRegister& value,
                                        MIRType valueType, const T& dest,
                                        MIRType slotType) {
   if (valueType == MIRType::Double) {
-    storeDouble(value.reg().typedReg().fpu(), dest);
+    boxDouble(value.reg().typedReg().fpu(), dest);
     return;
   }
 
   // For known integers and booleans, we can just store the unboxed value if
   // the slot has the same type.
   if ((valueType == MIRType::Int32 || valueType == MIRType::Boolean) &&
       slotType == valueType) {
     if (value.constant()) {
@@ -2066,16 +2072,22 @@ void MacroAssembler::storeUnboxedValue(c
 template void MacroAssembler::storeUnboxedValue(const ConstantOrRegister& value,
                                                 MIRType valueType,
                                                 const Address& dest,
                                                 MIRType slotType);
 template void MacroAssembler::storeUnboxedValue(
     const ConstantOrRegister& value, MIRType valueType,
     const BaseObjectElementIndex& dest, MIRType slotType);
 
+void MacroAssembler::PushBoxed(FloatRegister reg) {
+  subFromStackPtr(Imm32(sizeof(double)));
+  boxDouble(reg, Address(getStackPointer(), 0));
+  adjustFrame(sizeof(double));
+}
+
 void MacroAssembler::wasmBoundsCheck(Condition cond, Register index,
                                      Register boundsCheckLimit, Label* label) {
   ma_b(index, boundsCheckLimit, label, cond);
 }
 
 void MacroAssembler::wasmBoundsCheck(Condition cond, Register index,
                                      Address boundsCheckLimit, Label* label) {
   SecondScratchRegisterScope scratch2(*this);
--- a/js/src/jit/mips64/MacroAssembler-mips64.h
+++ b/js/src/jit/mips64/MacroAssembler-mips64.h
@@ -216,16 +216,18 @@ class MacroAssemblerMIPS64Compat : publi
   void mov(ImmPtr imm, Register dest) {
     mov(ImmWord(uintptr_t(imm.value)), dest);
   }
   void mov(CodeLabel* label, Register dest) { ma_li(dest, label); }
   void mov(Register src, Address dest) { MOZ_CRASH("NYI-IC"); }
   void mov(Address src, Register dest) { MOZ_CRASH("NYI-IC"); }
 
   void writeDataRelocation(const Value& val) {
+    // Raw GC pointer relocations and Value relocations both end up in
+    // TraceOneDataRelocation.
     if (val.isGCThing()) {
       gc::Cell* cell = val.toGCThing();
       if (cell && gc::IsInsideNursery(cell)) {
         embedsNurseryPointers_ = true;
       }
       dataRelocations_.writeUnsigned(currentOffset());
     }
   }
@@ -387,16 +389,17 @@ class MacroAssemblerMIPS64Compat : publi
   void unboxInt32(const BaseIndex& src, Register dest);
   void unboxBoolean(const ValueOperand& operand, Register dest);
   void unboxBoolean(Register src, Register dest);
   void unboxBoolean(const Address& src, Register dest);
   void unboxBoolean(const BaseIndex& src, Register dest);
   void unboxDouble(const ValueOperand& operand, FloatRegister dest);
   void unboxDouble(Register src, Register dest);
   void unboxDouble(const Address& src, FloatRegister dest);
+  void unboxDouble(const BaseIndex& src, FloatRegister dest);
   void unboxString(const ValueOperand& operand, Register dest);
   void unboxString(Register src, Register dest);
   void unboxString(const Address& src, Register dest);
   void unboxSymbol(const ValueOperand& src, Register dest);
   void unboxSymbol(Register src, Register dest);
   void unboxSymbol(const Address& src, Register dest);
   void unboxBigInt(const ValueOperand& operand, Register dest);
   void unboxBigInt(Register src, Register dest);