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
This diff is collapsed.
......@@ -12,6 +12,7 @@
#include "src/compilation-info.h"
#include "src/compiler.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/wasm-module.h"
#include "src/wasm/wasm-opcodes.h"
......@@ -73,55 +74,81 @@ enum RuntimeExceptionSupport : bool {
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::FunctionBody, wasm::WasmName,
int index, Handle<Code> centry_stub, Counters* = nullptr,
int index, Handle<Code> centry_stub,
CompilationMode = GetDefaultCompilationMode(),
Counters* = nullptr,
RuntimeExceptionSupport = kRuntimeExceptionSupport,
bool lower_simd = false);
~WasmCompilationUnit();
int func_index() const { return func_index_; }
void ExecuteCompilation();
MaybeHandle<Code> FinishCompilation(wasm::ErrorThrower* thrower);
MaybeHandle<Code> FinishCompilation(wasm::ErrorThrower*);
static MaybeHandle<Code> CompileWasmFunction(
wasm::ErrorThrower* thrower, Isolate* isolate,
const wasm::ModuleWireBytes& wire_bytes, ModuleEnv* env,
const wasm::WasmFunction* function);
wasm::ErrorThrower*, Isolate*, const wasm::ModuleWireBytes&, ModuleEnv*,
const wasm::WasmFunction*, CompilationMode = GetDefaultCompilationMode());
void set_memory_cost(size_t memory_cost) { memory_cost_ = memory_cost; }
size_t memory_cost() const { return memory_cost_; }
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);
Counters* counters() { return counters_; }
void ExecuteTurbofanCompilation();
MaybeHandle<Code> FinishTurbofanCompilation(wasm::ErrorThrower*);
// Liftoff.
bool ExecuteLiftoffCompilation();
MaybeHandle<Code> FinishLiftoffCompilation(wasm::ErrorThrower*);
Isolate* isolate_;
ModuleEnv* env_;
wasm::FunctionBody func_body_;
wasm::WasmName func_name_;
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_;
int func_index_;
wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
// See WasmGraphBuilder::runtime_exception_support_.
RuntimeExceptionSupport runtime_exception_support_;
bool ok_ = true;
size_t memory_cost_ = 0;
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);
};
......
......@@ -1244,10 +1244,12 @@ class RuntimeCallTimerScope {
/* Total count of functions compiled using the baseline compiler. */ \
SC(total_baseline_compile_count, V8.TotalBaselineCompileCount)
#define STATS_COUNTER_TS_LIST(SC) \
SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \
SC(wasm_reloc_size, V8.WasmRelocBytes) \
SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions)
#define STATS_COUNTER_TS_LIST(SC) \
SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \
SC(wasm_reloc_size, V8.WasmRelocBytes) \
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.
class Counters : public std::enable_shared_from_this<Counters> {
......
......@@ -505,6 +505,8 @@ DEFINE_BOOL(trace_wasm_streaming, false,
DEFINE_INT(trace_wasm_ast_start, 0,
"start function for wasm AST trace (inclusive)")
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_UINT(skip_compiling_wasm_funcs, 0, "start compiling at function N")
DEFINE_BOOL(wasm_break_on_decoder_error, false,
......
......@@ -480,10 +480,44 @@ class LiftoffCompiler {
};
} // 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 TRACE
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -89,6 +89,7 @@ class ModuleCompiler {
wasm::FunctionBody{function->sig, buffer_offset, bytes.begin(),
bytes.end()},
name, function->func_index, compiler_->centry_stub_,
compiler::WasmCompilationUnit::GetDefaultCompilationMode(),
compiler_->counters()));
}
......@@ -966,7 +967,7 @@ void ModuleCompiler::OnBackgroundTaskStopped() {
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,
// i.e. when the finisher_is_running_ flag is not set.
bool ModuleCompiler::FetchAndExecuteCompilationUnit(
......
......@@ -409,8 +409,10 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
func_wire_bytes.start(), func_wire_bytes.end()};
compiler::WasmCompilationUnit unit(
isolate(), &module_env, func_body, func_name, function_->func_index,
CEntryStub(isolate(), 1).GetCode(), isolate()->counters(),
builder_->runtime_exception_support(), builder_->lower_simd());
CEntryStub(isolate(), 1).GetCode(),
compiler::WasmCompilationUnit::GetDefaultCompilationMode(),
isolate()->counters(), builder_->runtime_exception_support(),
builder_->lower_simd());
unit.ExecuteCompilation();
Handle<Code> code = unit.FinishCompilation(&thrower).ToHandleChecked();
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