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(
result.protected_instructions = code_generator->GetProtectedInstructions();
result.frame_slot_count = code_generator->frame()->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.result_tier = wasm::ExecutionTier::kOptimized;
DCHECK(result.succeeded());
......@@ -2484,6 +2485,7 @@ void Pipeline::GenerateCodeForWasmFunction(
result->tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result->source_positions = code_generator->GetSourcePositionTable();
result->protected_instructions = code_generator->GetProtectedInstructions();
result->result_tier = wasm::ExecutionTier::kOptimized;
if (data.info()->trace_turbo_json_enabled()) {
TurboJsonFile json_of(data.info(), std::ios_base::app);
......
......@@ -6000,6 +6000,7 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry(
wasm_engine, incoming, &jsgraph, Code::WASM_INTERPRETER_ENTRY,
wasm::WasmCode::kInterpreterEntry, func_name.start(),
WasmStubAssemblerOptions());
result.result_tier = wasm::ExecutionTier::kInterpreter;
return result;
}
......
......@@ -2029,6 +2029,7 @@ WasmCompilationResult LiftoffCompilationUnit::ExecuteCompilation(
result.protected_instructions = compiler->GetProtectedInstructions();
result.frame_slot_count = compiler->GetTotalFrameSlotCount();
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
result.result_tier = ExecutionTier::kBaseline;
DCHECK(result.succeeded());
return result;
......
......@@ -16,18 +16,6 @@ namespace wasm {
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 {
public:
class View : public AssemblerBuffer {
......@@ -129,7 +117,7 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier(
WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine, int index,
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 &&
(FLAG_wasm_tier_mask_for_testing & (1 << index))) {
tier = ExecutionTier::kOptimized;
......@@ -157,31 +145,37 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation(
wasm_compile, function_time);
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) {
PrintF("Compiling wasm function %d with %s\n\n", func_index_,
GetExecutionTierAsString(executed_tier_));
const char* tier =
liftoff_unit_ ? "liftoff" : turbofan_unit_ ? "turbofan" : "interpreter";
PrintF("Compiling wasm function %d with %s\n\n", func_index_, tier);
}
WasmCompilationResult result;
switch (executed_tier_) {
case ExecutionTier::kBaseline:
result =
liftoff_unit_->ExecuteCompilation(env, func_body, counters, detected);
if (result.succeeded()) break;
// Otherwise, fall back to turbofan.
SwitchTier(ExecutionTier::kOptimized);
if (liftoff_unit_) {
result =
liftoff_unit_->ExecuteCompilation(env, func_body, counters, detected);
if (!result.succeeded()) {
// If Liftoff failed, fall back to turbofan.
// TODO(wasm): We could actually stop or remove the tiering unit for this
// function to avoid compiling it twice with TurboFan.
V8_FALLTHROUGH;
case ExecutionTier::kOptimized:
result = turbofan_unit_->ExecuteCompilation(env, func_body, counters,
detected);
break;
case ExecutionTier::kInterpreter:
result = interpreter_unit_->ExecuteCompilation(env, func_body, counters,
detected);
break;
SwitchTier(ExecutionTier::kOptimized);
DCHECK_NOT_NULL(turbofan_unit_);
}
}
if (turbofan_unit_) {
result =
turbofan_unit_->ExecuteCompilation(env, func_body, counters, detected);
}
if (interpreter_unit_) {
result = interpreter_unit_->ExecuteCompilation(env, func_body, counters,
detected);
}
result.func_index = func_index_;
result.requested_tier = tier_;
if (result.succeeded()) {
counters->wasm_generated_code_size()->Increment(
......@@ -192,34 +186,11 @@ WasmCompilationResult WasmCompilationUnit::ExecuteCompilation(
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) {
// This method is being called in the constructor, where neither
// {liftoff_unit_} nor {turbofan_unit_} nor {interpreter_unit_} are set, or to
// switch tier from kLiftoff to kTurbofan, in which case {liftoff_unit_} is
// already set.
executed_tier_ = new_tier;
switch (new_tier) {
case ExecutionTier::kBaseline:
DCHECK(!turbofan_unit_);
......@@ -259,7 +230,7 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate,
WasmCompilationResult result = unit.ExecuteCompilation(
&env, native_module->compilation_state()->GetWireBytesStorage(),
isolate->counters(), detected);
unit.Publish(std::move(result), native_module);
native_module->AddCompiledCode(std::move(result));
}
} // namespace wasm
......
......@@ -60,17 +60,15 @@ struct WasmCompilationResult {
uint32_t tagged_parameter_slots = 0;
OwnedVector<byte> source_positions;
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions;
int func_index;
ExecutionTier requested_tier;
ExecutionTier result_tier;
};
class WasmCompilationUnit final {
public:
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();
......@@ -79,10 +77,7 @@ class WasmCompilationUnit final {
CompilationEnv*, const std::shared_ptr<WireBytesStorage>&, Counters*,
WasmFeatures* detected);
WasmCode* Publish(WasmCompilationResult, NativeModule*);
ExecutionTier requested_tier() const { return requested_tier_; }
ExecutionTier executed_tier() const { return executed_tier_; }
ExecutionTier tier() const { return tier_; }
static void CompileWasmFunction(Isolate*, NativeModule*,
WasmFeatures* detected, const WasmFunction*,
......@@ -95,8 +90,7 @@ class WasmCompilationUnit final {
WasmEngine* const wasm_engine_;
const int func_index_;
ExecutionTier requested_tier_;
ExecutionTier executed_tier_;
ExecutionTier tier_;
// LiftoffCompilationUnit, set if {tier_ == kLiftoff}.
std::unique_ptr<LiftoffCompilationUnit> liftoff_unit_;
......
......@@ -322,7 +322,7 @@ void CompileLazy(Isolate* isolate, NativeModule* native_module,
&env, native_module->compilation_state()->GetWireBytesStorage(),
isolate->counters(),
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
// was verified before starting execution with lazy compilation.
......@@ -437,8 +437,8 @@ bool FetchAndExecuteCompilationUnit(CompilationEnv* env,
WasmCompilationResult result = unit->ExecuteCompilation(
env, compilation_state->GetWireBytesStorage(), counters, detected);
WasmCode* code = unit->Publish(std::move(result), native_module);
compilation_state->OnFinishedUnit(unit->requested_tier(), code);
WasmCode* code = native_module->AddCompiledCode(std::move(result));
compilation_state->OnFinishedUnit(result.requested_tier, code);
return true;
}
......@@ -658,7 +658,7 @@ class BackgroundCompileTask : public CancelableTask {
BackgroundCompileScope compile_scope(token_);
if (compile_scope.cancelled()) return;
WasmCode* code =
unit->Publish(std::move(result), compile_scope.native_module());
compile_scope.native_module()->AddCompiledCode(std::move(result));
if (code == nullptr) {
// Compile error.
compile_scope.compilation_state()->OnBackgroundTaskStopped(
......@@ -668,8 +668,8 @@ class BackgroundCompileTask : public CancelableTask {
}
// Successfully finished one unit.
compile_scope.compilation_state()->OnFinishedUnit(
unit->requested_tier(), code);
compile_scope.compilation_state()->OnFinishedUnit(result.requested_tier,
code);
if (deadline < MonotonicallyIncreasingTimeInMs()) {
compile_scope.compilation_state()->ReportDetectedFeatures(
detected_features);
......@@ -1518,8 +1518,7 @@ void CompilationStateImpl::AddCompilationUnits(
if (compile_mode_ == CompileMode::kTiering) {
DCHECK_EQ(baseline_units.size(), tiering_units.size());
DCHECK_EQ(tiering_units.back()->requested_tier(),
ExecutionTier::kOptimized);
DCHECK_EQ(tiering_units.back()->tier(), ExecutionTier::kOptimized);
tiering_compilation_units_.insert(
tiering_compilation_units_.end(),
std::make_move_iterator(tiering_units.begin()),
......
......@@ -1199,6 +1199,44 @@ void NativeModule::SampleCodeSize(
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) {
base::MutexGuard lock(&native_modules_mutex_);
TRACE_HEAP("Freeing NativeModule %p\n", native_module);
......
......@@ -32,6 +32,7 @@ namespace wasm {
class NativeModule;
class WasmCodeManager;
struct WasmCompilationResult;
class WasmEngine;
class WasmMemoryTracker;
class WasmImportWrapperCache;
......@@ -366,6 +367,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
enum CodeSamplingTime : int8_t { kAfterBaseline, kAfterTopTier, kSampling };
void SampleCodeSize(Counters*, CodeSamplingTime) const;
WasmCode* AddCompiledCode(WasmCompilationResult);
private:
friend class WasmCode;
friend class WasmCodeManager;
......
......@@ -495,7 +495,7 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
WasmCompilationResult result = unit.ExecuteCompilation(
&env, native_module->compilation_state()->GetWireBytesStorage(),
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);
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