Skip to content

Commit

Permalink
Fix unbox (mozilla#32)
Browse files Browse the repository at this point in the history
* fix unbox
  • Loading branch information
luyahan authored Sep 14, 2022
1 parent f465697 commit cd4090e
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 76 deletions.
155 changes: 105 additions & 50 deletions js/src/jit/riscv64/Assembler-riscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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<AutoWritableJitCode>& 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<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, "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<gc::Cell**>(&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<AutoWritableJitCode> 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<AutoWritableJitCode>& 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<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, "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<gc::Cell**>(&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<AutoWritableJitCode> awjc;
while (reader.more()) {
size_t offset = reader.readUnsigned();
Instruction* inst = (Instruction*)(code->raw() + offset);
TraceOneDataRelocation(trc, awjc, code, inst);
}
}


UseScratchRegisterScope::UseScratchRegisterScope(Assembler* assembler)
Expand Down Expand Up @@ -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
10 changes: 7 additions & 3 deletions js/src/jit/riscv64/Assembler-riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 14 additions & 4 deletions js/src/jit/riscv64/MacroAssembler-riscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down
16 changes: 1 addition & 15 deletions js/src/jit/riscv64/MacroAssembler-riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
void j(Condition, T) {
MOZ_CRASH();
}
void haltingAlign(int alignment) {
// TODO(loong64): Implement a proper halting align.
nopAlign(alignment);
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions js/src/jit/riscv64/Simulator-riscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion riscv64config/simulator-riscv64
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit cd4090e

Please sign in to comment.