Commit f56e2a02 authored by Eric Holk's avatar Eric Holk Committed by Commit Bot

[wasm] enable StoreMem_offset_oob_i64 test with trap handlers

The first part of this change updates StoreMem_offset_oob_i64 to use one page of
Wasm memory, rather than just a few bytes. Using less than a page was out of
spec for Wasm anyway, so this is better.

This required a small change in the test runner to set and clear the
thread_in_wasm flag around Wasm calls. This was accomplished by a
ThreadInWasmScope convenience class.

The majority of the changes are because the cctest environment does not support
runtime exceptions. In the code generator, where we used to throw a
WasmMemOutOfBounds exception, we now need to call out to the test hook instead
if runtime exceptions are not supported. This involved plumbing the
runtime_exception_support flag down to the code generator. Rather than adding
and shuffling around extra parameters everywhere, this CL packages the previous
protected instruction list in a new WasmCompilationData object that now includes
the runtime_exception_support flag as well.

Bug: v8:5277
Change-Id: Ic9c9e5a53a07a7773b58c0aee7c26bbd2ddf82f3
Reviewed-on: https://chromium-review.googlesource.com/989017
Commit-Queue: Eric Holk <eholk@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52368}
parent 6da12d42
......@@ -11,10 +11,10 @@
#include "src/compiler/code-generator-impl.h"
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/wasm-compiler.h"
#include "src/eh-frame.h"
#include "src/frames.h"
#include "src/macro-assembler-inl.h"
#include "src/trap-handler/trap-handler.h"
namespace v8 {
namespace internal {
......@@ -37,13 +37,14 @@ class CodeGenerator::JumpTable final : public ZoneObject {
size_t const target_count_;
};
CodeGenerator::CodeGenerator(
Zone* codegen_zone, Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info, Isolate* isolate,
base::Optional<OsrHelper> osr_helper, int start_source_position,
JumpOptimizationInfo* jump_opt,
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions,
PoisoningMitigationLevel poisoning_enabled)
CodeGenerator::CodeGenerator(Zone* codegen_zone, Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info,
Isolate* isolate,
base::Optional<OsrHelper> osr_helper,
int start_source_position,
JumpOptimizationInfo* jump_opt,
WasmCompilationData* wasm_compilation_data,
PoisoningMitigationLevel poisoning_enabled)
: zone_(codegen_zone),
isolate_(isolate),
frame_access_state_(nullptr),
......@@ -73,7 +74,7 @@ CodeGenerator::CodeGenerator(
osr_pc_offset_(-1),
optimized_out_literal_id_(-1),
source_position_table_builder_(info->SourcePositionRecordingMode()),
protected_instructions_(protected_instructions),
wasm_compilation_data_(wasm_compilation_data),
result_(kSuccess),
poisoning_enabled_(poisoning_enabled) {
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
......@@ -89,13 +90,15 @@ CodeGenerator::CodeGenerator(
}
}
bool CodeGenerator::wasm_runtime_exception_support() const {
DCHECK(wasm_compilation_data_);
return wasm_compilation_data_->runtime_exception_support();
}
void CodeGenerator::AddProtectedInstructionLanding(uint32_t instr_offset,
uint32_t landing_offset) {
if (protected_instructions_ != nullptr) {
trap_handler::ProtectedInstructionData data = {instr_offset,
landing_offset};
protected_instructions_->emplace_back(data);
}
DCHECK_NOT_NULL(wasm_compilation_data_);
wasm_compilation_data_->AddProtectedInstruction(instr_offset, landing_offset);
}
void CodeGenerator::CreateFrameAccessState(Frame* frame) {
......
......@@ -20,10 +20,6 @@ namespace internal {
class CompilationInfo;
namespace trap_handler {
struct ProtectedInstructionData;
} // namespace trap_handler
namespace compiler {
// Forward declarations.
......@@ -31,6 +27,7 @@ class DeoptimizationExit;
class FrameAccessState;
class Linkage;
class OutOfLineCode;
class WasmCompilationData;
struct BranchInfo {
FlagsCondition condition;
......@@ -85,8 +82,7 @@ class CodeGenerator final : public GapResolver::Assembler {
Isolate* isolate, base::Optional<OsrHelper> osr_helper,
int start_source_position,
JumpOptimizationInfo* jump_opt,
std::vector<trap_handler::ProtectedInstructionData>*
protected_instructions,
WasmCompilationData* wasm_compilation_data,
PoisoningMitigationLevel poisoning_enabled);
// Generate native code. After calling AssembleCode, call FinalizeCode to
......@@ -108,6 +104,8 @@ class CodeGenerator final : public GapResolver::Assembler {
void AddProtectedInstructionLanding(uint32_t instr_offset,
uint32_t landing_offset);
bool wasm_runtime_exception_support() const;
SourcePosition start_source_position() const {
return start_source_position_;
}
......@@ -414,7 +412,7 @@ class CodeGenerator final : public GapResolver::Assembler {
int osr_pc_offset_;
int optimized_out_literal_id_;
SourcePositionTableBuilder source_position_table_builder_;
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions_;
WasmCompilationData* wasm_compilation_data_;
CodeGenResult result_;
PoisoningMitigationLevel poisoning_enabled_;
};
......
......@@ -125,8 +125,7 @@ class PipelineData {
PipelineData(ZoneStats* zone_stats, Isolate* isolate, CompilationInfo* info,
JSGraph* jsgraph, PipelineStatistics* pipeline_statistics,
SourcePositionTable* source_positions,
std::vector<trap_handler::ProtectedInstructionData>*
protected_instructions)
WasmCompilationData* wasm_compilation_data)
: isolate_(isolate),
info_(info),
debug_name_(info_->GetDebugName()),
......@@ -145,7 +144,7 @@ class PipelineData {
codegen_zone_(codegen_zone_scope_.zone()),
register_allocation_zone_scope_(zone_stats_, ZONE_NAME),
register_allocation_zone_(register_allocation_zone_scope_.zone()),
protected_instructions_(protected_instructions) {}
wasm_compilation_data_(wasm_compilation_data) {}
// For machine graph testing entry point.
PipelineData(ZoneStats* zone_stats, CompilationInfo* info, Isolate* isolate,
......@@ -344,7 +343,7 @@ class PipelineData {
code_generator_ = new CodeGenerator(
codegen_zone(), frame(), linkage, sequence(), info(), isolate(),
osr_helper_, start_source_position_, jump_optimization_info_,
protected_instructions_,
wasm_compilation_data_,
info()->is_poison_loads() ? PoisoningMitigationLevel::kOn
: PoisoningMitigationLevel::kOff);
}
......@@ -417,8 +416,7 @@ class PipelineData {
// Source position output for --trace-turbo.
std::string source_position_output_;
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions_ =
nullptr;
WasmCompilationData* wasm_compilation_data_ = nullptr;
JumpOptimizationInfo* jump_optimization_info_ = nullptr;
......@@ -887,15 +885,14 @@ class PipelineWasmCompilationJob final : public CompilationJob {
explicit PipelineWasmCompilationJob(
CompilationInfo* info, Isolate* isolate, JSGraph* jsgraph,
CallDescriptor* call_descriptor, SourcePositionTable* source_positions,
std::vector<trap_handler::ProtectedInstructionData>* protected_insts,
bool asmjs_origin)
WasmCompilationData* wasm_compilation_data, bool asmjs_origin)
: CompilationJob(isolate->stack_guard()->real_climit(), nullptr, info,
"TurboFan", State::kReadyToExecute),
zone_stats_(isolate->allocator()),
pipeline_statistics_(CreatePipelineStatistics(
Handle<Script>::null(), info, isolate, &zone_stats_)),
data_(&zone_stats_, isolate, info, jsgraph, pipeline_statistics_.get(),
source_positions, protected_insts),
source_positions, wasm_compilation_data),
pipeline_(&data_),
linkage_(call_descriptor),
asmjs_origin_(asmjs_origin) {}
......@@ -2088,11 +2085,11 @@ CompilationJob* Pipeline::NewCompilationJob(Handle<JSFunction> function,
CompilationJob* Pipeline::NewWasmCompilationJob(
CompilationInfo* info, Isolate* isolate, JSGraph* jsgraph,
CallDescriptor* call_descriptor, SourcePositionTable* source_positions,
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions,
WasmCompilationData* wasm_compilation_data,
wasm::ModuleOrigin asmjs_origin) {
return new PipelineWasmCompilationJob(info, isolate, jsgraph, call_descriptor,
source_positions,
protected_instructions, asmjs_origin);
source_positions, wasm_compilation_data,
asmjs_origin);
}
bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
......
......@@ -20,10 +20,6 @@ class CompilationJob;
class RegisterConfiguration;
class JumpOptimizationInfo;
namespace trap_handler {
struct ProtectedInstructionData;
} // namespace trap_handler
namespace wasm {
enum ModuleOrigin : uint8_t;
} // namespace wasm
......@@ -36,6 +32,7 @@ class Graph;
class InstructionSequence;
class Schedule;
class SourcePositionTable;
class WasmCompilationData;
class Pipeline : public AllStatic {
public:
......@@ -47,8 +44,7 @@ class Pipeline : public AllStatic {
static CompilationJob* NewWasmCompilationJob(
CompilationInfo* info, Isolate* isolate, JSGraph* jsgraph,
CallDescriptor* call_descriptor, SourcePositionTable* source_positions,
std::vector<trap_handler::ProtectedInstructionData>*
protected_instructions,
WasmCompilationData* wasm_compilation_data,
wasm::ModuleOrigin wasm_origin);
// Run the pipeline on a machine graph and generate code. The {schedule} must
......
......@@ -5066,6 +5066,18 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
return code;
}
WasmCompilationData::WasmCompilationData(
RuntimeExceptionSupport runtime_exception_support)
: protected_instructions_(
new std::vector<trap_handler::ProtectedInstructionData>()),
runtime_exception_support_(runtime_exception_support) {}
void WasmCompilationData::AddProtectedInstruction(uint32_t instr_offset,
uint32_t landing_offset) {
protected_instructions_->emplace_back(
trap_handler::ProtectedInstructionData{instr_offset, landing_offset});
}
SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
double* decode_ms) {
base::ElapsedTimer decode_timer;
......@@ -5078,7 +5090,7 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
new (tf_.jsgraph_->zone()) SourcePositionTable(tf_.jsgraph_->graph());
WasmGraphBuilder builder(env_, tf_.jsgraph_->zone(), tf_.jsgraph_,
centry_stub_, func_body_.sig, source_position_table,
runtime_exception_support_);
wasm_compilation_data_.runtime_exception_support());
tf_.graph_construction_result_ =
wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_);
if (tf_.graph_construction_result_.failed()) {
......@@ -5149,11 +5161,9 @@ WasmCompilationUnit::WasmCompilationUnit(
counters_(counters ? counters : isolate->counters()),
centry_stub_(centry_stub),
func_index_(index),
runtime_exception_support_(exception_support),
native_module_(native_module),
lower_simd_(lower_simd),
protected_instructions_(
new std::vector<trap_handler::ProtectedInstructionData>()),
wasm_compilation_data_(exception_support),
mode_(mode) {
switch (mode_) {
case WasmCompilationUnit::CompilationMode::kLiftoff:
......@@ -5248,8 +5258,7 @@ void WasmCompilationUnit::ExecuteTurbofanCompilation() {
tf_.job_.reset(Pipeline::NewWasmCompilationJob(
tf_.info_.get(), isolate_, tf_.jsgraph_, call_descriptor,
source_positions, protected_instructions_.get(),
env_->module->origin()));
source_positions, &wasm_compilation_data_, env_->module->origin()));
ok_ = tf_.job_->ExecuteJob() == CompilationJob::SUCCEEDED;
// TODO(bradnelson): Improve histogram handling of size_t.
counters()->wasm_compile_function_peak_memory_bytes()->AddSample(
......@@ -5331,7 +5340,7 @@ wasm::WasmCode* WasmCompilationUnit::FinishTurbofanCompilation(
func_index_,
tf_.job_->compilation_info()->wasm_code_desc()->safepoint_table_offset,
tf_.job_->compilation_info()->wasm_code_desc()->handler_table_offset,
std::move(protected_instructions_),
wasm_compilation_data_.ReleaseProtectedInstructions(),
tf_.job_->compilation_info()->wasm_code_desc()->source_positions_table,
wasm::WasmCode::kTurbofan);
if (!code) return code;
......@@ -5355,8 +5364,9 @@ wasm::WasmCode* WasmCompilationUnit::FinishLiftoffCompilation(
wasm::WasmCode* code = native_module_->AddCode(
desc, liftoff_.asm_.GetTotalFrameSlotCount(), func_index_,
liftoff_.safepoint_table_offset_, 0, std::move(protected_instructions_),
source_positions, wasm::WasmCode::kLiftoff);
liftoff_.safepoint_table_offset_, 0,
wasm_compilation_data_.ReleaseProtectedInstructions(), source_positions,
wasm::WasmCode::kLiftoff);
return code;
}
......
......@@ -91,6 +91,33 @@ enum RuntimeExceptionSupport : bool {
kNoRuntimeExceptionSupport = false
};
// Information about Wasm compilation that needs to be plumbed through the
// different layers of the compiler.
class WasmCompilationData {
public:
explicit WasmCompilationData(RuntimeExceptionSupport);
void AddProtectedInstruction(uint32_t instr_offset, uint32_t landing_offset);
std::unique_ptr<std::vector<trap_handler::ProtectedInstructionData>>
ReleaseProtectedInstructions() {
return std::move(protected_instructions_);
}
RuntimeExceptionSupport runtime_exception_support() const {
return runtime_exception_support_;
}
private:
std::unique_ptr<std::vector<trap_handler::ProtectedInstructionData>>
protected_instructions_;
// See WasmGraphBuilder::runtime_exception_support_.
const RuntimeExceptionSupport runtime_exception_support_;
DISALLOW_COPY_AND_ASSIGN(WasmCompilationData);
};
class WasmCompilationUnit final {
public:
enum class CompilationMode : uint8_t { kLiftoff, kTurbofan };
......@@ -162,14 +189,11 @@ class WasmCompilationUnit final {
Counters* counters_;
Handle<Code> centry_stub_;
int func_index_;
// See WasmGraphBuilder::runtime_exception_support_.
RuntimeExceptionSupport runtime_exception_support_;
bool ok_ = true;
size_t memory_cost_ = 0;
wasm::NativeModule* native_module_;
bool lower_simd_;
std::unique_ptr<std::vector<trap_handler::ProtectedInstructionData>>
protected_instructions_;
WasmCompilationData wasm_compilation_data_;
CompilationMode mode_;
// {liftoff_} is valid if mode_ == kLiftoff, tf_ if mode_ == kTurbofan.
union {
......
......@@ -257,42 +257,83 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Zone* zone_;
};
class WasmOutOfLineTrap final : public OutOfLineCode {
class WasmOutOfLineTrap : public OutOfLineCode {
public:
WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided,
Instruction* instr)
WasmOutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
: OutOfLineCode(gen),
gen_(gen),
pc_(pc),
frame_elided_(frame_elided),
instr_(instr) {}
// TODO(eholk): Refactor this method to take the code generator as a
// parameter.
void Generate() final {
gen_->AddProtectedInstructionLanding(pc_, __ pc_offset());
void Generate() override {
X64OperandConverter i(gen_, instr_);
Builtins::Name trap_id =
static_cast<Builtins::Name>(i.InputInt32(instr_->InputCount() - 1));
GenerateWithTrapId(trap_id);
}
protected:
CodeGenerator* gen_;
void GenerateWithTrapId(Builtins::Name trap_id) {
bool old_has_frame = __ has_frame();
if (frame_elided_) {
__ set_has_frame(true);
__ EnterFrame(StackFrame::WASM_COMPILED);
}
gen_->AssembleSourcePosition(instr_);
__ Call(__ isolate()->builtins()->builtin_handle(
Builtins::kThrowWasmTrapMemOutOfBounds),
RelocInfo::CODE_TARGET);
ReferenceMap* reference_map = new (gen_->zone()) ReferenceMap(gen_->zone());
gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
Safepoint::kNoLazyDeopt);
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
GenerateCallToTrap(trap_id);
if (frame_elided_) {
__ set_has_frame(old_has_frame);
}
}
private:
CodeGenerator* gen_;
int pc_;
void GenerateCallToTrap(Builtins::Name trap_id) {
if (!gen_->wasm_runtime_exception_support()) {
// We cannot test calls to the runtime in cctest/test-run-wasm.
// Therefore we emit a call to C here instead of a call to the runtime.
__ PrepareCallCFunction(0);
__ CallCFunction(
ExternalReference::wasm_call_trap_callback_for_testing(__ isolate()),
0);
__ LeaveFrame(StackFrame::WASM_COMPILED);
auto call_descriptor = gen_->linkage()->GetIncomingDescriptor();
size_t pop_size = call_descriptor->StackParameterCount() * kPointerSize;
// Use rcx as a scratch register, we return anyways immediately.
__ Ret(static_cast<int>(pop_size), rcx);
} else {
gen_->AssembleSourcePosition(instr_);
__ Call(__ isolate()->builtins()->builtin_handle(trap_id),
RelocInfo::CODE_TARGET);
ReferenceMap* reference_map =
new (gen_->zone()) ReferenceMap(gen_->zone());
gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
Safepoint::kNoLazyDeopt);
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
}
bool frame_elided_;
Instruction* instr_;
};
class WasmProtectedInstructionTrap final : public WasmOutOfLineTrap {
public:
WasmProtectedInstructionTrap(CodeGenerator* gen, int pc, bool frame_elided,
Instruction* instr)
: WasmOutOfLineTrap(gen, frame_elided, instr), pc_(pc) {}
void Generate() final {
gen_->AddProtectedInstructionLanding(pc_, __ pc_offset());
GenerateWithTrapId(Builtins::kThrowWasmTrapMemOutOfBounds);
}
private:
int pc_;
};
void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
X64OperandConverter& i, int pc) {
......@@ -300,7 +341,7 @@ void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
static_cast<MemoryAccessMode>(MiscField::decode(opcode));
if (access_mode == kMemoryAccessProtected) {
const bool frame_elided = !codegen->frame_access_state()->has_frame();
new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, instr);
new (zone) WasmProtectedInstructionTrap(codegen, pc, frame_elided, instr);
}
}
......@@ -2967,62 +3008,8 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) {
void CodeGenerator::AssembleArchTrap(Instruction* instr,
FlagsCondition condition) {
class OutOfLineTrap final : public OutOfLineCode {
public:
OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
: OutOfLineCode(gen),
frame_elided_(frame_elided),
instr_(instr),
gen_(gen) {}
void Generate() final {
X64OperandConverter i(gen_, instr_);
Builtins::Name trap_id =
static_cast<Builtins::Name>(i.InputInt32(instr_->InputCount() - 1));
bool old_has_frame = __ has_frame();
if (frame_elided_) {
__ set_has_frame(true);
__ EnterFrame(StackFrame::WASM_COMPILED);
}
GenerateCallToTrap(trap_id);
if (frame_elided_) {
__ set_has_frame(old_has_frame);
}
}
private:
void GenerateCallToTrap(Builtins::Name trap_id) {
if (trap_id == Builtins::builtin_count) {
// We cannot test calls to the runtime in cctest/test-run-wasm.
// Therefore we emit a call to C here instead of a call to the runtime.
__ PrepareCallCFunction(0);
__ CallCFunction(ExternalReference::wasm_call_trap_callback_for_testing(
__ isolate()),
0);
__ LeaveFrame(StackFrame::WASM_COMPILED);
auto call_descriptor = gen_->linkage()->GetIncomingDescriptor();
size_t pop_size = call_descriptor->StackParameterCount() * kPointerSize;
// Use rcx as a scratch register, we return anyways immediately.
__ Ret(static_cast<int>(pop_size), rcx);
} else {
gen_->AssembleSourcePosition(instr_);
__ Call(__ isolate()->builtins()->builtin_handle(trap_id),
RelocInfo::CODE_TARGET);
ReferenceMap* reference_map =
new (gen_->zone()) ReferenceMap(gen_->zone());
gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
Safepoint::kNoLazyDeopt);
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
}
}
bool frame_elided_;
Instruction* instr_;
CodeGenerator* gen_;
};
bool frame_elided = !frame_access_state()->has_frame();
auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
auto ool = new (zone()) WasmOutOfLineTrap(this, frame_elided, instr);
Label* tlabel = ool->entry();
Label end;
if (condition == kUnorderedEqual) {
......
......@@ -93,6 +93,12 @@ inline void ClearThreadInWasm() {
}
}
class ThreadInWasmScope {
public:
ThreadInWasmScope() { SetThreadInWasm(); }
~ThreadInWasmScope() { ClearThreadInWasm(); }
};
bool RegisterDefaultSignalHandler();
V8_EXPORT_PRIVATE void RestoreOriginalSignalHandler();
......
......@@ -19,6 +19,8 @@ namespace v8 {
namespace internal {
namespace wasm {
using WasmCompilationData = compiler::WasmCompilationData;
constexpr auto kRegister = LiftoffAssembler::VarState::kRegister;
constexpr auto KIntConst = LiftoffAssembler::VarState::KIntConst;
constexpr auto kStack = LiftoffAssembler::VarState::kStack;
......@@ -121,10 +123,8 @@ class LiftoffCompiler {
LiftoffCompiler(LiftoffAssembler* liftoff_asm,
compiler::CallDescriptor* call_descriptor,
compiler::ModuleEnv* env,
compiler::RuntimeExceptionSupport runtime_exception_support,
SourcePositionTableBuilder* source_position_table_builder,
std::vector<trap_handler::ProtectedInstructionData>*
protected_instructions,
WasmCompilationData* wasm_compilation_data,
Zone* compilation_zone, std::unique_ptr<Zone>* codegen_zone)
: asm_(liftoff_asm),
descriptor_(
......@@ -135,9 +135,8 @@ class LiftoffCompiler {
? env_->module->maximum_pages
: wasm::kV8MaxWasmMemoryPages} *
wasm::kWasmPageSize),
runtime_exception_support_(runtime_exception_support),
source_position_table_builder_(source_position_table_builder),
protected_instructions_(protected_instructions),
wasm_compilation_data_(wasm_compilation_data),
compilation_zone_(compilation_zone),
codegen_zone_(codegen_zone),
safepoint_table_builder_(compilation_zone_) {}
......@@ -251,7 +250,10 @@ class LiftoffCompiler {
}
void StackCheck(wasm::WasmCodePosition position) {
if (FLAG_wasm_no_stack_checks || !runtime_exception_support_) return;
if (FLAG_wasm_no_stack_checks ||
!wasm_compilation_data_->runtime_exception_support()) {
return;
}
out_of_line_code_.push_back(
OutOfLineCode::StackCheck(position, __ cache_state()->used_registers));
OutOfLineCode& ool = out_of_line_code_.back();
......@@ -332,7 +334,16 @@ class LiftoffCompiler {
void GenerateOutOfLineCode(OutOfLineCode& ool) {
__ bind(ool.label.get());
const bool is_stack_check = ool.builtin == Builtins::kWasmStackGuard;
if (!runtime_exception_support_) {
const bool is_mem_out_of_bounds =
ool.builtin == Builtins::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());
wasm_compilation_data_->AddProtectedInstruction(ool.pc, pc);
}
if (!wasm_compilation_data_->runtime_exception_support()) {
// We cannot test calls to the runtime in cctest/test-run-wasm.
// Therefore we emit a call to C here instead of a call to the runtime.
// In this mode, we never generate stack checks.
......@@ -343,13 +354,6 @@ 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(
......@@ -1432,11 +1436,10 @@ class LiftoffCompiler {
// {min_size_} and {max_size_} are cached values computed from the ModuleEnv.
const uint64_t min_size_;
const uint64_t max_size_;
const compiler::RuntimeExceptionSupport runtime_exception_support_;
bool ok_ = true;
std::vector<OutOfLineCode> out_of_line_code_;
SourcePositionTableBuilder* const source_position_table_builder_;
std::vector<trap_handler::ProtectedInstructionData>* protected_instructions_;
WasmCompilationData* wasm_compilation_data_;
// 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.
......@@ -1487,9 +1490,8 @@ bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
base::in_place, counters()->liftoff_compile_time());
wasm::WasmFullDecoder<wasm::Decoder::kValidate, wasm::LiftoffCompiler>
decoder(&zone, module, func_body_, &liftoff_.asm_, call_descriptor, env_,
runtime_exception_support_,
&liftoff_.source_position_table_builder_,
protected_instructions_.get(), &zone, &liftoff_.codegen_zone_);
&liftoff_.source_position_table_builder_, &wasm_compilation_data_,
&zone, &liftoff_.codegen_zone_);
decoder.Decode();
liftoff_compile_time_scope.reset();
if (!decoder.interface().ok()) {
......
......@@ -1394,17 +1394,17 @@ WASM_EXEC_TEST(I64Rol) {
}
WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
// TODO(eholk): Fix this test for the trap handler.
if (trap_handler::IsTrapHandlerEnabled()) return;
static const MachineType machineTypes[] = {
MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(),
MachineType::Float64()};
constexpr size_t num_bytes = kWasmPageSize;
for (size_t m = 0; m < arraysize(machineTypes); m++) {
WasmRunner<int32_t, uint32_t> r(execution_mode);
byte* memory = r.builder().AddMemoryElems<byte>(32);
byte* memory = r.builder().AddMemoryElems<byte>(num_bytes);
r.builder().RandomizeMemory(1119 + static_cast<int>(m));
BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
......@@ -1412,7 +1412,7 @@ WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
WASM_ZERO);
byte memsize = WasmOpcodes::MemSize(machineTypes[m]);
uint32_t boundary = 24 - memsize;
uint32_t boundary = num_bytes - 8 - memsize;
CHECK_EQ(0, r.Call(boundary)); // in bounds.
CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize));
......
......@@ -452,6 +452,7 @@ class WasmRunner : public WasmRunnerBase {
ReturnType return_value = static_cast<ReturnType>(0xDEADBEEFDEADBEEF);
WasmRunnerBase::trap_happened = false;
auto trap_callback = []() -> void {
WasmRunnerBase::trap_happened = true;
set_trap_callback_for_testing(nullptr);
......@@ -466,8 +467,13 @@ class WasmRunner : public WasmRunnerBase {
Handle<Code> wrapper_code = wrapper_.GetWrapperCode();
compiler::CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
wrapper_code, wrapper_.signature());
int32_t result = runner.Call(static_cast<void*>(&p)...,
static_cast<void*>(&return_value));
int32_t result;
{
trap_handler::ThreadInWasmScope scope;
result = runner.Call(static_cast<void*>(&p)...,
static_cast<void*>(&return_value));
}
CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
return WasmRunnerBase::trap_happened
? static_cast<ReturnType>(0xDEADBEEFDEADBEEF)
......
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