Commit f11cf0af authored by Victor Gomes's avatar Victor Gomes Committed by Commit Bot

[compiler] Change AssembleReturn to use ret instead of jmp

- Improves return address prediction
- Fix PopAndReturn CSA tests

Change-Id: I5ed76e32bb997f47dcce725511a8653e34a4c398
Bug: v8:10201
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2435369
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Reviewed-by: 's avatarDan Elphick <delphick@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70169}
parent ce38a067
......@@ -208,6 +208,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void Popcnt(Register dst, Register src) { Popcnt(dst, Operand(src)); }
void Popcnt(Register dst, Operand src);
void PushReturnAddressFrom(Register src) { push(src); }
void PopReturnAddressTo(Register dst) { pop(dst); }
void Ret();
// Root register utility functions.
......@@ -820,8 +823,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void Pop(Register dst) { pop(dst); }
void Pop(Operand dst) { pop(dst); }
void PushReturnAddressFrom(Register src) { push(src); }
void PopReturnAddressTo(Register dst) { pop(dst); }
// ---------------------------------------------------------------------------
// In-place weak references.
......
......@@ -4834,10 +4834,11 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
} else {
Register pop_reg = g.ToRegister(pop);
Register scratch_reg = pop_reg == ecx ? edx : ecx;
__ pop(scratch_reg);
__ PopReturnAddressTo(scratch_reg);
__ lea(esp, Operand(esp, pop_reg, times_system_pointer_size,
static_cast<int>(pop_size)));
__ jmp(scratch_reg);
__ PushReturnAddressFrom(scratch_reg);
__ Ret();
}
}
......
......@@ -4622,9 +4622,10 @@ void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
} else {
Register pop_reg = g.ToRegister(pop);
Register scratch_reg = pop_reg == rcx ? rdx : rcx;
__ popq(scratch_reg);
__ PopReturnAddressTo(scratch_reg);
__ leaq(rsp, Operand(rsp, pop_reg, times_8, static_cast<int>(pop_size)));
__ jmp(scratch_reg);
__ PushReturnAddressFrom(scratch_reg);
__ Ret();
}
}
......
......@@ -1946,6 +1946,7 @@ TEST(PopAndReturnConstant) {
// Call a function that return |kNumProgramaticParams| parameters in addition
// to those specified by the static descriptor. |kNumProgramaticParams| is
// specified as a constant.
CSA_CHECK(&m, m.SmiEqual(m.CAST(m.Parameter(2)), m.SmiConstant(5678)));
m.PopAndReturn(m.Int32Constant(kNumProgrammaticParams),
m.SmiConstant(Smi::FromInt(1234)));
......@@ -1975,16 +1976,17 @@ TEST(PopAndReturnVariable) {
// to those specified by the static descriptor. |kNumProgramaticParams| is
// passed in as a parameter to the function so that it can't be recognized as
// a constant.
m.PopAndReturn(m.SmiUntag(m.CAST(m.Parameter(2))),
CSA_CHECK(&m, m.SmiEqual(m.CAST(m.Parameter(2)), m.SmiConstant(5678)));
m.PopAndReturn(m.SmiUntag(m.CAST(m.Parameter(1))),
m.SmiConstant(Smi::FromInt(1234)));
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
Handle<Object> result;
for (int test_count = 0; test_count < 100; ++test_count) {
result = ft.Call(isolate->factory()->undefined_value(),
result = ft.Call(Handle<Smi>(Smi::FromInt(kNumProgrammaticParams), isolate),
Handle<Smi>(Smi::FromInt(5678), isolate),
isolate->factory()->undefined_value(),
Handle<Smi>(Smi::FromInt(kNumProgrammaticParams), isolate))
isolate->factory()->undefined_value())
.ToHandleChecked();
CHECK_EQ(1234, Handle<Smi>::cast(result)->value());
}
......
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