Reland "[maglev] Inline allocation for heap numbers"
This is a reland of commit ef1e65d9ae
Original change's description:
> [maglev] Inline allocation for heap numbers
>
> Bug: v8:7700
> Change-Id: I2ce46fcfaab6716e6a31167ed517d2e8d9e433d8
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3788094
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Commit-Queue: Victor Gomes <victorgomes@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#82027}
Bug: v8:7700
Change-Id: I3d86880c20ef4b5765a87d272f18cad9fac210fe
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3790971
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82041}
This commit is contained in:
parent
cda6dab9cf
commit
cd02fe8edb
@ -87,7 +87,7 @@ void UseFixed(Input& input, Register reg) {
|
||||
input.SetUnallocated(compiler::UnallocatedOperand::FIXED_REGISTER, reg.code(),
|
||||
GetVirtualRegister(input.node()));
|
||||
}
|
||||
void UseFixed(Input& input, DoubleRegister reg) {
|
||||
[[maybe_unused]] void UseFixed(Input& input, DoubleRegister reg) {
|
||||
input.SetUnallocated(compiler::UnallocatedOperand::FIXED_FP_REGISTER,
|
||||
reg.code(), GetVirtualRegister(input.node()));
|
||||
}
|
||||
@ -225,6 +225,10 @@ struct CopyForDeferredHelper<EagerDeoptInfo*>
|
||||
template <>
|
||||
struct CopyForDeferredHelper<ZoneLabelRef>
|
||||
: public CopyForDeferredByValue<ZoneLabelRef> {};
|
||||
// Register snapshots are copied by value.
|
||||
template <>
|
||||
struct CopyForDeferredHelper<RegisterSnapshot>
|
||||
: public CopyForDeferredByValue<RegisterSnapshot> {};
|
||||
|
||||
template <typename T>
|
||||
T CopyForDeferred(MaglevCompilationInfo* compilation_info, T&& value) {
|
||||
@ -325,6 +329,68 @@ void JumpToDeferredIf(Condition cond, MaglevCodeGenState* code_gen_state,
|
||||
__ bind(&deferred_code->return_label);
|
||||
}
|
||||
|
||||
// ---
|
||||
// Inlined computations.
|
||||
// ---
|
||||
|
||||
void AllocateRaw(MaglevCodeGenState* code_gen_state,
|
||||
RegisterSnapshot& register_snapshot, Register object,
|
||||
int size_in_bytes,
|
||||
AllocationType alloc_type = AllocationType::kYoung,
|
||||
AllocationAlignment alignment = kTaggedAligned) {
|
||||
// TODO(victorgomes): Call the runtime for large object allocation.
|
||||
// TODO(victorgomes): Support double alignment.
|
||||
DCHECK_EQ(alignment, kTaggedAligned);
|
||||
if (FLAG_single_generation) {
|
||||
alloc_type = AllocationType::kOld;
|
||||
}
|
||||
bool in_new_space = alloc_type == AllocationType::kYoung;
|
||||
Isolate* isolate = code_gen_state->isolate();
|
||||
ExternalReference top =
|
||||
in_new_space
|
||||
? ExternalReference::new_space_allocation_top_address(isolate)
|
||||
: ExternalReference::old_space_allocation_top_address(isolate);
|
||||
ExternalReference limit =
|
||||
in_new_space
|
||||
? ExternalReference::new_space_allocation_limit_address(isolate)
|
||||
: ExternalReference::old_space_allocation_limit_address(isolate);
|
||||
|
||||
ZoneLabelRef done(code_gen_state->compilation_info()->zone());
|
||||
Register new_top = kScratchRegister;
|
||||
// Check if there is enough space.
|
||||
__ Move(object, __ ExternalReferenceAsOperand(top));
|
||||
__ leaq(new_top, Operand(object, size_in_bytes));
|
||||
__ cmpq(new_top, __ ExternalReferenceAsOperand(limit));
|
||||
// Otherwise call runtime.
|
||||
JumpToDeferredIf(
|
||||
greater_equal, code_gen_state,
|
||||
[](MaglevCodeGenState* code_gen_state, Label* return_label,
|
||||
RegisterSnapshot register_snapshot, Register object, Builtin builtin,
|
||||
int size_in_bytes, ZoneLabelRef done) {
|
||||
// Remove {object} from snapshot, since it is the returned allocated
|
||||
// HeapObject.
|
||||
register_snapshot.live_registers.clear(object);
|
||||
{
|
||||
SaveRegisterStateForCall save_register_state(code_gen_state,
|
||||
register_snapshot);
|
||||
using D = AllocateDescriptor;
|
||||
__ Move(D::GetRegisterParameter(D::kRequestedSize), size_in_bytes);
|
||||
__ CallBuiltin(builtin);
|
||||
save_register_state.DefineSafepoint();
|
||||
__ Move(object, kReturnRegister0);
|
||||
}
|
||||
__ jmp(*done);
|
||||
},
|
||||
register_snapshot, object,
|
||||
in_new_space ? Builtin::kAllocateRegularInYoungGeneration
|
||||
: Builtin::kAllocateRegularInOldGeneration,
|
||||
size_in_bytes, done);
|
||||
// Store new top and tag object.
|
||||
__ movq(__ ExternalReferenceAsOperand(top), new_top);
|
||||
__ addq(object, Immediate(kHeapObjectTag));
|
||||
__ bind(*done);
|
||||
}
|
||||
|
||||
void ToBoolean(MaglevCodeGenState* code_gen_state, Register value,
|
||||
ZoneLabelRef is_true, ZoneLabelRef is_false,
|
||||
bool fallthrough_when_true) {
|
||||
@ -1923,14 +1989,23 @@ void Int32Constant::PrintParams(std::ostream& os,
|
||||
}
|
||||
|
||||
void Float64Box::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
using D = NewHeapNumberDescriptor;
|
||||
UseFixed(input(), D::GetDoubleRegisterParameter(D::kValue));
|
||||
DefineAsFixed(vreg_state, this, kReturnRegister0);
|
||||
UseRegister(input());
|
||||
DefineAsRegister(vreg_state, this);
|
||||
}
|
||||
void Float64Box::GenerateCode(MaglevCodeGenState* code_gen_state,
|
||||
const ProcessingState& state) {
|
||||
// TODO(victorgomes): Inline heap number allocation.
|
||||
__ CallBuiltin(Builtin::kNewHeapNumber);
|
||||
DoubleRegister value = ToDoubleRegister(input());
|
||||
Register object = ToRegister(result());
|
||||
// In the case we need to call the runtime, we should spill the input
|
||||
// register. Even if it is not live in the next node, otherwise the allocation
|
||||
// call might trash it.
|
||||
RegisterSnapshot save_registers = register_snapshot();
|
||||
save_registers.live_double_registers.set(value);
|
||||
AllocateRaw(code_gen_state, save_registers, object, HeapNumber::kSize);
|
||||
__ LoadRoot(kScratchRegister, RootIndex::kHeapNumberMap);
|
||||
__ StoreTaggedField(FieldOperand(object, HeapObject::kMapOffset),
|
||||
kScratchRegister);
|
||||
__ Movsd(FieldOperand(object, HeapNumber::kValueOffset), value);
|
||||
}
|
||||
|
||||
void CheckedFloat64Unbox::AllocateVreg(MaglevVregAllocationState* vreg_state) {
|
||||
|
@ -1516,7 +1516,7 @@ class Float64Box : public FixedInputValueNodeT<1, Float64Box> {
|
||||
explicit Float64Box(uint64_t bitfield) : Base(bitfield) {}
|
||||
|
||||
static constexpr OpProperties kProperties =
|
||||
OpProperties::Call() | OpProperties::ConversionNode();
|
||||
OpProperties::DeferredCall() | OpProperties::ConversionNode();
|
||||
|
||||
Input& input() { return Node::input(0); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user