[wasm] Fix non-const references in Liftoff
R=ahaas@chromium.org Bug: v8:9429, v8:9396 Change-Id: I06657a7e339ed2f2c93f560bfcd3413761ad0733 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1701844 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#62716}
This commit is contained in:
parent
01a80fe30b
commit
9f8d52df20
@ -416,18 +416,17 @@ class LiftoffCompiler {
|
||||
DCHECK_EQ(__ num_locals(), __ cache_state()->stack_height());
|
||||
}
|
||||
|
||||
void GenerateOutOfLineCode(
|
||||
OutOfLineCode& ool) { // NOLINT(runtime/references)
|
||||
__ bind(ool.label.get());
|
||||
const bool is_stack_check = ool.stub == WasmCode::kWasmStackGuard;
|
||||
void GenerateOutOfLineCode(OutOfLineCode* ool) {
|
||||
__ bind(ool->label.get());
|
||||
const bool is_stack_check = ool->stub == WasmCode::kWasmStackGuard;
|
||||
const bool is_mem_out_of_bounds =
|
||||
ool.stub == WasmCode::kThrowWasmTrapMemOutOfBounds;
|
||||
ool->stub == WasmCode::kThrowWasmTrapMemOutOfBounds;
|
||||
|
||||
if (is_mem_out_of_bounds && env_->use_trap_handler) {
|
||||
uint32_t pc = static_cast<uint32_t>(__ pc_offset());
|
||||
DCHECK_EQ(pc, __ pc_offset());
|
||||
protected_instructions_.emplace_back(
|
||||
trap_handler::ProtectedInstructionData{ool.pc, pc});
|
||||
trap_handler::ProtectedInstructionData{ool->pc, pc});
|
||||
}
|
||||
|
||||
if (!env_->runtime_exception_support) {
|
||||
@ -442,16 +441,16 @@ class LiftoffCompiler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ool.regs_to_save.is_empty()) __ PushRegisters(ool.regs_to_save);
|
||||
if (!ool->regs_to_save.is_empty()) __ PushRegisters(ool->regs_to_save);
|
||||
|
||||
source_position_table_builder_.AddPosition(
|
||||
__ pc_offset(), SourcePosition(ool.position), false);
|
||||
__ CallRuntimeStub(ool.stub);
|
||||
__ pc_offset(), SourcePosition(ool->position), false);
|
||||
__ CallRuntimeStub(ool->stub);
|
||||
safepoint_table_builder_.DefineSafepoint(&asm_, Safepoint::kNoLazyDeopt);
|
||||
DCHECK_EQ(ool.continuation.get()->is_bound(), is_stack_check);
|
||||
if (!ool.regs_to_save.is_empty()) __ PopRegisters(ool.regs_to_save);
|
||||
DCHECK_EQ(ool->continuation.get()->is_bound(), is_stack_check);
|
||||
if (!ool->regs_to_save.is_empty()) __ PopRegisters(ool->regs_to_save);
|
||||
if (is_stack_check) {
|
||||
__ emit_jump(ool.continuation.get());
|
||||
__ emit_jump(ool->continuation.get());
|
||||
} else {
|
||||
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
|
||||
}
|
||||
@ -460,7 +459,7 @@ class LiftoffCompiler {
|
||||
void FinishFunction(FullDecoder* decoder) {
|
||||
if (DidAssemblerBailout(decoder)) return;
|
||||
for (OutOfLineCode& ool : out_of_line_code_) {
|
||||
GenerateOutOfLineCode(ool);
|
||||
GenerateOutOfLineCode(&ool);
|
||||
}
|
||||
__ PatchPrepareStackFrame(pc_offset_stack_frame_construction_,
|
||||
__ GetTotalFrameSlotCount());
|
||||
@ -1246,25 +1245,24 @@ class LiftoffCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
void SetLocalFromStackSlot(
|
||||
LiftoffAssembler::VarState& dst_slot, // NOLINT(runtime/references)
|
||||
uint32_t local_index) {
|
||||
void SetLocalFromStackSlot(LiftoffAssembler::VarState* dst_slot,
|
||||
uint32_t local_index) {
|
||||
auto& state = *__ cache_state();
|
||||
ValueType type = dst_slot.type();
|
||||
if (dst_slot.is_reg()) {
|
||||
LiftoffRegister slot_reg = dst_slot.reg();
|
||||
ValueType type = dst_slot->type();
|
||||
if (dst_slot->is_reg()) {
|
||||
LiftoffRegister slot_reg = dst_slot->reg();
|
||||
if (state.get_use_count(slot_reg) == 1) {
|
||||
__ Fill(dst_slot.reg(), state.stack_height() - 1, type);
|
||||
__ Fill(dst_slot->reg(), state.stack_height() - 1, type);
|
||||
return;
|
||||
}
|
||||
state.dec_used(slot_reg);
|
||||
dst_slot.MakeStack();
|
||||
dst_slot->MakeStack();
|
||||
}
|
||||
DCHECK_EQ(type, __ local_type(local_index));
|
||||
RegClass rc = reg_class_for(type);
|
||||
LiftoffRegister dst_reg = __ GetUnusedRegister(rc);
|
||||
__ Fill(dst_reg, __ cache_state()->stack_height() - 1, type);
|
||||
dst_slot = LiftoffAssembler::VarState(type, dst_reg);
|
||||
*dst_slot = LiftoffAssembler::VarState(type, dst_reg);
|
||||
__ cache_state()->inc_used(dst_reg);
|
||||
}
|
||||
|
||||
@ -1283,7 +1281,7 @@ class LiftoffCompiler {
|
||||
target_slot = source_slot;
|
||||
break;
|
||||
case kStack:
|
||||
SetLocalFromStackSlot(target_slot, local_index);
|
||||
SetLocalFromStackSlot(&target_slot, local_index);
|
||||
break;
|
||||
}
|
||||
if (!is_tee) __ cache_state()->stack_state.pop_back();
|
||||
@ -1299,15 +1297,13 @@ class LiftoffCompiler {
|
||||
SetLocal(imm.index, true);
|
||||
}
|
||||
|
||||
Register GetGlobalBaseAndOffset(
|
||||
const WasmGlobal* global,
|
||||
LiftoffRegList& pinned, // NOLINT(runtime/references)
|
||||
uint32_t* offset) {
|
||||
Register addr = pinned.set(__ GetUnusedRegister(kGpReg)).gp();
|
||||
Register GetGlobalBaseAndOffset(const WasmGlobal* global,
|
||||
LiftoffRegList* pinned, uint32_t* offset) {
|
||||
Register addr = pinned->set(__ GetUnusedRegister(kGpReg)).gp();
|
||||
if (global->mutability && global->imported) {
|
||||
LOAD_INSTANCE_FIELD(addr, ImportedMutableGlobals, kSystemPointerSize);
|
||||
__ Load(LiftoffRegister(addr), addr, no_reg,
|
||||
global->index * sizeof(Address), kPointerLoadType, pinned);
|
||||
global->index * sizeof(Address), kPointerLoadType, *pinned);
|
||||
*offset = 0;
|
||||
} else {
|
||||
LOAD_INSTANCE_FIELD(addr, GlobalsStart, kSystemPointerSize);
|
||||
@ -1323,7 +1319,7 @@ class LiftoffCompiler {
|
||||
return;
|
||||
LiftoffRegList pinned;
|
||||
uint32_t offset = 0;
|
||||
Register addr = GetGlobalBaseAndOffset(global, pinned, &offset);
|
||||
Register addr = GetGlobalBaseAndOffset(global, &pinned, &offset);
|
||||
LiftoffRegister value =
|
||||
pinned.set(__ GetUnusedRegister(reg_class_for(global->type), pinned));
|
||||
LoadType type = LoadType::ForValueType(global->type);
|
||||
@ -1338,7 +1334,7 @@ class LiftoffCompiler {
|
||||
return;
|
||||
LiftoffRegList pinned;
|
||||
uint32_t offset = 0;
|
||||
Register addr = GetGlobalBaseAndOffset(global, pinned, &offset);
|
||||
Register addr = GetGlobalBaseAndOffset(global, &pinned, &offset);
|
||||
LiftoffRegister reg = pinned.set(__ PopToRegister(pinned));
|
||||
StoreType type = StoreType::ForValueType(global->type);
|
||||
__ Store(addr, no_reg, offset, reg, type, {}, nullptr, true);
|
||||
@ -1418,9 +1414,8 @@ class LiftoffCompiler {
|
||||
// Generate a branch table case, potentially reusing previously generated
|
||||
// stack transfer code.
|
||||
void GenerateBrCase(FullDecoder* decoder, uint32_t br_depth,
|
||||
std::map<uint32_t, MovableLabel>&
|
||||
br_targets) { // NOLINT(runtime/references)
|
||||
MovableLabel& label = br_targets[br_depth];
|
||||
std::map<uint32_t, MovableLabel>* br_targets) {
|
||||
MovableLabel& label = (*br_targets)[br_depth];
|
||||
if (label.get()->is_bound()) {
|
||||
__ jmp(label.get());
|
||||
} else {
|
||||
@ -1433,15 +1428,13 @@ class LiftoffCompiler {
|
||||
// TODO(wasm): Generate a real branch table (like TF TableSwitch).
|
||||
void GenerateBrTable(FullDecoder* decoder, LiftoffRegister tmp,
|
||||
LiftoffRegister value, uint32_t min, uint32_t max,
|
||||
BranchTableIterator<validate>&
|
||||
table_iterator, // NOLINT(runtime/references)
|
||||
std::map<uint32_t, MovableLabel>&
|
||||
br_targets) { // NOLINT(runtime/references)
|
||||
BranchTableIterator<validate>* table_iterator,
|
||||
std::map<uint32_t, MovableLabel>* br_targets) {
|
||||
DCHECK_LT(min, max);
|
||||
// Check base case.
|
||||
if (max == min + 1) {
|
||||
DCHECK_EQ(min, table_iterator.cur_index());
|
||||
GenerateBrCase(decoder, table_iterator.next(), br_targets);
|
||||
DCHECK_EQ(min, table_iterator->cur_index());
|
||||
GenerateBrCase(decoder, table_iterator->next(), br_targets);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1473,14 +1466,14 @@ class LiftoffCompiler {
|
||||
__ emit_cond_jump(kUnsignedGreaterEqual, &case_default, kWasmI32,
|
||||
value.gp(), tmp.gp());
|
||||
|
||||
GenerateBrTable(decoder, tmp, value, 0, imm.table_count, table_iterator,
|
||||
br_targets);
|
||||
GenerateBrTable(decoder, tmp, value, 0, imm.table_count, &table_iterator,
|
||||
&br_targets);
|
||||
|
||||
__ bind(&case_default);
|
||||
}
|
||||
|
||||
// Generate the default case.
|
||||
GenerateBrCase(decoder, table_iterator.next(), br_targets);
|
||||
GenerateBrCase(decoder, table_iterator.next(), &br_targets);
|
||||
DCHECK(!table_iterator.has_next());
|
||||
}
|
||||
|
||||
@ -1643,9 +1636,8 @@ class LiftoffCompiler {
|
||||
safepoint_table_builder_.DefineSafepoint(&asm_, Safepoint::kNoLazyDeopt);
|
||||
}
|
||||
|
||||
Register AddMemoryMasking(
|
||||
Register index, uint32_t* offset,
|
||||
LiftoffRegList& pinned) { // NOLINT(runtime/references)
|
||||
Register AddMemoryMasking(Register index, uint32_t* offset,
|
||||
LiftoffRegList* pinned) {
|
||||
if (!FLAG_untrusted_code_mitigations || env_->use_trap_handler) {
|
||||
return index;
|
||||
}
|
||||
@ -1653,11 +1645,11 @@ class LiftoffCompiler {
|
||||
// Make sure that we can overwrite {index}.
|
||||
if (__ cache_state()->is_used(LiftoffRegister(index))) {
|
||||
Register old_index = index;
|
||||
pinned.clear(LiftoffRegister(old_index));
|
||||
index = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
|
||||
pinned->clear(LiftoffRegister(old_index));
|
||||
index = pinned->set(__ GetUnusedRegister(kGpReg, *pinned)).gp();
|
||||
if (index != old_index) __ Move(index, old_index, kWasmI32);
|
||||
}
|
||||
Register tmp = __ GetUnusedRegister(kGpReg, pinned).gp();
|
||||
Register tmp = __ GetUnusedRegister(kGpReg, *pinned).gp();
|
||||
__ emit_ptrsize_add(index, index, *offset);
|
||||
LOAD_INSTANCE_FIELD(tmp, MemoryMask, kSystemPointerSize);
|
||||
__ emit_ptrsize_and(index, index, tmp);
|
||||
@ -1677,7 +1669,7 @@ class LiftoffCompiler {
|
||||
return;
|
||||
}
|
||||
uint32_t offset = imm.offset;
|
||||
index = AddMemoryMasking(index, &offset, pinned);
|
||||
index = AddMemoryMasking(index, &offset, &pinned);
|
||||
DEBUG_CODE_COMMENT("Load from memory");
|
||||
Register addr = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
|
||||
LOAD_INSTANCE_FIELD(addr, MemoryStart, kSystemPointerSize);
|
||||
@ -1711,7 +1703,7 @@ class LiftoffCompiler {
|
||||
return;
|
||||
}
|
||||
uint32_t offset = imm.offset;
|
||||
index = AddMemoryMasking(index, &offset, pinned);
|
||||
index = AddMemoryMasking(index, &offset, &pinned);
|
||||
DEBUG_CODE_COMMENT("Store to memory");
|
||||
Register addr = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
|
||||
LOAD_INSTANCE_FIELD(addr, MemoryStart, kSystemPointerSize);
|
||||
@ -2045,9 +2037,7 @@ class LiftoffCompiler {
|
||||
unsupported(decoder, kBulkMemory, "table.copy");
|
||||
}
|
||||
void TableGrow(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
|
||||
Value& value, // NOLINT(runtime/references)
|
||||
Value& delta, // NOLINT(runtime/references)
|
||||
Value* result) {
|
||||
const Value& value, const Value& delta, Value* result) {
|
||||
unsupported(decoder, kAnyRef, "table.grow");
|
||||
}
|
||||
void TableSize(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
|
||||
@ -2055,8 +2045,7 @@ class LiftoffCompiler {
|
||||
unsupported(decoder, kAnyRef, "table.size");
|
||||
}
|
||||
void TableFill(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
|
||||
Value& start, Value& value, // NOLINT(runtime/references)
|
||||
Value& count) { // NOLINT(runtime/references)
|
||||
const Value& start, const Value& value, const Value& count) {
|
||||
unsupported(decoder, kAnyRef, "table.fill");
|
||||
}
|
||||
|
||||
|
@ -1235,9 +1235,8 @@ void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
|
||||
|
||||
namespace liftoff {
|
||||
|
||||
inline FPUCondition ConditionToConditionCmpFPU(
|
||||
bool& predicate, // NOLINT(runtime/references)
|
||||
Condition condition) {
|
||||
inline FPUCondition ConditionToConditionCmpFPU(Condition condition,
|
||||
bool* predicate) {
|
||||
switch (condition) {
|
||||
case kEqual:
|
||||
predicate = true;
|
||||
@ -1284,7 +1283,7 @@ void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
|
||||
|
||||
TurboAssembler::li(dst, 1);
|
||||
bool predicate;
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(predicate, cond);
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(cond, &predicate);
|
||||
TurboAssembler::CompareF32(fcond, lhs, rhs);
|
||||
if (predicate) {
|
||||
TurboAssembler::LoadZeroIfNotFPUCondition(dst);
|
||||
@ -1313,7 +1312,7 @@ void LiftoffAssembler::emit_f64_set_cond(Condition cond, Register dst,
|
||||
|
||||
TurboAssembler::li(dst, 1);
|
||||
bool predicate;
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(predicate, cond);
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(cond, predicate);
|
||||
TurboAssembler::CompareF64(fcond, lhs, rhs);
|
||||
if (predicate) {
|
||||
TurboAssembler::LoadZeroIfNotFPUCondition(dst);
|
||||
|
@ -1094,9 +1094,8 @@ void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
|
||||
|
||||
namespace liftoff {
|
||||
|
||||
inline FPUCondition ConditionToConditionCmpFPU(
|
||||
bool& predicate, // NOLINT(runtime/references)
|
||||
Condition condition) {
|
||||
inline FPUCondition ConditionToConditionCmpFPU(Condition condition,
|
||||
bool* predicate) {
|
||||
switch (condition) {
|
||||
case kEqual:
|
||||
predicate = true;
|
||||
@ -1143,7 +1142,7 @@ void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
|
||||
|
||||
TurboAssembler::li(dst, 1);
|
||||
bool predicate;
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(predicate, cond);
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(cond, &predicate);
|
||||
TurboAssembler::CompareF32(fcond, lhs, rhs);
|
||||
if (predicate) {
|
||||
TurboAssembler::LoadZeroIfNotFPUCondition(dst);
|
||||
@ -1172,7 +1171,7 @@ void LiftoffAssembler::emit_f64_set_cond(Condition cond, Register dst,
|
||||
|
||||
TurboAssembler::li(dst, 1);
|
||||
bool predicate;
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(predicate, cond);
|
||||
FPUCondition fcond = liftoff::ConditionToConditionCmpFPU(cond, &predicate);
|
||||
TurboAssembler::CompareF64(fcond, lhs, rhs);
|
||||
if (predicate) {
|
||||
TurboAssembler::LoadZeroIfNotFPUCondition(dst);
|
||||
|
Loading…
Reference in New Issue
Block a user