Commit c176c054 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Store protected instruction info

Store protected instruction info needed for the wasm trap handler.
This code will be used and covered by existing tests once we add support
for if-constructs to Liftoff.

R=titzer@chromium.org
CC=eholk@chromium.org

Bug: v8:6600, v8:5277
Change-Id: I508b0ab8572ef8b5c7943564714fcec7e9eb8e3b
Reviewed-on: https://chromium-review.googlesource.com/853497
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarEric Holk <eholk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50425}
parent 4bf80431
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -72,7 +72,8 @@ void LiftoffAssembler::SpillContext(Register context) {
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
Operand src_op = offset_reg == no_reg
? Operand(src_addr, offset_imm)
: Operand(src_addr, offset_reg, times_1, offset_imm);
......@@ -86,6 +87,7 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
}
src_op = Operand(src_addr, src, times_1, 0);
}
if (protected_load_pc) *protected_load_pc = pc_offset();
switch (type.value()) {
case LoadType::kI32Load8U:
movzx_b(dst.gp(), src_op);
......@@ -109,7 +111,8 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
Operand dst_op = offset_reg == no_reg
? Operand(dst_addr, offset_imm)
: Operand(dst_addr, offset_reg, times_1, offset_imm);
......@@ -123,6 +126,7 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
}
dst_op = Operand(dst_addr, dst, times_1, 0);
}
if (protected_store_pc) *protected_store_pc = pc_offset();
switch (type.value()) {
case StoreType::kI32Store8:
// Only the lower 4 registers can be addressed as 8-bit registers.
......
......@@ -268,11 +268,11 @@ class LiftoffAssembler : public TurboAssembler {
inline void LoadFromContext(Register dst, uint32_t offset, int size);
inline void SpillContext(Register context);
inline void Load(LiftoffRegister dst, Register src_addr, Register offset_reg,
uint32_t offset_imm, LoadType type,
LiftoffRegList pinned = {});
uint32_t offset_imm, LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc = nullptr);
inline void Store(Register dst_addr, Register offset_reg, uint32_t offset_imm,
LiftoffRegister src, StoreType type,
LiftoffRegList pinned = {});
LiftoffRegister src, StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc = nullptr);
inline void LoadCallerFrameSlot(LiftoffRegister, uint32_t caller_slot_idx);
inline void MoveStackValue(uint32_t dst_index, uint32_t src_index);
......
......@@ -84,21 +84,26 @@ class LiftoffCompiler {
Builtins::Name builtin;
wasm::WasmCodePosition position;
LiftoffRegList regs_to_save;
uint32_t pc; // for trap handler.
// Named constructors:
static OutOfLineCode Trap(Builtins::Name b, wasm::WasmCodePosition pos) {
return {{}, {}, b, pos, {}};
static OutOfLineCode Trap(Builtins::Name b, wasm::WasmCodePosition pos,
uint32_t pc) {
return {{}, {}, b, pos, {}, pc};
}
static OutOfLineCode StackCheck(wasm::WasmCodePosition pos,
LiftoffRegList regs) {
return {{}, MovableLabel::None(), Builtins::kWasmStackGuard, pos, regs};
return {{}, MovableLabel::None(), Builtins::kWasmStackGuard, pos, regs,
0};
}
};
LiftoffCompiler(LiftoffAssembler* liftoff_asm,
compiler::CallDescriptor* call_desc, compiler::ModuleEnv* env,
compiler::RuntimeExceptionSupport runtime_exception_support,
SourcePositionTableBuilder* source_position_table_builder)
SourcePositionTableBuilder* source_position_table_builder,
std::vector<trap_handler::ProtectedInstructionData>*
protected_instructions)
: asm_(liftoff_asm),
call_desc_(call_desc),
env_(env),
......@@ -109,6 +114,7 @@ class LiftoffCompiler {
wasm::WasmModule::kPageSize),
runtime_exception_support_(runtime_exception_support),
source_position_table_builder_(source_position_table_builder),
protected_instructions_(protected_instructions),
compilation_zone_(liftoff_asm->isolate()->allocator(),
"liftoff compilation"),
safepoint_table_builder_(&compilation_zone_) {
......@@ -294,6 +300,13 @@ class LiftoffCompiler {
return;
}
if (!is_stack_check && 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});
}
if (!ool.regs_to_save.is_empty()) __ PushRegisters(ool.regs_to_save);
source_position_table_builder_->AddPosition(
......@@ -620,14 +633,22 @@ class LiftoffCompiler {
unsupported(decoder, "else");
}
Label* AddOutOfLineTrap(wasm::WasmCodePosition position, uint32_t pc = 0) {
DCHECK(!FLAG_wasm_no_bounds_checks);
// The pc is needed exactly if trap handlers are enabled.
DCHECK_EQ(pc != 0, env_->use_trap_handler);
out_of_line_code_.push_back(OutOfLineCode::Trap(
Builtins::kThrowWasmTrapMemOutOfBounds, position, pc));
return out_of_line_code_.back().label.get();
}
void BoundsCheckMem(uint32_t access_size, uint32_t offset, Register index,
wasm::WasmCodePosition position, LiftoffRegList pinned) {
DCHECK(!env_->use_trap_handler);
if (FLAG_wasm_no_bounds_checks) return;
// Add OOL code.
out_of_line_code_.push_back(
OutOfLineCode::Trap(Builtins::kThrowWasmTrapMemOutOfBounds, position));
Label* trap_label = out_of_line_code_.back().label.get();
Label* trap_label = AddOutOfLineTrap(position);
if (access_size > max_size_ || offset > max_size_ - access_size) {
// The access will be out of bounds, even for the largest memory.
......@@ -674,7 +695,12 @@ class LiftoffCompiler {
__ LoadFromContext(addr, offsetof(WasmContext, mem_start), kPointerSize);
RegClass rc = reg_class_for(value_type);
LiftoffRegister value = pinned.set(__ GetUnusedRegister(rc, pinned));
__ Load(value, addr, index, operand.offset, type, pinned);
uint32_t protected_load_pc = 0;
__ Load(value, addr, index, operand.offset, type, pinned,
&protected_load_pc);
if (env_->use_trap_handler) {
AddOutOfLineTrap(decoder->position(), protected_load_pc);
}
__ PushRegister(value_type, value);
CheckStackSizeLimit(decoder);
}
......@@ -695,7 +721,12 @@ class LiftoffCompiler {
}
Register addr = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
__ LoadFromContext(addr, offsetof(WasmContext, mem_start), kPointerSize);
__ Store(addr, index, operand.offset, value, type, pinned);
uint32_t protected_store_pc = 0;
__ Store(addr, index, operand.offset, value, type, pinned,
&protected_store_pc);
if (env_->use_trap_handler) {
AddOutOfLineTrap(decoder->position(), protected_store_pc);
}
}
void CurrentMemoryPages(Decoder* decoder, Value* result) {
......@@ -759,6 +790,7 @@ class LiftoffCompiler {
bool ok_ = true;
std::vector<OutOfLineCode> out_of_line_code_;
SourcePositionTableBuilder* const source_position_table_builder_;
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions_;
// Zone used to store information during compilation. The result will be
// stored independently, such that this zone can die together with the
// LiftoffCompiler after compilation.
......@@ -804,7 +836,8 @@ bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
wasm::WasmFullDecoder<wasm::Decoder::kValidate, wasm::LiftoffCompiler>
decoder(&zone, module, func_body_, &liftoff_.asm_, call_desc, env_,
runtime_exception_support_,
&liftoff_.source_position_table_builder_);
&liftoff_.source_position_table_builder_,
protected_instructions_.get());
decoder.Decode();
liftoff_compile_time_scope.reset();
if (!decoder.interface().ok()) {
......
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -26,13 +26,15 @@ void LiftoffAssembler::SpillContext(Register context) { UNIMPLEMENTED(); }
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
UNIMPLEMENTED();
}
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
UNIMPLEMENTED();
}
......
......@@ -69,7 +69,8 @@ void LiftoffAssembler::SpillContext(Register context) {
void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
Register offset_reg, uint32_t offset_imm,
LoadType type, LiftoffRegList pinned) {
LoadType type, LiftoffRegList pinned,
uint32_t* protected_load_pc) {
Operand src_op = offset_reg == no_reg
? Operand(src_addr, offset_imm)
: Operand(src_addr, offset_reg, times_1, offset_imm);
......@@ -83,6 +84,7 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
}
src_op = Operand(src_addr, src, times_1, 0);
}
if (protected_load_pc) *protected_load_pc = pc_offset();
switch (type.value()) {
case LoadType::kI32Load8U:
movzxbl(dst.gp(), src_op);
......@@ -109,7 +111,8 @@ void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr,
void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
uint32_t offset_imm, LiftoffRegister src,
StoreType type, LiftoffRegList pinned) {
StoreType type, LiftoffRegList pinned,
uint32_t* protected_store_pc) {
Operand dst_op = offset_reg == no_reg
? Operand(dst_addr, offset_imm)
: Operand(dst_addr, offset_reg, times_1, offset_imm);
......@@ -123,6 +126,7 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
}
dst_op = Operand(dst_addr, dst, times_1, 0);
}
if (protected_store_pc) *protected_store_pc = pc_offset();
switch (type.value()) {
case StoreType::kI32Store8:
movb(dst_op, src.gp());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment