[maglev] Use accessors for DeoptInfo fields
... so that we can add logic to them later for builtin continuation deopts. Bug: v8:7700 Change-Id: I03a616243efecb5d637d6ab7d078392a0c51abf4 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3985907 Reviewed-by: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Auto-Submit: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/main@{#83953}
This commit is contained in:
parent
8852999115
commit
4d8055d41e
@ -72,7 +72,7 @@ Register MaglevAssembler::FromAnyToRegister(const Input& input,
|
||||
}
|
||||
|
||||
inline void MaglevAssembler::DefineLazyDeoptPoint(LazyDeoptInfo* info) {
|
||||
info->deopting_call_return_pc = pc_offset_for_safepoint();
|
||||
info->set_deopting_call_return_pc(pc_offset_for_safepoint());
|
||||
code_gen_state()->PushLazyDeopt(info);
|
||||
safepoint_table_builder()->DefineSafepoint(this);
|
||||
}
|
||||
@ -274,12 +274,12 @@ inline void MaglevAssembler::JumpToDeferredIf(Condition cond,
|
||||
|
||||
inline void MaglevAssembler::RegisterEagerDeopt(EagerDeoptInfo* deopt_info,
|
||||
DeoptimizeReason reason) {
|
||||
if (deopt_info->reason != DeoptimizeReason::kUnknown) {
|
||||
DCHECK_EQ(deopt_info->reason, reason);
|
||||
if (deopt_info->reason() != DeoptimizeReason::kUnknown) {
|
||||
DCHECK_EQ(deopt_info->reason(), reason);
|
||||
}
|
||||
if (deopt_info->deopt_entry_label.is_unused()) {
|
||||
if (deopt_info->deopt_entry_label()->is_unused()) {
|
||||
code_gen_state()->PushEagerDeopt(deopt_info);
|
||||
deopt_info->reason = reason;
|
||||
deopt_info->set_reason(reason);
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,7 +289,7 @@ inline void MaglevAssembler::EmitEagerDeopt(NodeT* node,
|
||||
static_assert(NodeT::kProperties.can_eager_deopt());
|
||||
RegisterEagerDeopt(node->eager_deopt_info(), reason);
|
||||
RecordComment("-- Jump to eager deopt");
|
||||
jmp(&node->eager_deopt_info()->deopt_entry_label);
|
||||
jmp(node->eager_deopt_info()->deopt_entry_label());
|
||||
}
|
||||
|
||||
template <typename NodeT>
|
||||
@ -299,7 +299,7 @@ inline void MaglevAssembler::EmitEagerDeoptIf(Condition cond,
|
||||
static_assert(NodeT::kProperties.can_eager_deopt());
|
||||
RegisterEagerDeopt(node->eager_deopt_info(), reason);
|
||||
RecordComment("-- Jump to eager deopt");
|
||||
j(cond, &node->eager_deopt_info()->deopt_entry_label);
|
||||
j(cond, node->eager_deopt_info()->deopt_entry_label());
|
||||
}
|
||||
|
||||
} // namespace maglev
|
||||
|
@ -484,8 +484,9 @@ class ExceptionHandlerTrampolineBuilder {
|
||||
ParallelMoveResolver<Register> direct_moves(masm_);
|
||||
MoveVector materialising_moves;
|
||||
bool save_accumulator = false;
|
||||
RecordMoves(deopt_info->unit, catch_block, deopt_info->state.register_frame,
|
||||
&direct_moves, &materialising_moves, &save_accumulator);
|
||||
RecordMoves(deopt_info->unit(), catch_block,
|
||||
deopt_info->state().register_frame, &direct_moves,
|
||||
&materialising_moves, &save_accumulator);
|
||||
|
||||
__ bind(&handler_info->trampoline_entry);
|
||||
__ RecordComment("-- Exception handler trampoline START");
|
||||
@ -990,33 +991,33 @@ class MaglevTranslationArrayBuilder {
|
||||
deopt_literals_(deopt_literals) {}
|
||||
|
||||
void BuildEagerDeopt(EagerDeoptInfo* deopt_info) {
|
||||
int frame_count = 1 + deopt_info->unit.inlining_depth();
|
||||
int frame_count = 1 + deopt_info->unit().inlining_depth();
|
||||
int jsframe_count = frame_count;
|
||||
int update_feedback_count = 0;
|
||||
deopt_info->translation_index =
|
||||
deopt_info->set_translation_index(
|
||||
translation_array_builder_->BeginTranslation(frame_count, jsframe_count,
|
||||
update_feedback_count);
|
||||
update_feedback_count));
|
||||
|
||||
const InputLocation* current_input_location = deopt_info->input_locations;
|
||||
BuildDeoptFrame(deopt_info->unit, deopt_info->state,
|
||||
const InputLocation* current_input_location = deopt_info->input_locations();
|
||||
BuildDeoptFrame(deopt_info->unit(), deopt_info->state(),
|
||||
current_input_location);
|
||||
}
|
||||
|
||||
void BuildLazyDeopt(LazyDeoptInfo* deopt_info) {
|
||||
int frame_count = 1 + deopt_info->unit.inlining_depth();
|
||||
int frame_count = 1 + deopt_info->unit().inlining_depth();
|
||||
int jsframe_count = frame_count;
|
||||
int update_feedback_count = 0;
|
||||
deopt_info->translation_index =
|
||||
deopt_info->set_translation_index(
|
||||
translation_array_builder_->BeginTranslation(frame_count, jsframe_count,
|
||||
update_feedback_count);
|
||||
update_feedback_count));
|
||||
|
||||
const MaglevCompilationUnit& unit = deopt_info->unit;
|
||||
const InputLocation* current_input_location = deopt_info->input_locations;
|
||||
const MaglevCompilationUnit& unit = deopt_info->unit();
|
||||
const InputLocation* current_input_location = deopt_info->input_locations();
|
||||
|
||||
if (deopt_info->state.parent) {
|
||||
if (deopt_info->state().parent) {
|
||||
// Deopt input locations are in the order of deopt frame emission, so
|
||||
// update the pointer after emitting the parent frame.
|
||||
BuildDeoptFrame(*unit.caller(), *deopt_info->state.parent,
|
||||
BuildDeoptFrame(*unit.caller(), *deopt_info->state().parent,
|
||||
current_input_location);
|
||||
}
|
||||
|
||||
@ -1024,10 +1025,10 @@ class MaglevTranslationArrayBuilder {
|
||||
// is the array [parameters..., locals..., accumulator]. Since it's the end,
|
||||
// we don't need to worry about earlier frames.
|
||||
int return_offset;
|
||||
if (deopt_info->result_location ==
|
||||
if (deopt_info->result_location() ==
|
||||
interpreter::Register::virtual_accumulator()) {
|
||||
return_offset = 0;
|
||||
} else if (deopt_info->result_location.is_parameter()) {
|
||||
} else if (deopt_info->result_location().is_parameter()) {
|
||||
// This is slightly tricky to reason about because of zero indexing and
|
||||
// fence post errors. As an example, consider a frame with 2 locals and
|
||||
// 2 parameters, where we want argument index 1 -- looking at the array
|
||||
@ -1037,19 +1038,19 @@ class MaglevTranslationArrayBuilder {
|
||||
// and this calculation gives, correctly:
|
||||
// 2 + 2 - 1 = 3
|
||||
return_offset = unit.register_count() + unit.parameter_count() -
|
||||
deopt_info->result_location.ToParameterIndex();
|
||||
deopt_info->result_location().ToParameterIndex();
|
||||
} else {
|
||||
return_offset =
|
||||
unit.register_count() - deopt_info->result_location.index();
|
||||
unit.register_count() - deopt_info->result_location().index();
|
||||
}
|
||||
translation_array_builder_->BeginInterpretedFrame(
|
||||
deopt_info->state.bytecode_position,
|
||||
deopt_info->state().bytecode_position,
|
||||
GetDeoptLiteral(*unit.shared_function_info().object()),
|
||||
unit.register_count(), return_offset, deopt_info->result_size);
|
||||
unit.register_count(), return_offset, deopt_info->result_size());
|
||||
|
||||
BuildDeoptFrameValues(unit, deopt_info->state.register_frame,
|
||||
current_input_location, deopt_info->result_location,
|
||||
deopt_info->result_size);
|
||||
BuildDeoptFrameValues(unit, deopt_info->state().register_frame,
|
||||
current_input_location, deopt_info->result_location(),
|
||||
deopt_info->result_size());
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1295,12 +1296,12 @@ void MaglevCodeGenerator::EmitDeopts() {
|
||||
translation_builder.BuildEagerDeopt(deopt_info);
|
||||
|
||||
if (masm_.compilation_info()->collect_source_positions()) {
|
||||
__ RecordDeoptReason(deopt_info->reason, 0, deopt_info->source_position,
|
||||
deopt_index);
|
||||
__ RecordDeoptReason(deopt_info->reason(), 0,
|
||||
deopt_info->source_position(), deopt_index);
|
||||
}
|
||||
__ bind(&deopt_info->deopt_entry_label);
|
||||
__ bind(deopt_info->deopt_entry_label());
|
||||
__ CallForDeoptimization(Builtin::kDeoptimizationEntry_Eager, deopt_index,
|
||||
&deopt_info->deopt_entry_label,
|
||||
deopt_info->deopt_entry_label(),
|
||||
DeoptimizeKind::kEager, nullptr, nullptr);
|
||||
deopt_index++;
|
||||
}
|
||||
@ -1313,16 +1314,16 @@ void MaglevCodeGenerator::EmitDeopts() {
|
||||
|
||||
if (masm_.compilation_info()->collect_source_positions()) {
|
||||
__ RecordDeoptReason(DeoptimizeReason::kUnknown, 0,
|
||||
deopt_info->source_position, deopt_index);
|
||||
deopt_info->source_position(), deopt_index);
|
||||
}
|
||||
__ bind(&deopt_info->deopt_entry_label);
|
||||
__ bind(deopt_info->deopt_entry_label());
|
||||
__ CallForDeoptimization(Builtin::kDeoptimizationEntry_Lazy, deopt_index,
|
||||
&deopt_info->deopt_entry_label,
|
||||
deopt_info->deopt_entry_label(),
|
||||
DeoptimizeKind::kLazy, nullptr, nullptr);
|
||||
|
||||
last_updated_safepoint = safepoint_table_builder_.UpdateDeoptimizationInfo(
|
||||
deopt_info->deopting_call_return_pc,
|
||||
deopt_info->deopt_entry_label.pos(), last_updated_safepoint,
|
||||
deopt_info->deopting_call_return_pc(),
|
||||
deopt_info->deopt_entry_label()->pos(), last_updated_safepoint,
|
||||
deopt_index);
|
||||
deopt_index++;
|
||||
}
|
||||
@ -1430,22 +1431,22 @@ Handle<DeoptimizationData> MaglevCodeGenerator::GenerateDeoptimizationData(
|
||||
// Populate deoptimization entries.
|
||||
int i = 0;
|
||||
for (EagerDeoptInfo* deopt_info : code_gen_state_.eager_deopts()) {
|
||||
DCHECK_NE(deopt_info->translation_index, -1);
|
||||
raw_data.SetBytecodeOffset(i, deopt_info->state.bytecode_position);
|
||||
DCHECK_NE(deopt_info->translation_index(), -1);
|
||||
raw_data.SetBytecodeOffset(i, deopt_info->state().bytecode_position);
|
||||
raw_data.SetTranslationIndex(i,
|
||||
Smi::FromInt(deopt_info->translation_index));
|
||||
raw_data.SetPc(i, Smi::FromInt(deopt_info->deopt_entry_label.pos()));
|
||||
Smi::FromInt(deopt_info->translation_index()));
|
||||
raw_data.SetPc(i, Smi::FromInt(deopt_info->deopt_entry_label()->pos()));
|
||||
#ifdef DEBUG
|
||||
raw_data.SetNodeId(i, Smi::FromInt(i));
|
||||
#endif // DEBUG
|
||||
i++;
|
||||
}
|
||||
for (LazyDeoptInfo* deopt_info : code_gen_state_.lazy_deopts()) {
|
||||
DCHECK_NE(deopt_info->translation_index, -1);
|
||||
raw_data.SetBytecodeOffset(i, deopt_info->state.bytecode_position);
|
||||
DCHECK_NE(deopt_info->translation_index(), -1);
|
||||
raw_data.SetBytecodeOffset(i, deopt_info->state().bytecode_position);
|
||||
raw_data.SetTranslationIndex(i,
|
||||
Smi::FromInt(deopt_info->translation_index));
|
||||
raw_data.SetPc(i, Smi::FromInt(deopt_info->deopt_entry_label.pos()));
|
||||
Smi::FromInt(deopt_info->translation_index()));
|
||||
raw_data.SetPc(i, Smi::FromInt(deopt_info->deopt_entry_label()->pos()));
|
||||
#ifdef DEBUG
|
||||
raw_data.SetNodeId(i, Smi::FromInt(i));
|
||||
#endif // DEBUG
|
||||
|
@ -859,10 +859,7 @@ class MaglevGraphBuilder {
|
||||
DCHECK_EQ(NodeT::kProperties.can_lazy_deopt(),
|
||||
value->properties().can_lazy_deopt());
|
||||
if constexpr (NodeT::kProperties.can_lazy_deopt()) {
|
||||
DCHECK(result_location.is_valid());
|
||||
DCHECK(!value->lazy_deopt_info()->result_location.is_valid());
|
||||
value->lazy_deopt_info()->result_location = result_location;
|
||||
value->lazy_deopt_info()->result_size = result_size;
|
||||
value->lazy_deopt_info()->SetResultLocation(result_location, result_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,8 +405,8 @@ void PrintEagerDeopt(std::ostream& os, std::vector<BasicBlock*> targets,
|
||||
NodeBase* node, MaglevGraphLabeller* graph_labeller,
|
||||
int max_node_id) {
|
||||
EagerDeoptInfo* deopt_info = node->eager_deopt_info();
|
||||
InputLocation* current_input_location = deopt_info->input_locations;
|
||||
RecursivePrintEagerDeopt(os, targets, deopt_info->state, deopt_info->unit,
|
||||
InputLocation* current_input_location = deopt_info->input_locations();
|
||||
RecursivePrintEagerDeopt(os, targets, deopt_info->state(), deopt_info->unit(),
|
||||
graph_labeller, max_node_id, current_input_location);
|
||||
}
|
||||
|
||||
@ -454,20 +454,20 @@ void PrintLazyDeopt(std::ostream& os, std::vector<BasicBlock*> targets,
|
||||
NodeT* node, MaglevGraphLabeller* graph_labeller,
|
||||
int max_node_id) {
|
||||
LazyDeoptInfo* deopt_info = node->lazy_deopt_info();
|
||||
InputLocation* current_input_location = deopt_info->input_locations;
|
||||
if (deopt_info->state.parent) {
|
||||
RecursivePrintLazyDeopt(os, targets, *deopt_info->state.parent,
|
||||
*deopt_info->unit.caller(), graph_labeller,
|
||||
InputLocation* current_input_location = deopt_info->input_locations();
|
||||
if (deopt_info->state().parent) {
|
||||
RecursivePrintLazyDeopt(os, targets, *deopt_info->state().parent,
|
||||
*deopt_info->unit().caller(), graph_labeller,
|
||||
max_node_id, current_input_location);
|
||||
}
|
||||
|
||||
PrintVerticalArrows(os, targets);
|
||||
PrintPadding(os, graph_labeller, max_node_id, 0);
|
||||
|
||||
os << " ↳ lazy @" << deopt_info->state.bytecode_position << " : {";
|
||||
os << " ↳ lazy @" << deopt_info->state().bytecode_position << " : {";
|
||||
bool first = true;
|
||||
deopt_info->state.register_frame->ForEachValue(
|
||||
deopt_info->unit, [&](ValueNode* node, interpreter::Register reg) {
|
||||
deopt_info->state().register_frame->ForEachValue(
|
||||
deopt_info->unit(), [&](ValueNode* node, interpreter::Register reg) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
@ -513,8 +513,8 @@ void PrintExceptionHandlerPoint(std::ostream& os,
|
||||
|
||||
os << " ↳ throw @" << handler_offset << " : {";
|
||||
bool first = true;
|
||||
deopt_info->state.register_frame->ForEachValue(
|
||||
deopt_info->unit, [&](ValueNode* node, interpreter::Register reg) {
|
||||
deopt_info->state().register_frame->ForEachValue(
|
||||
deopt_info->unit(), [&](ValueNode* node, interpreter::Register reg) {
|
||||
if (!reg.is_parameter() && !liveness->RegisterIsLive(reg.index())) {
|
||||
// Skip, since not live at the handler offset.
|
||||
return;
|
||||
|
@ -721,8 +721,8 @@ class MergePointInterpreterFrameState {
|
||||
} else {
|
||||
tagged = Node::New<CheckedSmiTag, std::initializer_list<ValueNode*>>(
|
||||
compilation_unit.zone(), compilation_unit,
|
||||
value->eager_deopt_info()->state,
|
||||
value->eager_deopt_info()->source_position, {value});
|
||||
value->eager_deopt_info()->state(),
|
||||
value->eager_deopt_info()->source_position(), {value});
|
||||
}
|
||||
|
||||
Node::List::AddAfter(value, tagged);
|
||||
|
@ -16,14 +16,14 @@ namespace detail {
|
||||
|
||||
template <typename Function>
|
||||
void DeepForEachInputImpl(const MaglevCompilationUnit& unit,
|
||||
const CheckpointedInterpreterState* state,
|
||||
const CheckpointedInterpreterState& state,
|
||||
InputLocation* input_locations, int& index,
|
||||
Function&& f) {
|
||||
if (state->parent) {
|
||||
DeepForEachInputImpl(*unit.caller(), state->parent, input_locations, index,
|
||||
if (state.parent) {
|
||||
DeepForEachInputImpl(*unit.caller(), *state.parent, input_locations, index,
|
||||
f);
|
||||
}
|
||||
state->register_frame->ForEachValue(
|
||||
state.register_frame->ForEachValue(
|
||||
unit, [&](ValueNode* node, interpreter::Register reg) {
|
||||
f(node, reg, &input_locations[index++]);
|
||||
});
|
||||
@ -32,25 +32,26 @@ void DeepForEachInputImpl(const MaglevCompilationUnit& unit,
|
||||
template <typename Function>
|
||||
void DeepForEachInput(const EagerDeoptInfo* deopt_info, Function&& f) {
|
||||
int index = 0;
|
||||
DeepForEachInputImpl(deopt_info->unit, &deopt_info->state,
|
||||
deopt_info->input_locations, index, f);
|
||||
DeepForEachInputImpl(deopt_info->unit(), deopt_info->state(),
|
||||
deopt_info->input_locations(), index, f);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void DeepForEachInput(const LazyDeoptInfo* deopt_info, Function&& f) {
|
||||
int index = 0;
|
||||
if (deopt_info->state.parent) {
|
||||
DeepForEachInputImpl(*deopt_info->unit.caller(), deopt_info->state.parent,
|
||||
deopt_info->input_locations, index, f);
|
||||
if (deopt_info->state().parent) {
|
||||
DeepForEachInputImpl(*deopt_info->unit().caller(),
|
||||
*deopt_info->state().parent,
|
||||
deopt_info->input_locations(), index, f);
|
||||
}
|
||||
// Handle the top-of-frame info separately, since we have to skip the result
|
||||
// location.
|
||||
deopt_info->state.register_frame->ForEachValue(
|
||||
deopt_info->unit, [&](ValueNode* node, interpreter::Register reg) {
|
||||
deopt_info->state().register_frame->ForEachValue(
|
||||
deopt_info->unit(), [&](ValueNode* node, interpreter::Register reg) {
|
||||
// Skip over the result location since it is irrelevant for lazy deopts
|
||||
// (unoptimized code will recreate the result).
|
||||
if (deopt_info->IsResultRegister(reg)) return;
|
||||
f(node, reg, &deopt_info->input_locations[index++]);
|
||||
f(node, reg, &deopt_info->input_locations()[index++]);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,8 @@ class SaveRegisterStateForCall {
|
||||
|
||||
MaglevSafepointTableBuilder::Safepoint DefineSafepointWithLazyDeopt(
|
||||
LazyDeoptInfo* lazy_deopt_info) {
|
||||
lazy_deopt_info->deopting_call_return_pc = masm->pc_offset_for_safepoint();
|
||||
lazy_deopt_info->set_deopting_call_return_pc(
|
||||
masm->pc_offset_for_safepoint());
|
||||
masm->code_gen_state()->PushLazyDeopt(lazy_deopt_info);
|
||||
return DefineSafepoint();
|
||||
}
|
||||
@ -389,25 +390,25 @@ size_t GetInputLocationsArraySize(const MaglevCompilationUnit& compilation_unit,
|
||||
DeoptInfo::DeoptInfo(Zone* zone, const MaglevCompilationUnit& compilation_unit,
|
||||
CheckpointedInterpreterState state,
|
||||
SourcePosition source_position)
|
||||
: unit(compilation_unit),
|
||||
state(state),
|
||||
input_locations(zone->NewArray<InputLocation>(
|
||||
: unit_(compilation_unit),
|
||||
state_(state),
|
||||
input_locations_(zone->NewArray<InputLocation>(
|
||||
GetInputLocationsArraySize(compilation_unit, state))),
|
||||
source_position(source_position) {
|
||||
source_position_(source_position) {
|
||||
// Initialise InputLocations so that they correctly don't have a next use id.
|
||||
for (size_t i = 0; i < GetInputLocationsArraySize(compilation_unit, state);
|
||||
++i) {
|
||||
new (&input_locations[i]) InputLocation();
|
||||
new (&input_locations_[i]) InputLocation();
|
||||
}
|
||||
}
|
||||
|
||||
bool LazyDeoptInfo::IsResultRegister(interpreter::Register reg) const {
|
||||
if (V8_LIKELY(result_size == 1)) {
|
||||
return reg == result_location;
|
||||
if (V8_LIKELY(result_size_ == 1)) {
|
||||
return reg == result_location_;
|
||||
}
|
||||
DCHECK_EQ(result_size, 2);
|
||||
return reg == result_location ||
|
||||
reg == interpreter::Register(result_location.index() + 1);
|
||||
DCHECK_EQ(result_size_, 2);
|
||||
return reg == result_location_ ||
|
||||
reg == interpreter::Register(result_location_.index() + 1);
|
||||
}
|
||||
|
||||
// ---
|
||||
@ -1231,7 +1232,7 @@ void CheckMaps::GenerateCode(MaglevAssembler* masm,
|
||||
// deopt when we intersect the map sets.
|
||||
if (maps().is_empty()) {
|
||||
__ RegisterEagerDeopt(eager_deopt_info(), DeoptimizeReason::kWrongMap);
|
||||
__ jmp(&eager_deopt_info()->deopt_entry_label);
|
||||
__ jmp(eager_deopt_info()->deopt_entry_label());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1377,7 +1378,7 @@ void CheckMapsWithMigration::GenerateCode(MaglevAssembler* masm,
|
||||
// TODO(victorgomes): This can happen, because we do not emit an unconditional
|
||||
// deopt when we intersect the map sets.
|
||||
if (maps().is_empty()) {
|
||||
__ jmp(&eager_deopt_info()->deopt_entry_label);
|
||||
__ jmp(eager_deopt_info()->deopt_entry_label());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1387,7 +1388,7 @@ void CheckMapsWithMigration::GenerateCode(MaglevAssembler* masm,
|
||||
__ AssertNotSmi(object);
|
||||
} else {
|
||||
Condition is_smi = __ CheckSmi(object);
|
||||
__ j(is_smi, &eager_deopt_info()->deopt_entry_label);
|
||||
__ j(is_smi, eager_deopt_info()->deopt_entry_label());
|
||||
}
|
||||
|
||||
ZoneLabelRef done(masm);
|
||||
@ -1453,13 +1454,13 @@ void CheckMapsWithMigration::GenerateCode(MaglevAssembler* masm,
|
||||
// If this is the last map to check, we should deopt if we fail.
|
||||
// This is safe to do, since {eager_deopt_info} is ZoneAllocated.
|
||||
(last_map ? ZoneLabelRef::UnsafeFromLabelPointer(
|
||||
&eager_deopt_info()->deopt_entry_label)
|
||||
eager_deopt_info()->deopt_entry_label())
|
||||
: continue_label),
|
||||
done, object, i, this);
|
||||
} else if (last_map) {
|
||||
// If it is the last map and it is not a migration target, we should deopt
|
||||
// if the check fails.
|
||||
__ j(not_equal, &eager_deopt_info()->deopt_entry_label);
|
||||
__ j(not_equal, eager_deopt_info()->deopt_entry_label());
|
||||
}
|
||||
|
||||
if (!last_map) {
|
||||
@ -1586,10 +1587,10 @@ void CheckedInternalizedString::GenerateCode(MaglevAssembler* masm,
|
||||
static_assert(kThinStringTagBit > 0);
|
||||
// Deopt if this isn't a string.
|
||||
__ testw(map_tmp, Immediate(kIsNotStringMask));
|
||||
__ j(not_zero, &deopt_info->deopt_entry_label);
|
||||
__ j(not_zero, deopt_info->deopt_entry_label());
|
||||
// Deopt if this isn't a thin string.
|
||||
__ testb(map_tmp, Immediate(kThinStringTagBit));
|
||||
__ j(zero, &deopt_info->deopt_entry_label);
|
||||
__ j(zero, deopt_info->deopt_entry_label());
|
||||
__ LoadTaggedPointerField(
|
||||
object, FieldOperand(object, ThinString::kActualOffset));
|
||||
if (v8_flags.debug_code) {
|
||||
|
@ -682,12 +682,22 @@ class DeoptInfo {
|
||||
SourcePosition source_position);
|
||||
|
||||
public:
|
||||
const MaglevCompilationUnit& unit;
|
||||
CheckpointedInterpreterState state;
|
||||
InputLocation* input_locations = nullptr;
|
||||
Label deopt_entry_label;
|
||||
SourcePosition source_position;
|
||||
int translation_index = -1;
|
||||
const MaglevCompilationUnit& unit() const { return unit_; }
|
||||
CheckpointedInterpreterState state() const { return state_; }
|
||||
InputLocation* input_locations() const { return input_locations_; }
|
||||
Label* deopt_entry_label() { return &deopt_entry_label_; }
|
||||
SourcePosition source_position() const { return source_position_; }
|
||||
|
||||
int translation_index() const { return translation_index_; }
|
||||
void set_translation_index(int index) { translation_index_ = index; }
|
||||
|
||||
private:
|
||||
const MaglevCompilationUnit& unit_;
|
||||
const CheckpointedInterpreterState state_;
|
||||
InputLocation* const input_locations_;
|
||||
Label deopt_entry_label_;
|
||||
const SourcePosition source_position_;
|
||||
int translation_index_ = -1;
|
||||
};
|
||||
|
||||
struct RegisterSnapshot {
|
||||
@ -702,7 +712,12 @@ class EagerDeoptInfo : public DeoptInfo {
|
||||
CheckpointedInterpreterState checkpoint,
|
||||
SourcePosition source_position)
|
||||
: DeoptInfo(zone, compilation_unit, checkpoint, source_position) {}
|
||||
DeoptimizeReason reason = DeoptimizeReason::kUnknown;
|
||||
|
||||
DeoptimizeReason reason() const { return reason_; }
|
||||
void set_reason(DeoptimizeReason reason) { reason_ = reason; }
|
||||
|
||||
private:
|
||||
DeoptimizeReason reason_ = DeoptimizeReason::kUnknown;
|
||||
};
|
||||
|
||||
class LazyDeoptInfo : public DeoptInfo {
|
||||
@ -712,12 +727,26 @@ class LazyDeoptInfo : public DeoptInfo {
|
||||
SourcePosition source_position)
|
||||
: DeoptInfo(zone, compilation_unit, checkpoint, source_position) {}
|
||||
|
||||
bool IsResultRegister(interpreter::Register reg) const;
|
||||
interpreter::Register result_location() const { return result_location_; }
|
||||
int result_size() const { return result_size_; }
|
||||
|
||||
int deopting_call_return_pc = -1;
|
||||
interpreter::Register result_location =
|
||||
bool IsResultRegister(interpreter::Register reg) const;
|
||||
void SetResultLocation(interpreter::Register result_location,
|
||||
int result_size) {
|
||||
DCHECK(result_location.is_valid());
|
||||
DCHECK(!result_location_.is_valid());
|
||||
result_location_ = result_location;
|
||||
result_size_ = result_size;
|
||||
}
|
||||
|
||||
int deopting_call_return_pc() const { return deopting_call_return_pc_; }
|
||||
void set_deopting_call_return_pc(int pc) { deopting_call_return_pc_ = pc; }
|
||||
|
||||
private:
|
||||
int deopting_call_return_pc_ = -1;
|
||||
interpreter::Register result_location_ =
|
||||
interpreter::Register::invalid_value();
|
||||
int result_size = 1;
|
||||
int result_size_ = 1;
|
||||
};
|
||||
|
||||
class ExceptionHandlerInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user