[wasm] Tear apart the WasmCompilationUnit
This refactoring is a big step towards separating Turbofan-related code from backend independent code. This will allow us to include way less headers from "src/compiler" at various places. The {WasmCompilationUnit} contained information for Turbofan compilation, and for Liftoff compilation. This CL tears this apart, such that {WasmCompilationUnit} holds backend-independent information, plus a pointer to either {LiftoffCompilationUnit} or {TurbofanWasmCompilationUnit}. These pointers are opaque, so that {function-compiler.h}, defining {WasmCompilationUnit}, does not need to include any Turbofan specific or Liftoff specific headers. R=ahaas@chromium.org, titzer@chromium.org, mstarzinger@chromium.org Bug: v8:7570, v8:6600 Change-Id: I024c9a23508ee1b4b3cbe1d068c8e785d732daca Reviewed-on: https://chromium-review.googlesource.com/1016640 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#52684}
This commit is contained in:
parent
a0c59cbfd3
commit
0da7ec58c9
3
BUILD.gn
3
BUILD.gn
@ -2304,6 +2304,7 @@ v8_source_set("v8_base") {
|
||||
"src/wasm/baseline/liftoff-assembler.cc",
|
||||
"src/wasm/baseline/liftoff-assembler.h",
|
||||
"src/wasm/baseline/liftoff-compiler.cc",
|
||||
"src/wasm/baseline/liftoff-compiler.h",
|
||||
"src/wasm/baseline/liftoff-register.h",
|
||||
"src/wasm/compilation-manager.cc",
|
||||
"src/wasm/compilation-manager.h",
|
||||
@ -2311,6 +2312,8 @@ v8_source_set("v8_base") {
|
||||
"src/wasm/function-body-decoder-impl.h",
|
||||
"src/wasm/function-body-decoder.cc",
|
||||
"src/wasm/function-body-decoder.h",
|
||||
"src/wasm/function-compiler.cc",
|
||||
"src/wasm/function-compiler.h",
|
||||
"src/wasm/leb-helper.h",
|
||||
"src/wasm/local-decl-encoder.cc",
|
||||
"src/wasm/local-decl-encoder.h",
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "src/macro-assembler-inl.h"
|
||||
#include "src/trap-handler/trap-handler.h"
|
||||
#include "src/wasm/function-body-decoder.h"
|
||||
#include "src/wasm/function-compiler.h"
|
||||
#include "src/wasm/memory-tracing.h"
|
||||
#include "src/wasm/wasm-code-manager.h"
|
||||
#include "src/wasm/wasm-limits.h"
|
||||
@ -97,10 +98,10 @@ bool ContainsSimd(wasm::FunctionSig* sig) {
|
||||
} // namespace
|
||||
|
||||
WasmGraphBuilder::WasmGraphBuilder(
|
||||
ModuleEnv* env, Zone* zone, JSGraph* jsgraph, Handle<Code> centry_stub,
|
||||
Handle<Oddball> anyref_null, wasm::FunctionSig* sig,
|
||||
compiler::SourcePositionTable* source_position_table,
|
||||
RuntimeExceptionSupport exception_support)
|
||||
wasm::ModuleEnv* env, Zone* zone, JSGraph* jsgraph,
|
||||
Handle<Code> centry_stub, Handle<Oddball> anyref_null,
|
||||
wasm::FunctionSig* sig,
|
||||
compiler::SourcePositionTable* source_position_table)
|
||||
: zone_(zone),
|
||||
jsgraph_(jsgraph),
|
||||
centry_stub_node_(jsgraph_->HeapConstant(centry_stub)),
|
||||
@ -110,7 +111,6 @@ WasmGraphBuilder::WasmGraphBuilder(
|
||||
cur_bufsize_(kDefaultBufferSize),
|
||||
has_simd_(ContainsSimd(sig)),
|
||||
untrusted_code_mitigations_(FLAG_untrusted_code_mitigations),
|
||||
runtime_exception_support_(exception_support),
|
||||
sig_(sig),
|
||||
source_position_table_(source_position_table) {
|
||||
DCHECK_IMPLIES(use_trap_handler(), trap_handler::IsTrapHandlerEnabled());
|
||||
@ -221,7 +221,7 @@ void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position,
|
||||
Node** effect, Node** control) {
|
||||
// TODO(mtrofin): "!env_" happens when we generate a wrapper.
|
||||
// We should factor wrappers separately from wasm codegen.
|
||||
if (FLAG_wasm_no_stack_checks || !env_ || !runtime_exception_support_) {
|
||||
if (FLAG_wasm_no_stack_checks || !env_ || !env_->runtime_exception_support) {
|
||||
return;
|
||||
}
|
||||
if (effect == nullptr) effect = effect_;
|
||||
@ -878,7 +878,9 @@ Node* WasmGraphBuilder::BranchExpectFalse(Node* cond, Node** true_node,
|
||||
}
|
||||
|
||||
Builtins::Name WasmGraphBuilder::GetBuiltinIdForTrap(wasm::TrapReason reason) {
|
||||
if (runtime_exception_support_ == kNoRuntimeExceptionSupport) {
|
||||
// TODO(wasm): "!env_" should not happen when compiling an actual wasm
|
||||
// function.
|
||||
if (!env_ || !env_->runtime_exception_support) {
|
||||
// We use Builtins::builtin_count as a marker to tell the code generator
|
||||
// to generate a call to a testing c-function instead of a runtime
|
||||
// function. This code should only be called from a cctest.
|
||||
@ -4645,7 +4647,7 @@ void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
|
||||
Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
|
||||
Handle<WeakCell> weak_instance,
|
||||
wasm::WasmCode* wasm_code, uint32_t index,
|
||||
bool use_trap_handler) {
|
||||
wasm::UseTrapHandler use_trap_handler) {
|
||||
const wasm::WasmFunction* func = &module->functions[index];
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -4664,7 +4666,7 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
|
||||
Node* effect = nullptr;
|
||||
|
||||
// TODO(titzer): compile JS to WASM wrappers without a {ModuleEnv}.
|
||||
ModuleEnv env(module, use_trap_handler);
|
||||
wasm::ModuleEnv env(module, use_trap_handler, wasm::kRuntimeExceptionSupport);
|
||||
|
||||
WasmGraphBuilder builder(&env, &zone, &jsgraph,
|
||||
CEntryStub(isolate, 1).GetCode(),
|
||||
@ -4750,7 +4752,7 @@ void ValidateImportWrapperReferencesImmovables(Handle<Code> wrapper) {
|
||||
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
|
||||
wasm::FunctionSig* sig, uint32_t index,
|
||||
wasm::ModuleOrigin origin,
|
||||
bool use_trap_handler) {
|
||||
wasm::UseTrapHandler use_trap_handler) {
|
||||
//----------------------------------------------------------------------------
|
||||
// Create the Graph
|
||||
//----------------------------------------------------------------------------
|
||||
@ -4770,7 +4772,10 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
|
||||
origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph)
|
||||
: nullptr;
|
||||
|
||||
ModuleEnv env(nullptr, use_trap_handler);
|
||||
// TODO(wasm): Generate wasm-to-js wrappers without a ModuleEnv.
|
||||
wasm::ModuleEnv env(nullptr, use_trap_handler,
|
||||
wasm::kRuntimeExceptionSupport);
|
||||
|
||||
WasmGraphBuilder builder(
|
||||
&env, &zone, &jsgraph, CEntryStub(isolate, 1).GetCode(),
|
||||
isolate->factory()->null_value(), sig, source_position_table);
|
||||
@ -4948,7 +4953,7 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
|
||||
}
|
||||
|
||||
WasmCompilationData::WasmCompilationData(
|
||||
RuntimeExceptionSupport runtime_exception_support)
|
||||
wasm::RuntimeExceptionSupport runtime_exception_support)
|
||||
: protected_instructions_(
|
||||
new std::vector<trap_handler::ProtectedInstructionData>()),
|
||||
runtime_exception_support_(runtime_exception_support) {}
|
||||
@ -4964,7 +4969,7 @@ int FixedArrayOffsetMinusTag(uint32_t index) {
|
||||
return access.offset - access.tag();
|
||||
}
|
||||
|
||||
SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
|
||||
SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
|
||||
double* decode_ms) {
|
||||
base::ElapsedTimer decode_timer;
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
@ -4973,20 +4978,20 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
|
||||
// Create a TF graph during decoding.
|
||||
|
||||
SourcePositionTable* source_position_table =
|
||||
new (tf_.jsgraph_->zone()) SourcePositionTable(tf_.jsgraph_->graph());
|
||||
new (jsgraph_->zone()) SourcePositionTable(jsgraph_->graph());
|
||||
// We get the handle for {null_value()} directly from the isolate although we
|
||||
// are on a background task because the handle is stored in the isolate
|
||||
// anyways, and it is immortal and immovable.
|
||||
WasmGraphBuilder builder(env_, tf_.jsgraph_->zone(), tf_.jsgraph_,
|
||||
centry_stub_, isolate_->factory()->null_value(),
|
||||
func_body_.sig, source_position_table,
|
||||
wasm_compilation_data_.runtime_exception_support());
|
||||
tf_.graph_construction_result_ =
|
||||
wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_);
|
||||
if (tf_.graph_construction_result_.failed()) {
|
||||
WasmGraphBuilder builder(wasm_unit_->env_, jsgraph_->zone(), jsgraph_,
|
||||
wasm_unit_->centry_stub_,
|
||||
wasm_unit_->isolate_->factory()->null_value(),
|
||||
wasm_unit_->func_body_.sig, source_position_table);
|
||||
graph_construction_result_ = wasm::BuildTFGraph(
|
||||
wasm_unit_->isolate_->allocator(), &builder, wasm_unit_->func_body_);
|
||||
if (graph_construction_result_.failed()) {
|
||||
if (FLAG_trace_wasm_compiler) {
|
||||
OFStream os(stdout);
|
||||
os << "Compilation failed: " << tf_.graph_construction_result_.error_msg()
|
||||
os << "Compilation failed: " << graph_construction_result_.error_msg()
|
||||
<< std::endl;
|
||||
}
|
||||
return nullptr;
|
||||
@ -4995,14 +5000,14 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
|
||||
builder.LowerInt64();
|
||||
|
||||
if (builder.has_simd() &&
|
||||
(!CpuFeatures::SupportsWasmSimd128() || lower_simd_)) {
|
||||
SimdScalarLowering(tf_.jsgraph_, func_body_.sig).LowerGraph();
|
||||
(!CpuFeatures::SupportsWasmSimd128() || wasm_unit_->lower_simd_)) {
|
||||
SimdScalarLowering(jsgraph_, wasm_unit_->func_body_.sig).LowerGraph();
|
||||
}
|
||||
|
||||
if (func_index_ >= FLAG_trace_wasm_ast_start &&
|
||||
func_index_ < FLAG_trace_wasm_ast_end) {
|
||||
PrintRawWasmCode(isolate_->allocator(), func_body_, env_->module,
|
||||
wasm::kPrintLocals);
|
||||
if (wasm_unit_->func_index_ >= FLAG_trace_wasm_ast_start &&
|
||||
wasm_unit_->func_index_ < FLAG_trace_wasm_ast_end) {
|
||||
PrintRawWasmCode(wasm_unit_->isolate_->allocator(), wasm_unit_->func_body_,
|
||||
wasm_unit_->env_->module, wasm::kPrintLocals);
|
||||
}
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
*decode_ms = decode_timer.Elapsed().InMillisecondsF();
|
||||
@ -5032,88 +5037,15 @@ Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
WasmCompilationUnit::CompilationMode
|
||||
WasmCompilationUnit::GetDefaultCompilationMode() {
|
||||
return FLAG_liftoff ? WasmCompilationUnit::CompilationMode::kLiftoff
|
||||
: WasmCompilationUnit::CompilationMode::kTurbofan;
|
||||
}
|
||||
|
||||
WasmCompilationUnit::WasmCompilationUnit(
|
||||
Isolate* isolate, ModuleEnv* env, wasm::NativeModule* native_module,
|
||||
wasm::FunctionBody body, wasm::WasmName name, int index,
|
||||
Handle<Code> centry_stub, CompilationMode mode, Counters* counters,
|
||||
RuntimeExceptionSupport exception_support, bool lower_simd)
|
||||
: isolate_(isolate),
|
||||
env_(env),
|
||||
func_body_(body),
|
||||
func_name_(name),
|
||||
counters_(counters ? counters : isolate->counters()),
|
||||
centry_stub_(centry_stub),
|
||||
func_index_(index),
|
||||
native_module_(native_module),
|
||||
lower_simd_(lower_simd),
|
||||
wasm_compilation_data_(exception_support),
|
||||
mode_(mode) {
|
||||
switch (mode_) {
|
||||
case WasmCompilationUnit::CompilationMode::kLiftoff:
|
||||
new (&liftoff_) LiftoffData(isolate);
|
||||
break;
|
||||
case WasmCompilationUnit::CompilationMode::kTurbofan:
|
||||
new (&tf_) TurbofanData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WasmCompilationUnit::~WasmCompilationUnit() {
|
||||
switch (mode_) {
|
||||
case WasmCompilationUnit::CompilationMode::kLiftoff:
|
||||
liftoff_.~LiftoffData();
|
||||
break;
|
||||
case WasmCompilationUnit::CompilationMode::kTurbofan:
|
||||
tf_.~TurbofanData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WasmCompilationUnit::ExecuteCompilation() {
|
||||
auto size_histogram = env_->module->is_wasm()
|
||||
? counters()->wasm_wasm_function_size_bytes()
|
||||
: counters()->wasm_asm_function_size_bytes();
|
||||
size_histogram->AddSample(
|
||||
static_cast<int>(func_body_.end - func_body_.start));
|
||||
auto timed_histogram = env_->module->is_wasm()
|
||||
? counters()->wasm_compile_wasm_function_time()
|
||||
: counters()->wasm_compile_asm_function_time();
|
||||
TimedHistogramScope wasm_compile_function_time_scope(timed_histogram);
|
||||
|
||||
if (FLAG_trace_wasm_compiler) {
|
||||
PrintF("Compiling wasm function %d\n\n", func_index_);
|
||||
}
|
||||
|
||||
switch (mode_) {
|
||||
case WasmCompilationUnit::CompilationMode::kLiftoff:
|
||||
if (ExecuteLiftoffCompilation()) break;
|
||||
// Otherwise, fall back to turbofan.
|
||||
liftoff_.~LiftoffData();
|
||||
mode_ = WasmCompilationUnit::CompilationMode::kTurbofan;
|
||||
new (&tf_) TurbofanData();
|
||||
V8_FALLTHROUGH;
|
||||
case WasmCompilationUnit::CompilationMode::kTurbofan:
|
||||
ExecuteTurbofanCompilation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WasmCompilationUnit::ExecuteTurbofanCompilation() {
|
||||
void TurbofanWasmCompilationUnit::ExecuteCompilation() {
|
||||
double decode_ms = 0;
|
||||
size_t node_count = 0;
|
||||
|
||||
// Scope for the {graph_zone}.
|
||||
{
|
||||
Zone graph_zone(isolate_->allocator(), ZONE_NAME);
|
||||
tf_.jsgraph_ = new (&graph_zone) JSGraph(
|
||||
isolate_, new (&graph_zone) Graph(&graph_zone),
|
||||
Zone graph_zone(wasm_unit_->isolate_->allocator(), ZONE_NAME);
|
||||
jsgraph_ = new (&graph_zone) JSGraph(
|
||||
wasm_unit_->isolate_, new (&graph_zone) Graph(&graph_zone),
|
||||
new (&graph_zone) CommonOperatorBuilder(&graph_zone), nullptr, nullptr,
|
||||
new (&graph_zone) MachineOperatorBuilder(
|
||||
&graph_zone, MachineType::PointerRepresentation(),
|
||||
@ -5122,91 +5054,75 @@ void WasmCompilationUnit::ExecuteTurbofanCompilation() {
|
||||
SourcePositionTable* source_positions =
|
||||
BuildGraphForWasmFunction(&decode_ms);
|
||||
|
||||
if (tf_.graph_construction_result_.failed()) {
|
||||
if (graph_construction_result_.failed()) {
|
||||
ok_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
base::ElapsedTimer pipeline_timer;
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
node_count = tf_.jsgraph_->graph()->NodeCount();
|
||||
node_count = jsgraph_->graph()->NodeCount();
|
||||
pipeline_timer.Start();
|
||||
}
|
||||
|
||||
tf_.compilation_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME));
|
||||
compilation_zone_.reset(
|
||||
new Zone(wasm_unit_->isolate_->allocator(), ZONE_NAME));
|
||||
|
||||
// Run the compiler pipeline to generate machine code.
|
||||
auto call_descriptor =
|
||||
GetWasmCallDescriptor(tf_.compilation_zone_.get(), func_body_.sig);
|
||||
if (tf_.jsgraph_->machine()->Is32()) {
|
||||
call_descriptor = GetI32WasmCallDescriptor(tf_.compilation_zone_.get(),
|
||||
call_descriptor);
|
||||
auto call_descriptor = GetWasmCallDescriptor(compilation_zone_.get(),
|
||||
wasm_unit_->func_body_.sig);
|
||||
if (jsgraph_->machine()->Is32()) {
|
||||
call_descriptor =
|
||||
GetI32WasmCallDescriptor(compilation_zone_.get(), call_descriptor);
|
||||
}
|
||||
tf_.info_.reset(new OptimizedCompilationInfo(
|
||||
GetDebugName(tf_.compilation_zone_.get(), func_name_, func_index_),
|
||||
tf_.compilation_zone_.get(), Code::WASM_FUNCTION));
|
||||
info_.reset(new OptimizedCompilationInfo(
|
||||
GetDebugName(compilation_zone_.get(), wasm_unit_->func_name_,
|
||||
wasm_unit_->func_index_),
|
||||
compilation_zone_.get(), Code::WASM_FUNCTION));
|
||||
|
||||
tf_.job_.reset(Pipeline::NewWasmCompilationJob(
|
||||
tf_.info_.get(), isolate_, tf_.jsgraph_, call_descriptor,
|
||||
source_positions, &wasm_compilation_data_, env_->module->origin()));
|
||||
ok_ = tf_.job_->ExecuteJob() == CompilationJob::SUCCEEDED;
|
||||
job_.reset(Pipeline::NewWasmCompilationJob(
|
||||
info_.get(), wasm_unit_->isolate_, jsgraph_, call_descriptor,
|
||||
source_positions, &wasm_compilation_data_,
|
||||
wasm_unit_->env_->module->origin()));
|
||||
ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED;
|
||||
// TODO(bradnelson): Improve histogram handling of size_t.
|
||||
counters()->wasm_compile_function_peak_memory_bytes()->AddSample(
|
||||
static_cast<int>(tf_.jsgraph_->graph()->zone()->allocation_size()));
|
||||
wasm_unit_->counters_->wasm_compile_function_peak_memory_bytes()->AddSample(
|
||||
static_cast<int>(jsgraph_->graph()->zone()->allocation_size()));
|
||||
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF();
|
||||
PrintF(
|
||||
"wasm-compilation phase 1 ok: %u bytes, %0.3f ms decode, %zu nodes, "
|
||||
"%0.3f ms pipeline\n",
|
||||
static_cast<unsigned>(func_body_.end - func_body_.start), decode_ms,
|
||||
node_count, pipeline_ms);
|
||||
static_cast<unsigned>(wasm_unit_->func_body_.end -
|
||||
wasm_unit_->func_body_.start),
|
||||
decode_ms, node_count, pipeline_ms);
|
||||
}
|
||||
// The graph zone is about to get out of scope. Avoid invalid references.
|
||||
tf_.jsgraph_ = nullptr;
|
||||
jsgraph_ = nullptr;
|
||||
}
|
||||
|
||||
// Record the memory cost this unit places on the system until
|
||||
// it is finalized.
|
||||
memory_cost_ = tf_.job_->AllocatedMemory();
|
||||
wasm_unit_->memory_cost_ = job_->AllocatedMemory();
|
||||
}
|
||||
|
||||
// WasmCompilationUnit::ExecuteLiftoffCompilation() is defined in
|
||||
// liftoff-compiler.cc.
|
||||
|
||||
wasm::WasmCode* WasmCompilationUnit::FinishCompilation(
|
||||
wasm::ErrorThrower* thrower) {
|
||||
wasm::WasmCode* ret;
|
||||
switch (mode_) {
|
||||
case WasmCompilationUnit::CompilationMode::kLiftoff:
|
||||
ret = FinishLiftoffCompilation(thrower);
|
||||
break;
|
||||
case WasmCompilationUnit::CompilationMode::kTurbofan:
|
||||
ret = FinishTurbofanCompilation(thrower);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (ret == nullptr) {
|
||||
thrower->RuntimeError("Error finalizing code.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
wasm::WasmCode* WasmCompilationUnit::FinishTurbofanCompilation(
|
||||
wasm::WasmCode* TurbofanWasmCompilationUnit::FinishCompilation(
|
||||
wasm::ErrorThrower* thrower) {
|
||||
if (!ok_) {
|
||||
if (tf_.graph_construction_result_.failed()) {
|
||||
if (graph_construction_result_.failed()) {
|
||||
// Add the function as another context for the exception.
|
||||
EmbeddedVector<char, 128> message;
|
||||
if (func_name_.start() == nullptr) {
|
||||
SNPrintF(message, "Compiling wasm function #%d failed", func_index_);
|
||||
if (wasm_unit_->func_name_.start() == nullptr) {
|
||||
SNPrintF(message, "Compiling wasm function #%d failed",
|
||||
wasm_unit_->func_index_);
|
||||
} else {
|
||||
wasm::TruncatedUserString<> trunc_name(func_name_);
|
||||
wasm::TruncatedUserString<> trunc_name(wasm_unit_->func_name_);
|
||||
SNPrintF(message, "Compiling wasm function #%d:%.*s failed",
|
||||
func_index_, trunc_name.length(), trunc_name.start());
|
||||
wasm_unit_->func_index_, trunc_name.length(),
|
||||
trunc_name.start());
|
||||
}
|
||||
thrower->CompileFailed(message.start(), tf_.graph_construction_result_);
|
||||
thrower->CompileFailed(message.start(), graph_construction_result_);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -5216,69 +5132,34 @@ wasm::WasmCode* WasmCompilationUnit::FinishTurbofanCompilation(
|
||||
codegen_timer.Start();
|
||||
}
|
||||
|
||||
if (tf_.job_->FinalizeJob(isolate_) != CompilationJob::SUCCEEDED) {
|
||||
if (job_->FinalizeJob(wasm_unit_->isolate_) != CompilationJob::SUCCEEDED) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(mtrofin): when we crystalize a design in lieu of WasmCodeDesc, that
|
||||
// works for both wasm and non-wasm, we can simplify AddCode to just take
|
||||
// that as a parameter.
|
||||
const CodeDesc& desc =
|
||||
tf_.job_->compilation_info()->wasm_code_desc()->code_desc;
|
||||
wasm::WasmCode* code = native_module_->AddCode(
|
||||
desc, tf_.job_->compilation_info()->wasm_code_desc()->frame_slot_count,
|
||||
func_index_,
|
||||
tf_.job_->compilation_info()->wasm_code_desc()->safepoint_table_offset,
|
||||
tf_.job_->compilation_info()->wasm_code_desc()->handler_table_offset,
|
||||
const CodeDesc& desc = job_->compilation_info()->wasm_code_desc()->code_desc;
|
||||
wasm::WasmCode* code = wasm_unit_->native_module_->AddCode(
|
||||
desc, job_->compilation_info()->wasm_code_desc()->frame_slot_count,
|
||||
wasm_unit_->func_index_,
|
||||
job_->compilation_info()->wasm_code_desc()->safepoint_table_offset,
|
||||
job_->compilation_info()->wasm_code_desc()->handler_table_offset,
|
||||
wasm_compilation_data_.ReleaseProtectedInstructions(),
|
||||
tf_.job_->compilation_info()->wasm_code_desc()->source_positions_table,
|
||||
job_->compilation_info()->wasm_code_desc()->source_positions_table,
|
||||
wasm::WasmCode::kTurbofan);
|
||||
if (!code) return code;
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
double codegen_ms = codegen_timer.Elapsed().InMillisecondsF();
|
||||
PrintF("wasm-code-generation ok: %u bytes, %0.3f ms code generation\n",
|
||||
static_cast<unsigned>(func_body_.end - func_body_.start),
|
||||
static_cast<unsigned>(wasm_unit_->func_body_.end -
|
||||
wasm_unit_->func_body_.start),
|
||||
codegen_ms);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
wasm::WasmCode* WasmCompilationUnit::FinishLiftoffCompilation(
|
||||
wasm::ErrorThrower* thrower) {
|
||||
CodeDesc desc;
|
||||
liftoff_.asm_.GetCode(isolate_, &desc);
|
||||
|
||||
Handle<ByteArray> source_positions =
|
||||
liftoff_.source_position_table_builder_.ToSourcePositionTable(isolate_);
|
||||
|
||||
wasm::WasmCode* code = native_module_->AddCode(
|
||||
desc, liftoff_.asm_.GetTotalFrameSlotCount(), func_index_,
|
||||
liftoff_.safepoint_table_offset_, 0,
|
||||
wasm_compilation_data_.ReleaseProtectedInstructions(), source_positions,
|
||||
wasm::WasmCode::kLiftoff);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// static
|
||||
wasm::WasmCode* WasmCompilationUnit::CompileWasmFunction(
|
||||
wasm::NativeModule* native_module, wasm::ErrorThrower* thrower,
|
||||
Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
|
||||
const wasm::WasmFunction* function, CompilationMode mode) {
|
||||
wasm::FunctionBody function_body{
|
||||
function->sig, function->code.offset(),
|
||||
wire_bytes.start() + function->code.offset(),
|
||||
wire_bytes.start() + function->code.end_offset()};
|
||||
|
||||
WasmCompilationUnit unit(isolate, env, native_module, function_body,
|
||||
wire_bytes.GetNameOrNull(function, env->module),
|
||||
function->func_index,
|
||||
CEntryStub(isolate, 1).GetCode(), mode);
|
||||
unit.ExecuteCompilation();
|
||||
return unit.FinishCompilation(thrower);
|
||||
}
|
||||
|
||||
#undef WASM_64
|
||||
#undef FATAL_UNSUPPORTED_OPCODE
|
||||
#undef WASM_INSTANCE_OBJECT_OFFSET
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "src/compiler.h"
|
||||
#include "src/optimized-compilation-info.h"
|
||||
#include "src/trap-handler/trap-handler.h"
|
||||
#include "src/wasm/baseline/liftoff-assembler.h"
|
||||
#include "src/wasm/function-body-decoder.h"
|
||||
#include "src/wasm/function-compiler.h"
|
||||
#include "src/wasm/wasm-module.h"
|
||||
#include "src/wasm/wasm-opcodes.h"
|
||||
#include "src/wasm/wasm-result.h"
|
||||
@ -43,31 +43,12 @@ class WasmCode;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
// The {ModuleEnv} encapsulates the module data that is used by the
|
||||
// {WasmGraphBuilder} during graph building.
|
||||
// ModuleEnvs are shareable across multiple compilations.
|
||||
struct ModuleEnv {
|
||||
// A pointer to the decoded module's static representation.
|
||||
const wasm::WasmModule* module;
|
||||
|
||||
// True if trap handling should be used in compiled code, rather than
|
||||
// compiling in bounds checks for each memory access.
|
||||
const bool use_trap_handler;
|
||||
|
||||
ModuleEnv(const wasm::WasmModule* module, bool use_trap_handler)
|
||||
: module(module), use_trap_handler(use_trap_handler) {}
|
||||
};
|
||||
|
||||
enum RuntimeExceptionSupport : bool {
|
||||
kRuntimeExceptionSupport = true,
|
||||
kNoRuntimeExceptionSupport = false
|
||||
};
|
||||
|
||||
// Information about Wasm compilation that needs to be plumbed through the
|
||||
// different layers of the compiler.
|
||||
class WasmCompilationData {
|
||||
public:
|
||||
explicit WasmCompilationData(RuntimeExceptionSupport);
|
||||
explicit WasmCompilationData(
|
||||
wasm::RuntimeExceptionSupport runtime_exception_support);
|
||||
|
||||
void AddProtectedInstruction(uint32_t instr_offset, uint32_t landing_offset);
|
||||
|
||||
@ -76,7 +57,7 @@ class WasmCompilationData {
|
||||
return std::move(protected_instructions_);
|
||||
}
|
||||
|
||||
RuntimeExceptionSupport runtime_exception_support() const {
|
||||
wasm::RuntimeExceptionSupport runtime_exception_support() const {
|
||||
return runtime_exception_support_;
|
||||
}
|
||||
|
||||
@ -84,115 +65,56 @@ class WasmCompilationData {
|
||||
std::unique_ptr<std::vector<trap_handler::ProtectedInstructionData>>
|
||||
protected_instructions_;
|
||||
|
||||
// See WasmGraphBuilder::runtime_exception_support_.
|
||||
const RuntimeExceptionSupport runtime_exception_support_;
|
||||
// See ModuleEnv::runtime_exception_support_.
|
||||
wasm::RuntimeExceptionSupport runtime_exception_support_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WasmCompilationData);
|
||||
};
|
||||
|
||||
class WasmCompilationUnit final {
|
||||
class TurbofanWasmCompilationUnit {
|
||||
public:
|
||||
enum class CompilationMode : uint8_t { kLiftoff, kTurbofan };
|
||||
static CompilationMode GetDefaultCompilationMode();
|
||||
explicit TurbofanWasmCompilationUnit(wasm::WasmCompilationUnit* wasm_unit)
|
||||
: wasm_unit_(wasm_unit),
|
||||
wasm_compilation_data_(wasm_unit->env_->runtime_exception_support) {}
|
||||
|
||||
// If constructing from a background thread, pass in a Counters*, and ensure
|
||||
// that the Counters live at least as long as this compilation unit (which
|
||||
// typically means to hold a std::shared_ptr<Counters>).
|
||||
// If no such pointer is passed, Isolate::counters() will be called. This is
|
||||
// only allowed to happen on the foreground thread.
|
||||
WasmCompilationUnit(Isolate*, ModuleEnv*, wasm::NativeModule*,
|
||||
wasm::FunctionBody, wasm::WasmName, int index,
|
||||
Handle<Code> centry_stub,
|
||||
CompilationMode = GetDefaultCompilationMode(),
|
||||
Counters* = nullptr,
|
||||
RuntimeExceptionSupport = kRuntimeExceptionSupport,
|
||||
bool lower_simd = false);
|
||||
|
||||
~WasmCompilationUnit();
|
||||
SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
|
||||
|
||||
void ExecuteCompilation();
|
||||
wasm::WasmCode* FinishCompilation(wasm::ErrorThrower* thrower);
|
||||
|
||||
static wasm::WasmCode* CompileWasmFunction(
|
||||
wasm::NativeModule* native_module, wasm::ErrorThrower* thrower,
|
||||
Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
|
||||
const wasm::WasmFunction* function,
|
||||
CompilationMode = GetDefaultCompilationMode());
|
||||
|
||||
size_t memory_cost() const { return memory_cost_; }
|
||||
wasm::NativeModule* native_module() const { return native_module_; }
|
||||
wasm::WasmCode* FinishCompilation(wasm::ErrorThrower*);
|
||||
|
||||
private:
|
||||
struct LiftoffData {
|
||||
wasm::LiftoffAssembler asm_;
|
||||
int safepoint_table_offset_;
|
||||
SourcePositionTableBuilder source_position_table_builder_;
|
||||
// The {codegen_zone_} needs to survive until FinishCompilation. It's only
|
||||
// rarely used (e.g. for runtime calls), so it's only allocated when needed.
|
||||
std::unique_ptr<Zone> codegen_zone_;
|
||||
explicit LiftoffData(Isolate* isolate) : asm_(isolate) {}
|
||||
};
|
||||
struct TurbofanData {
|
||||
// The graph zone is deallocated at the end of ExecuteCompilation by virtue
|
||||
// of it being zone allocated.
|
||||
JSGraph* jsgraph_ = nullptr;
|
||||
// The compilation_zone_, info_, and job_ fields need to survive past
|
||||
// ExecuteCompilation, onto FinishCompilation (which happens on the main
|
||||
// thread).
|
||||
std::unique_ptr<Zone> compilation_zone_;
|
||||
std::unique_ptr<OptimizedCompilationInfo> info_;
|
||||
std::unique_ptr<OptimizedCompilationJob> job_;
|
||||
wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
|
||||
};
|
||||
|
||||
// Turbofan.
|
||||
SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
|
||||
void ExecuteTurbofanCompilation();
|
||||
wasm::WasmCode* FinishTurbofanCompilation(wasm::ErrorThrower*);
|
||||
|
||||
// Liftoff.
|
||||
bool ExecuteLiftoffCompilation();
|
||||
wasm::WasmCode* FinishLiftoffCompilation(wasm::ErrorThrower*);
|
||||
|
||||
Isolate* isolate_;
|
||||
ModuleEnv* env_;
|
||||
wasm::FunctionBody func_body_;
|
||||
wasm::WasmName func_name_;
|
||||
Counters* counters_;
|
||||
Handle<Code> centry_stub_;
|
||||
int func_index_;
|
||||
bool ok_ = true;
|
||||
size_t memory_cost_ = 0;
|
||||
wasm::NativeModule* native_module_;
|
||||
bool lower_simd_;
|
||||
wasm::WasmCompilationUnit* const wasm_unit_;
|
||||
WasmCompilationData wasm_compilation_data_;
|
||||
CompilationMode mode_;
|
||||
// {liftoff_} is valid if mode_ == kLiftoff, tf_ if mode_ == kTurbofan.
|
||||
union {
|
||||
LiftoffData liftoff_;
|
||||
TurbofanData tf_;
|
||||
};
|
||||
bool ok_ = true;
|
||||
// The graph zone is deallocated at the end of {ExecuteCompilation} by virtue
|
||||
// of it being zone allocated.
|
||||
JSGraph* jsgraph_ = nullptr;
|
||||
// The compilation_zone_, info_, and job_ fields need to survive past
|
||||
// {ExecuteCompilation}, onto {FinishCompilation} (which happens on the main
|
||||
// thread).
|
||||
std::unique_ptr<Zone> compilation_zone_;
|
||||
std::unique_ptr<OptimizedCompilationInfo> info_;
|
||||
std::unique_ptr<OptimizedCompilationJob> job_;
|
||||
wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
|
||||
|
||||
Counters* counters() { return counters_; }
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit);
|
||||
DISALLOW_COPY_AND_ASSIGN(TurbofanWasmCompilationUnit);
|
||||
};
|
||||
|
||||
// Wraps a JS function, producing a code object that can be called from wasm.
|
||||
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
|
||||
wasm::FunctionSig* sig, uint32_t index,
|
||||
wasm::ModuleOrigin origin,
|
||||
bool use_trap_handler);
|
||||
Handle<Code> CompileWasmToJSWrapper(Isolate*, Handle<JSReceiver> target,
|
||||
wasm::FunctionSig*, uint32_t index,
|
||||
wasm::ModuleOrigin, wasm::UseTrapHandler);
|
||||
|
||||
// Wraps a given wasm code object, producing a code object.
|
||||
V8_EXPORT_PRIVATE Handle<Code> CompileJSToWasmWrapper(
|
||||
Isolate* isolate, wasm::WasmModule* module, Handle<WeakCell> weak_instance,
|
||||
wasm::WasmCode* wasm_code, uint32_t index, bool use_trap_handler);
|
||||
Isolate*, wasm::WasmModule*, Handle<WeakCell> weak_instance,
|
||||
wasm::WasmCode*, uint32_t index, wasm::UseTrapHandler);
|
||||
|
||||
// Compiles a stub that redirects a call to a wasm function to the wasm
|
||||
// interpreter. It's ABI compatible with the compiled wasm function.
|
||||
Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index,
|
||||
wasm::FunctionSig* sig);
|
||||
Handle<Code> CompileWasmInterpreterEntry(Isolate*, uint32_t func_index,
|
||||
wasm::FunctionSig*);
|
||||
|
||||
// Helper function to get the offset into a fixed array for a given {index}.
|
||||
// TODO(titzer): access-builder.h is not accessible outside compiler. Move?
|
||||
@ -228,11 +150,10 @@ class WasmGraphBuilder {
|
||||
public:
|
||||
enum EnforceBoundsCheck : bool { kNeedsBoundsCheck, kCanOmitBoundsCheck };
|
||||
|
||||
WasmGraphBuilder(ModuleEnv* env, Zone* zone, JSGraph* graph,
|
||||
WasmGraphBuilder(wasm::ModuleEnv* env, Zone* zone, JSGraph* graph,
|
||||
Handle<Code> centry_stub, Handle<Oddball> anyref_null,
|
||||
wasm::FunctionSig* sig,
|
||||
compiler::SourcePositionTable* spt = nullptr,
|
||||
RuntimeExceptionSupport res = kRuntimeExceptionSupport);
|
||||
compiler::SourcePositionTable* spt = nullptr);
|
||||
|
||||
Node** Buffer(size_t count) {
|
||||
if (count > cur_bufsize_) {
|
||||
@ -423,7 +344,7 @@ class WasmGraphBuilder {
|
||||
Node* const anyref_null_node_;
|
||||
// env_ == nullptr means we're not compiling Wasm functions, such as for
|
||||
// wrappers or interpreter stubs.
|
||||
ModuleEnv* const env_ = nullptr;
|
||||
wasm::ModuleEnv* const env_ = nullptr;
|
||||
SetOncePointer<Node> instance_node_;
|
||||
struct FunctionTableNodes {
|
||||
Node* table_addr;
|
||||
@ -439,10 +360,6 @@ class WasmGraphBuilder {
|
||||
bool has_simd_ = false;
|
||||
bool needs_stack_check_ = false;
|
||||
const bool untrusted_code_mitigations_ = true;
|
||||
// If the runtime doesn't support exception propagation,
|
||||
// we won't generate stack checks, and trap handling will also
|
||||
// be generated differently.
|
||||
const RuntimeExceptionSupport runtime_exception_support_;
|
||||
|
||||
wasm::FunctionSig* const sig_;
|
||||
SetOncePointer<const Operator> allocate_heap_number_operator_;
|
||||
|
@ -2,15 +2,18 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/wasm/baseline/liftoff-assembler.h"
|
||||
#include "src/wasm/baseline/liftoff-compiler.h"
|
||||
|
||||
#include "src/assembler-inl.h"
|
||||
#include "src/base/optional.h"
|
||||
// TODO(clemensh): Remove dependences on compiler stuff.
|
||||
#include "src/compiler/linkage.h"
|
||||
#include "src/compiler/wasm-compiler.h"
|
||||
#include "src/counters.h"
|
||||
#include "src/macro-assembler-inl.h"
|
||||
#include "src/wasm/baseline/liftoff-assembler.h"
|
||||
#include "src/wasm/function-body-decoder-impl.h"
|
||||
#include "src/wasm/function-compiler.h"
|
||||
#include "src/wasm/memory-tracing.h"
|
||||
#include "src/wasm/wasm-objects.h"
|
||||
#include "src/wasm/wasm-opcodes.h"
|
||||
@ -19,8 +22,6 @@ 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;
|
||||
@ -122,10 +123,10 @@ class LiftoffCompiler {
|
||||
};
|
||||
|
||||
LiftoffCompiler(LiftoffAssembler* liftoff_asm,
|
||||
compiler::CallDescriptor* call_descriptor,
|
||||
compiler::ModuleEnv* env,
|
||||
compiler::CallDescriptor* call_descriptor, ModuleEnv* env,
|
||||
SourcePositionTableBuilder* source_position_table_builder,
|
||||
WasmCompilationData* wasm_compilation_data,
|
||||
std::vector<trap_handler::ProtectedInstructionData>*
|
||||
protected_instructions,
|
||||
Zone* compilation_zone, std::unique_ptr<Zone>* codegen_zone,
|
||||
WasmCode* const* code_table_entry)
|
||||
: asm_(liftoff_asm),
|
||||
@ -138,7 +139,7 @@ class LiftoffCompiler {
|
||||
: wasm::kV8MaxWasmMemoryPages} *
|
||||
wasm::kWasmPageSize),
|
||||
source_position_table_builder_(source_position_table_builder),
|
||||
wasm_compilation_data_(wasm_compilation_data),
|
||||
protected_instructions_(protected_instructions),
|
||||
compilation_zone_(compilation_zone),
|
||||
codegen_zone_(codegen_zone),
|
||||
safepoint_table_builder_(compilation_zone_),
|
||||
@ -280,10 +281,7 @@ class LiftoffCompiler {
|
||||
}
|
||||
|
||||
void StackCheck(wasm::WasmCodePosition position) {
|
||||
if (FLAG_wasm_no_stack_checks ||
|
||||
!wasm_compilation_data_->runtime_exception_support()) {
|
||||
return;
|
||||
}
|
||||
if (FLAG_wasm_no_stack_checks || !env_->runtime_exception_support) return;
|
||||
out_of_line_code_.push_back(
|
||||
OutOfLineCode::StackCheck(position, __ cache_state()->used_registers));
|
||||
OutOfLineCode& ool = out_of_line_code_.back();
|
||||
@ -444,10 +442,11 @@ class LiftoffCompiler {
|
||||
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);
|
||||
protected_instructions_->emplace_back(
|
||||
trap_handler::ProtectedInstructionData{ool.pc, pc});
|
||||
}
|
||||
|
||||
if (!wasm_compilation_data_->runtime_exception_support()) {
|
||||
if (!env_->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.
|
||||
@ -1610,14 +1609,14 @@ class LiftoffCompiler {
|
||||
private:
|
||||
LiftoffAssembler* const asm_;
|
||||
compiler::CallDescriptor* const descriptor_;
|
||||
compiler::ModuleEnv* const env_;
|
||||
ModuleEnv* const env_;
|
||||
// {min_size_} and {max_size_} are cached values computed from the ModuleEnv.
|
||||
const uint64_t min_size_;
|
||||
const uint64_t max_size_;
|
||||
bool ok_ = true;
|
||||
std::vector<OutOfLineCode> out_of_line_code_;
|
||||
SourcePositionTableBuilder* const source_position_table_builder_;
|
||||
WasmCompilationData* wasm_compilation_data_;
|
||||
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.
|
||||
@ -1657,30 +1656,37 @@ class LiftoffCompiler {
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace wasm
|
||||
|
||||
bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
|
||||
bool LiftoffCompilationUnit::ExecuteCompilation() {
|
||||
base::ElapsedTimer compile_timer;
|
||||
if (FLAG_trace_wasm_decode_time) {
|
||||
compile_timer.Start();
|
||||
}
|
||||
|
||||
Zone zone(isolate_->allocator(), "LiftoffCompilationZone");
|
||||
const wasm::WasmModule* module = env_ ? env_->module : nullptr;
|
||||
auto call_descriptor = compiler::GetWasmCallDescriptor(&zone, func_body_.sig);
|
||||
Zone zone(wasm_unit_->isolate_->allocator(), "LiftoffCompilationZone");
|
||||
const wasm::WasmModule* module =
|
||||
wasm_unit_->env_ ? wasm_unit_->env_->module : nullptr;
|
||||
auto call_descriptor =
|
||||
compiler::GetWasmCallDescriptor(&zone, wasm_unit_->func_body_.sig);
|
||||
base::Optional<TimedHistogramScope> liftoff_compile_time_scope(
|
||||
base::in_place, counters()->liftoff_compile_time());
|
||||
base::in_place, wasm_unit_->counters_->liftoff_compile_time());
|
||||
wasm::WasmCode* const* code_table_entry =
|
||||
native_module_->code_table().data() + func_index_;
|
||||
wasm_unit_->native_module_->code_table().data() + wasm_unit_->func_index_;
|
||||
DCHECK(!protected_instructions_);
|
||||
protected_instructions_.reset(
|
||||
new std::vector<trap_handler::ProtectedInstructionData>());
|
||||
wasm::WasmFullDecoder<wasm::Decoder::kValidate, wasm::LiftoffCompiler>
|
||||
decoder(&zone, module, func_body_, &liftoff_.asm_, call_descriptor, env_,
|
||||
&liftoff_.source_position_table_builder_, &wasm_compilation_data_,
|
||||
&zone, &liftoff_.codegen_zone_, code_table_entry);
|
||||
decoder(&zone, module, wasm_unit_->func_body_, &asm_, call_descriptor,
|
||||
wasm_unit_->env_, &source_position_table_builder_,
|
||||
protected_instructions_.get(), &zone, &codegen_zone_,
|
||||
code_table_entry);
|
||||
decoder.Decode();
|
||||
liftoff_compile_time_scope.reset();
|
||||
if (!decoder.interface().ok()) {
|
||||
// Liftoff compilation failed.
|
||||
isolate_->counters()->liftoff_unsupported_functions()->Increment();
|
||||
wasm_unit_->isolate_->counters()
|
||||
->liftoff_unsupported_functions()
|
||||
->Increment();
|
||||
return false;
|
||||
}
|
||||
if (decoder.failed()) return false; // Validation error
|
||||
@ -1690,22 +1696,46 @@ bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
|
||||
PrintF(
|
||||
"wasm-compilation liftoff phase 1 ok: %u bytes, %0.3f ms decode and "
|
||||
"compile\n",
|
||||
static_cast<unsigned>(func_body_.end - func_body_.start), compile_ms);
|
||||
static_cast<unsigned>(wasm_unit_->func_body_.end -
|
||||
wasm_unit_->func_body_.start),
|
||||
compile_ms);
|
||||
}
|
||||
|
||||
// Record the memory cost this unit places on the system until
|
||||
// it is finalized.
|
||||
memory_cost_ = liftoff_.asm_.pc_offset();
|
||||
liftoff_.safepoint_table_offset_ =
|
||||
decoder.interface().GetSafepointTableOffset();
|
||||
isolate_->counters()->liftoff_compiled_functions()->Increment();
|
||||
wasm_unit_->memory_cost_ =
|
||||
asm_.pc_offset() +
|
||||
protected_instructions_->size() *
|
||||
sizeof(trap_handler::ProtectedInstructionData) +
|
||||
(codegen_zone_ ? codegen_zone_->allocation_size() : 0);
|
||||
|
||||
safepoint_table_offset_ = decoder.interface().GetSafepointTableOffset();
|
||||
wasm_unit_->isolate_->counters()->liftoff_compiled_functions()->Increment();
|
||||
return true;
|
||||
}
|
||||
|
||||
wasm::WasmCode* LiftoffCompilationUnit::FinishCompilation(
|
||||
wasm::ErrorThrower* thrower) {
|
||||
CodeDesc desc;
|
||||
asm_.GetCode(wasm_unit_->isolate_, &desc);
|
||||
|
||||
Handle<ByteArray> source_positions =
|
||||
source_position_table_builder_.ToSourcePositionTable(
|
||||
wasm_unit_->isolate_);
|
||||
|
||||
wasm::WasmCode* code = wasm_unit_->native_module_->AddCode(
|
||||
desc, asm_.GetTotalFrameSlotCount(), wasm_unit_->func_index_,
|
||||
safepoint_table_offset_, 0, std::move(protected_instructions_),
|
||||
source_positions, wasm::WasmCode::kLiftoff);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
#undef __
|
||||
#undef TRACE
|
||||
#undef WASM_INSTANCE_OBJECT_OFFSET
|
||||
#undef LOAD_INSTANCE_FIELD
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
45
src/wasm/baseline/liftoff-compiler.h
Normal file
45
src/wasm/baseline/liftoff-compiler.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_WASM_BASELINE_LIFTOFF_COMPILER_H_
|
||||
#define V8_WASM_BASELINE_LIFTOFF_COMPILER_H_
|
||||
|
||||
#include "src/source-position-table.h"
|
||||
#include "src/trap-handler/trap-handler.h"
|
||||
#include "src/wasm/baseline/liftoff-assembler.h"
|
||||
#include "src/wasm/function-body-decoder.h"
|
||||
#include "src/wasm/function-compiler.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace wasm {
|
||||
|
||||
class LiftoffCompilationUnit final {
|
||||
public:
|
||||
explicit LiftoffCompilationUnit(WasmCompilationUnit* wasm_unit)
|
||||
: wasm_unit_(wasm_unit), asm_(wasm_unit->isolate_) {}
|
||||
|
||||
bool ExecuteCompilation();
|
||||
wasm::WasmCode* FinishCompilation(wasm::ErrorThrower*);
|
||||
|
||||
private:
|
||||
WasmCompilationUnit* const wasm_unit_;
|
||||
wasm::LiftoffAssembler asm_;
|
||||
int safepoint_table_offset_;
|
||||
SourcePositionTableBuilder source_position_table_builder_;
|
||||
std::unique_ptr<std::vector<trap_handler::ProtectedInstructionData>>
|
||||
protected_instructions_;
|
||||
|
||||
// The {codegen_zone_} needs to survive until FinishCompilation. It's only
|
||||
// rarely used (e.g. for runtime calls), so it's only allocated when needed.
|
||||
std::unique_ptr<Zone> codegen_zone_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LiftoffCompilationUnit);
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_WASM_BASELINE_LIFTOFF_COMPILER_H_
|
133
src/wasm/function-compiler.cc
Normal file
133
src/wasm/function-compiler.cc
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/wasm/function-compiler.h"
|
||||
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/compiler/wasm-compiler.h"
|
||||
#include "src/counters.h"
|
||||
#include "src/macro-assembler-inl.h"
|
||||
#include "src/wasm/baseline/liftoff-compiler.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace wasm {
|
||||
|
||||
// static
|
||||
WasmCompilationUnit::CompilationMode
|
||||
WasmCompilationUnit::GetDefaultCompilationMode() {
|
||||
return FLAG_liftoff ? CompilationMode::kLiftoff : CompilationMode::kTurbofan;
|
||||
}
|
||||
|
||||
WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, ModuleEnv* env,
|
||||
wasm::NativeModule* native_module,
|
||||
wasm::FunctionBody body,
|
||||
wasm::WasmName name, int index,
|
||||
Handle<Code> centry_stub,
|
||||
CompilationMode mode,
|
||||
Counters* counters, bool lower_simd)
|
||||
: isolate_(isolate),
|
||||
env_(env),
|
||||
func_body_(body),
|
||||
func_name_(name),
|
||||
counters_(counters ? counters : isolate->counters()),
|
||||
centry_stub_(centry_stub),
|
||||
func_index_(index),
|
||||
native_module_(native_module),
|
||||
lower_simd_(lower_simd),
|
||||
mode_(mode) {
|
||||
SwitchMode(mode);
|
||||
}
|
||||
|
||||
// Declared here such that {LiftoffCompilationUnit} and
|
||||
// {TurbofanWasmCompilationUnit} can be opaque in the header file.
|
||||
WasmCompilationUnit::~WasmCompilationUnit() {}
|
||||
|
||||
void WasmCompilationUnit::ExecuteCompilation() {
|
||||
auto size_histogram = env_->module->is_wasm()
|
||||
? counters_->wasm_wasm_function_size_bytes()
|
||||
: counters_->wasm_asm_function_size_bytes();
|
||||
size_histogram->AddSample(
|
||||
static_cast<int>(func_body_.end - func_body_.start));
|
||||
auto timed_histogram = env_->module->is_wasm()
|
||||
? counters_->wasm_compile_wasm_function_time()
|
||||
: counters_->wasm_compile_asm_function_time();
|
||||
TimedHistogramScope wasm_compile_function_time_scope(timed_histogram);
|
||||
|
||||
if (FLAG_trace_wasm_compiler) {
|
||||
PrintF("Compiling wasm function %d\n\n", func_index_);
|
||||
}
|
||||
|
||||
switch (mode_) {
|
||||
case WasmCompilationUnit::CompilationMode::kLiftoff:
|
||||
if (liftoff_unit_->ExecuteCompilation()) break;
|
||||
// Otherwise, fall back to turbofan.
|
||||
SwitchMode(CompilationMode::kTurbofan);
|
||||
V8_FALLTHROUGH;
|
||||
case WasmCompilationUnit::CompilationMode::kTurbofan:
|
||||
turbofan_unit_->ExecuteCompilation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wasm::WasmCode* WasmCompilationUnit::FinishCompilation(
|
||||
wasm::ErrorThrower* thrower) {
|
||||
wasm::WasmCode* ret;
|
||||
switch (mode_) {
|
||||
case CompilationMode::kLiftoff:
|
||||
ret = liftoff_unit_->FinishCompilation(thrower);
|
||||
break;
|
||||
case CompilationMode::kTurbofan:
|
||||
ret = turbofan_unit_->FinishCompilation(thrower);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (ret == nullptr) {
|
||||
thrower->RuntimeError("Error finalizing code.");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void WasmCompilationUnit::SwitchMode(CompilationMode new_mode) {
|
||||
// This method is being called in the constructor, where neither
|
||||
// {liftoff_unit_} nor {turbofan_unit_} are set, or to switch mode from
|
||||
// kLiftoff to kTurbofan, in which case {liftoff_unit_} is already set.
|
||||
mode_ = new_mode;
|
||||
switch (new_mode) {
|
||||
case CompilationMode::kLiftoff:
|
||||
DCHECK(!turbofan_unit_);
|
||||
DCHECK(!liftoff_unit_);
|
||||
liftoff_unit_.reset(new LiftoffCompilationUnit(this));
|
||||
return;
|
||||
case CompilationMode::kTurbofan:
|
||||
DCHECK(!turbofan_unit_);
|
||||
liftoff_unit_.reset();
|
||||
turbofan_unit_.reset(new compiler::TurbofanWasmCompilationUnit(this));
|
||||
return;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// static
|
||||
wasm::WasmCode* WasmCompilationUnit::CompileWasmFunction(
|
||||
wasm::NativeModule* native_module, wasm::ErrorThrower* thrower,
|
||||
Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
|
||||
const wasm::WasmFunction* function, CompilationMode mode) {
|
||||
wasm::FunctionBody function_body{
|
||||
function->sig, function->code.offset(),
|
||||
wire_bytes.start() + function->code.offset(),
|
||||
wire_bytes.start() + function->code.end_offset()};
|
||||
|
||||
WasmCompilationUnit unit(isolate, env, native_module, function_body,
|
||||
wire_bytes.GetNameOrNull(function, env->module),
|
||||
function->func_index,
|
||||
CEntryStub(isolate, 1).GetCode(), mode);
|
||||
unit.ExecuteCompilation();
|
||||
return unit.FinishCompilation(thrower);
|
||||
}
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
} // namespace v8
|
114
src/wasm/function-compiler.h
Normal file
114
src/wasm/function-compiler.h
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_WASM_FUNCTION_COMPILER_H_
|
||||
#define V8_WASM_FUNCTION_COMPILER_H_
|
||||
|
||||
#include "src/wasm/function-body-decoder.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace compiler {
|
||||
class TurbofanWasmCompilationUnit;
|
||||
} // namespace compiler
|
||||
|
||||
namespace wasm {
|
||||
|
||||
class LiftoffCompilationUnit;
|
||||
struct ModuleWireBytes;
|
||||
class NativeModule;
|
||||
class WasmCode;
|
||||
struct WasmFunction;
|
||||
|
||||
enum RuntimeExceptionSupport : bool {
|
||||
kRuntimeExceptionSupport = true,
|
||||
kNoRuntimeExceptionSupport = false
|
||||
};
|
||||
|
||||
enum UseTrapHandler : bool { kUseTrapHandler = true, kNoTrapHandler = false };
|
||||
|
||||
// The {ModuleEnv} encapsulates the module data that is used during compilation.
|
||||
// ModuleEnvs are shareable across multiple compilations.
|
||||
struct ModuleEnv {
|
||||
// A pointer to the decoded module's static representation.
|
||||
const WasmModule* const module;
|
||||
|
||||
// True if trap handling should be used in compiled code, rather than
|
||||
// compiling in bounds checks for each memory access.
|
||||
const UseTrapHandler use_trap_handler;
|
||||
|
||||
// If the runtime doesn't support exception propagation,
|
||||
// we won't generate stack checks, and trap handling will also
|
||||
// be generated differently.
|
||||
const RuntimeExceptionSupport runtime_exception_support;
|
||||
|
||||
constexpr ModuleEnv(const WasmModule* module, UseTrapHandler use_trap_handler,
|
||||
RuntimeExceptionSupport runtime_exception_support)
|
||||
: module(module),
|
||||
use_trap_handler(use_trap_handler),
|
||||
runtime_exception_support(runtime_exception_support) {}
|
||||
};
|
||||
|
||||
class WasmCompilationUnit final {
|
||||
public:
|
||||
enum class CompilationMode : uint8_t { kLiftoff, kTurbofan };
|
||||
static CompilationMode GetDefaultCompilationMode();
|
||||
|
||||
// If constructing from a background thread, pass in a Counters*, and ensure
|
||||
// that the Counters live at least as long as this compilation unit (which
|
||||
// typically means to hold a std::shared_ptr<Counters>).
|
||||
// If no such pointer is passed, Isolate::counters() will be called. This is
|
||||
// only allowed to happen on the foreground thread.
|
||||
WasmCompilationUnit(Isolate*, ModuleEnv*, wasm::NativeModule*,
|
||||
wasm::FunctionBody, wasm::WasmName, int index,
|
||||
Handle<Code> centry_stub,
|
||||
CompilationMode = GetDefaultCompilationMode(),
|
||||
Counters* = nullptr, bool lower_simd = false);
|
||||
|
||||
~WasmCompilationUnit();
|
||||
|
||||
void ExecuteCompilation();
|
||||
wasm::WasmCode* FinishCompilation(wasm::ErrorThrower* thrower);
|
||||
|
||||
static wasm::WasmCode* CompileWasmFunction(
|
||||
wasm::NativeModule* native_module, wasm::ErrorThrower* thrower,
|
||||
Isolate* isolate, const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
|
||||
const wasm::WasmFunction* function,
|
||||
CompilationMode = GetDefaultCompilationMode());
|
||||
|
||||
size_t memory_cost() const { return memory_cost_; }
|
||||
wasm::NativeModule* native_module() const { return native_module_; }
|
||||
|
||||
private:
|
||||
friend class LiftoffCompilationUnit;
|
||||
friend class compiler::TurbofanWasmCompilationUnit;
|
||||
|
||||
Isolate* isolate_;
|
||||
ModuleEnv* env_;
|
||||
wasm::FunctionBody func_body_;
|
||||
wasm::WasmName func_name_;
|
||||
Counters* counters_;
|
||||
Handle<Code> centry_stub_;
|
||||
int func_index_;
|
||||
size_t memory_cost_ = 0;
|
||||
wasm::NativeModule* native_module_;
|
||||
// TODO(wasm): Put {lower_simd_} inside the {ModuleEnv}.
|
||||
bool lower_simd_;
|
||||
CompilationMode mode_;
|
||||
// LiftoffCompilationUnit, set if {mode_ == kLiftoff}.
|
||||
std::unique_ptr<LiftoffCompilationUnit> liftoff_unit_;
|
||||
// TurbofanWasmCompilationUnit, set if {mode_ == kTurbofan}.
|
||||
std::unique_ptr<compiler::TurbofanWasmCompilationUnit> turbofan_unit_;
|
||||
|
||||
void SwitchMode(CompilationMode new_mode);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit);
|
||||
};
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_WASM_FUNCTION_COMPILER_H_
|
@ -80,15 +80,14 @@ class CompilationState {
|
||||
|
||||
// Inserts new functions to compile and kicks off compilation.
|
||||
void AddCompilationUnits(
|
||||
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>& units);
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> GetNextCompilationUnit();
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> GetNextExecutedUnit();
|
||||
std::vector<std::unique_ptr<WasmCompilationUnit>>& units);
|
||||
std::unique_ptr<WasmCompilationUnit> GetNextCompilationUnit();
|
||||
std::unique_ptr<WasmCompilationUnit> GetNextExecutedUnit();
|
||||
bool HasCompilationUnitToFinish();
|
||||
|
||||
void OnError(Handle<Object> error, NotifyCompilationCallback notify);
|
||||
void OnFinishedUnit(NotifyCompilationCallback notify);
|
||||
void ScheduleUnitForFinishing(
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit);
|
||||
void ScheduleUnitForFinishing(std::unique_ptr<WasmCompilationUnit> unit);
|
||||
|
||||
void CancelAndWait();
|
||||
void OnBackgroundTaskStopped();
|
||||
@ -122,13 +121,12 @@ class CompilationState {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Protected by {mutex_}:
|
||||
|
||||
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>
|
||||
compilation_units_;
|
||||
std::vector<std::unique_ptr<WasmCompilationUnit>> compilation_units_;
|
||||
bool finisher_is_running_ = false;
|
||||
bool failed_ = false;
|
||||
size_t num_background_tasks_ = 0;
|
||||
|
||||
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> finish_units_;
|
||||
std::vector<std::unique_ptr<WasmCompilationUnit>> finish_units_;
|
||||
size_t allocated_memory_ = 0;
|
||||
|
||||
// End of fields protected by {mutex_}.
|
||||
@ -152,11 +150,9 @@ namespace {
|
||||
|
||||
class JSToWasmWrapperCache {
|
||||
public:
|
||||
Handle<Code> CloneOrCompileJSToWasmWrapper(Isolate* isolate,
|
||||
wasm::WasmModule* module,
|
||||
wasm::WasmCode* wasm_code,
|
||||
uint32_t index,
|
||||
bool use_trap_handler) {
|
||||
Handle<Code> CloneOrCompileJSToWasmWrapper(
|
||||
Isolate* isolate, wasm::WasmModule* module, wasm::WasmCode* wasm_code,
|
||||
uint32_t index, wasm::UseTrapHandler use_trap_handler) {
|
||||
const wasm::WasmFunction* func = &module->functions[index];
|
||||
int cached_idx = sig_map_.Find(func->sig);
|
||||
if (cached_idx >= 0) {
|
||||
@ -240,7 +236,10 @@ class InstanceBuilder {
|
||||
|
||||
Counters* counters() const { return async_counters().get(); }
|
||||
|
||||
bool use_trap_handler() const { return compiled_module_->use_trap_handler(); }
|
||||
wasm::UseTrapHandler use_trap_handler() const {
|
||||
return compiled_module_->use_trap_handler() ? kUseTrapHandler
|
||||
: kNoTrapHandler;
|
||||
}
|
||||
|
||||
// Helper routines to print out errors with imports.
|
||||
#define ERROR_THROWER_WITH_MESSAGE(TYPE) \
|
||||
@ -435,12 +434,13 @@ class IndirectPatcher {
|
||||
int misses_ = 0;
|
||||
};
|
||||
|
||||
compiler::ModuleEnv CreateModuleEnvFromCompiledModule(
|
||||
ModuleEnv CreateModuleEnvFromCompiledModule(
|
||||
Isolate* isolate, Handle<WasmCompiledModule> compiled_module) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
WasmModule* module = compiled_module->shared()->module();
|
||||
compiler::ModuleEnv result(module, compiled_module->use_trap_handler());
|
||||
return result;
|
||||
wasm::UseTrapHandler use_trap_handler =
|
||||
compiled_module->use_trap_handler() ? kUseTrapHandler : kNoTrapHandler;
|
||||
return ModuleEnv(module, use_trap_handler, wasm::kRuntimeExceptionSupport);
|
||||
}
|
||||
|
||||
const wasm::WasmCode* LazyCompileFunction(
|
||||
@ -469,7 +469,7 @@ const wasm::WasmCode* LazyCompileFunction(
|
||||
|
||||
TRACE_LAZY("Compiling function %s, %d.\n", func_name.c_str(), func_index);
|
||||
|
||||
compiler::ModuleEnv module_env =
|
||||
ModuleEnv module_env =
|
||||
CreateModuleEnvFromCompiledModule(isolate, compiled_module);
|
||||
|
||||
const uint8_t* module_start =
|
||||
@ -481,10 +481,10 @@ const wasm::WasmCode* LazyCompileFunction(
|
||||
module_start + func->code.end_offset()};
|
||||
|
||||
ErrorThrower thrower(isolate, "WasmLazyCompile");
|
||||
compiler::WasmCompilationUnit unit(isolate, &module_env,
|
||||
compiled_module->GetNativeModule(), body,
|
||||
CStrVector(func_name.c_str()), func_index,
|
||||
CEntryStub(isolate, 1).GetCode());
|
||||
WasmCompilationUnit unit(isolate, &module_env,
|
||||
compiled_module->GetNativeModule(), body,
|
||||
CStrVector(func_name.c_str()), func_index,
|
||||
CEntryStub(isolate, 1).GetCode());
|
||||
unit.ExecuteCompilation();
|
||||
wasm::WasmCode* wasm_code = unit.FinishCompilation(&thrower);
|
||||
|
||||
@ -885,17 +885,17 @@ double MonotonicallyIncreasingTimeInMs() {
|
||||
base::Time::kMillisecondsPerSecond;
|
||||
}
|
||||
|
||||
std::unique_ptr<compiler::ModuleEnv> CreateDefaultModuleEnv(
|
||||
Isolate* isolate, WasmModule* module) {
|
||||
ModuleEnv CreateDefaultModuleEnv(Isolate* isolate, WasmModule* module) {
|
||||
// TODO(kschimpf): Add module-specific policy handling here (see v8:7143)?
|
||||
bool use_trap_handler = trap_handler::IsTrapHandlerEnabled();
|
||||
return base::make_unique<compiler::ModuleEnv>(module, use_trap_handler);
|
||||
UseTrapHandler use_trap_handler =
|
||||
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler;
|
||||
return ModuleEnv(module, use_trap_handler, kRuntimeExceptionSupport);
|
||||
}
|
||||
|
||||
Handle<WasmCompiledModule> NewCompiledModule(Isolate* isolate,
|
||||
WasmModule* module,
|
||||
Handle<FixedArray> export_wrappers,
|
||||
compiler::ModuleEnv* env) {
|
||||
ModuleEnv* env) {
|
||||
Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New(
|
||||
isolate, module, export_wrappers, env->use_trap_handler);
|
||||
return compiled_module;
|
||||
@ -913,7 +913,7 @@ size_t GetMaxUsableMemorySize(Isolate* isolate) {
|
||||
class CompilationUnitBuilder {
|
||||
public:
|
||||
explicit CompilationUnitBuilder(NativeModule* native_module,
|
||||
compiler::ModuleEnv* module_env,
|
||||
ModuleEnv* module_env,
|
||||
Handle<Code> centry_stub)
|
||||
: native_module_(native_module),
|
||||
compilation_state_(native_module->compilation_state()),
|
||||
@ -922,12 +922,12 @@ class CompilationUnitBuilder {
|
||||
|
||||
void AddUnit(const WasmFunction* function, uint32_t buffer_offset,
|
||||
Vector<const uint8_t> bytes, WasmName name) {
|
||||
units_.emplace_back(new compiler::WasmCompilationUnit(
|
||||
units_.emplace_back(new WasmCompilationUnit(
|
||||
compilation_state_->isolate(), module_env_, native_module_,
|
||||
wasm::FunctionBody{function->sig, buffer_offset, bytes.begin(),
|
||||
bytes.end()},
|
||||
name, function->func_index, centry_stub_,
|
||||
compiler::WasmCompilationUnit::GetDefaultCompilationMode(),
|
||||
WasmCompilationUnit::GetDefaultCompilationMode(),
|
||||
compilation_state_->isolate()->async_counters().get()));
|
||||
}
|
||||
|
||||
@ -943,9 +943,9 @@ class CompilationUnitBuilder {
|
||||
private:
|
||||
NativeModule* native_module_;
|
||||
CompilationState* compilation_state_;
|
||||
compiler::ModuleEnv* module_env_;
|
||||
ModuleEnv* module_env_;
|
||||
Handle<Code> centry_stub_;
|
||||
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> units_;
|
||||
std::vector<std::unique_ptr<WasmCompilationUnit>> units_;
|
||||
};
|
||||
|
||||
// Run by each compilation task and by the main thread (i.e. in both
|
||||
@ -958,7 +958,7 @@ bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state) {
|
||||
DisallowHandleDereference no_deref;
|
||||
DisallowCodeDependencyChange no_dependency_change;
|
||||
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit =
|
||||
std::unique_ptr<WasmCompilationUnit> unit =
|
||||
compilation_state->GetNextCompilationUnit();
|
||||
if (unit == nullptr) return false;
|
||||
|
||||
@ -969,7 +969,7 @@ bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state) {
|
||||
}
|
||||
|
||||
size_t GetNumFunctionsToCompile(const std::vector<WasmFunction>& functions,
|
||||
compiler::ModuleEnv* module_env) {
|
||||
ModuleEnv* module_env) {
|
||||
// TODO(kimanh): Remove, FLAG_skip_compiling_wasm_funcs: previously used for
|
||||
// debugging, and now not necessarily working anymore.
|
||||
uint32_t start = module_env->module->num_imported_functions +
|
||||
@ -981,8 +981,7 @@ size_t GetNumFunctionsToCompile(const std::vector<WasmFunction>& functions,
|
||||
|
||||
void InitializeCompilationUnits(const std::vector<WasmFunction>& functions,
|
||||
const ModuleWireBytes& wire_bytes,
|
||||
compiler::ModuleEnv* module_env,
|
||||
Handle<Code> centry_stub,
|
||||
ModuleEnv* module_env, Handle<Code> centry_stub,
|
||||
NativeModule* native_module) {
|
||||
uint32_t start = module_env->module->num_imported_functions +
|
||||
FLAG_skip_compiling_wasm_funcs;
|
||||
@ -1006,7 +1005,7 @@ void FinishCompilationUnits(CompilationState* compilation_state,
|
||||
ErrorThrower* thrower) {
|
||||
while (true) {
|
||||
if (compilation_state->failed()) break;
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit =
|
||||
std::unique_ptr<WasmCompilationUnit> unit =
|
||||
compilation_state->GetNextExecutedUnit();
|
||||
if (unit == nullptr) break;
|
||||
wasm::WasmCode* result = unit->FinishCompilation(thrower);
|
||||
@ -1022,8 +1021,7 @@ void FinishCompilationUnits(CompilationState* compilation_state,
|
||||
}
|
||||
|
||||
void CompileInParallel(Isolate* isolate, NativeModule* native_module,
|
||||
const ModuleWireBytes& wire_bytes,
|
||||
compiler::ModuleEnv* module_env,
|
||||
const ModuleWireBytes& wire_bytes, ModuleEnv* module_env,
|
||||
Handle<Code> centry_stub, ErrorThrower* thrower) {
|
||||
const WasmModule* module = module_env->module;
|
||||
// Data structures for the parallel compilation.
|
||||
@ -1098,8 +1096,7 @@ void CompileInParallel(Isolate* isolate, NativeModule* native_module,
|
||||
|
||||
void CompileSequentially(Isolate* isolate, NativeModule* native_module,
|
||||
const ModuleWireBytes& wire_bytes,
|
||||
compiler::ModuleEnv* module_env,
|
||||
ErrorThrower* thrower) {
|
||||
ModuleEnv* module_env, ErrorThrower* thrower) {
|
||||
DCHECK(!thrower->error());
|
||||
|
||||
const WasmModule* module = module_env->module;
|
||||
@ -1109,7 +1106,7 @@ void CompileSequentially(Isolate* isolate, NativeModule* native_module,
|
||||
if (func.imported) continue; // Imports are compiled at instantiation time.
|
||||
|
||||
// Compile the function.
|
||||
wasm::WasmCode* code = compiler::WasmCompilationUnit::CompileWasmFunction(
|
||||
wasm::WasmCode* code = WasmCompilationUnit::CompileWasmFunction(
|
||||
native_module, thrower, isolate, wire_bytes, module_env, &func);
|
||||
if (code == nullptr) {
|
||||
TruncatedUserString<> name(wire_bytes.GetName(&func, module));
|
||||
@ -1121,8 +1118,7 @@ void CompileSequentially(Isolate* isolate, NativeModule* native_module,
|
||||
}
|
||||
|
||||
void ValidateSequentially(Isolate* isolate, const ModuleWireBytes& wire_bytes,
|
||||
compiler::ModuleEnv* module_env,
|
||||
ErrorThrower* thrower) {
|
||||
ModuleEnv* module_env, ErrorThrower* thrower) {
|
||||
DCHECK(!thrower->error());
|
||||
|
||||
const WasmModule* module = module_env->module;
|
||||
@ -1209,14 +1205,14 @@ MaybeHandle<WasmModuleObject> CompileToModuleObjectInternal(
|
||||
for (int i = 0, e = export_wrappers->length(); i < e; ++i) {
|
||||
export_wrappers->set(i, *init_builtin);
|
||||
}
|
||||
auto env = CreateDefaultModuleEnv(isolate, wasm_module);
|
||||
ModuleEnv env = CreateDefaultModuleEnv(isolate, wasm_module);
|
||||
|
||||
// Create the compiled module object and populate with compiled functions
|
||||
// and information needed at instantiation time. This object needs to be
|
||||
// serializable. Instantiation may occur off a deserialized version of this
|
||||
// object.
|
||||
Handle<WasmCompiledModule> compiled_module =
|
||||
NewCompiledModule(isolate, shared->module(), export_wrappers, env.get());
|
||||
NewCompiledModule(isolate, shared->module(), export_wrappers, &env);
|
||||
NativeModule* native_module = compiled_module->GetNativeModule();
|
||||
compiled_module->set_shared(*shared);
|
||||
if (lazy_compile) {
|
||||
@ -1227,7 +1223,7 @@ MaybeHandle<WasmModuleObject> CompileToModuleObjectInternal(
|
||||
// TODO(clemensh): According to the spec, we can actually skip validation
|
||||
// at module creation time, and return a function that always traps at
|
||||
// (lazy) compilation time.
|
||||
ValidateSequentially(isolate, wire_bytes, env.get(), thrower);
|
||||
ValidateSequentially(isolate, wire_bytes, &env, thrower);
|
||||
if (thrower->error()) return {};
|
||||
}
|
||||
|
||||
@ -1241,11 +1237,10 @@ MaybeHandle<WasmModuleObject> CompileToModuleObjectInternal(
|
||||
V8::GetCurrentPlatform()->NumberOfWorkerThreads() > 0;
|
||||
|
||||
if (compile_parallel) {
|
||||
CompileInParallel(isolate, native_module, wire_bytes, env.get(),
|
||||
centry_stub, thrower);
|
||||
CompileInParallel(isolate, native_module, wire_bytes, &env, centry_stub,
|
||||
thrower);
|
||||
} else {
|
||||
CompileSequentially(isolate, native_module, wire_bytes, env.get(),
|
||||
thrower);
|
||||
CompileSequentially(isolate, native_module, wire_bytes, &env, thrower);
|
||||
}
|
||||
if (thrower->error()) return {};
|
||||
|
||||
@ -1297,7 +1292,7 @@ class FinishCompileTask : public CancelableTask {
|
||||
while (true) {
|
||||
compilation_state_->RestartBackgroundTasks();
|
||||
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit =
|
||||
std::unique_ptr<WasmCompilationUnit> unit =
|
||||
compilation_state_->GetNextExecutedUnit();
|
||||
|
||||
if (unit == nullptr) {
|
||||
@ -1676,8 +1671,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
|
||||
native_module->GetIndirectlyCallableCode(start_index);
|
||||
FunctionSig* sig = module_->functions[start_index].sig;
|
||||
Handle<Code> wrapper_code = js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
|
||||
isolate_, module_, start_code, start_index,
|
||||
compiled_module_->use_trap_handler());
|
||||
isolate_, module_, start_code, start_index, use_trap_handler());
|
||||
start_function_ = WasmExportedFunction::New(
|
||||
isolate_, instance, MaybeHandle<String>(), start_index,
|
||||
static_cast<int>(sig->parameter_count()), wrapper_code);
|
||||
@ -1928,8 +1922,7 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
|
||||
Handle<JSReceiver> js_receiver(JSReceiver::cast(*value), isolate_);
|
||||
Handle<Code> wrapper_code = compiler::CompileWasmToJSWrapper(
|
||||
isolate_, js_receiver, expected_sig, func_index,
|
||||
module_->origin(),
|
||||
instance->compiled_module()->use_trap_handler());
|
||||
module_->origin(), use_trap_handler());
|
||||
RecordStats(*wrapper_code, counters());
|
||||
|
||||
WasmCode* wasm_code = native_module->AddCodeCopy(
|
||||
@ -2396,7 +2389,7 @@ void InstanceBuilder::LoadTableSegments(Handle<WasmInstanceObject> instance) {
|
||||
Handle<Code> wrapper_code =
|
||||
js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
|
||||
isolate_, module_, wasm_code, func_index,
|
||||
instance->compiled_module()->use_trap_handler());
|
||||
use_trap_handler());
|
||||
MaybeHandle<String> func_name;
|
||||
if (module_->is_asm_js()) {
|
||||
// For modules arising from asm.js, honor the names section.
|
||||
@ -2698,7 +2691,9 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
|
||||
|
||||
Isolate* isolate = job_->isolate_;
|
||||
|
||||
job_->module_env_ = CreateDefaultModuleEnv(isolate, module_);
|
||||
DCHECK_NULL(job_->module_env_);
|
||||
job_->module_env_.reset(
|
||||
new ModuleEnv(CreateDefaultModuleEnv(isolate, module_)));
|
||||
|
||||
Handle<Code> centry_stub = CEntryStub(isolate, 1).GetCode();
|
||||
{
|
||||
@ -3101,7 +3096,7 @@ void CompilationState::AddCallback(
|
||||
}
|
||||
|
||||
void CompilationState::AddCompilationUnits(
|
||||
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>& units) {
|
||||
std::vector<std::unique_ptr<WasmCompilationUnit>>& units) {
|
||||
{
|
||||
base::LockGuard<base::Mutex> guard(&mutex_);
|
||||
compilation_units_.insert(compilation_units_.end(),
|
||||
@ -3111,25 +3106,23 @@ void CompilationState::AddCompilationUnits(
|
||||
RestartBackgroundTasks(units.size());
|
||||
}
|
||||
|
||||
std::unique_ptr<compiler::WasmCompilationUnit>
|
||||
std::unique_ptr<WasmCompilationUnit>
|
||||
CompilationState::GetNextCompilationUnit() {
|
||||
base::LockGuard<base::Mutex> guard(&mutex_);
|
||||
if (!compilation_units_.empty()) {
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit =
|
||||
std::unique_ptr<WasmCompilationUnit> unit =
|
||||
std::move(compilation_units_.back());
|
||||
compilation_units_.pop_back();
|
||||
return unit;
|
||||
}
|
||||
|
||||
return std::unique_ptr<compiler::WasmCompilationUnit>();
|
||||
return std::unique_ptr<WasmCompilationUnit>();
|
||||
}
|
||||
|
||||
std::unique_ptr<compiler::WasmCompilationUnit>
|
||||
CompilationState::GetNextExecutedUnit() {
|
||||
std::unique_ptr<WasmCompilationUnit> CompilationState::GetNextExecutedUnit() {
|
||||
base::LockGuard<base::Mutex> guard(&mutex_);
|
||||
if (finish_units_.empty()) return {};
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> ret =
|
||||
std::move(finish_units_.back());
|
||||
std::unique_ptr<WasmCompilationUnit> ret = std::move(finish_units_.back());
|
||||
finish_units_.pop_back();
|
||||
allocated_memory_ -= ret->memory_cost();
|
||||
return ret;
|
||||
@ -3162,7 +3155,7 @@ void CompilationState::OnFinishedUnit(NotifyCompilationCallback notify) {
|
||||
}
|
||||
|
||||
void CompilationState::ScheduleUnitForFinishing(
|
||||
std::unique_ptr<compiler::WasmCompilationUnit> unit) {
|
||||
std::unique_ptr<WasmCompilationUnit> unit) {
|
||||
size_t cost = unit->memory_cost();
|
||||
base::LockGuard<base::Mutex> guard(&mutex_);
|
||||
finish_units_.push_back(std::move(unit));
|
||||
@ -3258,13 +3251,15 @@ void CompileJsToWasmWrappers(Isolate* isolate,
|
||||
Handle<FixedArray> export_wrappers(compiled_module->export_wrappers(),
|
||||
isolate);
|
||||
NativeModule* native_module = compiled_module->GetNativeModule();
|
||||
wasm::UseTrapHandler use_trap_handler =
|
||||
compiled_module->use_trap_handler() ? kUseTrapHandler : kNoTrapHandler;
|
||||
for (auto exp : compiled_module->shared()->module()->export_table) {
|
||||
if (exp.kind != kExternalFunction) continue;
|
||||
wasm::WasmCode* wasm_code =
|
||||
native_module->GetIndirectlyCallableCode(exp.index);
|
||||
Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
|
||||
isolate, compiled_module->shared()->module(), wasm_code, exp.index,
|
||||
compiled_module->use_trap_handler());
|
||||
use_trap_handler);
|
||||
export_wrappers->set(wrapper_index, *wrapper_code);
|
||||
RecordStats(*wrapper_code, counters);
|
||||
++wrapper_index;
|
||||
|
@ -20,9 +20,10 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace wasm {
|
||||
|
||||
class ModuleCompiler;
|
||||
class WasmCode;
|
||||
class CompilationState;
|
||||
class ModuleCompiler;
|
||||
struct ModuleEnv;
|
||||
class WasmCode;
|
||||
|
||||
struct CompilationStateDeleter {
|
||||
void operator()(CompilationState* compilation_state) const;
|
||||
@ -137,7 +138,7 @@ class AsyncCompileJob {
|
||||
ModuleWireBytes wire_bytes_;
|
||||
Handle<Context> context_;
|
||||
Handle<JSPromise> module_promise_;
|
||||
std::unique_ptr<compiler::ModuleEnv> module_env_;
|
||||
std::unique_ptr<ModuleEnv> module_env_;
|
||||
std::unique_ptr<WasmModule> module_;
|
||||
|
||||
std::vector<DeferredHandles*> deferred_handles_;
|
||||
|
@ -13,13 +13,10 @@
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace compiler {
|
||||
struct ModuleEnv;
|
||||
}
|
||||
|
||||
namespace wasm {
|
||||
|
||||
struct ModuleEnv;
|
||||
|
||||
inline bool IsValidSectionCode(uint8_t byte) {
|
||||
return kTypeSectionCode <= byte && byte <= kLastKnownModuleSection;
|
||||
}
|
||||
@ -82,10 +79,9 @@ V8_EXPORT_PRIVATE FunctionResult SyncDecodeWasmFunction(
|
||||
const WasmModule* module, const byte* function_start,
|
||||
const byte* function_end);
|
||||
|
||||
V8_EXPORT_PRIVATE FunctionResult
|
||||
AsyncDecodeWasmFunction(Isolate* isolate, Zone* zone, compiler::ModuleEnv* env,
|
||||
const byte* function_start, const byte* function_end,
|
||||
const std::shared_ptr<Counters> async_counters);
|
||||
V8_EXPORT_PRIVATE FunctionResult AsyncDecodeWasmFunction(
|
||||
Isolate* isolate, Zone* zone, ModuleEnv* env, const byte* function_start,
|
||||
const byte* function_end, const std::shared_ptr<Counters> async_counters);
|
||||
|
||||
V8_EXPORT_PRIVATE WasmInitExpr DecodeWasmInitExprForTesting(const byte* start,
|
||||
const byte* end);
|
||||
|
@ -1972,8 +1972,7 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
|
||||
byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode),
|
||||
WASM_END};
|
||||
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
|
||||
code + arraysize(code),
|
||||
compiler::kNoRuntimeExceptionSupport);
|
||||
code + arraysize(code));
|
||||
} else {
|
||||
CHECK_EQ(2, sig->parameter_count());
|
||||
byte code[] = {WASM_NO_LOCALS,
|
||||
@ -1984,8 +1983,7 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
|
||||
static_cast<byte>(opcode),
|
||||
WASM_END};
|
||||
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
|
||||
code + arraysize(code),
|
||||
compiler::kNoRuntimeExceptionSupport);
|
||||
code + arraysize(code));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,8 +158,7 @@ WASM_EXEC_TEST(CollectDetailedWasmStack_WasmError) {
|
||||
int unreachable_pos = 1 << (8 * pos_shift);
|
||||
TestSignatures sigs;
|
||||
// Create a WasmRunner with stack checks and traps enabled.
|
||||
WasmRunner<int> r(execution_mode, 0, "main",
|
||||
compiler::kRuntimeExceptionSupport);
|
||||
WasmRunner<int> r(execution_mode, 0, "main", kRuntimeExceptionSupport);
|
||||
|
||||
std::vector<byte> code(unreachable_pos + 1, kExprNop);
|
||||
code[unreachable_pos] = kExprUnreachable;
|
||||
|
@ -70,8 +70,7 @@ void CheckExceptionInfos(v8::internal::Isolate* i_isolate, Handle<Object> exc,
|
||||
// Trigger a trap for executing unreachable.
|
||||
WASM_EXEC_TEST(Unreachable) {
|
||||
// Create a WasmRunner with stack checks and traps enabled.
|
||||
WasmRunner<void> r(execution_mode, 0, "main",
|
||||
compiler::kRuntimeExceptionSupport);
|
||||
WasmRunner<void> r(execution_mode, 0, "main", kRuntimeExceptionSupport);
|
||||
TestSignatures sigs;
|
||||
|
||||
BUILD(r, WASM_UNREACHABLE);
|
||||
@ -105,8 +104,7 @@ WASM_EXEC_TEST(Unreachable) {
|
||||
|
||||
// Trigger a trap for loading from out-of-bounds.
|
||||
WASM_EXEC_TEST(IllegalLoad) {
|
||||
WasmRunner<void> r(execution_mode, 0, "main",
|
||||
compiler::kRuntimeExceptionSupport);
|
||||
WasmRunner<void> r(execution_mode, 0, "main", kRuntimeExceptionSupport);
|
||||
TestSignatures sigs;
|
||||
|
||||
r.builder().AddMemory(0L);
|
||||
|
@ -15,7 +15,7 @@ namespace wasm {
|
||||
|
||||
TestingModuleBuilder::TestingModuleBuilder(
|
||||
Zone* zone, ManuallyImportedJSFunction* maybe_import,
|
||||
WasmExecutionMode mode, compiler::RuntimeExceptionSupport exception_support,
|
||||
WasmExecutionMode mode, RuntimeExceptionSupport exception_support,
|
||||
LowerSimd lower_simd)
|
||||
: test_module_ptr_(&test_module_),
|
||||
isolate_(CcTest::InitIsolateOnce()),
|
||||
@ -45,7 +45,8 @@ TestingModuleBuilder::TestingModuleBuilder(
|
||||
Handle<Code> code = compiler::CompileWasmToJSWrapper(
|
||||
isolate_, maybe_import->js_function, maybe_import->sig,
|
||||
maybe_import_index, test_module_.origin(),
|
||||
trap_handler::IsTrapHandlerEnabled());
|
||||
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler
|
||||
: kNoTrapHandler);
|
||||
native_module_->ResizeCodeTableForTesting(maybe_import_index + 1,
|
||||
kMaxFunctions);
|
||||
auto wasm_to_js_wrapper = native_module_->AddCodeCopy(
|
||||
@ -126,7 +127,7 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
|
||||
isolate_);
|
||||
Handle<Code> ret_code = compiler::CompileJSToWasmWrapper(
|
||||
isolate_, &test_module_, weak_instance, code, index,
|
||||
trap_handler::IsTrapHandlerEnabled());
|
||||
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler);
|
||||
Handle<JSFunction> ret = WasmExportedFunction::New(
|
||||
isolate_, instance_object(), MaybeHandle<String>(),
|
||||
static_cast<int>(index),
|
||||
@ -192,8 +193,11 @@ uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) {
|
||||
return bytes_offset;
|
||||
}
|
||||
|
||||
compiler::ModuleEnv TestingModuleBuilder::CreateModuleEnv() {
|
||||
return {&test_module_, trap_handler::IsTrapHandlerEnabled()};
|
||||
ModuleEnv TestingModuleBuilder::CreateModuleEnv() {
|
||||
return {
|
||||
&test_module_,
|
||||
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler,
|
||||
runtime_exception_support_};
|
||||
}
|
||||
|
||||
const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
|
||||
@ -263,22 +267,21 @@ void TestBuildingGraphWithBuilder(compiler::WasmGraphBuilder* builder,
|
||||
}
|
||||
}
|
||||
|
||||
void TestBuildingGraph(
|
||||
Zone* zone, compiler::JSGraph* jsgraph, compiler::ModuleEnv* module,
|
||||
FunctionSig* sig, compiler::SourcePositionTable* source_position_table,
|
||||
const byte* start, const byte* end,
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support) {
|
||||
void TestBuildingGraph(Zone* zone, compiler::JSGraph* jsgraph,
|
||||
ModuleEnv* module, FunctionSig* sig,
|
||||
compiler::SourcePositionTable* source_position_table,
|
||||
const byte* start, const byte* end) {
|
||||
if (module) {
|
||||
compiler::WasmGraphBuilder builder(
|
||||
module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(),
|
||||
jsgraph->isolate()->factory()->null_value(), sig, source_position_table,
|
||||
runtime_exception_support);
|
||||
jsgraph->isolate()->factory()->null_value(), sig,
|
||||
source_position_table);
|
||||
TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
|
||||
} else {
|
||||
compiler::WasmGraphBuilder builder(
|
||||
nullptr, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(),
|
||||
jsgraph->isolate()->factory()->null_value(), sig, source_position_table,
|
||||
runtime_exception_support);
|
||||
jsgraph->isolate()->factory()->null_value(), sig,
|
||||
source_position_table);
|
||||
TestBuildingGraphWithBuilder(&builder, zone, sig, start, end);
|
||||
}
|
||||
}
|
||||
@ -422,7 +425,7 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
|
||||
Handle<SeqOneByteString> wire_bytes(compiled_module->shared()->module_bytes(),
|
||||
isolate());
|
||||
|
||||
compiler::ModuleEnv module_env = builder_->CreateModuleEnv();
|
||||
ModuleEnv module_env = builder_->CreateModuleEnv();
|
||||
ErrorThrower thrower(isolate(), "WasmFunctionCompiler::Build");
|
||||
ScopedVector<uint8_t> func_wire_bytes(function_->code.length());
|
||||
memcpy(func_wire_bytes.start(),
|
||||
@ -436,15 +439,14 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
|
||||
|
||||
FunctionBody func_body{function_->sig, function_->code.offset(),
|
||||
func_wire_bytes.start(), func_wire_bytes.end()};
|
||||
compiler::WasmCompilationUnit::CompilationMode comp_mode =
|
||||
WasmCompilationUnit::CompilationMode comp_mode =
|
||||
builder_->execution_mode() == WasmExecutionMode::kExecuteLiftoff
|
||||
? compiler::WasmCompilationUnit::CompilationMode::kLiftoff
|
||||
: compiler::WasmCompilationUnit::CompilationMode::kTurbofan;
|
||||
compiler::WasmCompilationUnit unit(
|
||||
isolate(), &module_env, native_module, func_body, func_name,
|
||||
function_->func_index, CEntryStub(isolate(), 1).GetCode(), comp_mode,
|
||||
isolate()->counters(), builder_->runtime_exception_support(),
|
||||
builder_->lower_simd());
|
||||
? WasmCompilationUnit::CompilationMode::kLiftoff
|
||||
: WasmCompilationUnit::CompilationMode::kTurbofan;
|
||||
WasmCompilationUnit unit(isolate(), &module_env, native_module, func_body,
|
||||
func_name, function_->func_index,
|
||||
CEntryStub(isolate(), 1).GetCode(), comp_mode,
|
||||
isolate()->counters(), builder_->lower_simd());
|
||||
unit.ExecuteCompilation();
|
||||
wasm::WasmCode* wasm_code = unit.FinishCompilation(&thrower);
|
||||
if (wasm::WasmCode::ShouldBeLogged(isolate())) {
|
||||
|
@ -92,7 +92,7 @@ struct ManuallyImportedJSFunction {
|
||||
class TestingModuleBuilder {
|
||||
public:
|
||||
TestingModuleBuilder(Zone*, ManuallyImportedJSFunction*, WasmExecutionMode,
|
||||
compiler::RuntimeExceptionSupport, LowerSimd);
|
||||
RuntimeExceptionSupport, LowerSimd);
|
||||
|
||||
void ChangeOriginToAsmjs() { test_module_.set_origin(kAsmJsOrigin); }
|
||||
|
||||
@ -215,11 +215,11 @@ class TestingModuleBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
compiler::ModuleEnv CreateModuleEnv();
|
||||
ModuleEnv CreateModuleEnv();
|
||||
|
||||
WasmExecutionMode execution_mode() const { return execution_mode_; }
|
||||
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support() const {
|
||||
RuntimeExceptionSupport runtime_exception_support() const {
|
||||
return runtime_exception_support_;
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ class TestingModuleBuilder {
|
||||
Handle<WasmInstanceObject> instance_object_;
|
||||
NativeModule* native_module_ = nullptr;
|
||||
bool linked_ = false;
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support_;
|
||||
RuntimeExceptionSupport runtime_exception_support_;
|
||||
LowerSimd lower_simd_;
|
||||
|
||||
const WasmGlobal* AddGlobal(ValueType type);
|
||||
@ -244,11 +244,10 @@ class TestingModuleBuilder {
|
||||
Handle<WasmInstanceObject> InitInstanceObject();
|
||||
};
|
||||
|
||||
void TestBuildingGraph(
|
||||
Zone* zone, compiler::JSGraph* jsgraph, compiler::ModuleEnv* module,
|
||||
FunctionSig* sig, compiler::SourcePositionTable* source_position_table,
|
||||
const byte* start, const byte* end,
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support);
|
||||
void TestBuildingGraph(Zone* zone, compiler::JSGraph* jsgraph,
|
||||
ModuleEnv* module, FunctionSig* sig,
|
||||
compiler::SourcePositionTable* source_position_table,
|
||||
const byte* start, const byte* end);
|
||||
|
||||
class WasmFunctionWrapper : private compiler::GraphAndBuilders {
|
||||
public:
|
||||
@ -348,7 +347,7 @@ class WasmRunnerBase : public HandleAndZoneScope {
|
||||
public:
|
||||
WasmRunnerBase(ManuallyImportedJSFunction* maybe_import,
|
||||
WasmExecutionMode execution_mode, int num_params,
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support,
|
||||
RuntimeExceptionSupport runtime_exception_support,
|
||||
LowerSimd lower_simd)
|
||||
: zone_(&allocator_, ZONE_NAME),
|
||||
builder_(&zone_, maybe_import, execution_mode,
|
||||
@ -431,8 +430,8 @@ class WasmRunner : public WasmRunnerBase {
|
||||
WasmRunner(WasmExecutionMode execution_mode,
|
||||
ManuallyImportedJSFunction* maybe_import = nullptr,
|
||||
const char* main_fn_name = "main",
|
||||
compiler::RuntimeExceptionSupport runtime_exception_support =
|
||||
compiler::kNoRuntimeExceptionSupport,
|
||||
RuntimeExceptionSupport runtime_exception_support =
|
||||
kNoRuntimeExceptionSupport,
|
||||
LowerSimd lower_simd = kNoLowerSimd)
|
||||
: WasmRunnerBase(maybe_import, execution_mode, sizeof...(ParamTypes),
|
||||
runtime_exception_support, lower_simd) {
|
||||
@ -443,8 +442,8 @@ class WasmRunner : public WasmRunnerBase {
|
||||
}
|
||||
|
||||
WasmRunner(WasmExecutionMode execution_mode, LowerSimd lower_simd)
|
||||
: WasmRunner(execution_mode, nullptr, "main",
|
||||
compiler::kNoRuntimeExceptionSupport, lower_simd) {}
|
||||
: WasmRunner(execution_mode, nullptr, "main", kNoRuntimeExceptionSupport,
|
||||
lower_simd) {}
|
||||
|
||||
ReturnType Call(ParamTypes... p) {
|
||||
DCHECK(compiled_);
|
||||
|
Loading…
Reference in New Issue
Block a user