Commit 8f234751 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[turbofan] Hoist out {ComputeCodeStartAddress} helper.

R=rmcilroy@chromium.org

Change-Id: I0f6d628e49c1a3e3123c8e6f59f584fd5bb3a0ca
Reviewed-on: https://chromium-review.googlesource.com/919064Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51307}
parent 8076b280
......@@ -2307,6 +2307,11 @@ bool AreAliased(Register reg1,
}
#endif
void TurboAssembler::ComputeCodeStartAddress(Register dst) {
// We can use the register pc - 8 for the address of the current instruction.
sub(dst, pc, Operand(pc_offset() + TurboAssembler::kPcLoadDelta));
}
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
} // namespace internal
......
......@@ -534,6 +534,10 @@ class TurboAssembler : public Assembler {
#endif
}
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(Register dst);
void ResetSpeculationPoisonRegister();
private:
......
......@@ -3299,6 +3299,11 @@ InlineSmiCheckInfo::InlineSmiCheckInfo(Address info)
}
}
void TurboAssembler::ComputeCodeStartAddress(const Register& rd) {
// We can use adr to load a pc relative location.
adr(rd, -pc_offset());
}
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
#undef __
......
......@@ -1195,6 +1195,10 @@ class TurboAssembler : public Assembler {
inline void Fcvtas(const Register& rd, const VRegister& fn);
inline void Fcvtau(const Register& rd, const VRegister& fn);
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(const Register& rd);
void ResetSpeculationPoisonRegister();
protected:
......
......@@ -584,9 +584,7 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
void CodeGenerator::AssembleCodeStartRegisterCheck() {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.Acquire();
int pc_offset = __ pc_offset();
// We can use the register pc - 8 for the address of the current instruction.
__ sub(scratch, pc, Operand(pc_offset + TurboAssembler::kPcLoadDelta));
__ ComputeCodeStartAddress(scratch);
__ cmp(scratch, kJavaScriptCallCodeStartRegister);
__ Assert(eq, AbortReason::kWrongFunctionCodeStart);
}
......@@ -615,14 +613,11 @@ void CodeGenerator::GenerateSpeculationPoison() {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.Acquire();
// We can use the register pc - 8 for the address of the current instruction.
int pc_offset = __ pc_offset();
__ sub(scratch, pc, Operand(pc_offset + TurboAssembler::kPcLoadDelta));
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ ComputeCodeStartAddress(scratch);
__ mov(kSpeculationPoisonRegister, scratch);
__ sub(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
......
......@@ -537,8 +537,7 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
void CodeGenerator::AssembleCodeStartRegisterCheck() {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.AcquireX();
int pc_offset = __ pc_offset();
__ adr(scratch, -pc_offset);
__ ComputeCodeStartAddress(scratch);
__ cmp(scratch, kJavaScriptCallCodeStartRegister);
__ Assert(eq, AbortReason::kWrongFunctionCodeStart);
}
......@@ -569,14 +568,11 @@ void CodeGenerator::GenerateSpeculationPoison() {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.AcquireX();
// We can use adr to load a pc relative location.
int pc_offset = __ pc_offset();
__ adr(scratch, -pc_offset);
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ ComputeCodeStartAddress(scratch);
__ Mov(kSpeculationPoisonRegister, scratch);
__ Sub(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
......
......@@ -498,15 +498,7 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
// Check that {kJavaScriptCallCodeStartRegister} is correct.
void CodeGenerator::AssembleCodeStartRegisterCheck() {
__ push(eax); // Push eax so we can use it as a scratch register.
Label current;
__ call(&current);
int pc = __ pc_offset();
__ bind(&current);
// In order to get the address of the current instruction, we first need
// to use a call and then use a pop, thus pushing the return address to
// the stack and then popping it into the register.
__ pop(eax);
__ sub(eax, Immediate(pc));
__ ComputeCodeStartAddress(eax);
__ cmp(eax, kJavaScriptCallCodeStartRegister);
__ Assert(equal, AbortReason::kWrongFunctionCodeStart);
__ pop(eax); // Restore eax.
......@@ -532,20 +524,11 @@ void CodeGenerator::BailoutIfDeoptimized() {
void CodeGenerator::GenerateSpeculationPoison() {
__ push(eax); // Push eax so we can use it as a scratch register.
// In order to get the address of the current instruction, we first need
// to use a call and then use a pop, thus pushing the return address to
// the stack and then popping it into the register.
Label current;
__ call(&current);
int pc = __ pc_offset();
__ bind(&current);
__ pop(eax);
__ sub(eax, Immediate(pc));
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ ComputeCodeStartAddress(eax);
__ mov(kSpeculationPoisonRegister, eax);
__ sub(kSpeculationPoisonRegister, kJavaScriptCallCodeStartRegister);
__ sub(kJavaScriptCallCodeStartRegister, eax);
......
......@@ -620,21 +620,9 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
// Check that {kJavaScriptCallCodeStartRegister} is correct.
void CodeGenerator::AssembleCodeStartRegisterCheck() {
Label current;
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing frames for deoptimization.
__ push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
__ bal(&current);
__ nop();
int pc = __ pc_offset();
__ bind(&current);
__ li(at, pc);
__ subu(at, ra, at);
__ ComputeCodeStartAddress(at);
__ Assert(eq, AbortReason::kWrongFunctionCodeStart,
kJavaScriptCallCodeStartRegister, Operand(at));
__ pop(ra);
}
// Check if the code object is marked for deoptimization. If it is, then it
......@@ -655,24 +643,11 @@ void CodeGenerator::BailoutIfDeoptimized() {
}
void CodeGenerator::GenerateSpeculationPoison() {
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing speculation poison.
__ push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
Label current;
__ bal(&current);
__ nop();
int pc = __ pc_offset();
__ bind(&current);
__ li(at, pc);
__ subu(at, ra, at);
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ ComputeCodeStartAddress(at);
__ Move(kSpeculationPoisonRegister, at);
__ subu(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
......@@ -684,8 +659,6 @@ void CodeGenerator::GenerateSpeculationPoison() {
kBitsPerPointer - 1);
__ nor(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kSpeculationPoisonRegister);
__ pop(ra); // Restore ra
}
// Assembles an instruction after register allocation, producing machine code.
......
......@@ -636,21 +636,9 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
// Check that {kJavaScriptCallCodeStartRegister} is correct.
void CodeGenerator::AssembleCodeStartRegisterCheck() {
Label current;
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing frames for deoptimization.
__ push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
__ bal(&current);
__ nop();
int pc = __ pc_offset();
__ bind(&current);
__ li(at, Operand(pc));
__ Dsubu(at, ra, at);
__ ComputeCodeStartAddress(at);
__ Assert(eq, AbortReason::kWrongFunctionCodeStart,
kJavaScriptCallCodeStartRegister, Operand(at));
__ pop(ra);
}
// Check if the code object is marked for deoptimization. If it is, then it
......@@ -671,24 +659,11 @@ void CodeGenerator::BailoutIfDeoptimized() {
}
void CodeGenerator::GenerateSpeculationPoison() {
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing speculation poison.
__ push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
Label current;
__ bal(&current);
__ nop();
int pc = __ pc_offset();
__ bind(&current);
__ li(at, Operand(pc));
__ Dsubu(at, ra, at);
// Calculate a mask which has all bits set in the normal case, but has all
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
__ ComputeCodeStartAddress(at);
__ Move(kSpeculationPoisonRegister, at);
__ subu(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kJavaScriptCallCodeStartRegister);
......@@ -700,8 +675,6 @@ void CodeGenerator::GenerateSpeculationPoison() {
kBitsPerPointer - 1);
__ nor(kSpeculationPoisonRegister, kSpeculationPoisonRegister,
kSpeculationPoisonRegister);
__ pop(ra); // Restore ra
}
// Assembles an instruction after register allocation, producing machine code.
......
......@@ -584,12 +584,7 @@ void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
// Check that {kJavaScriptCallCodeStartRegister} is correct.
void CodeGenerator::AssembleCodeStartRegisterCheck() {
Label current;
// Load effective address to get the address of the current instruction.
__ leaq(rbx, Operand(&current));
__ bind(&current);
int pc = __ pc_offset();
__ subq(rbx, Immediate(pc));
__ ComputeCodeStartAddress(rbx);
__ cmpq(rbx, kJavaScriptCallCodeStartRegister);
__ Assert(equal, AbortReason::kWrongFunctionCodeStart);
}
......@@ -616,13 +611,7 @@ void CodeGenerator::GenerateSpeculationPoison() {
// bits cleared if we are speculatively executing the wrong PC.
// difference = (current - expected) | (expected - current)
// poison = ~(difference >> (kBitsPerPointer - 1))
Label current;
__ bind(&current);
int pc = __ pc_offset();
__ leaq(rbx, Operand(&current));
if (pc != 0) {
__ subq(rbx, Immediate(pc));
}
__ ComputeCodeStartAddress(rbx);
__ movp(kSpeculationPoisonRegister, rbx);
__ subq(kSpeculationPoisonRegister, kJavaScriptCallCodeStartRegister);
__ subq(kJavaScriptCallCodeStartRegister, rbx);
......
......@@ -1666,6 +1666,20 @@ void TurboAssembler::CheckPageFlag(Register object, Register scratch, int mask,
j(cc, condition_met, condition_met_distance);
}
void TurboAssembler::ComputeCodeStartAddress(Register dst) {
// In order to get the address of the current instruction, we first need
// to use a call and then use a pop, thus pushing the return address to
// the stack and then popping it into the register.
Label current;
call(&current);
int pc = pc_offset();
bind(&current);
pop(dst);
if (pc != 0) {
sub(dst, Immediate(pc));
}
}
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
} // namespace internal
......
......@@ -328,6 +328,10 @@ class TurboAssembler : public Assembler {
Register exclusion2 = no_reg,
Register exclusion3 = no_reg);
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(Register dst);
void ResetSpeculationPoisonRegister();
private:
......
......@@ -5292,6 +5292,24 @@ bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
return n_of_valid_regs != n_of_non_aliasing_regs;
}
void TurboAssembler::ComputeCodeStartAddress(Register dst) {
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing the code start address.
push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
Label current;
bal(&current);
nop();
int pc = pc_offset();
bind(&current);
li(dst, pc);
subu(dst, ra, dst);
pop(ra); // Restore ra
}
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
} // namespace internal
......
......@@ -847,6 +847,10 @@ class TurboAssembler : public Assembler {
BranchF64(bd, target, nan, cc, cmp1, cmp2);
}
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(Register dst);
void ResetSpeculationPoisonRegister();
protected:
......
......@@ -5558,6 +5558,24 @@ bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
return n_of_valid_regs != n_of_non_aliasing_regs;
}
void TurboAssembler::ComputeCodeStartAddress(Register dst) {
// This push on ra and the pop below together ensure that we restore the
// register ra, which is needed while computing the code start address.
push(ra);
// The bal instruction puts the address of the current instruction into
// the return address (ra) register, which we can use later on.
Label current;
bal(&current);
nop();
int pc = pc_offset();
bind(&current);
li(dst, Operand(pc));
Dsubu(dst, ra, dst);
pop(ra); // Restore ra
}
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
} // namespace internal
......
......@@ -878,6 +878,10 @@ class TurboAssembler : public Assembler {
void Dlsa(Register rd, Register rs, Register rt, uint8_t sa,
Register scratch = at);
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(Register dst);
void ResetSpeculationPoisonRegister();
protected:
......
......@@ -2764,6 +2764,17 @@ void TurboAssembler::CheckPageFlag(Register object, Register scratch, int mask,
j(cc, condition_met, condition_met_distance);
}
void TurboAssembler::ComputeCodeStartAddress(Register dst) {
Label current;
// Load effective address to get the address of the current instruction.
leaq(dst, Operand(&current));
bind(&current);
int pc = pc_offset();
if (pc != 0) {
subq(dst, Immediate(pc));
}
}
void TurboAssembler::ResetSpeculationPoisonRegister() {
Set(kSpeculationPoisonRegister, -1);
}
......
......@@ -479,6 +479,10 @@ class TurboAssembler : public Assembler {
Register exclusion2 = no_reg,
Register exclusion3 = no_reg);
// Compute the start of the generated instruction stream from the current PC.
// This is an alternative to embedding the {CodeObject} handle as a reference.
void ComputeCodeStartAddress(Register dst);
void ResetSpeculationPoisonRegister();
protected:
......
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