Commit a5667321 authored by Junliang Yan's avatar Junliang Yan Committed by V8 LUCI CQ

PPC:s390: [sparkplug][arm][arm64[ia32] Callee-saved registers for RecordWrite

Port c5d41ae6

Original Message:
    Migrate the remaining architectures to the new callee save
    RecordWrite approach.

Bug: v8:11420
Change-Id: I20ddf47690203fe9a0cd76dea3a08658582faf9d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2953486
Auto-Submit: Junliang Yan <junyan@redhat.com>
Reviewed-by: 's avatarMilad Fa <mfarazma@redhat.com>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/master@{#75104}
parent c26965bd
......@@ -342,13 +342,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// -- r4 : the JSGeneratorObject to resume
// -- lr : return address
// -----------------------------------
__ AssertGeneratorObject(r4);
// Store input value into generator object.
__ StoreTaggedField(
r3, FieldMemOperand(r4, JSGeneratorObject::kInputOrDebugPosOffset), r0);
__ RecordWriteField(r4, JSGeneratorObject::kInputOrDebugPosOffset, r3, r6,
kLRHasNotBeenSaved, SaveFPRegsMode::kIgnore);
// Check that r4 is still valid, RecordWrite might have clobbered it.
__ AssertGeneratorObject(r4);
// Load suspended function and context.
__ LoadTaggedPointerField(
......@@ -792,12 +792,18 @@ static void ReplaceClosureCodeWithOptimizedCode(MacroAssembler* masm,
Register optimized_code,
Register closure,
Register scratch1,
Register scratch2) {
Register slot_address) {
DCHECK(!AreAliased(optimized_code, closure, scratch1, slot_address));
DCHECK_EQ(closure, kJSFunctionRegister);
DCHECK(!AreAliased(optimized_code, closure));
// Store code entry in the closure.
__ StoreTaggedField(optimized_code,
FieldMemOperand(closure, JSFunction::kCodeOffset), r0);
__ mr(scratch1, optimized_code); // Write barrier clobbers scratch1 below.
__ RecordWriteField(closure, JSFunction::kCodeOffset, scratch1, scratch2,
// Write barrier clobbers scratch1 below.
Register value = scratch1;
__ mr(value, optimized_code);
__ RecordWriteField(closure, JSFunction::kCodeOffset, value, slot_address,
kLRHasNotBeenSaved, SaveFPRegsMode::kIgnore,
RememberedSetAction::kOmit, SmiCheck::kOmit);
}
......@@ -1006,6 +1012,7 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
static void MaybeOptimizeCodeOrTailCallOptimizedCodeSlot(
MacroAssembler* masm, Register optimization_state,
Register feedback_vector) {
DCHECK(!AreAliased(optimization_state, feedback_vector));
Label maybe_has_optimized_code;
// Check if optimized code is available
__ TestBitMask(optimization_state,
......
......@@ -334,13 +334,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
// -- r3 : the JSGeneratorObject to resume
// -- lr : return address
// -----------------------------------
__ AssertGeneratorObject(r3);
// Store input value into generator object.
__ StoreTaggedField(
r2, FieldMemOperand(r3, JSGeneratorObject::kInputOrDebugPosOffset), r0);
__ RecordWriteField(r3, JSGeneratorObject::kInputOrDebugPosOffset, r2, r5,
kLRHasNotBeenSaved, SaveFPRegsMode::kIgnore);
// Check that r3 is still valid, RecordWrite might have clobbered it.
__ AssertGeneratorObject(r3);
// Load suspended function and context.
__ LoadTaggedPointerField(
......@@ -847,13 +847,18 @@ static void ReplaceClosureCodeWithOptimizedCode(MacroAssembler* masm,
Register optimized_code,
Register closure,
Register scratch1,
Register scratch2) {
Register slot_address) {
DCHECK(!AreAliased(optimized_code, closure, scratch1, slot_address));
DCHECK_EQ(closure, kJSFunctionRegister);
DCHECK(!AreAliased(optimized_code, closure));
// Store code entry in the closure.
__ StoreTaggedField(optimized_code,
FieldMemOperand(closure, JSFunction::kCodeOffset), r0);
__ mov(scratch1,
optimized_code); // Write barrier clobbers scratch1 below.
__ RecordWriteField(closure, JSFunction::kCodeOffset, scratch1, scratch2,
// Write barrier clobbers scratch1 below.
Register value = scratch1;
__ mov(value, optimized_code);
__ RecordWriteField(closure, JSFunction::kCodeOffset, value, slot_address,
kLRHasNotBeenSaved, SaveFPRegsMode::kIgnore,
RememberedSetAction::kOmit, SmiCheck::kOmit);
}
......@@ -1061,6 +1066,7 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
static void MaybeOptimizeCodeOrTailCallOptimizedCodeSlot(
MacroAssembler* masm, Register optimization_state,
Register feedback_vector) {
DCHECK(!AreAliased(optimization_state, feedback_vector));
Label maybe_has_optimized_code;
// Check if optimized code is available
__ TestBitMask(optimization_state,
......
......@@ -38,7 +38,7 @@ void StaticCallInterfaceDescriptor<DerivedDescriptor>::
// static
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, r7);
return RegisterArray(r4, r8, r7, r5, r3);
}
// static
......
......@@ -572,7 +572,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination,
}
void MacroAssembler::RecordWriteField(Register object, int offset,
Register value, Register dst,
Register value, Register slot_address,
LinkRegisterStatus lr_status,
SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action,
......@@ -590,17 +590,17 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
// of the object, so so offset must be a multiple of kSystemPointerSize.
DCHECK(IsAligned(offset, kTaggedSize));
Add(dst, object, offset - kHeapObjectTag, r0);
Add(slot_address, object, offset - kHeapObjectTag, r0);
if (FLAG_debug_code) {
Label ok;
andi(r0, dst, Operand(kTaggedSize - 1));
andi(r0, slot_address, Operand(kTaggedSize - 1));
beq(&ok, cr0);
stop();
bind(&ok);
}
RecordWrite(object, dst, value, lr_status, save_fp, remembered_set_action,
SmiCheck::kOmit);
RecordWrite(object, slot_address, value, lr_status, save_fp,
remembered_set_action, SmiCheck::kOmit);
bind(&done);
......@@ -608,7 +608,7 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(value, Operand(bit_cast<intptr_t>(kZapValue + 4)));
mov(dst, Operand(bit_cast<intptr_t>(kZapValue + 8)));
mov(slot_address, Operand(bit_cast<intptr_t>(kZapValue + 8)));
}
}
......@@ -720,14 +720,14 @@ void TurboAssembler::CallRecordWriteStub(
// Will clobber 4 registers: object, address, scratch, ip. The
// register 'object' contains a heap object pointer. The heap object
// tag is shifted away.
void MacroAssembler::RecordWrite(Register object, Register address,
void MacroAssembler::RecordWrite(Register object, Register slot_address,
Register value, LinkRegisterStatus lr_status,
SaveFPRegsMode fp_mode,
RememberedSetAction remembered_set_action,
SmiCheck smi_check) {
DCHECK(!AreAliased(object, value, address));
DCHECK(!AreAliased(object, value, slot_address));
if (FLAG_debug_code) {
LoadTaggedPointerField(r0, MemOperand(address));
LoadTaggedPointerField(r0, MemOperand(slot_address));
cmp(r0, value);
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
......@@ -758,19 +758,21 @@ void MacroAssembler::RecordWrite(Register object, Register address,
mflr(r0);
push(r0);
}
CallRecordWriteStubSaveRegisters(object, address, remembered_set_action,
CallRecordWriteStubSaveRegisters(object, slot_address, remembered_set_action,
fp_mode);
if (lr_status == kLRHasNotBeenSaved) {
pop(r0);
mtlr(r0);
}
if (FLAG_debug_code) mov(slot_address, Operand(kZapValue));
bind(&done);
// Clobber clobbered registers when running with the debug-code flag
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(address, Operand(bit_cast<intptr_t>(kZapValue + 12)));
mov(slot_address, Operand(bit_cast<intptr_t>(kZapValue + 12)));
mov(value, Operand(bit_cast<intptr_t>(kZapValue + 16)));
}
}
......
......@@ -749,7 +749,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// The offset is the offset from the start of the object, not the offset from
// the tagged HeapObject pointer. For use with FieldMemOperand(reg, off).
void RecordWriteField(
Register object, int offset, Register value, Register scratch,
Register object, int offset, Register value, Register slot_address,
LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
SmiCheck smi_check = SmiCheck::kInline);
......@@ -758,7 +758,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// has been written. |value| is the object being stored. The value and
// address registers are clobbered by the operation.
void RecordWrite(
Register object, Register address, Register value,
Register object, Register slot_address, Register value,
LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
SmiCheck smi_check = SmiCheck::kInline);
......
......@@ -38,7 +38,7 @@ void StaticCallInterfaceDescriptor<DerivedDescriptor>::
// static
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, r6);
return RegisterArray(r3, r7, r6, r4, r2);
}
// static
......
......@@ -805,7 +805,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination,
RecordComment("]");
}
void MacroAssembler::RecordWriteField(Register object, int offset,
Register value, Register dst,
Register value, Register slot_address,
LinkRegisterStatus lr_status,
SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action,
......@@ -823,17 +823,17 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
// of the object, so so offset must be a multiple of kSystemPointerSize.
DCHECK(IsAligned(offset, kTaggedSize));
lay(dst, MemOperand(object, offset - kHeapObjectTag));
lay(slot_address, MemOperand(object, offset - kHeapObjectTag));
if (FLAG_debug_code) {
Label ok;
AndP(r0, dst, Operand(kTaggedSize - 1));
AndP(r0, slot_address, Operand(kTaggedSize - 1));
beq(&ok, Label::kNear);
stop();
bind(&ok);
}
RecordWrite(object, dst, value, lr_status, save_fp, remembered_set_action,
SmiCheck::kOmit);
RecordWrite(object, slot_address, value, lr_status, save_fp,
remembered_set_action, SmiCheck::kOmit);
bind(&done);
......@@ -841,7 +841,7 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(value, Operand(bit_cast<intptr_t>(kZapValue + 4)));
mov(dst, Operand(bit_cast<intptr_t>(kZapValue + 8)));
mov(slot_address, Operand(bit_cast<intptr_t>(kZapValue + 8)));
}
}
......@@ -951,14 +951,14 @@ void TurboAssembler::CallRecordWriteStub(
// Will clobber 4 registers: object, address, scratch, ip. The
// register 'object' contains a heap object pointer. The heap object
// tag is shifted away.
void MacroAssembler::RecordWrite(Register object, Register address,
void MacroAssembler::RecordWrite(Register object, Register slot_address,
Register value, LinkRegisterStatus lr_status,
SaveFPRegsMode fp_mode,
RememberedSetAction remembered_set_action,
SmiCheck smi_check) {
DCHECK(!AreAliased(object, address, value));
DCHECK(!AreAliased(object, slot_address, value));
if (FLAG_debug_code) {
LoadTaggedPointerField(r0, MemOperand(address));
LoadTaggedPointerField(r0, MemOperand(slot_address));
CmpS64(value, r0);
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
......@@ -987,18 +987,20 @@ void MacroAssembler::RecordWrite(Register object, Register address,
if (lr_status == kLRHasNotBeenSaved) {
push(r14);
}
CallRecordWriteStubSaveRegisters(object, address, remembered_set_action,
CallRecordWriteStubSaveRegisters(object, slot_address, remembered_set_action,
fp_mode);
if (lr_status == kLRHasNotBeenSaved) {
pop(r14);
}
if (FLAG_debug_code) mov(slot_address, Operand(kZapValue));
bind(&done);
// Clobber clobbered registers when running with the debug-code flag
// turned on to provoke errors.
if (FLAG_debug_code) {
mov(address, Operand(bit_cast<intptr_t>(kZapValue + 12)));
mov(slot_address, Operand(bit_cast<intptr_t>(kZapValue + 12)));
mov(value, Operand(bit_cast<intptr_t>(kZapValue + 16)));
}
}
......
......@@ -1359,7 +1359,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// The offset is the offset from the start of the object, not the offset from
// the tagged HeapObject pointer. For use with FieldMemOperand(reg, off).
void RecordWriteField(
Register object, int offset, Register value, Register scratch,
Register object, int offset, Register value, Register slot_address,
LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
SmiCheck smi_check = SmiCheck::kInline);
......@@ -1368,7 +1368,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// has been written. |value| is the object being stored. The value and
// address registers are clobbered by the operation.
void RecordWrite(
Register object, Register address, Register value,
Register object, Register slot_address, Register value,
LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
RememberedSetAction remembered_set_action = RememberedSetAction::kEmit,
SmiCheck smi_check = SmiCheck::kInline);
......
......@@ -4079,7 +4079,6 @@ void CodeGenerator::FinishFrame(Frame* frame) {
// register save area does not include the fp or constant pool pointer.
const int num_saves =
kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0);
DCHECK(num_saves == base::bits::CountPopulation(saves));
frame->AllocateSavedCalleeRegisterSlots(num_saves);
}
}
......@@ -4273,9 +4272,9 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
// If {parameter_slots} == 0, it means it is a builtin with
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
// itself.
const bool drop_jsargs = frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall() &&
parameter_slots != 0;
const bool drop_jsargs = parameter_slots != 0 &&
frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall();
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();
......@@ -4293,6 +4292,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
if (drop_jsargs) {
// Get the actual argument count.
DCHECK_EQ(0u, call_descriptor->CalleeSavedRegisters() & argc_reg.bit());
__ LoadU64(argc_reg, MemOperand(fp, StandardFrameConstants::kArgCOffset));
}
AssembleDeconstructFrame();
......
......@@ -4116,7 +4116,6 @@ void CodeGenerator::FinishFrame(Frame* frame) {
if (saves != 0) {
// register save area does not include the fp or constant pool pointer.
const int num_saves = kNumCalleeSaved - 1;
DCHECK(num_saves == base::bits::CountPopulation(saves));
frame->AllocateSavedCalleeRegisterSlots(num_saves);
}
}
......@@ -4298,9 +4297,9 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
// If {parameter_slots} == 0, it means it is a builtin with
// kDontAdaptArgumentsSentinel, which takes care of JS arguments popping
// itself.
const bool drop_jsargs = frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall() &&
parameter_slots != 0;
const bool drop_jsargs = parameter_slots != 0 &&
frame_access_state()->has_frame() &&
call_descriptor->IsJSFunctionCall();
if (call_descriptor->IsCFunctionCall()) {
AssembleDeconstructFrame();
......@@ -4318,6 +4317,7 @@ void CodeGenerator::AssembleReturn(InstructionOperand* additional_pop_count) {
}
if (drop_jsargs) {
// Get the actual argument count.
DCHECK_EQ(0u, call_descriptor->CalleeSavedRegisters() & argc_reg.bit());
__ LoadU64(argc_reg, MemOperand(fp, StandardFrameConstants::kArgCOffset));
}
AssembleDeconstructFrame();
......
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