[wasm] Store whether code was generated for debugging
This adds a flag to {WasmCode} objects to store whether this code was generated for debugging. This flag can be set for Liftoff code (in which case the code will e.g. have an extended prologue for debugging), but it can also be set for TurboFan, in case Liftoff bailed out when producing the debugging code. Having this flag allows us to remove the hack to pass the compilation results to {OnFinishedUnits} just to check whether we actually wanted to compile Liftoff functions. Drive-by: Replace the {ReachedRecompilationTierField} by a {MissingRecompilationField}, because all we need to know is if we are still waiting for that function to get recompiled. R=ahaas@chromium.org Bug: v8:10330,v8:10410 Change-Id: Ia023df8955a60d9f5595a6cb2737e14d83baf716 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2142259 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#67119}
This commit is contained in:
parent
8c6f906725
commit
4721585bee
@ -6626,7 +6626,7 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), wasm::WasmCode::kWasmToCapiWrapper,
|
||||
wasm::ExecutionTier::kNone);
|
||||
wasm::ExecutionTier::kNone, wasm::kNoDebugging);
|
||||
return native_module->PublishCode(std::move(wasm_code));
|
||||
}
|
||||
|
||||
|
@ -3323,6 +3323,7 @@ WasmCompilationResult ExecuteLiftoffCompilation(
|
||||
result.tagged_parameter_slots = call_descriptor->GetTaggedParameterSlots();
|
||||
result.func_index = func_index;
|
||||
result.result_tier = ExecutionTier::kLiftoff;
|
||||
result.for_debugging = for_debugging;
|
||||
if (debug_sidetable) {
|
||||
*debug_sidetable = debug_sidetable_builder->GenerateDebugSideTable();
|
||||
}
|
||||
|
@ -202,6 +202,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation(
|
||||
case ExecutionTier::kTurbofan:
|
||||
result = compiler::ExecuteTurbofanWasmCompilation(
|
||||
wasm_engine, env, func_body, func_index_, counters, detected);
|
||||
result.for_debugging = for_debugging_;
|
||||
break;
|
||||
|
||||
case ExecutionTier::kInterpreter:
|
||||
|
@ -72,6 +72,7 @@ struct WasmCompilationResult {
|
||||
ExecutionTier requested_tier;
|
||||
ExecutionTier result_tier;
|
||||
Kind kind = kFunction;
|
||||
ForDebugging for_debugging = kNoDebugging;
|
||||
};
|
||||
|
||||
class V8_EXPORT_PRIVATE WasmCompilationUnit final {
|
||||
|
@ -409,7 +409,7 @@ class CompilationStateImpl {
|
||||
void FinalizeJSToWasmWrappers(Isolate* isolate, const WasmModule* module,
|
||||
Handle<FixedArray>* export_wrappers_out);
|
||||
|
||||
void OnFinishedUnits(Vector<WasmCode*>, Vector<WasmCompilationResult>);
|
||||
void OnFinishedUnits(Vector<WasmCode*>);
|
||||
void OnFinishedJSToWasmWrapperUnits(int num);
|
||||
|
||||
void OnBackgroundTaskStopped(int task_id, const WasmFeatures& detected);
|
||||
@ -564,7 +564,7 @@ class CompilationStateImpl {
|
||||
using RequiredBaselineTierField = base::BitField8<ExecutionTier, 0, 2>;
|
||||
using RequiredTopTierField = base::BitField8<ExecutionTier, 2, 2>;
|
||||
using ReachedTierField = base::BitField8<ExecutionTier, 4, 2>;
|
||||
using ReachedRecompilationTierField = base::BitField8<ExecutionTier, 6, 2>;
|
||||
using MissingRecompilationField = base::BitField8<bool, 6, 1>;
|
||||
};
|
||||
|
||||
CompilationStateImpl* Impl(CompilationState* compilation_state) {
|
||||
@ -1061,6 +1061,7 @@ bool ExecuteCompilationUnits(
|
||||
std::vector<std::unique_ptr<WasmCode>> unpublished_code =
|
||||
compile_scope->native_module()->AddCompiledCode(
|
||||
VectorOf(results_to_publish));
|
||||
results_to_publish.clear();
|
||||
// TODO(clemensb): Avoid blocking to publish code
|
||||
// (https://crbug.com/v8/10330).
|
||||
std::vector<WasmCode*> code_vector =
|
||||
@ -1070,7 +1071,6 @@ bool ExecuteCompilationUnits(
|
||||
// For import wrapper compilation units, add result to the cache.
|
||||
const NativeModule* native_module = compile_scope->native_module();
|
||||
int num_imported_functions = native_module->num_imported_functions();
|
||||
DCHECK_EQ(code_vector.size(), results_to_publish.size());
|
||||
WasmImportWrapperCache* cache = native_module->import_wrapper_cache();
|
||||
for (WasmCode* code : code_vector) {
|
||||
int func_index = code->index();
|
||||
@ -1092,9 +1092,7 @@ bool ExecuteCompilationUnits(
|
||||
|
||||
native_module->engine()->LogCode(VectorOf(code_vector));
|
||||
|
||||
compile_scope->compilation_state()->OnFinishedUnits(
|
||||
VectorOf(code_vector), VectorOf(results_to_publish));
|
||||
results_to_publish.clear();
|
||||
compile_scope->compilation_state()->OnFinishedUnits(VectorOf(code_vector));
|
||||
};
|
||||
|
||||
bool compilation_failed = false;
|
||||
@ -2548,14 +2546,12 @@ void CompilationStateImpl::InitializeRecompilation(
|
||||
ReachedTierField::decode(compilation_progress_[slot_index]);
|
||||
// Ignore Liftoff code, since we don't know if it was compiled with
|
||||
// debugging support.
|
||||
// TODO(clemensb): Introduce {kLiftoffDebug} as a separate tier.
|
||||
bool has_correct_tier =
|
||||
tier == ExecutionTier::kTurbofan && reached_tier == tier &&
|
||||
native_module_->HasCodeWithTier(function_index, tier);
|
||||
if (!has_correct_tier) {
|
||||
compilation_progress_[slot_index] =
|
||||
ReachedRecompilationTierField::update(
|
||||
compilation_progress_[slot_index], ExecutionTier::kNone);
|
||||
compilation_progress_[slot_index] = MissingRecompilationField::update(
|
||||
compilation_progress_[slot_index], true);
|
||||
outstanding_recompilation_functions_++;
|
||||
builder.AddRecompilationUnit(function_index, tier);
|
||||
}
|
||||
@ -2649,8 +2645,7 @@ CompilationStateImpl::GetNextCompilationUnit(
|
||||
return compilation_unit_queues_.GetNextUnit(task_id, baseline_only);
|
||||
}
|
||||
|
||||
void CompilationStateImpl::OnFinishedUnits(
|
||||
Vector<WasmCode*> code_vector, Vector<WasmCompilationResult> results) {
|
||||
void CompilationStateImpl::OnFinishedUnits(Vector<WasmCode*> code_vector) {
|
||||
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "OnFinishedUnits",
|
||||
"num_units", code_vector.size());
|
||||
|
||||
@ -2715,21 +2710,21 @@ void CompilationStateImpl::OnFinishedUnits(
|
||||
outstanding_top_tier_functions_--;
|
||||
}
|
||||
|
||||
// If there is recompilation in progress, we would only count the
|
||||
// functions which are not Liftoff already, and would only decrement the
|
||||
// counter once a function reaches Liftoff.
|
||||
if (outstanding_recompilation_functions_ > 0) {
|
||||
// TODO(duongn): extend this logic for tier up.
|
||||
ExecutionTier recompilation_tier =
|
||||
ReachedRecompilationTierField::decode(function_progress);
|
||||
if (results[i].requested_tier == recompilation_tier_ &&
|
||||
recompilation_tier == ExecutionTier::kNone) {
|
||||
DCHECK(code->tier() >= recompilation_tier_);
|
||||
if (V8_UNLIKELY(outstanding_recompilation_functions_ > 0) &&
|
||||
MissingRecompilationField::decode(function_progress)) {
|
||||
// If tiering up, accept any TurboFan code. For tiering down, look at
|
||||
// the {for_debugging} flag. The tier can be Liftoff or TurboFan and is
|
||||
// irrelevant here. In particular, we want to ignore any outstanding
|
||||
// non-debugging units.
|
||||
// TODO(clemensb): Replace {recompilation_tier_} by a better flag.
|
||||
bool matches = recompilation_tier_ == ExecutionTier::kLiftoff
|
||||
? code->for_debugging()
|
||||
: code->tier() == ExecutionTier::kTurbofan;
|
||||
if (matches) {
|
||||
outstanding_recompilation_functions_--;
|
||||
// Update function's recompilation progress.
|
||||
compilation_progress_[slot_index] =
|
||||
ReachedRecompilationTierField::update(
|
||||
compilation_progress_[slot_index], code->tier());
|
||||
compilation_progress_[slot_index] = MissingRecompilationField::update(
|
||||
compilation_progress_[slot_index], false);
|
||||
if (outstanding_recompilation_functions_ == 0) {
|
||||
triggered_events.Add(CompilationEvent::kFinishedRecompilation);
|
||||
}
|
||||
@ -2988,7 +2983,7 @@ WasmCode* CompileImportWrapper(
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), GetCodeKind(result),
|
||||
ExecutionTier::kNone);
|
||||
ExecutionTier::kNone, kNoDebugging);
|
||||
WasmCode* published_code = native_module->PublishCode(std::move(wasm_code));
|
||||
(*cache_scope)[key] = published_code;
|
||||
published_code->IncRef();
|
||||
|
@ -896,7 +896,8 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
|
||||
reloc_info.as_vector(), // reloc_info
|
||||
source_pos.as_vector(), // source positions
|
||||
WasmCode::kFunction, // kind
|
||||
ExecutionTier::kNone}}; // tier
|
||||
ExecutionTier::kNone, // tier
|
||||
kNoDebugging}}; // for_debugging
|
||||
new_code->MaybePrint(nullptr);
|
||||
new_code->Validate();
|
||||
|
||||
@ -942,23 +943,23 @@ std::unique_ptr<WasmCode> NativeModule::AddCode(
|
||||
int index, const CodeDesc& desc, int stack_slots,
|
||||
int tagged_parameter_slots, Vector<const byte> protected_instructions_data,
|
||||
Vector<const byte> source_position_table, WasmCode::Kind kind,
|
||||
ExecutionTier tier) {
|
||||
ExecutionTier tier, ForDebugging for_debugging) {
|
||||
Vector<byte> code_space =
|
||||
code_allocator_.AllocateForCode(this, desc.instr_size);
|
||||
auto jump_table_ref =
|
||||
FindJumpTablesForRegion(base::AddressRegionOf(code_space));
|
||||
return AddCodeWithCodeSpace(index, desc, stack_slots, tagged_parameter_slots,
|
||||
protected_instructions_data,
|
||||
source_position_table, kind, tier, code_space,
|
||||
jump_table_ref);
|
||||
source_position_table, kind, tier, for_debugging,
|
||||
code_space, jump_table_ref);
|
||||
}
|
||||
|
||||
std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
|
||||
int index, const CodeDesc& desc, int stack_slots,
|
||||
int tagged_parameter_slots, Vector<const byte> protected_instructions_data,
|
||||
Vector<const byte> source_position_table, WasmCode::Kind kind,
|
||||
ExecutionTier tier, Vector<uint8_t> dst_code_bytes,
|
||||
const JumpTablesRef& jump_tables) {
|
||||
ExecutionTier tier, ForDebugging for_debugging,
|
||||
Vector<uint8_t> dst_code_bytes, const JumpTablesRef& jump_tables) {
|
||||
Vector<byte> reloc_info{desc.buffer + desc.buffer_size - desc.reloc_size,
|
||||
static_cast<size_t>(desc.reloc_size)};
|
||||
|
||||
@ -1008,7 +1009,7 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace(
|
||||
this, index, dst_code_bytes, stack_slots, tagged_parameter_slots,
|
||||
safepoint_table_offset, handler_table_offset, constant_pool_offset,
|
||||
code_comments_offset, instr_size, protected_instructions_data, reloc_info,
|
||||
source_position_table, kind, tier}};
|
||||
source_position_table, kind, tier, for_debugging}};
|
||||
code->MaybePrint();
|
||||
code->Validate();
|
||||
|
||||
@ -1120,7 +1121,7 @@ WasmCode* NativeModule::AddDeserializedCode(
|
||||
this, index, dst_code_bytes, stack_slots, tagged_parameter_slots,
|
||||
safepoint_table_offset, handler_table_offset, constant_pool_offset,
|
||||
code_comments_offset, unpadded_binary_size, protected_instructions_data,
|
||||
reloc_info, source_position_table, kind, tier}};
|
||||
reloc_info, source_position_table, kind, tier, kNoDebugging}};
|
||||
|
||||
// Note: we do not flush the i-cache here, since the code needs to be
|
||||
// relocated anyway. The caller is responsible for flushing the i-cache later.
|
||||
@ -1172,21 +1173,22 @@ WasmCode* NativeModule::CreateEmptyJumpTableInRegion(
|
||||
DCHECK(!code_space.empty());
|
||||
ZapCode(reinterpret_cast<Address>(code_space.begin()), code_space.size());
|
||||
std::unique_ptr<WasmCode> code{
|
||||
new WasmCode{this, // native_module
|
||||
kAnonymousFuncIndex, // index
|
||||
code_space, // instructions
|
||||
0, // stack_slots
|
||||
0, // tagged_parameter_slots
|
||||
0, // safepoint_table_offset
|
||||
jump_table_size, // handler_table_offset
|
||||
jump_table_size, // constant_pool_offset
|
||||
jump_table_size, // code_comments_offset
|
||||
jump_table_size, // unpadded_binary_size
|
||||
{}, // protected_instructions
|
||||
{}, // reloc_info
|
||||
{}, // source_pos
|
||||
WasmCode::kJumpTable, // kind
|
||||
ExecutionTier::kNone}}; // tier
|
||||
new WasmCode{this, // native_module
|
||||
kAnonymousFuncIndex, // index
|
||||
code_space, // instructions
|
||||
0, // stack_slots
|
||||
0, // tagged_parameter_slots
|
||||
0, // safepoint_table_offset
|
||||
jump_table_size, // handler_table_offset
|
||||
jump_table_size, // constant_pool_offset
|
||||
jump_table_size, // code_comments_offset
|
||||
jump_table_size, // unpadded_binary_size
|
||||
{}, // protected_instructions
|
||||
{}, // reloc_info
|
||||
{}, // source_pos
|
||||
WasmCode::kJumpTable, // kind
|
||||
ExecutionTier::kNone, // tier
|
||||
kNoDebugging}}; // for_debugging
|
||||
return PublishCode(std::move(code));
|
||||
}
|
||||
|
||||
@ -1819,7 +1821,8 @@ std::vector<std::unique_ptr<WasmCode>> NativeModule::AddCompiledCode(
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), GetCodeKind(result),
|
||||
result.result_tier, this_code_space, jump_tables));
|
||||
result.result_tier, result.for_debugging, this_code_space,
|
||||
jump_tables));
|
||||
}
|
||||
DCHECK_EQ(0, code_space.size());
|
||||
|
||||
|
@ -225,6 +225,10 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
||||
// Returns the last source position before {offset}.
|
||||
int GetSourcePositionBefore(int offset);
|
||||
|
||||
// Returns whether this code was generated for debugging. If this returns
|
||||
// true, but {tier()} is not {kLiftoff}, then Liftoff compilation bailed out.
|
||||
bool for_debugging() const { return ForDebuggingField::decode(flags_); }
|
||||
|
||||
enum FlushICache : bool { kFlushICache = true, kNoFlushICache = false };
|
||||
|
||||
private:
|
||||
@ -238,10 +242,11 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
||||
Vector<const byte> protected_instructions_data,
|
||||
Vector<const byte> reloc_info,
|
||||
Vector<const byte> source_position_table, Kind kind,
|
||||
ExecutionTier tier)
|
||||
ExecutionTier tier, ForDebugging for_debugging)
|
||||
: native_module_(native_module),
|
||||
instructions_(instructions.begin()),
|
||||
flags_(KindField::encode(kind) | ExecutionTierField::encode(tier)),
|
||||
flags_(KindField::encode(kind) | ExecutionTierField::encode(tier) |
|
||||
ForDebuggingField::encode(for_debugging)),
|
||||
meta_data_(ConcatenateBytes(
|
||||
{protected_instructions_data, reloc_info, source_position_table})),
|
||||
instructions_size_(instructions.length()),
|
||||
@ -315,7 +320,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
||||
// Bits encoded in {flags_}:
|
||||
using KindField = base::BitField8<Kind, 0, 3>;
|
||||
using ExecutionTierField = KindField::Next<ExecutionTier, 2>;
|
||||
// TODO(clemensb): Add "is_debug" flag.
|
||||
using ForDebuggingField = ExecutionTierField::Next<ForDebugging, 1>;
|
||||
|
||||
// WasmCode is ref counted. Counters are held by:
|
||||
// 1) The jump table / code table.
|
||||
@ -447,7 +452,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
||||
int stack_slots, int tagged_parameter_slots,
|
||||
Vector<const byte> protected_instructions,
|
||||
Vector<const byte> source_position_table,
|
||||
WasmCode::Kind kind, ExecutionTier tier);
|
||||
WasmCode::Kind kind, ExecutionTier tier,
|
||||
ForDebugging for_debugging);
|
||||
|
||||
// {PublishCode} makes the code available to the system by entering it into
|
||||
// the code table and patching the jump table. It returns a raw pointer to the
|
||||
@ -630,8 +636,8 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
||||
int tagged_parameter_slots,
|
||||
Vector<const byte> protected_instructions_data,
|
||||
Vector<const byte> source_position_table, WasmCode::Kind kind,
|
||||
ExecutionTier tier, Vector<uint8_t> code_space,
|
||||
const JumpTablesRef& jump_tables_ref);
|
||||
ExecutionTier tier, ForDebugging for_debugging,
|
||||
Vector<uint8_t> code_space, const JumpTablesRef& jump_tables_ref);
|
||||
|
||||
WasmCode* CreateEmptyJumpTableInRegion(
|
||||
int jump_table_size, base::AddressRegion,
|
||||
|
@ -1124,7 +1124,7 @@ void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info,
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), wasm::WasmCode::kInterpreterEntry,
|
||||
wasm::ExecutionTier::kInterpreter);
|
||||
wasm::ExecutionTier::kInterpreter, wasm::kNoDebugging);
|
||||
native_module->PublishCode(std::move(wasm_code));
|
||||
DCHECK(native_module->IsRedirectedToInterpreter(func_index));
|
||||
}
|
||||
|
@ -1455,7 +1455,7 @@ void WasmInstanceObject::ImportWasmJSFunctionIntoTable(
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), GetCodeKind(result),
|
||||
wasm::ExecutionTier::kNone);
|
||||
wasm::ExecutionTier::kNone, wasm::kNoDebugging);
|
||||
wasm::WasmCode* published_code =
|
||||
native_module->PublishCode(std::move(wasm_code));
|
||||
isolate->counters()->wasm_generated_code_size()->Increment(
|
||||
|
@ -3752,9 +3752,9 @@ TEST(Liftoff_tier_up) {
|
||||
memcpy(buffer.get(), sub_code->instructions().begin(), sub_size);
|
||||
desc.buffer = buffer.get();
|
||||
desc.instr_size = static_cast<int>(sub_size);
|
||||
std::unique_ptr<WasmCode> new_code =
|
||||
native_module->AddCode(add.function_index(), desc, 0, 0, {}, {},
|
||||
WasmCode::kFunction, ExecutionTier::kTurbofan);
|
||||
std::unique_ptr<WasmCode> new_code = native_module->AddCode(
|
||||
add.function_index(), desc, 0, 0, {}, {}, WasmCode::kFunction,
|
||||
ExecutionTier::kTurbofan, kNoDebugging);
|
||||
native_module->PublishCode(std::move(new_code));
|
||||
|
||||
// Second run should now execute {sub}.
|
||||
|
@ -178,7 +178,7 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
|
||||
result.tagged_parameter_slots,
|
||||
result.protected_instructions_data.as_vector(),
|
||||
result.source_positions.as_vector(), wasm::WasmCode::kInterpreterEntry,
|
||||
wasm::ExecutionTier::kInterpreter);
|
||||
wasm::ExecutionTier::kInterpreter, wasm::kNoDebugging);
|
||||
native_module_->PublishCode(std::move(code));
|
||||
}
|
||||
DCHECK_LT(index, kMaxFunctions); // limited for testing.
|
||||
|
@ -4,7 +4,10 @@
|
||||
|
||||
// Flags: --experimental-wasm-anyref
|
||||
|
||||
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
// Test that tiering up and tiering down works even if functions cannot be
|
||||
// compiled with Liftoff.
|
||||
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
// Create a simple Wasm module.
|
||||
function create_builder(i) {
|
||||
|
Loading…
Reference in New Issue
Block a user