Commit 834f5adf authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Integrate Liftoff in the compilation pipeline

A WasmCompilationUnit can now either compile the code in liftoff or with
Turbofan. If liftoff compilation fails (because of unsupported
instructions), we fall back to TF.
This new pipeline is only enabled if the --liftoff flag is enabled.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I63669cfd8b7f0c89b08dcbd4d125d5ed44c7265b
Reviewed-on: https://chromium-review.googlesource.com/733091
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48924}
parent 697b2c09
...@@ -4623,17 +4623,17 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -4623,17 +4623,17 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
// Create a TF graph during decoding. // Create a TF graph during decoding.
SourcePositionTable* source_position_table = SourcePositionTable* source_position_table =
new (jsgraph_->zone()) SourcePositionTable(jsgraph_->graph()); new (tf_.jsgraph_->zone()) SourcePositionTable(tf_.jsgraph_->graph());
WasmGraphBuilder builder(env_, jsgraph_->zone(), jsgraph_, centry_stub_, WasmGraphBuilder builder(env_, tf_.jsgraph_->zone(), tf_.jsgraph_,
func_body_.sig, source_position_table, centry_stub_, func_body_.sig, source_position_table,
runtime_exception_support_); runtime_exception_support_);
graph_construction_result_ = tf_.graph_construction_result_ =
wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_);
if (graph_construction_result_.failed()) { if (tf_.graph_construction_result_.failed()) {
if (FLAG_trace_wasm_compiler) { if (FLAG_trace_wasm_compiler) {
OFStream os(stdout); OFStream os(stdout);
os << "Compilation failed: " << graph_construction_result_.error_msg() os << "Compilation failed: " << tf_.graph_construction_result_.error_msg()
<< std::endl; << std::endl;
} }
return nullptr; return nullptr;
...@@ -4643,7 +4643,7 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -4643,7 +4643,7 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
if (builder.has_simd() && if (builder.has_simd() &&
(!CpuFeatures::SupportsWasmSimd128() || lower_simd_)) { (!CpuFeatures::SupportsWasmSimd128() || lower_simd_)) {
SimdScalarLowering(jsgraph_, func_body_.sig).LowerGraph(); SimdScalarLowering(tf_.jsgraph_, func_body_.sig).LowerGraph();
} }
if (func_index_ >= FLAG_trace_wasm_ast_start && if (func_index_ >= FLAG_trace_wasm_ast_start &&
...@@ -4674,13 +4674,21 @@ Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) { ...@@ -4674,13 +4674,21 @@ Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) {
memcpy(index_name, name_vector.start(), name_len); memcpy(index_name, name_vector.start(), name_len);
return Vector<const char>(index_name, name_len); return Vector<const char>(index_name, name_len);
} }
} // namespace } // namespace
// static
WasmCompilationUnit::CompilationMode
WasmCompilationUnit::GetDefaultCompilationMode() {
return FLAG_liftoff ? WasmCompilationUnit::CompilationMode::kLiftoff
: WasmCompilationUnit::CompilationMode::kTurbofan;
}
WasmCompilationUnit::WasmCompilationUnit( WasmCompilationUnit::WasmCompilationUnit(
Isolate* isolate, ModuleEnv* env, wasm::FunctionBody body, Isolate* isolate, ModuleEnv* env, wasm::FunctionBody body,
wasm::WasmName name, int index, Handle<Code> centry_stub, wasm::WasmName name, int index, Handle<Code> centry_stub,
Counters* counters, RuntimeExceptionSupport exception_support, CompilationMode mode, Counters* counters,
bool lower_simd) RuntimeExceptionSupport exception_support, bool lower_simd)
: isolate_(isolate), : isolate_(isolate),
env_(env), env_(env),
func_body_(body), func_body_(body),
...@@ -4689,7 +4697,28 @@ WasmCompilationUnit::WasmCompilationUnit( ...@@ -4689,7 +4697,28 @@ WasmCompilationUnit::WasmCompilationUnit(
centry_stub_(centry_stub), centry_stub_(centry_stub),
func_index_(index), func_index_(index),
runtime_exception_support_(exception_support), runtime_exception_support_(exception_support),
lower_simd_(lower_simd) {} lower_simd_(lower_simd),
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() { void WasmCompilationUnit::ExecuteCompilation() {
auto timed_histogram = env_->module->is_wasm() auto timed_histogram = env_->module->is_wasm()
...@@ -4706,13 +4735,28 @@ void WasmCompilationUnit::ExecuteCompilation() { ...@@ -4706,13 +4735,28 @@ void WasmCompilationUnit::ExecuteCompilation() {
} }
} }
switch (mode_) {
case WasmCompilationUnit::CompilationMode::kLiftoff:
if (ExecuteLiftoffCompilation()) break;
// Otherwise, fall back to turbofan.
liftoff_.~LiftoffData();
mode_ = WasmCompilationUnit::CompilationMode::kTurbofan;
new (&tf_) TurbofanData();
// fall-through
case WasmCompilationUnit::CompilationMode::kTurbofan:
ExecuteTurbofanCompilation();
break;
}
}
void WasmCompilationUnit::ExecuteTurbofanCompilation() {
double decode_ms = 0; double decode_ms = 0;
size_t node_count = 0; size_t node_count = 0;
// Scope for the {graph_zone}. // Scope for the {graph_zone}.
{ {
Zone graph_zone(isolate_->allocator(), ZONE_NAME); Zone graph_zone(isolate_->allocator(), ZONE_NAME);
jsgraph_ = new (&graph_zone) JSGraph( tf_.jsgraph_ = new (&graph_zone) JSGraph(
isolate_, new (&graph_zone) Graph(&graph_zone), isolate_, new (&graph_zone) Graph(&graph_zone),
new (&graph_zone) CommonOperatorBuilder(&graph_zone), nullptr, nullptr, new (&graph_zone) CommonOperatorBuilder(&graph_zone), nullptr, nullptr,
new (&graph_zone) MachineOperatorBuilder( new (&graph_zone) MachineOperatorBuilder(
...@@ -4722,39 +4766,39 @@ void WasmCompilationUnit::ExecuteCompilation() { ...@@ -4722,39 +4766,39 @@ void WasmCompilationUnit::ExecuteCompilation() {
SourcePositionTable* source_positions = SourcePositionTable* source_positions =
BuildGraphForWasmFunction(&decode_ms); BuildGraphForWasmFunction(&decode_ms);
if (graph_construction_result_.failed()) { if (tf_.graph_construction_result_.failed()) {
ok_ = false; ok_ = false;
return; return;
} }
base::ElapsedTimer pipeline_timer; base::ElapsedTimer pipeline_timer;
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
node_count = jsgraph_->graph()->NodeCount(); node_count = tf_.jsgraph_->graph()->NodeCount();
pipeline_timer.Start(); pipeline_timer.Start();
} }
compilation_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME)); tf_.compilation_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME));
// Run the compiler pipeline to generate machine code. // Run the compiler pipeline to generate machine code.
CallDescriptor* descriptor = CallDescriptor* descriptor =
GetWasmCallDescriptor(compilation_zone_.get(), func_body_.sig); GetWasmCallDescriptor(tf_.compilation_zone_.get(), func_body_.sig);
if (jsgraph_->machine()->Is32()) { if (tf_.jsgraph_->machine()->Is32()) {
descriptor = descriptor =
GetI32WasmCallDescriptor(compilation_zone_.get(), descriptor); GetI32WasmCallDescriptor(tf_.compilation_zone_.get(), descriptor);
} }
info_.reset(new CompilationInfo( tf_.info_.reset(new CompilationInfo(
GetDebugName(compilation_zone_.get(), func_name_, func_index_), GetDebugName(tf_.compilation_zone_.get(), func_name_, func_index_),
isolate_, compilation_zone_.get(), Code::WASM_FUNCTION)); isolate_, tf_.compilation_zone_.get(), Code::WASM_FUNCTION));
ZoneVector<trap_handler::ProtectedInstructionData> protected_instructions( ZoneVector<trap_handler::ProtectedInstructionData> protected_instructions(
compilation_zone_.get()); tf_.compilation_zone_.get());
job_.reset(Pipeline::NewWasmCompilationJob( tf_.job_.reset(Pipeline::NewWasmCompilationJob(
info_.get(), jsgraph_, descriptor, source_positions, tf_.info_.get(), tf_.jsgraph_, descriptor, source_positions,
&protected_instructions, env_->module->origin())); &protected_instructions, env_->module->origin()));
ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; ok_ = tf_.job_->ExecuteJob() == CompilationJob::SUCCEEDED;
// TODO(bradnelson): Improve histogram handling of size_t. // TODO(bradnelson): Improve histogram handling of size_t.
counters()->wasm_compile_function_peak_memory_bytes()->AddSample( counters()->wasm_compile_function_peak_memory_bytes()->AddSample(
static_cast<int>(jsgraph_->graph()->zone()->allocation_size())); static_cast<int>(tf_.jsgraph_->graph()->zone()->allocation_size()));
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF(); double pipeline_ms = pipeline_timer.Elapsed().InMillisecondsF();
...@@ -4765,19 +4809,32 @@ void WasmCompilationUnit::ExecuteCompilation() { ...@@ -4765,19 +4809,32 @@ void WasmCompilationUnit::ExecuteCompilation() {
node_count, pipeline_ms); node_count, pipeline_ms);
} }
// The graph zone is about to get out of scope. Avoid invalid references. // The graph zone is about to get out of scope. Avoid invalid references.
jsgraph_ = nullptr; tf_.jsgraph_ = nullptr;
} }
// Record the memory cost this unit places on the system until // Record the memory cost this unit places on the system until
// it is finalized. // it is finalized.
size_t cost = job_->AllocatedMemory(); memory_cost_ = tf_.job_->AllocatedMemory();
set_memory_cost(cost);
} }
// WasmCompilationUnit::ExecuteLiftoffCompilation() is defined in
// liftoff-compiler.cc.
MaybeHandle<Code> WasmCompilationUnit::FinishCompilation( MaybeHandle<Code> WasmCompilationUnit::FinishCompilation(
wasm::ErrorThrower* thrower) { wasm::ErrorThrower* thrower) {
switch (mode_) {
case WasmCompilationUnit::CompilationMode::kLiftoff:
return FinishLiftoffCompilation(thrower);
case WasmCompilationUnit::CompilationMode::kTurbofan:
return FinishTurbofanCompilation(thrower);
}
UNREACHABLE();
}
MaybeHandle<Code> WasmCompilationUnit::FinishTurbofanCompilation(
wasm::ErrorThrower* thrower) {
if (!ok_) { if (!ok_) {
if (graph_construction_result_.failed()) { if (tf_.graph_construction_result_.failed()) {
// Add the function as another context for the exception. // Add the function as another context for the exception.
EmbeddedVector<char, 128> message; EmbeddedVector<char, 128> message;
if (func_name_.start() == nullptr) { if (func_name_.start() == nullptr) {
...@@ -4787,7 +4844,7 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation( ...@@ -4787,7 +4844,7 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation(
SNPrintF(message, "Compiling wasm function #%d:%.*s failed", SNPrintF(message, "Compiling wasm function #%d:%.*s failed",
func_index_, trunc_name.length(), trunc_name.start()); func_index_, trunc_name.length(), trunc_name.start());
} }
thrower->CompileFailed(message.start(), graph_construction_result_); thrower->CompileFailed(message.start(), tf_.graph_construction_result_);
} }
return {}; return {};
...@@ -4796,10 +4853,10 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation( ...@@ -4796,10 +4853,10 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation(
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
codegen_timer.Start(); codegen_timer.Start();
} }
if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { if (tf_.job_->FinalizeJob() != CompilationJob::SUCCEEDED) {
return Handle<Code>::null(); return Handle<Code>::null();
} }
Handle<Code> code = info_->code(); Handle<Code> code = tf_.info_->code();
DCHECK(!code.is_null()); DCHECK(!code.is_null());
if (must_record_function_compilation(isolate_)) { if (must_record_function_compilation(isolate_)) {
...@@ -4819,18 +4876,45 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation( ...@@ -4819,18 +4876,45 @@ MaybeHandle<Code> WasmCompilationUnit::FinishCompilation(
return code; return code;
} }
MaybeHandle<Code> WasmCompilationUnit::FinishLiftoffCompilation(
wasm::ErrorThrower* thrower) {
CodeDesc desc;
liftoff_.asm_.GetCode(isolate_, &desc);
Handle<Code> code;
code = isolate_->factory()->NewCode(desc, Code::WASM_FUNCTION, code);
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code || FLAG_print_wasm_code) {
// TODO(wasm): Use proper log files, here and elsewhere.
OFStream os(stdout);
os << "--- Wasm liftoff code ---\n";
EmbeddedVector<char, 32> func_name;
func_name.Truncate(SNPrintF(func_name, "wasm#%d-liftoff", func_index_));
code->Disassemble(func_name.start(), os);
os << "--- End code ---\n";
}
#endif
if (isolate_->logger()->is_logging_code_events() ||
isolate_->is_profiling()) {
RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code,
"wasm#%d-liftoff", func_index_);
}
return code;
}
// static // static
MaybeHandle<Code> WasmCompilationUnit::CompileWasmFunction( MaybeHandle<Code> WasmCompilationUnit::CompileWasmFunction(
wasm::ErrorThrower* thrower, Isolate* isolate, wasm::ErrorThrower* thrower, Isolate* isolate,
const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env, const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
const wasm::WasmFunction* function) { const wasm::WasmFunction* function, CompilationMode mode) {
wasm::FunctionBody function_body{ wasm::FunctionBody function_body{
function->sig, function->code.offset(), function->sig, function->code.offset(),
wire_bytes.start() + function->code.offset(), wire_bytes.start() + function->code.offset(),
wire_bytes.start() + function->code.end_offset()}; wire_bytes.start() + function->code.end_offset()};
WasmCompilationUnit unit( WasmCompilationUnit unit(
isolate, env, function_body, wire_bytes.GetNameOrNull(function), isolate, env, function_body, wire_bytes.GetNameOrNull(function),
function->func_index, CEntryStub(isolate, 1).GetCode()); function->func_index, CEntryStub(isolate, 1).GetCode(), mode);
unit.ExecuteCompilation(); unit.ExecuteCompilation();
return unit.FinishCompilation(thrower); return unit.FinishCompilation(thrower);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler.h" #include "src/compiler.h"
#include "src/trap-handler/trap-handler.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-body-decoder.h"
#include "src/wasm/wasm-module.h" #include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes.h" #include "src/wasm/wasm-opcodes.h"
...@@ -73,55 +74,81 @@ enum RuntimeExceptionSupport : bool { ...@@ -73,55 +74,81 @@ enum RuntimeExceptionSupport : bool {
class WasmCompilationUnit final { class WasmCompilationUnit final {
public: public:
enum class CompilationMode : uint8_t { kLiftoff, kTurbofan };
static CompilationMode GetDefaultCompilationMode();
// If constructing from a background thread, pass in a Counters*, and ensure // 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 // that the Counters live at least as long as this compilation unit (which
// typically means to hold a std::shared_ptr<Counters>). // typically means to hold a std::shared_ptr<Counters>).
// If no such pointer is passed, Isolate::counters() will be called. This is // If no such pointer is passed, Isolate::counters() will be called. This is
// only allowed to happen on the foreground thread. // only allowed to happen on the foreground thread.
WasmCompilationUnit(Isolate*, ModuleEnv*, wasm::FunctionBody, wasm::WasmName, WasmCompilationUnit(Isolate*, ModuleEnv*, wasm::FunctionBody, wasm::WasmName,
int index, Handle<Code> centry_stub, Counters* = nullptr, int index, Handle<Code> centry_stub,
CompilationMode = GetDefaultCompilationMode(),
Counters* = nullptr,
RuntimeExceptionSupport = kRuntimeExceptionSupport, RuntimeExceptionSupport = kRuntimeExceptionSupport,
bool lower_simd = false); bool lower_simd = false);
~WasmCompilationUnit();
int func_index() const { return func_index_; } int func_index() const { return func_index_; }
void ExecuteCompilation(); void ExecuteCompilation();
MaybeHandle<Code> FinishCompilation(wasm::ErrorThrower* thrower); MaybeHandle<Code> FinishCompilation(wasm::ErrorThrower*);
static MaybeHandle<Code> CompileWasmFunction( static MaybeHandle<Code> CompileWasmFunction(
wasm::ErrorThrower* thrower, Isolate* isolate, wasm::ErrorThrower*, Isolate*, const wasm::ModuleWireBytes&, ModuleEnv*,
const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env, const wasm::WasmFunction*, CompilationMode = GetDefaultCompilationMode());
const wasm::WasmFunction* function);
void set_memory_cost(size_t memory_cost) { memory_cost_ = memory_cost; }
size_t memory_cost() const { return memory_cost_; } size_t memory_cost() const { return memory_cost_; }
private: private:
struct LiftoffData {
wasm::LiftoffAssembler asm_;
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<CompilationInfo> info_;
std::unique_ptr<CompilationJob> job_;
wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
};
// Turbofan.
SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms); SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
Counters* counters() { return counters_; } void ExecuteTurbofanCompilation();
MaybeHandle<Code> FinishTurbofanCompilation(wasm::ErrorThrower*);
// Liftoff.
bool ExecuteLiftoffCompilation();
MaybeHandle<Code> FinishLiftoffCompilation(wasm::ErrorThrower*);
Isolate* isolate_; Isolate* isolate_;
ModuleEnv* env_; ModuleEnv* env_;
wasm::FunctionBody func_body_; wasm::FunctionBody func_body_;
wasm::WasmName func_name_; wasm::WasmName func_name_;
Counters* counters_; Counters* counters_;
// 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<CompilationInfo> info_;
std::unique_ptr<CompilationJob> job_;
Handle<Code> centry_stub_; Handle<Code> centry_stub_;
int func_index_; int func_index_;
wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
// See WasmGraphBuilder::runtime_exception_support_. // See WasmGraphBuilder::runtime_exception_support_.
RuntimeExceptionSupport runtime_exception_support_; RuntimeExceptionSupport runtime_exception_support_;
bool ok_ = true; bool ok_ = true;
size_t memory_cost_ = 0; size_t memory_cost_ = 0;
bool lower_simd_; bool lower_simd_;
CompilationMode mode_;
// {liftoff_} is valid if mode_ == kLiftoff, tf_ if mode_ == kTurbofan.
union {
LiftoffData liftoff_;
TurbofanData tf_;
};
Counters* counters() { return counters_; }
DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit); DISALLOW_COPY_AND_ASSIGN(WasmCompilationUnit);
}; };
......
...@@ -1244,10 +1244,12 @@ class RuntimeCallTimerScope { ...@@ -1244,10 +1244,12 @@ class RuntimeCallTimerScope {
/* Total count of functions compiled using the baseline compiler. */ \ /* Total count of functions compiled using the baseline compiler. */ \
SC(total_baseline_compile_count, V8.TotalBaselineCompileCount) SC(total_baseline_compile_count, V8.TotalBaselineCompileCount)
#define STATS_COUNTER_TS_LIST(SC) \ #define STATS_COUNTER_TS_LIST(SC) \
SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \ SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \
SC(wasm_reloc_size, V8.WasmRelocBytes) \ SC(wasm_reloc_size, V8.WasmRelocBytes) \
SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions) SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions) \
SC(liftoff_compiled_functions, V8.LiftoffCompiledFunctions) \
SC(liftoff_unsupported_functions, V8.LiftoffUnsupportedFunctions)
// This file contains all the v8 counters that are in use. // This file contains all the v8 counters that are in use.
class Counters : public std::enable_shared_from_this<Counters> { class Counters : public std::enable_shared_from_this<Counters> {
......
...@@ -505,6 +505,8 @@ DEFINE_BOOL(trace_wasm_streaming, false, ...@@ -505,6 +505,8 @@ DEFINE_BOOL(trace_wasm_streaming, false,
DEFINE_INT(trace_wasm_ast_start, 0, DEFINE_INT(trace_wasm_ast_start, 0,
"start function for wasm AST trace (inclusive)") "start function for wasm AST trace (inclusive)")
DEFINE_INT(trace_wasm_ast_end, 0, "end function for wasm AST trace (exclusive)") DEFINE_INT(trace_wasm_ast_end, 0, "end function for wasm AST trace (exclusive)")
DEFINE_BOOL(liftoff, false,
"enable liftoff, the experimental wasm baseline compiler")
DEFINE_BOOL(trace_liftoff, false, "trace liftoff, the wasm baseline compiler") DEFINE_BOOL(trace_liftoff, false, "trace liftoff, the wasm baseline compiler")
DEFINE_UINT(skip_compiling_wasm_funcs, 0, "start compiling at function N") DEFINE_UINT(skip_compiling_wasm_funcs, 0, "start compiling at function N")
DEFINE_BOOL(wasm_break_on_decoder_error, false, DEFINE_BOOL(wasm_break_on_decoder_error, false,
......
...@@ -480,10 +480,44 @@ class LiftoffCompiler { ...@@ -480,10 +480,44 @@ class LiftoffCompiler {
}; };
} // namespace } // namespace
} // namespace wasm
bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
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_desc = compiler::GetWasmCallDescriptor(&zone, func_body_.sig);
wasm::WasmFullDecoder<wasm::Decoder::kValidate, wasm::LiftoffCompiler>
decoder(&zone, module, func_body_, &liftoff_.asm_, call_desc, env_);
decoder.Decode();
if (!decoder.interface().ok()) {
// Liftoff compilation failed.
isolate_->counters()->liftoff_unsupported_functions()->Increment();
return false;
}
if (decoder.failed()) return false; // Validation error
if (FLAG_trace_wasm_decode_time) {
double compile_ms = compile_timer.Elapsed().InMillisecondsF();
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);
}
// Record the memory cost this unit places on the system until
// it is finalized.
memory_cost_ = liftoff_.asm_.pc_offset();
isolate_->counters()->liftoff_compiled_functions()->Increment();
return true;
}
#undef __ #undef __
#undef TRACE #undef TRACE
} // namespace wasm
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -89,6 +89,7 @@ class ModuleCompiler { ...@@ -89,6 +89,7 @@ class ModuleCompiler {
wasm::FunctionBody{function->sig, buffer_offset, bytes.begin(), wasm::FunctionBody{function->sig, buffer_offset, bytes.begin(),
bytes.end()}, bytes.end()},
name, function->func_index, compiler_->centry_stub_, name, function->func_index, compiler_->centry_stub_,
compiler::WasmCompilationUnit::GetDefaultCompilationMode(),
compiler_->counters())); compiler_->counters()));
} }
...@@ -966,7 +967,7 @@ void ModuleCompiler::OnBackgroundTaskStopped() { ...@@ -966,7 +967,7 @@ void ModuleCompiler::OnBackgroundTaskStopped() {
DCHECK_LE(stopped_compilation_tasks_, num_background_tasks_); DCHECK_LE(stopped_compilation_tasks_, num_background_tasks_);
} }
// Run by each compilation task The no_finisher_callback is called // Run by each compilation task. The no_finisher_callback is called
// within the result_mutex_ lock when no finishing task is running, // within the result_mutex_ lock when no finishing task is running,
// i.e. when the finisher_is_running_ flag is not set. // i.e. when the finisher_is_running_ flag is not set.
bool ModuleCompiler::FetchAndExecuteCompilationUnit( bool ModuleCompiler::FetchAndExecuteCompilationUnit(
......
...@@ -409,8 +409,10 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) { ...@@ -409,8 +409,10 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
func_wire_bytes.start(), func_wire_bytes.end()}; func_wire_bytes.start(), func_wire_bytes.end()};
compiler::WasmCompilationUnit unit( compiler::WasmCompilationUnit unit(
isolate(), &module_env, func_body, func_name, function_->func_index, isolate(), &module_env, func_body, func_name, function_->func_index,
CEntryStub(isolate(), 1).GetCode(), isolate()->counters(), CEntryStub(isolate(), 1).GetCode(),
builder_->runtime_exception_support(), builder_->lower_simd()); compiler::WasmCompilationUnit::GetDefaultCompilationMode(),
isolate()->counters(), builder_->runtime_exception_support(),
builder_->lower_simd());
unit.ExecuteCompilation(); unit.ExecuteCompilation();
Handle<Code> code = unit.FinishCompilation(&thrower).ToHandleChecked(); Handle<Code> code = unit.FinishCompilation(&thrower).ToHandleChecked();
CHECK(!thrower.error()); CHECK(!thrower.error());
......
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