Commit 2328b5ad authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Make WasmCompilationResult self-contained

This makes it easier to publish them in batches. Function index and
requested compilation tier are duplicated from the WasmCompilationUnit.

R=titzer@chromium.org

Bug: v8:8916
Change-Id: I87852670be029b1d729f98f01729362ca379fb50
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1529009Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60325}
parent 4f719cca
...@@ -2237,6 +2237,7 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub( ...@@ -2237,6 +2237,7 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
result.protected_instructions = code_generator->GetProtectedInstructions(); result.protected_instructions = code_generator->GetProtectedInstructions();
result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount(); result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.result_tier = wasm::ExecutionTier::kOptimized;
DCHECK(result.succeeded()); DCHECK(result.succeeded());
...@@ -2484,6 +2485,7 @@ void Pipeline::GenerateCodeForWasmFunction( ...@@ -2484,6 +2485,7 @@ void Pipeline::GenerateCodeForWasmFunction(
result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result->source_positions = code_generator->GetSourcePositionTable(); result->source_positions = code_generator->GetSourcePositionTable();
result->protected_instructions = code_generator->GetProtectedInstructions(); result->protected_instructions = code_generator->GetProtectedInstructions();
result->result_tier = wasm::ExecutionTier::kOptimized;
if (data.info()->trace_turbo_json_enabled()) { if (data.info()->trace_turbo_json_enabled()) {
TurboJsonFile json_of(data.info(), std::ios_base::app); TurboJsonFile json_of(data.info(), std::ios_base::app);
......
...@@ -6000,6 +6000,7 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry( ...@@ -6000,6 +6000,7 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
wasm_engine, incoming, &jsgraph, Code::WASM_INTERPRETER_ENTRY, wasm_engine, incoming, &jsgraph, Code::WASM_INTERPRETER_ENTRY,
wasm::WasmCode::kInterpreterEntry, func_name.start(), wasm::WasmCode::kInterpreterEntry, func_name.start(),
WasmStubAssemblerOptions()); WasmStubAssemblerOptions());
result.result_tier = wasm::ExecutionTier::kInterpreter;
return result; return result;
} }
......
...@@ -2029,6 +2029,7 @@ WasmCompilationResult LiftoffCompilationUnit::ExecuteCompilation( ...@@ -2029,6 +2029,7 @@ WasmCompilationResult LiftoffCompilationUnit::ExecuteCompilation(
result.protected_instructions = compiler->GetProtectedInstructions(); result.protected_instructions = compiler->GetProtectedInstructions();
result.frame_slot_count = compiler->GetTotalFrameSlotCount(); result.frame_slot_count = compiler->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots(); result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.result_tier = ExecutionTier::kBaseline;
DCHECK(result.succeeded()); DCHECK(result.succeeded());
return result; return result;
......
...@@ -16,18 +16,6 @@ namespace wasm { ...@@ -16,18 +16,6 @@ namespace wasm {
namespace { namespace {
const char* GetExecutionTierAsString(ExecutionTier tier) {
switch (tier) {
case ExecutionTier::kBaseline:
return "liftoff";
case ExecutionTier::kOptimized:
return "turbofan";
case ExecutionTier::kInterpreter:
return "interpreter";
}
UNREACHABLE();
}
class WasmInstructionBufferImpl { class WasmInstructionBufferImpl {
public: public:
class View : public AssemblerBuffer { class View : public AssemblerBuffer {
...@@ -129,7 +117,7 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier( ...@@ -129,7 +117,7 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier(
WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine, int index, WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine, int index,
ExecutionTier tier) ExecutionTier tier)
: wasm_engine_(wasm_engine), func_index_(index), requested_tier_(tier) { : wasm_engine_(wasm_engine), func_index_(index), tier_(tier) {
if (V8_UNLIKELY(FLAG_wasm_tier_mask_for_testing) && index < 32 && if (V8_UNLIKELY(FLAG_wasm_tier_mask_for_testing) && index < 32 &&
(FLAG_wasm_tier_mask_for_testing & (1 << index))) { (FLAG_wasm_tier_mask_for_testing & (1 << index))) {
tier = ExecutionTier::kOptimized; tier = ExecutionTier::kOptimized;
...@@ -157,31 +145,37 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation( ...@@ -157,31 +145,37 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation(
wasm_compile, function_time); wasm_compile, function_time);
TimedHistogramScope wasm_compile_function_time_scope(timed_histogram); TimedHistogramScope wasm_compile_function_time_scope(timed_histogram);
// Exactly one compiler-specific unit must be set.
DCHECK_EQ(1, !!liftoff_unit_ + !!turbofan_unit_ + !!interpreter_unit_);
if (FLAG_trace_wasm_compiler) { if (FLAG_trace_wasm_compiler) {
PrintF("Compiling wasm function %d with %s\n\n", func_index_, const char* tier =
GetExecutionTierAsString(executed_tier_)); liftoff_unit_ ? "liftoff" : turbofan_unit_ ? "turbofan" : "interpreter";
PrintF("Compiling wasm function %d with %s\n\n", func_index_, tier);
} }
WasmCompilationResult result; WasmCompilationResult result;
switch (executed_tier_) { if (liftoff_unit_) {
case ExecutionTier::kBaseline: result =
result = liftoff_unit_->ExecuteCompilation(env, func_body, counters, detected);
liftoff_unit_->ExecuteCompilation(env, func_body, counters, detected); if (!result.succeeded()) {
if (result.succeeded()) break; // If Liftoff failed, fall back to turbofan.
// Otherwise, fall back to turbofan.
SwitchTier(ExecutionTier::kOptimized);
// TODO(wasm): We could actually stop or remove the tiering unit for this // TODO(wasm): We could actually stop or remove the tiering unit for this
// function to avoid compiling it twice with TurboFan. // function to avoid compiling it twice with TurboFan.
V8_FALLTHROUGH; SwitchTier(ExecutionTier::kOptimized);
case ExecutionTier::kOptimized: DCHECK_NOT_NULL(turbofan_unit_);
result = turbofan_unit_->ExecuteCompilation(env, func_body, counters, }
detected); }
break; if (turbofan_unit_) {
case ExecutionTier::kInterpreter: result =
result = interpreter_unit_->ExecuteCompilation(env, func_body, counters, turbofan_unit_->ExecuteCompilation(env, func_body, counters, detected);
detected);
break;
} }
if (interpreter_unit_) {
result = interpreter_unit_->ExecuteCompilation(env, func_body, counters,
detected);
}
result.func_index = func_index_;
result.requested_tier = tier_;
if (result.succeeded()) { if (result.succeeded()) {
counters->wasm_generated_code_size()->Increment( counters->wasm_generated_code_size()->Increment(
...@@ -192,34 +186,11 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation( ...@@ -192,34 +186,11 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation(
return result; return result;
} }
WasmCode* WasmCompilationUnit::Publish(WasmCompilationResult result,
NativeModule* native_module) {
if (!result.succeeded()) {
native_module->compilation_state()->SetError();
return nullptr;
}
DCHECK(result.succeeded());
WasmCode::Tier code_tier = executed_tier_ == ExecutionTier::kBaseline
? WasmCode::kLiftoff
: WasmCode::kTurbofan;
DCHECK_EQ(result.code_desc.buffer, result.instr_buffer.get());
WasmCode::Kind code_kind = executed_tier_ == ExecutionTier::kInterpreter
? WasmCode::Kind::kInterpreterEntry
: WasmCode::Kind::kFunction;
WasmCode* code = native_module->AddCode(
func_index_, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots, std::move(result.protected_instructions),
std::move(result.source_positions), code_kind, code_tier);
return code;
}
void WasmCompilationUnit::SwitchTier(ExecutionTier new_tier) { void WasmCompilationUnit::SwitchTier(ExecutionTier new_tier) {
// This method is being called in the constructor, where neither // This method is being called in the constructor, where neither
// {liftoff_unit_} nor {turbofan_unit_} nor {interpreter_unit_} are set, or to // {liftoff_unit_} nor {turbofan_unit_} nor {interpreter_unit_} are set, or to
// switch tier from kLiftoff to kTurbofan, in which case {liftoff_unit_} is // switch tier from kLiftoff to kTurbofan, in which case {liftoff_unit_} is
// already set. // already set.
executed_tier_ = new_tier;
switch (new_tier) { switch (new_tier) {
case ExecutionTier::kBaseline: case ExecutionTier::kBaseline:
DCHECK(!turbofan_unit_); DCHECK(!turbofan_unit_);
...@@ -259,7 +230,7 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate, ...@@ -259,7 +230,7 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate,
WasmCompilationResult result = unit.ExecuteCompilation( WasmCompilationResult result = unit.ExecuteCompilation(
&env, native_module->compilation_state()->GetWireBytesStorage(), &env, native_module->compilation_state()->GetWireBytesStorage(),
isolate->counters(), detected); isolate->counters(), detected);
unit.Publish(std::move(result), native_module); native_module->AddCompiledCode(std::move(result));
} }
} // namespace wasm } // namespace wasm
......
...@@ -60,17 +60,15 @@ struct WasmCompilationResult { ...@@ -60,17 +60,15 @@ struct WasmCompilationResult {
uint32_t tagged_parameter_slots = 0; uint32_t tagged_parameter_slots = 0;
OwnedVector<byte> source_positions; OwnedVector<byte> source_positions;
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions; OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions;
int func_index;
ExecutionTier requested_tier;
ExecutionTier result_tier;
}; };
class WasmCompilationUnit final { class WasmCompilationUnit final {
public: public:
static ExecutionTier GetDefaultExecutionTier(const WasmModule*); static ExecutionTier GetDefaultExecutionTier(const WasmModule*);
// 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 used exclusively from a foreground thread, Isolate::counters() may be
// used by callers to pass Counters.
WasmCompilationUnit(WasmEngine*, int index, ExecutionTier); WasmCompilationUnit(WasmEngine*, int index, ExecutionTier);
~WasmCompilationUnit(); ~WasmCompilationUnit();
...@@ -79,10 +77,7 @@ class WasmCompilationUnit final { ...@@ -79,10 +77,7 @@ class WasmCompilationUnit final {
CompilationEnv*, const std::shared_ptr<WireBytesStorage>&, Counters*, CompilationEnv*, const std::shared_ptr<WireBytesStorage>&, Counters*,
WasmFeatures* detected); WasmFeatures* detected);
WasmCode* Publish(WasmCompilationResult, NativeModule*); ExecutionTier tier() const { return tier_; }
ExecutionTier requested_tier() const { return requested_tier_; }
ExecutionTier executed_tier() const { return executed_tier_; }
static void CompileWasmFunction(Isolate*, NativeModule*, static void CompileWasmFunction(Isolate*, NativeModule*,
WasmFeatures* detected, const WasmFunction*, WasmFeatures* detected, const WasmFunction*,
...@@ -95,8 +90,7 @@ class WasmCompilationUnit final { ...@@ -95,8 +90,7 @@ class WasmCompilationUnit final {
WasmEngine* const wasm_engine_; WasmEngine* const wasm_engine_;
const int func_index_; const int func_index_;
ExecutionTier requested_tier_; ExecutionTier tier_;
ExecutionTier executed_tier_;
// LiftoffCompilationUnit, set if {tier_ == kLiftoff}. // LiftoffCompilationUnit, set if {tier_ == kLiftoff}.
std::unique_ptr<LiftoffCompilationUnit> liftoff_unit_; std::unique_ptr<LiftoffCompilationUnit> liftoff_unit_;
......
...@@ -322,7 +322,7 @@ void CompileLazy(Isolate* isolate, NativeModule* native_module, ...@@ -322,7 +322,7 @@ void CompileLazy(Isolate* isolate, NativeModule* native_module,
&env, native_module->compilation_state()->GetWireBytesStorage(), &env, native_module->compilation_state()->GetWireBytesStorage(),
isolate->counters(), isolate->counters(),
Impl(native_module->compilation_state())->detected_features()); Impl(native_module->compilation_state())->detected_features());
WasmCode* code = unit.Publish(std::move(result), native_module); WasmCode* code = native_module->AddCompiledCode(std::move(result));
// During lazy compilation, we should never get compilation errors. The module // During lazy compilation, we should never get compilation errors. The module
// was verified before starting execution with lazy compilation. // was verified before starting execution with lazy compilation.
...@@ -437,8 +437,8 @@ bool FetchAndExecuteCompilationUnit(CompilationEnv* env, ...@@ -437,8 +437,8 @@ bool FetchAndExecuteCompilationUnit(CompilationEnv* env,
WasmCompilationResult result = unit->ExecuteCompilation( WasmCompilationResult result = unit->ExecuteCompilation(
env, compilation_state->GetWireBytesStorage(), counters, detected); env, compilation_state->GetWireBytesStorage(), counters, detected);
WasmCode* code = unit->Publish(std::move(result), native_module); WasmCode* code = native_module->AddCompiledCode(std::move(result));
compilation_state->OnFinishedUnit(unit->requested_tier(), code); compilation_state->OnFinishedUnit(result.requested_tier, code);
return true; return true;
} }
...@@ -658,7 +658,7 @@ class BackgroundCompileTask : public CancelableTask { ...@@ -658,7 +658,7 @@ class BackgroundCompileTask : public CancelableTask {
BackgroundCompileScope compile_scope(token_); BackgroundCompileScope compile_scope(token_);
if (compile_scope.cancelled()) return; if (compile_scope.cancelled()) return;
WasmCode* code = WasmCode* code =
unit->Publish(std::move(result), compile_scope.native_module()); compile_scope.native_module()->AddCompiledCode(std::move(result));
if (code == nullptr) { if (code == nullptr) {
// Compile error. // Compile error.
compile_scope.compilation_state()->OnBackgroundTaskStopped( compile_scope.compilation_state()->OnBackgroundTaskStopped(
...@@ -668,8 +668,8 @@ class BackgroundCompileTask : public CancelableTask { ...@@ -668,8 +668,8 @@ class BackgroundCompileTask : public CancelableTask {
} }
// Successfully finished one unit. // Successfully finished one unit.
compile_scope.compilation_state()->OnFinishedUnit( compile_scope.compilation_state()->OnFinishedUnit(result.requested_tier,
unit->requested_tier(), code); code);
if (deadline < MonotonicallyIncreasingTimeInMs()) { if (deadline < MonotonicallyIncreasingTimeInMs()) {
compile_scope.compilation_state()->ReportDetectedFeatures( compile_scope.compilation_state()->ReportDetectedFeatures(
detected_features); detected_features);
...@@ -1518,8 +1518,7 @@ void CompilationStateImpl::AddCompilationUnits( ...@@ -1518,8 +1518,7 @@ void CompilationStateImpl::AddCompilationUnits(
if (compile_mode_ == CompileMode::kTiering) { if (compile_mode_ == CompileMode::kTiering) {
DCHECK_EQ(baseline_units.size(), tiering_units.size()); DCHECK_EQ(baseline_units.size(), tiering_units.size());
DCHECK_EQ(tiering_units.back()->requested_tier(), DCHECK_EQ(tiering_units.back()->tier(), ExecutionTier::kOptimized);
ExecutionTier::kOptimized);
tiering_compilation_units_.insert( tiering_compilation_units_.insert(
tiering_compilation_units_.end(), tiering_compilation_units_.end(),
std::make_move_iterator(tiering_units.begin()), std::make_move_iterator(tiering_units.begin()),
......
...@@ -1199,6 +1199,44 @@ void NativeModule::SampleCodeSize( ...@@ -1199,6 +1199,44 @@ void NativeModule::SampleCodeSize(
histogram->AddSample(code_size_mb); histogram->AddSample(code_size_mb);
} }
namespace {
WasmCode::Tier GetCodeTierForExecutionTier(ExecutionTier tier) {
switch (tier) {
case ExecutionTier::kInterpreter:
return WasmCode::Tier::kOther;
case ExecutionTier::kBaseline:
return WasmCode::Tier::kLiftoff;
case ExecutionTier::kOptimized:
return WasmCode::Tier::kTurbofan;
}
}
WasmCode::Kind GetCodeKindForExecutionTier(ExecutionTier tier) {
switch (tier) {
case ExecutionTier::kInterpreter:
return WasmCode::Kind::kInterpreterEntry;
case ExecutionTier::kBaseline:
case ExecutionTier::kOptimized:
return WasmCode::Kind::kFunction;
}
}
} // namespace
WasmCode* NativeModule::AddCompiledCode(WasmCompilationResult result) {
if (!result.succeeded()) {
compilation_state_->SetError();
return nullptr;
}
DCHECK_EQ(result.code_desc.buffer, result.instr_buffer.get());
return AddCode(result.func_index, result.code_desc, result.frame_slot_count,
result.tagged_parameter_slots,
std::move(result.protected_instructions),
std::move(result.source_positions),
GetCodeKindForExecutionTier(result.result_tier),
GetCodeTierForExecutionTier(result.result_tier));
}
void WasmCodeManager::FreeNativeModule(NativeModule* native_module) { void WasmCodeManager::FreeNativeModule(NativeModule* native_module) {
base::MutexGuard lock(&native_modules_mutex_); base::MutexGuard lock(&native_modules_mutex_);
TRACE_HEAP("Freeing NativeModule %p\n", native_module); TRACE_HEAP("Freeing NativeModule %p\n", native_module);
......
...@@ -32,6 +32,7 @@ namespace wasm { ...@@ -32,6 +32,7 @@ namespace wasm {
class NativeModule; class NativeModule;
class WasmCodeManager; class WasmCodeManager;
struct WasmCompilationResult;
class WasmEngine; class WasmEngine;
class WasmMemoryTracker; class WasmMemoryTracker;
class WasmImportWrapperCache; class WasmImportWrapperCache;
...@@ -366,6 +367,8 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -366,6 +367,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
enum CodeSamplingTime : int8_t { kAfterBaseline, kAfterTopTier, kSampling }; enum CodeSamplingTime : int8_t { kAfterBaseline, kAfterTopTier, kSampling };
void SampleCodeSize(Counters*, CodeSamplingTime) const; void SampleCodeSize(Counters*, CodeSamplingTime) const;
WasmCode* AddCompiledCode(WasmCompilationResult);
private: private:
friend class WasmCode; friend class WasmCode;
friend class WasmCodeManager; friend class WasmCodeManager;
......
...@@ -495,7 +495,7 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) { ...@@ -495,7 +495,7 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
WasmCompilationResult result = unit.ExecuteCompilation( WasmCompilationResult result = unit.ExecuteCompilation(
&env, native_module->compilation_state()->GetWireBytesStorage(), &env, native_module->compilation_state()->GetWireBytesStorage(),
isolate()->counters(), &unused_detected_features); isolate()->counters(), &unused_detected_features);
WasmCode* code = unit.Publish(std::move(result), native_module); WasmCode* code = native_module->AddCompiledCode(std::move(result));
DCHECK_NOT_NULL(code); DCHECK_NOT_NULL(code);
if (WasmCode::ShouldBeLogged(isolate())) code->LogCode(isolate()); if (WasmCode::ShouldBeLogged(isolate())) code->LogCode(isolate());
} }
......
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