@@ -1485,7 +1485,7 @@ void Assembler::TransitionNativeToGenerated(Register state,
14851485 StoreToOffset (state, THR, target::Thread::exit_through_ffi_offset ());
14861486}
14871487
1488- void Assembler::EnterCallRuntimeFrame (intptr_t frame_size) {
1488+ void Assembler::EnterCallRuntimeFrame (intptr_t frame_size, bool is_leaf ) {
14891489 Comment (" EnterCallRuntimeFrame" );
14901490 EnterFrame (0 );
14911491 if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
@@ -1510,19 +1510,30 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
15101510 Push (reg);
15111511 }
15121512
1513- ReserveAlignedFrameSpace (frame_size);
1513+ if (!is_leaf) { // Leaf calling sequence aligns the stack itself.
1514+ ReserveAlignedFrameSpace (frame_size);
1515+ } else {
1516+ PushPair (kCallLeafRuntimeCalleeSaveScratch1 ,
1517+ kCallLeafRuntimeCalleeSaveScratch2 );
1518+ }
15141519}
15151520
1516- void Assembler::LeaveCallRuntimeFrame () {
1521+ void Assembler::LeaveCallRuntimeFrame (bool is_leaf ) {
15171522 // SP might have been modified to reserve space for arguments
15181523 // and ensure proper alignment of the stack frame.
15191524 // We need to restore it before restoring registers.
1525+ const intptr_t fixed_frame_words_without_pc_and_fp =
1526+ target::frame_layout.dart_fixed_frame_size - 2 ;
15201527 const intptr_t kPushedRegistersSize =
1521- kDartVolatileCpuRegCount * target:: kWordSize +
1522- kDartVolatileFpuRegCount * target:: kWordSize +
1523- (target::frame_layout. dart_fixed_frame_size - 2 ) *
1524- target::kWordSize ; // From EnterStubFrame (excluding PC / FP)
1528+ kDartVolatileFpuRegCount * sizeof ( double ) +
1529+ ( kDartVolatileCpuRegCount + (is_leaf ? 2 : 0 ) +
1530+ fixed_frame_words_without_pc_and_fp ) *
1531+ target::kWordSize ;
15251532 AddImmediate (SP, FP, -kPushedRegistersSize );
1533+ if (is_leaf) {
1534+ PopPair (kCallLeafRuntimeCalleeSaveScratch1 ,
1535+ kCallLeafRuntimeCalleeSaveScratch2 );
1536+ }
15261537 for (int i = kDartLastVolatileCpuReg ; i >= kDartFirstVolatileCpuReg ; i--) {
15271538 const Register reg = static_cast <Register>(i);
15281539 Pop (reg);
@@ -1547,6 +1558,37 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
15471558 entry.Call (this , argument_count);
15481559}
15491560
1561+ void Assembler::CallRuntimeScope::Call (intptr_t argument_count) {
1562+ assembler_->CallRuntime (entry_, argument_count);
1563+ }
1564+
1565+ Assembler::CallRuntimeScope::~CallRuntimeScope () {
1566+ if (preserve_registers_) {
1567+ assembler_->LeaveCallRuntimeFrame (entry_.is_leaf ());
1568+ if (restore_code_reg_) {
1569+ assembler_->Pop (CODE_REG);
1570+ }
1571+ }
1572+ }
1573+
1574+ Assembler::CallRuntimeScope::CallRuntimeScope (Assembler* assembler,
1575+ const RuntimeEntry& entry,
1576+ intptr_t frame_size,
1577+ bool preserve_registers,
1578+ const Address* caller)
1579+ : assembler_(assembler),
1580+ entry_ (entry),
1581+ preserve_registers_(preserve_registers),
1582+ restore_code_reg_(caller != nullptr ) {
1583+ if (preserve_registers_) {
1584+ if (caller != nullptr ) {
1585+ assembler_->Push (CODE_REG);
1586+ assembler_->ldr (CODE_REG, *caller);
1587+ }
1588+ assembler_->EnterCallRuntimeFrame (frame_size, entry.is_leaf ());
1589+ }
1590+ }
1591+
15501592void Assembler::EnterStubFrame () {
15511593 EnterDartFrame (0 );
15521594}
0 commit comments