PPC:s390: [sparkplug][arm][arm64[ia32] Callee-saved registers for RecordWrite
Port c5d41ae6d2
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: Milad Fa <mfarazma@redhat.com>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/master@{#75104}
This commit is contained in:
parent
c26965bded
commit
a566732140
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user