diff --git a/js/src/jit/riscv64/Assembler-riscv64.cpp b/js/src/jit/riscv64/Assembler-riscv64.cpp index bdceaf9428d13..d92acd80b05d7 100644 --- a/js/src/jit/riscv64/Assembler-riscv64.cpp +++ b/js/src/jit/riscv64/Assembler-riscv64.cpp @@ -63,6 +63,18 @@ void Assembler::nop() { // Size of the instruction stream, in bytes. size_t Assembler::size() const { return m_buffer.size(); } +bool Assembler::swapBuffer(wasm::Bytes& bytes) { + // For now, specialize to the one use case. As long as wasm::Bytes is a + // Vector, not a linked-list of chunks, there's not much we can do other + // than copy. + MOZ_ASSERT(bytes.empty()); + if (!bytes.resize(bytesNeeded())) { + return false; + } + m_buffer.executableCopy(bytes.begin()); + return true; +} + // Size of the relocation table, in bytes. size_t Assembler::jumpRelocationTableBytes() const { return jumpRelocations_.length(); @@ -1168,56 +1180,62 @@ bool Assembler::reserve(size_t size) { // now vs. on-demand. return !oom(); } -// void Assembler::TraceJumpRelocations(JSTracer* trc, JitCode* code, -// CompactBufferReader& reader) { -// while (reader.more()) { -// JitCode* child = -// CodeFromJump((Instruction*)(code->raw() + reader.readUnsigned())); -// TraceManuallyBarrieredEdge(trc, &child, "rel32"); -// } -// } - -// static void TraceOneDataRelocation(JSTracer* trc, -// mozilla::Maybe& awjc, -// JitCode* code, Instruction* inst) { -// void* ptr = (void*)Assembler::ExtractLoad64Value(inst); -// void* prior = ptr; - -// // 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(ptr); -// if (word >> JSVAL_TAG_SHIFT) { -// // This relocation is a Value with a non-zero tag. -// Value v = Value::fromRawBits(word); -// TraceManuallyBarrieredEdge(trc, &v, "jit-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(&ptr), "jit-masm-ptr"); -// } - -// if (ptr != prior) { -// if (awjc.isNothing()) { -// awjc.emplace(code); -// } -// Assembler::UpdateLoad64Value(inst, uint64_t(ptr)); -// } -// } - -// /* static */ -// void Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, -// CompactBufferReader& reader) { -// mozilla::Maybe awjc; -// while (reader.more()) { -// size_t offset = reader.readUnsigned(); -// Instruction* inst = (Instruction*)(code->raw() + offset); -// TraceOneDataRelocation(trc, awjc, code, inst); -// } -// } + +static JitCode* CodeFromJump(Instruction* jump) { + uint8_t* target = (uint8_t*)Assembler::ExtractLoad64Value(jump); + return JitCode::FromExecutable(target); +} + +void Assembler::TraceJumpRelocations(JSTracer* trc, JitCode* code, + CompactBufferReader& reader) { + while (reader.more()) { + JitCode* child = + CodeFromJump((Instruction*)(code->raw() + reader.readUnsigned())); + TraceManuallyBarrieredEdge(trc, &child, "rel32"); + } +} + +static void TraceOneDataRelocation(JSTracer* trc, + mozilla::Maybe& awjc, + JitCode* code, Instruction* inst) { + void* ptr = (void*)Assembler::ExtractLoad64Value(inst); + void* prior = ptr; + + // 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(ptr); + if (word >> JSVAL_TAG_SHIFT) { + // This relocation is a Value with a non-zero tag. + Value v = Value::fromRawBits(word); + TraceManuallyBarrieredEdge(trc, &v, "jit-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(&ptr), "jit-masm-ptr"); + } + + if (ptr != prior) { + if (awjc.isNothing()) { + awjc.emplace(code); + } + Assembler::UpdateLoad64Value(inst, uint64_t(ptr)); + } +} + +/* static */ +void Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, + CompactBufferReader& reader) { + mozilla::Maybe awjc; + while (reader.more()) { + size_t offset = reader.readUnsigned(); + Instruction* inst = (Instruction*)(code->raw() + offset); + TraceOneDataRelocation(trc, awjc, code, inst); + } +} UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler) @@ -1272,5 +1290,42 @@ void Assembler::retarget(Label* label, Label* target) { label->reset(); } + bool Assembler::appendRawCode(const uint8_t* code, size_t numBytes) { + if (m_buffer.oom()) { + return false; + } + while (numBytes > SliceSize) { + m_buffer.putBytes(SliceSize, code); + numBytes -= SliceSize; + code += SliceSize; + } + m_buffer.putBytes(numBytes, code); + return !m_buffer.oom(); + } + + void Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled) { + Instruction* i0 = (Instruction*)inst_.raw(); + Instruction* i1 = (Instruction*)(inst_.raw() + 1 * kInstrSize); + Instruction* i2 = (Instruction*)(inst_.raw() + 2 * kInstrSize); + Instruction* i3 = (Instruction*)(inst_.raw() + 3 * kInstrSize); + Instruction* i4 = (Instruction*)(inst_.raw() + 4 * kInstrSize); + Instruction* i5 = (Instruction*)(inst_.raw() + 5 * kInstrSize); + Instruction* i6 = (Instruction*)(inst_.raw() + 6 * kInstrSize); + + MOZ_ASSERT(IsLui(i0->InstructionBits())); + MOZ_ASSERT(IsAddi(i1->InstructionBits())); + MOZ_ASSERT(IsSlli(i2->InstructionBits())); + MOZ_ASSERT(IsOri(i3->InstructionBits())); + MOZ_ASSERT(IsSlli(i4->InstructionBits())); + MOZ_ASSERT(IsOri(i5->InstructionBits())); + if (enabled) { + Instr jalr_ = JALR | (ra.code() << kRdShift) | (0x0 << kFunct3Shift) | + (i5->RdValue() << kRs1Shift) | (0x0 << kImm12Shift); + *((Instr*)i6) = jalr_; + } else { + *((Instr*)i6) = kNopByte; + } + } + } // namespace jit } // namespace js diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h index 032303867230c..5c9c999ba5a88 100644 --- a/js/src/jit/riscv64/Assembler-riscv64.h +++ b/js/src/jit/riscv64/Assembler-riscv64.h @@ -267,6 +267,8 @@ class Assembler : public AssemblerShared, MOZ_ASSERT(!isFinished); isFinished = true; } + + bool swapBuffer(wasm::Bytes& bytes); // Size of the instruction stream, in bytes. size_t size() const; // Size of the data table, in bytes. @@ -456,13 +458,13 @@ class Assembler : public AssemblerShared, static uint32_t PatchWrite_NearCallSize() { return 7; } static void TraceJumpRelocations(JSTracer* trc, JitCode* code, - CompactBufferReader& reader){ MOZ_CRASH(); } + CompactBufferReader& reader); static void TraceDataRelocations(JSTracer* trc, JitCode* code, - CompactBufferReader& reader){ MOZ_CRASH(); } + CompactBufferReader& reader); static void ToggleToJmp(CodeLocationLabel inst_); static void ToggleToCmp(CodeLocationLabel inst_); - static void ToggleCall(CodeLocationLabel inst_, bool) { MOZ_CRASH(); } + static void ToggleCall(CodeLocationLabel inst_, bool enable); static void Bind(uint8_t* rawCode, const CodeLabel& label); // label operations @@ -546,6 +548,8 @@ class Assembler : public AssemblerShared, } } + bool appendRawCode(const uint8_t* code, size_t numBytes); + void assertNoGCThings() const { #ifdef DEBUG MOZ_ASSERT(dataRelocations_.length() == 0); diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp index c5a410c6802ab..864bf33bc37d0 100644 --- a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp +++ b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp @@ -392,6 +392,12 @@ void MacroAssemblerRiscv64::ma_compareF32(Register rd, case DoubleGreaterThan: flt_s(rd, cmp2, cmp1); break; + case DoubleOrdered: + CompareIsNotNanF32(rd, cmp1, cmp2); + return; + case DoubleUnordered: + CompareIsNanF32(rd, cmp1, cmp2); + return; } if (cc >= FIRST_UNORDERED && cc <= LAST_UNORDERED) { UseScratchRegisterScope temps(this); @@ -431,6 +437,12 @@ void MacroAssemblerRiscv64::ma_compareF64(Register rd, case DoubleGreaterThan: flt_d(rd, cmp2, cmp1); break; + case DoubleOrdered: + CompareIsNotNanF64(rd, cmp1, cmp2); + return; + case DoubleUnordered: + CompareIsNanF64(rd, cmp1, cmp2); + return; } if (cc >= FIRST_UNORDERED && cc <= LAST_UNORDERED) { UseScratchRegisterScope temps(this); @@ -1380,11 +1392,11 @@ void MacroAssemblerRiscv64Compat::testUndefinedSet(Condition cond, void MacroAssemblerRiscv64Compat::unboxInt32(const ValueOperand& operand, Register dest) { - slli(dest, operand.valueReg(), 0); + slliw(dest, operand.valueReg(), 0); } void MacroAssemblerRiscv64Compat::unboxInt32(Register src, Register dest) { - slli(dest, src, 0); + slliw(dest, src, 0); } void MacroAssemblerRiscv64Compat::unboxInt32(const Address& src, @@ -1963,10 +1975,8 @@ CodeOffset MacroAssemblerRiscv64Compat::toggledCall(JitCode* target, ma_liPatchable(ScratchRegister, ImmPtr(target->raw())); if (enabled) { jalr(ScratchRegister); - nop(); } else { nop(); - nop(); } MOZ_ASSERT_IF(!oom(), nextOffset().getOffset() - offset.offset() == ToggledCallSize(nullptr)); diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.h b/js/src/jit/riscv64/MacroAssembler-riscv64.h index 72eef104dd7e1..410d4bf336e0c 100644 --- a/js/src/jit/riscv64/MacroAssembler-riscv64.h +++ b/js/src/jit/riscv64/MacroAssembler-riscv64.h @@ -67,23 +67,9 @@ class MacroAssemblerRiscv64 : public Assembler { MoveResolver moveResolver_; - size_t preBarrierTableBytes() const { MOZ_CRASH(); } - - size_t numCodeLabels() const { MOZ_CRASH(); } - CodeLabel codeLabel(size_t) { MOZ_CRASH(); } - - bool appendRawCode(const uint8_t* code, size_t numBytes) { MOZ_CRASH(); } - bool swapBuffer(wasm::Bytes& bytes) { MOZ_CRASH(); } - - void assertNoGCThings() const { MOZ_CRASH(); } - static bool SupportsFloatingPoint() { return true; } static bool SupportsUnalignedAccesses() { return true; } static bool SupportsFastUnalignedFPAccesses() { return true; } - template - void j(Condition, T) { - MOZ_CRASH(); - } void haltingAlign(int alignment) { // TODO(loong64): Implement a proper halting align. nopAlign(alignment); @@ -711,7 +697,7 @@ class MacroAssemblerRiscv64Compat : public MacroAssemblerRiscv64 { static size_t ToggledCallSize(uint8_t* code) { // Four instructions used in: MacroAssemblerRiscv64Compat::toggledCall - return 4 * sizeof(uint32_t); + return 7 * sizeof(uint32_t); } CodeOffset pushWithPatch(ImmWord imm) { diff --git a/js/src/jit/riscv64/Simulator-riscv64.cpp b/js/src/jit/riscv64/Simulator-riscv64.cpp index fb23e37f051fa..fa37c1e440107 100644 --- a/js/src/jit/riscv64/Simulator-riscv64.cpp +++ b/js/src/jit/riscv64/Simulator-riscv64.cpp @@ -2124,12 +2124,12 @@ void Simulator::SoftwareInterrupt() { } } else { // uint8_t code = get_ebreak_code(instr_.instr()) - kMaxStopCode - 1; -// switch (JSOp(code)) { +// switch (LNode::Opcode(code)) { // #define EMIT_OP(OP, ...) \ -// case JSOp::OP:\ +// case LNode::Opcode::OP:\ // std::cout << #OP << std::endl; \ // break; -// FOR_EACH_OPCODE(EMIT_OP); +// LIR_OPCODE_LIST(EMIT_OP); // #undef EMIT_OP // } DieOrDebug(); diff --git a/riscv64config/simulator-riscv64 b/riscv64config/simulator-riscv64 index 01435731dd00d..c35d2484a1dec 100644 --- a/riscv64config/simulator-riscv64 +++ b/riscv64config/simulator-riscv64 @@ -2,7 +2,7 @@ ac_add_options --enable-application=js # Enable optimization for speed -ac_add_options --disable-optimize +ac_add_options --enable-optimize # Disable debug checks to better match a release build of Firefox. ac_add_options --enable-debug