mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 16:19:07 +00:00
[VM] Use one instruction to unwind frame and return instead of two on ARM
This reduces AOT flutter gallery RX size by 0.81 %. Issue https://github.com/dart-lang/sdk/issues/33274 Change-Id: I1a3c3f48af9ae5d89d3d89da1d86c798145dbd99 Reviewed-on: https://dart-review.googlesource.com/72383 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
parent
ffdcc72678
commit
c5295037c4
|
@ -3007,8 +3007,8 @@ void Assembler::EnterFrame(RegList regs, intptr_t frame_size) {
|
|||
}
|
||||
}
|
||||
|
||||
void Assembler::LeaveFrame(RegList regs) {
|
||||
ASSERT((regs & (1 << PC)) == 0); // Must not pop PC.
|
||||
void Assembler::LeaveFrame(RegList regs, bool allow_pop_pc) {
|
||||
ASSERT(allow_pop_pc || (regs & (1 << PC)) == 0); // Must not pop PC.
|
||||
if ((regs & (1 << FP)) != 0) {
|
||||
// Use FP to set SP.
|
||||
sub(SP, FP, Operand(4 * NumRegsBelowFP(regs)));
|
||||
|
@ -3122,18 +3122,26 @@ void Assembler::EnterOsrFrame(intptr_t extra_size) {
|
|||
AddImmediate(SP, -extra_size);
|
||||
}
|
||||
|
||||
void Assembler::LeaveDartFrame(RestorePP restore_pp) {
|
||||
if (restore_pp == kRestoreCallerPP) {
|
||||
ldr(PP,
|
||||
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
|
||||
set_constant_pool_allowed(false);
|
||||
}
|
||||
void Assembler::LeaveDartFrame() {
|
||||
ldr(PP,
|
||||
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
|
||||
set_constant_pool_allowed(false);
|
||||
|
||||
// This will implicitly drop saved PP, PC marker due to restoring SP from FP
|
||||
// first.
|
||||
LeaveFrame((1 << FP) | (1 << LR));
|
||||
}
|
||||
|
||||
void Assembler::LeaveDartFrameAndReturn() {
|
||||
ldr(PP,
|
||||
Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
|
||||
set_constant_pool_allowed(false);
|
||||
|
||||
// This will implicitly drop saved PP, PC marker due to restoring SP from FP
|
||||
// first.
|
||||
LeaveFrame((1 << FP) | (1 << PC), /*allow_pop_pc=*/true);
|
||||
}
|
||||
|
||||
void Assembler::EnterStubFrame() {
|
||||
EnterDartFrame(0);
|
||||
}
|
||||
|
|
|
@ -1010,7 +1010,7 @@ class Assembler : public ValueObject {
|
|||
|
||||
// Function frame setup and tear down.
|
||||
void EnterFrame(RegList regs, intptr_t frame_space);
|
||||
void LeaveFrame(RegList regs);
|
||||
void LeaveFrame(RegList regs, bool allow_pop_pc = false);
|
||||
void Ret();
|
||||
void ReserveAlignedFrameSpace(intptr_t frame_space);
|
||||
|
||||
|
@ -1026,7 +1026,22 @@ class Assembler : public ValueObject {
|
|||
// enable easy access to the RawInstruction object of code corresponding
|
||||
// to this frame.
|
||||
void EnterDartFrame(intptr_t frame_size);
|
||||
void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP);
|
||||
|
||||
void LeaveDartFrame();
|
||||
|
||||
// Leaves the frame and returns.
|
||||
//
|
||||
// The difference to "LeaveDartFrame(); Ret();" is that we return using
|
||||
//
|
||||
// ldmia sp!, {fp, pc}
|
||||
//
|
||||
// instead of
|
||||
//
|
||||
// ldmia sp!, {fp, lr}
|
||||
// blx lr
|
||||
//
|
||||
// This means that our return must go to ARM mode (and not thumb).
|
||||
void LeaveDartFrameAndReturn();
|
||||
|
||||
// Set up a Dart frame for a function compiled for on-stack replacement.
|
||||
// The frame layout is a normal Dart frame, but the frame is partially set
|
||||
|
|
|
@ -138,8 +138,7 @@ void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
__ Bind(&stack_ok);
|
||||
#endif
|
||||
ASSERT(__ constant_pool_allowed());
|
||||
__ LeaveDartFrame(); // Disallows constant pool use.
|
||||
__ Ret();
|
||||
__ LeaveDartFrameAndReturn(); // Disallows constant pool use.
|
||||
// This ReturnInstr may be emitted out of order by the optimizer. The next
|
||||
// block may be a target expecting a properly set constant pool pointer.
|
||||
__ set_constant_pool_allowed(true);
|
||||
|
|
|
@ -36,8 +36,7 @@ void GenerateEmbedStringInCode(Assembler* assembler, const char* str) {
|
|||
const String& string_object =
|
||||
String::ZoneHandle(String::New(str, Heap::kOld));
|
||||
__ LoadObject(R0, string_object);
|
||||
__ LeaveDartFrame();
|
||||
__ Ret();
|
||||
__ LeaveDartFrameAndReturn();
|
||||
}
|
||||
|
||||
// Generate a dart code sequence that embeds a smi object in it.
|
||||
|
|
|
@ -46,8 +46,7 @@ static void GenerateCallToCallRuntimeStub(Assembler* assembler, int length) {
|
|||
__ CallRuntime(kAllocateArrayRuntimeEntry, argc);
|
||||
__ AddImmediate(SP, argc * kWordSize);
|
||||
__ Pop(R0); // Pop return value from return slot.
|
||||
__ LeaveDartFrame();
|
||||
__ Ret();
|
||||
__ LeaveDartFrameAndReturn();
|
||||
}
|
||||
|
||||
TEST_CASE(CallRuntimeStubCode) {
|
||||
|
@ -83,8 +82,7 @@ static void GenerateCallToCallLeafRuntimeStub(Assembler* assembler,
|
|||
__ LoadObject(R2, rhs_index);
|
||||
__ LoadObject(R3, length);
|
||||
__ CallRuntime(kCaseInsensitiveCompareUC16RuntimeEntry, 4);
|
||||
__ LeaveDartFrame();
|
||||
__ Ret(); // Return value is in R0.
|
||||
__ LeaveDartFrameAndReturn(); // Return value is in R0.
|
||||
}
|
||||
|
||||
TEST_CASE(CallLeafRuntimeStubCode) {
|
||||
|
|
Loading…
Reference in a new issue