[turbofan] Support CallDescriptor::kFixedTargetRegister for [tail]calls to code objects.
In order to port CompileLazy and DeserializeLazy builtins to CSA we need to support this mode to be able to tail call to compiled or deserialized JS code object. Bug: v8:5269, v8:7703 Change-Id: I6abdc989af16774f6454b2ea0a97b1ce5ece5125 Reviewed-on: https://chromium-review.googlesource.com/1087452 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#53543}
This commit is contained in:
parent
1c40429844
commit
9c07c61c92
@ -677,11 +677,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
UseScratchRegisterScope temps(tasm());
|
||||
Register scratch = temps.Acquire();
|
||||
__ add(scratch, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(scratch);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ add(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(reg);
|
||||
}
|
||||
RecordCallPosition(instr);
|
||||
DCHECK_EQ(LeaveCC, i.OutputSBit());
|
||||
@ -721,11 +722,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
UseScratchRegisterScope temps(tasm());
|
||||
Register scratch = temps.Acquire();
|
||||
__ add(scratch, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(scratch);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ add(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(reg);
|
||||
}
|
||||
DCHECK_EQ(LeaveCC, i.OutputSBit());
|
||||
unwinding_info_writer_.MarkBlockWillExit();
|
||||
@ -754,7 +756,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
unwinding_info_writer_.MarkBlockWillExit();
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
|
@ -609,9 +609,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register target = i.InputRegister(0);
|
||||
__ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(target);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Add(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(reg);
|
||||
}
|
||||
RecordCallPosition(instr);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
@ -645,9 +648,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register target = i.InputRegister(0);
|
||||
__ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(target);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Add(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(reg);
|
||||
}
|
||||
unwinding_info_writer_.MarkBlockWillExit();
|
||||
frame_access_state()->ClearSPDelta();
|
||||
@ -670,7 +676,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
unwinding_info_writer_.MarkBlockWillExit();
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
|
@ -587,6 +587,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ call(code, RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineCall(reg);
|
||||
@ -636,6 +639,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ jmp(code, RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineJump(reg);
|
||||
@ -669,6 +675,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
MoveOperandIfAliasedWithPoisonRegister(instr, this);
|
||||
CHECK(!HasImmediateInput(instr, 0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineJump(reg);
|
||||
} else {
|
||||
|
@ -605,8 +605,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ Call(kScratchReg, i.InputRegister(0),
|
||||
Code::kHeaderSize - kHeapObjectTag);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Call(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
}
|
||||
RecordCallPosition(instr);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
@ -634,8 +637,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ Jump(kScratchReg, i.InputRegister(0),
|
||||
Code::kHeaderSize - kHeapObjectTag);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
}
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
@ -655,7 +661,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
break;
|
||||
|
@ -618,9 +618,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ daddiu(kScratchReg, i.InputRegister(0),
|
||||
Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(kScratchReg);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ daddiu(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(reg);
|
||||
}
|
||||
RecordCallPosition(instr);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
@ -654,9 +657,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
if (instr->InputAt(0)->IsImmediate()) {
|
||||
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ daddiu(kScratchReg, i.InputRegister(0),
|
||||
Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(kScratchReg);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ daddiu(reg, reg, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(reg);
|
||||
}
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
@ -677,7 +683,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
break;
|
||||
|
@ -913,9 +913,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
|
||||
tasm());
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
__ addi(ip, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(ip);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ addi(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(reg);
|
||||
} else {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -951,9 +954,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
__ addi(ip, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(ip);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ addi(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(reg);
|
||||
} else {
|
||||
// We cannot use the constant pool to load the target since
|
||||
// we've already restored the caller's frame.
|
||||
@ -986,7 +992,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
break;
|
||||
|
@ -1354,9 +1354,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchCallCodeObject: {
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
__ AddP(ip, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(ip);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ AddP(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Call(reg);
|
||||
} else {
|
||||
__ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
@ -1390,9 +1393,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
i.TempRegister(2));
|
||||
}
|
||||
if (HasRegisterInput(instr, 0)) {
|
||||
__ AddP(ip, i.InputRegister(0),
|
||||
Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(ip);
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ AddP(reg, reg, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(reg);
|
||||
} else {
|
||||
// We cannot use the constant pool to load the target since
|
||||
// we've already restored the caller's frame.
|
||||
@ -1423,7 +1429,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
}
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!instr->InputAt(0)->IsImmediate());
|
||||
__ Jump(i.InputRegister(0));
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ Jump(reg);
|
||||
frame_access_state()->ClearSPDelta();
|
||||
frame_access_state()->SetFrameAccessToDefault();
|
||||
break;
|
||||
|
@ -676,6 +676,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ Call(code, RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineCall(reg);
|
||||
@ -724,6 +727,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
__ Jump(code, RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
Register reg = i.InputRegister(0);
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
__ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineJump(reg);
|
||||
@ -762,10 +768,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
case kArchTailCallAddress: {
|
||||
CHECK(!HasImmediateInput(instr, 0));
|
||||
Register reg = i.InputRegister(0);
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister)) {
|
||||
static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch");
|
||||
DCHECK_EQ(rcx, reg);
|
||||
}
|
||||
DCHECK_IMPLIES(
|
||||
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
|
||||
reg == kJavaScriptCallCodeStartRegister);
|
||||
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
|
||||
__ RetpolineJump(reg);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user