Commit 0e2d90c7 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Remove the need for a tmp and pointer decompress in CheckMaps

Use the Operand overload of Cmp to avoid loading the object map into a
temporary in CheckMaps; this also avoids uncompressing the map pointer
when loading it.

It does mean that the migration path of CheckMapsWithMigration has to
re-load the map, and heavier use of the scratch register in that
implementation, but it's a deferred path so that should be ok.

Bug: v8:7700
Change-Id: I6741d5b5a8ad402bdef9025c43a86aca21db050e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3762574
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81719}
parent 3fbe85ba
...@@ -737,16 +737,12 @@ void CreateClosure::PrintParams(std::ostream& os, ...@@ -737,16 +737,12 @@ void CreateClosure::PrintParams(std::ostream& os,
void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) { void CheckMaps::AllocateVreg(MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input()); UseRegister(receiver_input());
set_temporaries_needed(1);
} }
void CheckMaps::GenerateCode(MaglevCodeGenState* code_gen_state, void CheckMaps::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
Register object = ToRegister(receiver_input()); Register object = ToRegister(receiver_input());
RegList temps = temporaries();
Register map_tmp = temps.PopFirst();
__ LoadMap(map_tmp, object); __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map().object());
__ Cmp(map_tmp, map().object());
EmitEagerDeoptIf(not_equal, code_gen_state, this); EmitEagerDeoptIf(not_equal, code_gen_state, this);
} }
void CheckMaps::PrintParams(std::ostream& os, void CheckMaps::PrintParams(std::ostream& os,
...@@ -780,26 +776,26 @@ void CheckHeapObject::PrintParams(std::ostream& os, ...@@ -780,26 +776,26 @@ void CheckHeapObject::PrintParams(std::ostream& os,
void CheckMapsWithMigration::AllocateVreg( void CheckMapsWithMigration::AllocateVreg(
MaglevVregAllocationState* vreg_state) { MaglevVregAllocationState* vreg_state) {
UseRegister(receiver_input()); UseRegister(receiver_input());
set_temporaries_needed(1);
} }
void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state, void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
Register object = ToRegister(receiver_input()); Register object = ToRegister(receiver_input());
RegList temps = temporaries();
Register map_tmp = temps.PopFirst();
__ LoadMap(map_tmp, object); __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map().object());
__ Cmp(map_tmp, map().object());
JumpToDeferredIf( JumpToDeferredIf(
not_equal, code_gen_state, not_equal, code_gen_state,
[](MaglevCodeGenState* code_gen_state, Label* return_label, [](MaglevCodeGenState* code_gen_state, Label* return_label,
Register object, CheckMapsWithMigration* node, Register object, CheckMapsWithMigration* node,
EagerDeoptInfo* deopt_info, Register map_tmp) { EagerDeoptInfo* deopt_info) {
RegisterEagerDeopt(code_gen_state, deopt_info); RegisterEagerDeopt(code_gen_state, deopt_info);
// Reload the map to avoid needing to save it on a temporary in the fast
// path.
__ LoadMap(kScratchRegister, object);
// If the map is not deprecated, deopt straight away. // If the map is not deprecated, deopt straight away.
__ movl(kScratchRegister, FieldOperand(map_tmp, Map::kBitField3Offset)); __ movl(kScratchRegister,
FieldOperand(kScratchRegister, Map::kBitField3Offset));
__ testl(kScratchRegister, __ testl(kScratchRegister,
Immediate(Map::Bits3::IsDeprecatedBit::kMask)); Immediate(Map::Bits3::IsDeprecatedBit::kMask));
__ j(zero, &deopt_info->deopt_entry_label); __ j(zero, &deopt_info->deopt_entry_label);
...@@ -821,9 +817,10 @@ void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -821,9 +817,10 @@ void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state,
// restoring pop all. // restoring pop all.
return_val = kReturnRegister0; return_val = kReturnRegister0;
if (node->register_snapshot().live_registers.has(return_val)) { if (node->register_snapshot().live_registers.has(return_val)) {
DCHECK(!node->register_snapshot().live_registers.has(map_tmp)); DCHECK(!node->register_snapshot().live_registers.has(
__ Move(map_tmp, return_val); kScratchRegister));
return_val = map_tmp; __ movq(kScratchRegister, return_val);
return_val = kScratchRegister;
} }
} }
...@@ -833,12 +830,13 @@ void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -833,12 +830,13 @@ void CheckMapsWithMigration::GenerateCode(MaglevCodeGenState* code_gen_state,
// The migrated object is returned on success, retry the map check. // The migrated object is returned on success, retry the map check.
__ Move(object, return_val); __ Move(object, return_val);
__ LoadMap(map_tmp, object); // Manually load the map pointer without uncompressing it.
__ Cmp(map_tmp, node->map().object()); __ Cmp(FieldOperand(object, HeapObject::kMapOffset),
node->map().object());
__ j(equal, return_label); __ j(equal, return_label);
__ jmp(&deopt_info->deopt_entry_label); __ jmp(&deopt_info->deopt_entry_label);
}, },
object, this, eager_deopt_info(), map_tmp); object, this, eager_deopt_info());
} }
void CheckMapsWithMigration::PrintParams( void CheckMapsWithMigration::PrintParams(
std::ostream& os, MaglevGraphLabeller* graph_labeller) const { std::ostream& os, MaglevGraphLabeller* graph_labeller) const {
......
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