diff options
author | 2016-07-28 12:01:51 +0100 | |
---|---|---|
committer | 2016-08-04 14:51:52 +0100 | |
commit | 952dbb19cd094b8bfb01dbb33e0878db429e499a (patch) | |
tree | 82932c2b00245042e2c129f3d4133f6431657da3 | |
parent | df638c66d1f385d4e217b2ab22c5e48a7eefdef4 (diff) |
Change suspend entrypoint to save all registers.
We avoid the need to save/restore registers in slow paths
and get significant code size savings. On Nexus 9, AOSP:
- 32-bit boot.oat: -1.4MiB (-1.9%)
- 64-bit boot.oat: -2.0MiB (-2.3%)
- other 32-bit oat files in dalvik-cache: -200KiB (-1.7%)
- other 64-bit oat files in dalvik-cache: -2.3MiB (-2.1%)
Test: Run ART test suite on host and Nexus 9 with gc stress.
Bug: 30212852
Change-Id: I7015afc1e7d30341618c9200a3dc9ae277afd134
35 files changed, 1090 insertions, 111 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 063eb11718..0f6944ac6a 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -1377,6 +1377,8 @@ void ImageWriter::CalculateNewObjectOffsets() { runtime->GetCalleeSaveMethod(Runtime::kRefsOnly); image_methods_[ImageHeader::kRefsAndArgsSaveMethod] = runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs); + image_methods_[ImageHeader::kSaveEverythingMethod] = + runtime->GetCalleeSaveMethod(Runtime::kSaveEverything); // Visit image methods first to have the main runtime methods in the first image. for (auto* m : image_methods_) { CHECK(m != nullptr); diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 3269dc6605..94ecb1c63c 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -765,16 +765,24 @@ void CodeGenerator::RecordPcInfo(HInstruction* instruction, LocationSummary* locations = instruction->GetLocations(); uint32_t register_mask = locations->GetRegisterMask(); - if (locations->OnlyCallsOnSlowPath()) { - // In case of slow path, we currently set the location of caller-save registers - // to register (instead of their stack location when pushed before the slow-path - // call). Therefore register_mask contains both callee-save and caller-save - // registers that hold objects. We must remove the caller-save from the mask, since - // they will be overwritten by the callee. - register_mask &= core_callee_save_mask_; + if (instruction->IsSuspendCheck()) { + // Suspend check has special ABI that saves the caller-save registers in callee, + // so we want to emit stack maps containing the registers. + // TODO: Register allocator still reserves space for the caller-save registers. + // We should add slow-path-specific caller-save information into LocationSummary + // and refactor the code here as well as in the register allocator to use it. + } else { + if (locations->OnlyCallsOnSlowPath()) { + // In case of slow path, we currently set the location of caller-save registers + // to register (instead of their stack location when pushed before the slow-path + // call). Therefore register_mask contains both callee-save and caller-save + // registers that hold objects. We must remove the caller-save from the mask, since + // they will be overwritten by the callee. + register_mask &= core_callee_save_mask_; + } + // The register mask must be a subset of callee-save registers. + DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask); } - // The register mask must be a subset of callee-save registers. - DCHECK_EQ(register_mask & core_callee_save_mask_, register_mask); stack_map_stream_.BeginStackMapEntry(outer_dex_pc, native_pc, register_mask, diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 124a61fe67..62f3ee9be7 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -119,11 +119,9 @@ class SuspendCheckSlowPathARM : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); arm_codegen->InvokeRuntime( QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ b(GetReturnLabel()); } else { diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index efeef7bb6f..21ca506077 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -398,11 +398,9 @@ class SuspendCheckSlowPathARM64 : public SlowPathCodeARM64 { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM64* arm64_codegen = down_cast<CodeGeneratorARM64*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); arm64_codegen->InvokeRuntime( QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ B(GetReturnLabel()); } else { diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 334d30d90e..bdd75b634b 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -351,14 +351,12 @@ class SuspendCheckSlowPathMIPS : public SlowPathCodeMIPS { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorMIPS* mips_codegen = down_cast<CodeGeneratorMIPS*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); mips_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this, IsDirectEntrypoint(kQuickTestSuspend)); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ B(GetReturnLabel()); } else { diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 29b8c206e6..e16abc52d1 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -300,13 +300,11 @@ class SuspendCheckSlowPathMIPS64 : public SlowPathCodeMIPS64 { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorMIPS64* mips64_codegen = down_cast<CodeGeneratorMIPS64*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); mips64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ Bc(GetReturnLabel()); } else { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 528e94f76b..3fb4fe8c72 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -192,13 +192,11 @@ class SuspendCheckSlowPathX86 : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ jmp(GetReturnLabel()); } else { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 0f0129b421..b0c3caa5b1 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -149,13 +149,11 @@ class SuspendCheckSlowPathX86_64 : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorX86_64* x86_64_codegen = down_cast<CodeGeneratorX86_64*>(codegen); __ Bind(GetEntryLabel()); - SaveLiveRegisters(codegen, instruction_->GetLocations()); x86_64_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); - RestoreLiveRegisters(codegen, instruction_->GetLocations()); if (successor_ == nullptr) { __ jmp(GetReturnLabel()); } else { diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 64349b5bc3..532bccf842 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -76,6 +76,7 @@ const char* image_methods_descriptions_[] = { "kCalleeSaveMethod", "kRefsOnlySaveMethod", "kRefsAndArgsSaveMethod", + "kSaveEverythingMethod", }; const char* image_roots_descriptions_[] = { diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc index ee31c58979..6d80eb6198 100644 --- a/runtime/arch/arch_test.cc +++ b/runtime/arch/arch_test.cc @@ -69,7 +69,9 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace arm namespace arm64 { #include "arch/arm64/asm_support_arm64.h" @@ -79,7 +81,9 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace arm64 namespace mips { #include "arch/mips/asm_support_mips.h" @@ -89,7 +93,9 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace mips namespace mips64 { #include "arch/mips64/asm_support_mips64.h" @@ -99,7 +105,9 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace mips64 namespace x86 { #include "arch/x86/asm_support_x86.h" @@ -109,7 +117,9 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace x86 namespace x86_64 { #include "arch/x86_64/asm_support_x86_64.h" @@ -119,13 +129,18 @@ static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALL #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE -} +static constexpr size_t kFrameSizeSaveEverythingCalleeSave = FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE; +#undef FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE +} // namespace x86_64 // Check architecture specific constants are sound. TEST_F(ArchTest, ARM) { CheckFrameSize(InstructionSet::kArm, Runtime::kSaveAll, arm::kFrameSizeSaveAllCalleeSave); CheckFrameSize(InstructionSet::kArm, Runtime::kRefsOnly, arm::kFrameSizeRefsOnlyCalleeSave); CheckFrameSize(InstructionSet::kArm, Runtime::kRefsAndArgs, arm::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kArm, + Runtime::kSaveEverything, + arm::kFrameSizeSaveEverythingCalleeSave); } @@ -134,33 +149,51 @@ TEST_F(ArchTest, ARM64) { CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsOnly, arm64::kFrameSizeRefsOnlyCalleeSave); CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsAndArgs, arm64::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kArm64, + Runtime::kSaveEverything, + arm64::kFrameSizeSaveEverythingCalleeSave); } TEST_F(ArchTest, MIPS) { CheckFrameSize(InstructionSet::kMips, Runtime::kSaveAll, mips::kFrameSizeSaveAllCalleeSave); CheckFrameSize(InstructionSet::kMips, Runtime::kRefsOnly, mips::kFrameSizeRefsOnlyCalleeSave); - CheckFrameSize(InstructionSet::kMips, Runtime::kRefsAndArgs, + CheckFrameSize(InstructionSet::kMips, + Runtime::kRefsAndArgs, mips::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kMips, + Runtime::kSaveEverything, + mips::kFrameSizeSaveEverythingCalleeSave); } TEST_F(ArchTest, MIPS64) { CheckFrameSize(InstructionSet::kMips64, Runtime::kSaveAll, mips64::kFrameSizeSaveAllCalleeSave); CheckFrameSize(InstructionSet::kMips64, Runtime::kRefsOnly, mips64::kFrameSizeRefsOnlyCalleeSave); - CheckFrameSize(InstructionSet::kMips64, Runtime::kRefsAndArgs, + CheckFrameSize(InstructionSet::kMips64, + Runtime::kRefsAndArgs, mips64::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kMips64, + Runtime::kSaveEverything, + mips64::kFrameSizeSaveEverythingCalleeSave); } TEST_F(ArchTest, X86) { CheckFrameSize(InstructionSet::kX86, Runtime::kSaveAll, x86::kFrameSizeSaveAllCalleeSave); CheckFrameSize(InstructionSet::kX86, Runtime::kRefsOnly, x86::kFrameSizeRefsOnlyCalleeSave); CheckFrameSize(InstructionSet::kX86, Runtime::kRefsAndArgs, x86::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kX86, + Runtime::kSaveEverything, + x86::kFrameSizeSaveEverythingCalleeSave); } TEST_F(ArchTest, X86_64) { CheckFrameSize(InstructionSet::kX86_64, Runtime::kSaveAll, x86_64::kFrameSizeSaveAllCalleeSave); CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsOnly, x86_64::kFrameSizeRefsOnlyCalleeSave); - CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsAndArgs, + CheckFrameSize(InstructionSet::kX86_64, + Runtime::kRefsAndArgs, x86_64::kFrameSizeRefsAndArgsCalleeSave); + CheckFrameSize(InstructionSet::kX86_64, + Runtime::kSaveEverything, + x86_64::kFrameSizeSaveEverythingCalleeSave); } } // namespace art diff --git a/runtime/arch/arm/asm_support_arm.h b/runtime/arch/arm/asm_support_arm.h index 1fa566bb5c..67f6f7a4c4 100644 --- a/runtime/arch/arm/asm_support_arm.h +++ b/runtime/arch/arm/asm_support_arm.h @@ -22,6 +22,7 @@ #define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 112 #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 32 #define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 112 +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE 192 // Flag for enabling R4 optimization in arm runtime // #define ARM_R4_SUSPEND_FLAG diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 34d3158c62..ee59068698 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -168,6 +168,65 @@ .cfi_adjust_cfa_offset -40 .endm + /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything) + */ +.macro SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME rTemp + push {r0-r12, lr} @ 14 words of callee saves and args. + .cfi_adjust_cfa_offset 56 + .cfi_rel_offset r0, 0 + .cfi_rel_offset r1, 4 + .cfi_rel_offset r2, 8 + .cfi_rel_offset r3, 12 + .cfi_rel_offset r4, 16 + .cfi_rel_offset r5, 20 + .cfi_rel_offset r6, 24 + .cfi_rel_offset r7, 28 + .cfi_rel_offset r8, 32 + .cfi_rel_offset r9, 36 + .cfi_rel_offset r10, 40 + .cfi_rel_offset r11, 44 + .cfi_rel_offset ip, 48 + .cfi_rel_offset lr, 52 + vpush {s0-s31} @ 32 words of float args. + .cfi_adjust_cfa_offset 128 + sub sp, #8 @ 2 words of space, alignment padding and Method* + .cfi_adjust_cfa_offset 8 + RUNTIME_CURRENT1 \rTemp @ Load Runtime::Current into rTemp. + @ Load kSaveEverything Method* to rTemp. + ldr \rTemp, [\rTemp, #RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET] + str \rTemp, [sp, #0] @ Store kSaveEverything Method* to the bottom of the stack. + str sp, [r9, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame. + + // Ugly compile-time check, but we only have the preprocessor. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 56 + 128 + 8) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(ARM) size not as expected." +#endif +.endm + +.macro RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + add sp, #8 @ rewind sp + .cfi_adjust_cfa_offset -8 + vpop {s0-s31} + .cfi_adjust_cfa_offset -128 + pop {r0-r12, lr} @ 14 words of callee saves + .cfi_restore r0 + .cfi_restore r1 + .cfi_restore r2 + .cfi_restore r3 + .cfi_restore r5 + .cfi_restore r6 + .cfi_restore r7 + .cfi_restore r8 + .cfi_restore r9 + .cfi_restore r10 + .cfi_restore r11 + .cfi_restore r12 + .cfi_restore lr + .cfi_adjust_cfa_offset -56 +.endm + .macro RETURN_IF_RESULT_IS_ZERO cbnz r0, 1f @ result non-zero branch over bx lr @ return @@ -1212,17 +1271,18 @@ END art_quick_alloc_object_region_tlab .extern artTestSuspendFromCode ENTRY art_quick_test_suspend #ifdef ARM_R4_SUSPEND_FLAG - ldrh r0, [rSELF, #THREAD_FLAGS_OFFSET] - mov rSUSPEND, #SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL - cbnz r0, 1f @ check Thread::Current()->suspend_count_ == 0 - bx lr @ return if suspend_count_ == 0 + ldrh rSUSPEND, [rSELF, #THREAD_FLAGS_OFFSET] + cbnz rSUSPEND, 1f @ check Thread::Current()->suspend_count_ == 0 + mov rSUSPEND, #SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL + bx lr @ return if suspend_count_ == 0 1: + mov rSUSPEND, #SUSPEND_CHECK_INTERVAL @ reset rSUSPEND to SUSPEND_CHECK_INTERVAL #endif + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME r0 @ save everything for GC stack crawl mov r0, rSELF - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME r1 @ save callee saves for GC stack crawl - @ TODO: save FPRs to enable access in the debugger? - bl artTestSuspendFromCode @ (Thread*) - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN + bl artTestSuspendFromCode @ (Thread*) + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + bx lr END art_quick_test_suspend ENTRY art_quick_implicit_suspend diff --git a/runtime/arch/arm/quick_method_frame_info_arm.h b/runtime/arch/arm/quick_method_frame_info_arm.h index 5580ee4f17..3e726e0cb6 100644 --- a/runtime/arch/arm/quick_method_frame_info_arm.h +++ b/runtime/arch/arm/quick_method_frame_info_arm.h @@ -34,6 +34,9 @@ static constexpr uint32_t kArmCalleeSaveArgSpills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3); static constexpr uint32_t kArmCalleeSaveAllSpills = (1 << art::arm::R4) | (1 << art::arm::R9); +static constexpr uint32_t kArmCalleeSaveEverythingSpills = + (1 << art::arm::R0) | (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3) | + (1 << art::arm::R4) | (1 << art::arm::R9) | (1 << art::arm::R12); static constexpr uint32_t kArmCalleeSaveFpAlwaysSpills = 0; static constexpr uint32_t kArmCalleeSaveFpRefSpills = 0; @@ -47,17 +50,21 @@ static constexpr uint32_t kArmCalleeSaveFpAllSpills = (1 << art::arm::S20) | (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) | (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) | (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) | (1 << art::arm::S30) | (1 << art::arm::S31); +static constexpr uint32_t kArmCalleeSaveFpEverythingSpills = + kArmCalleeSaveFpArgSpills | kArmCalleeSaveFpAllSpills; constexpr uint32_t ArmCalleeSaveCoreSpills(Runtime::CalleeSaveType type) { return kArmCalleeSaveAlwaysSpills | kArmCalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kArmCalleeSaveArgSpills : 0) | - (type == Runtime::kSaveAll ? kArmCalleeSaveAllSpills : 0); + (type == Runtime::kSaveAll ? kArmCalleeSaveAllSpills : 0) | + (type == Runtime::kSaveEverything ? kArmCalleeSaveEverythingSpills : 0); } constexpr uint32_t ArmCalleeSaveFpSpills(Runtime::CalleeSaveType type) { return kArmCalleeSaveFpAlwaysSpills | kArmCalleeSaveFpRefSpills | (type == Runtime::kRefsAndArgs ? kArmCalleeSaveFpArgSpills: 0) | - (type == Runtime::kSaveAll ? kArmCalleeSaveFpAllSpills : 0); + (type == Runtime::kSaveAll ? kArmCalleeSaveFpAllSpills : 0) | + (type == Runtime::kSaveEverything ? kArmCalleeSaveFpEverythingSpills : 0); } constexpr uint32_t ArmCalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/arch/arm64/asm_support_arm64.h b/runtime/arch/arm64/asm_support_arm64.h index 989ecc6c5b..68d12e9306 100644 --- a/runtime/arch/arm64/asm_support_arm64.h +++ b/runtime/arch/arm64/asm_support_arm64.h @@ -22,5 +22,6 @@ #define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 176 #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 96 #define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 224 +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE 512 #endif // ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_ diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index a5be52d8a0..971b84388f 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -316,6 +316,204 @@ .cfi_adjust_cfa_offset -224 .endm + /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything) + */ +.macro SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + sub sp, sp, #512 + .cfi_adjust_cfa_offset 512 + + // Ugly compile-time check, but we only have the preprocessor. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 512) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(ARM64) size not as expected." +#endif + + // Save FP registers. + stp d0, d1, [sp, #8] + stp d2, d3, [sp, #24] + stp d4, d5, [sp, #40] + stp d6, d7, [sp, #56] + stp d8, d9, [sp, #72] + stp d10, d11, [sp, #88] + stp d12, d13, [sp, #104] + stp d14, d15, [sp, #120] + stp d16, d17, [sp, #136] + stp d18, d19, [sp, #152] + stp d20, d21, [sp, #168] + stp d22, d23, [sp, #184] + stp d24, d25, [sp, #200] + stp d26, d27, [sp, #216] + stp d28, d29, [sp, #232] + stp d30, d31, [sp, #248] + + // Save core registers. + str x0, [sp, #264] + .cfi_rel_offset x0, 264 + + stp x1, x2, [sp, #272] + .cfi_rel_offset x1, 272 + .cfi_rel_offset x2, 280 + + stp x3, x4, [sp, #288] + .cfi_rel_offset x3, 288 + .cfi_rel_offset x4, 296 + + stp x5, x6, [sp, #304] + .cfi_rel_offset x5, 304 + .cfi_rel_offset x6, 312 + + stp x7, x8, [sp, #320] + .cfi_rel_offset x7, 320 + .cfi_rel_offset x8, 328 + + stp x9, x10, [sp, #336] + .cfi_rel_offset x9, 336 + .cfi_rel_offset x10, 344 + + stp x11, x12, [sp, #352] + .cfi_rel_offset x11, 352 + .cfi_rel_offset x12, 360 + + stp x13, x14, [sp, #368] + .cfi_rel_offset x13, 368 + .cfi_rel_offset x14, 376 + + stp x15, x16, [sp, #384] + .cfi_rel_offset x15, 384 + .cfi_rel_offset x16, 392 + + stp x17, x18, [sp, #400] + .cfi_rel_offset x17, 400 + .cfi_rel_offset x18, 408 + + stp x19, x20, [sp, #416] + .cfi_rel_offset x19, 416 + .cfi_rel_offset x20, 424 + + stp x21, x22, [sp, #432] + .cfi_rel_offset x21, 432 + .cfi_rel_offset x22, 440 + + stp x23, x24, [sp, #448] + .cfi_rel_offset x23, 448 + .cfi_rel_offset x24, 456 + + stp x25, x26, [sp, #464] + .cfi_rel_offset x25, 464 + .cfi_rel_offset x26, 472 + + stp x27, x28, [sp, #480] + .cfi_rel_offset x27, 480 + .cfi_rel_offset x28, 488 + + stp x29, xLR, [sp, #496] + .cfi_rel_offset x29, 496 + .cfi_rel_offset x30, 504 + + adrp xIP0, :got:_ZN3art7Runtime9instance_E + ldr xIP0, [xIP0, #:got_lo12:_ZN3art7Runtime9instance_E] + + ldr xIP0, [xIP0] // xIP0 = & (art::Runtime * art::Runtime.instance_) . + + // xIP0 = (ArtMethod*) Runtime.instance_.callee_save_methods[kSaveEverything] . + // Loads appropriate callee-save-method. + ldr xIP0, [xIP0, RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET ] + + // Store ArtMethod* Runtime::callee_save_methods_[kSaveEverything]. + str xIP0, [sp] + // Place sp in Thread::Current()->top_quick_frame. + mov xIP0, sp + str xIP0, [xSELF, # THREAD_TOP_QUICK_FRAME_OFFSET] +.endm + +.macro RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + // Restore FP registers. + ldp d0, d1, [sp, #8] + ldp d2, d3, [sp, #24] + ldp d4, d5, [sp, #40] + ldp d6, d7, [sp, #56] + ldp d8, d9, [sp, #72] + ldp d10, d11, [sp, #88] + ldp d12, d13, [sp, #104] + ldp d14, d15, [sp, #120] + ldp d16, d17, [sp, #136] + ldp d18, d19, [sp, #152] + ldp d20, d21, [sp, #168] + ldp d22, d23, [sp, #184] + ldp d24, d25, [sp, #200] + ldp d26, d27, [sp, #216] + ldp d28, d29, [sp, #232] + ldp d30, d31, [sp, #248] + + // Restore core registers. + ldr x0, [sp, #264] + .cfi_restore x0 + + ldp x1, x2, [sp, #272] + .cfi_restore x1 + .cfi_restore x2 + + ldp x3, x4, [sp, #288] + .cfi_restore x3 + .cfi_restore x4 + + ldp x5, x6, [sp, #304] + .cfi_restore x5 + .cfi_restore x6 + + ldp x7, x8, [sp, #320] + .cfi_restore x7 + .cfi_restore x8 + + ldp x9, x10, [sp, #336] + .cfi_restore x9 + .cfi_restore x10 + + ldp x11, x12, [sp, #352] + .cfi_restore x11 + .cfi_restore x12 + + ldp x13, x14, [sp, #368] + .cfi_restore x13 + .cfi_restore x14 + + ldp x15, x16, [sp, #384] + .cfi_restore x15 + .cfi_restore x16 + + ldp x17, x18, [sp, #400] + .cfi_restore x17 + .cfi_restore x18 + + ldp x19, x20, [sp, #416] + .cfi_restore x19 + .cfi_restore x20 + + ldp x21, x22, [sp, #432] + .cfi_restore x21 + .cfi_restore x22 + + ldp x23, x24, [sp, #448] + .cfi_restore x23 + .cfi_restore x24 + + ldp x25, x26, [sp, #464] + .cfi_restore x25 + .cfi_restore x26 + + ldp x27, x28, [sp, #480] + .cfi_restore x27 + .cfi_restore x28 + + ldp x29, xLR, [sp, #496] + .cfi_restore x29 + .cfi_restore x30 + + add sp, sp, #512 + .cfi_adjust_cfa_offset -512 +.endm + .macro RETURN_IF_RESULT_IS_ZERO cbnz x0, 1f // result non-zero branch over ret // return @@ -1821,14 +2019,11 @@ END art_quick_alloc_object_region_tlab */ .extern artTestSuspendFromCode ENTRY art_quick_test_suspend - ldrh w0, [xSELF, #THREAD_FLAGS_OFFSET] // get xSELF->state_and_flags.as_struct.flags - cbnz w0, .Lneed_suspend // check flags == 0 - ret // return if flags == 0 -.Lneed_suspend: + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME // save callee saves for stack crawl mov x0, xSELF - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME // save callee saves for stack crawl bl artTestSuspendFromCode // (Thread*) - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + ret END art_quick_test_suspend ENTRY art_quick_implicit_suspend diff --git a/runtime/arch/arm64/quick_method_frame_info_arm64.h b/runtime/arch/arm64/quick_method_frame_info_arm64.h index b525309e96..46ddf680a6 100644 --- a/runtime/arch/arm64/quick_method_frame_info_arm64.h +++ b/runtime/arch/arm64/quick_method_frame_info_arm64.h @@ -29,7 +29,7 @@ namespace arm64 { static constexpr uint32_t kArm64CalleeSaveAlwaysSpills = // Note: ArtMethod::GetReturnPcOffsetInBytes() rely on the assumption that // LR is always saved on the top of the frame for all targets. - // That is, lr = *(sp + framesize - pointsize). + // That is, lr = *(sp + framesize - pointer_size). (1 << art::arm64::LR); // Callee saved registers static constexpr uint32_t kArm64CalleeSaveRefSpills = @@ -44,6 +44,14 @@ static constexpr uint32_t kArm64CalleeSaveArgSpills = (1 << art::arm64::X7); static constexpr uint32_t kArm64CalleeSaveAllSpills = (1 << art::arm64::X19); +static constexpr uint32_t kArm64CalleeSaveEverythingSpills = + (1 << art::arm64::X0) | (1 << art::arm64::X1) | (1 << art::arm64::X2) | + (1 << art::arm64::X3) | (1 << art::arm64::X4) | (1 << art::arm64::X5) | + (1 << art::arm64::X6) | (1 << art::arm64::X7) | (1 << art::arm64::X8) | + (1 << art::arm64::X9) | (1 << art::arm64::X10) | (1 << art::arm64::X11) | + (1 << art::arm64::X12) | (1 << art::arm64::X13) | (1 << art::arm64::X14) | + (1 << art::arm64::X15) | (1 << art::arm64::X16) | (1 << art::arm64::X17) | + (1 << art::arm64::X18) | (1 << art::arm64::X19); static constexpr uint32_t kArm64CalleeSaveFpAlwaysSpills = 0; static constexpr uint32_t kArm64CalleeSaveFpRefSpills = 0; @@ -55,17 +63,31 @@ static constexpr uint32_t kArm64CalleeSaveFpAllSpills = (1 << art::arm64::D8) | (1 << art::arm64::D9) | (1 << art::arm64::D10) | (1 << art::arm64::D11) | (1 << art::arm64::D12) | (1 << art::arm64::D13) | (1 << art::arm64::D14) | (1 << art::arm64::D15); +static constexpr uint32_t kArm64CalleeSaveFpEverythingSpills = + (1 << art::arm64::D0) | (1 << art::arm64::D1) | (1 << art::arm64::D2) | + (1 << art::arm64::D3) | (1 << art::arm64::D4) | (1 << art::arm64::D5) | + (1 << art::arm64::D6) | (1 << art::arm64::D7) | (1 << art::arm64::D8) | + (1 << art::arm64::D9) | (1 << art::arm64::D10) | (1 << art::arm64::D11) | + (1 << art::arm64::D12) | (1 << art::arm64::D13) | (1 << art::arm64::D14) | + (1 << art::arm64::D15) | (1 << art::arm64::D16) | (1 << art::arm64::D17) | + (1 << art::arm64::D18) | (1 << art::arm64::D19) | (1 << art::arm64::D20) | + (1 << art::arm64::D21) | (1 << art::arm64::D22) | (1 << art::arm64::D23) | + (1 << art::arm64::D24) | (1 << art::arm64::D25) | (1 << art::arm64::D26) | + (1 << art::arm64::D27) | (1 << art::arm64::D28) | (1 << art::arm64::D29) | + (1 << art::arm64::D30) | (1 << art::arm64::D31); constexpr uint32_t Arm64CalleeSaveCoreSpills(Runtime::CalleeSaveType type) { return kArm64CalleeSaveAlwaysSpills | kArm64CalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kArm64CalleeSaveArgSpills : 0) | - (type == Runtime::kSaveAll ? kArm64CalleeSaveAllSpills : 0); + (type == Runtime::kSaveAll ? kArm64CalleeSaveAllSpills : 0) | + (type == Runtime::kSaveEverything ? kArm64CalleeSaveEverythingSpills : 0); } constexpr uint32_t Arm64CalleeSaveFpSpills(Runtime::CalleeSaveType type) { return kArm64CalleeSaveFpAlwaysSpills | kArm64CalleeSaveFpRefSpills | (type == Runtime::kRefsAndArgs ? kArm64CalleeSaveFpArgSpills: 0) | - (type == Runtime::kSaveAll ? kArm64CalleeSaveFpAllSpills : 0); + (type == Runtime::kSaveAll ? kArm64CalleeSaveFpAllSpills : 0) | + (type == Runtime::kSaveEverything ? kArm64CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t Arm64CalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/arch/mips/asm_support_mips.h b/runtime/arch/mips/asm_support_mips.h index 453056d7bf..2ef45f5679 100644 --- a/runtime/arch/mips/asm_support_mips.h +++ b/runtime/arch/mips/asm_support_mips.h @@ -22,5 +22,6 @@ #define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 96 #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 48 #define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 80 +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE 256 #endif // ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_ diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index c1b8044be9..b926bdfb9f 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -277,6 +277,197 @@ .endm /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything). + * Callee-save: $at, $v0-$v1, $a0-$a3, $t0-$t7, $s0-$s7, $t8-$t9, $gp, $fp $ra, $f0-$f31; + * 28(GPR)+ 32(FPR) + 3 words for padding and 1 word for Method* + * Clobbers $t0 and $t1. + * Allocates ARG_SLOT_SIZE bytes at the bottom of the stack for arg slots. + * Reserves FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack. + * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP. + */ +.macro SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + addiu $sp, $sp, -256 + .cfi_adjust_cfa_offset 256 + + // Ugly compile-time check, but we only have the preprocessor. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 256) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(MIPS) size not as expected." +#endif + + sw $ra, 252($sp) + .cfi_rel_offset 31, 252 + sw $fp, 248($sp) + .cfi_rel_offset 30, 248 + sw $gp, 244($sp) + .cfi_rel_offset 28, 244 + sw $t9, 240($sp) + .cfi_rel_offset 25, 240 + sw $t8, 236($sp) + .cfi_rel_offset 24, 236 + sw $s7, 232($sp) + .cfi_rel_offset 23, 232 + sw $s6, 228($sp) + .cfi_rel_offset 22, 228 + sw $s5, 224($sp) + .cfi_rel_offset 21, 224 + sw $s4, 220($sp) + .cfi_rel_offset 20, 220 + sw $s3, 216($sp) + .cfi_rel_offset 19, 216 + sw $s2, 212($sp) + .cfi_rel_offset 18, 212 + sw $s1, 208($sp) + .cfi_rel_offset 17, 208 + sw $s0, 204($sp) + .cfi_rel_offset 16, 204 + sw $t7, 200($sp) + .cfi_rel_offset 15, 200 + sw $t6, 196($sp) + .cfi_rel_offset 14, 196 + sw $t5, 192($sp) + .cfi_rel_offset 13, 192 + sw $t4, 188($sp) + .cfi_rel_offset 12, 188 + sw $t3, 184($sp) + .cfi_rel_offset 11, 184 + sw $t2, 180($sp) + .cfi_rel_offset 10, 180 + sw $t1, 176($sp) + .cfi_rel_offset 9, 176 + sw $t0, 172($sp) + .cfi_rel_offset 8, 172 + sw $a3, 168($sp) + .cfi_rel_offset 7, 168 + sw $a2, 164($sp) + .cfi_rel_offset 6, 164 + sw $a1, 160($sp) + .cfi_rel_offset 5, 160 + sw $a0, 156($sp) + .cfi_rel_offset 4, 156 + sw $v1, 152($sp) + .cfi_rel_offset 3, 152 + sw $v0, 148($sp) + .cfi_rel_offset 2, 148 + + // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction. + bal 1f + sw $at, 144($sp) + .cfi_rel_offset 1, 144 +1: + .cpload $ra + + SDu $f30, $f31, 136, $sp, $t1 + SDu $f28, $f29, 128, $sp, $t1 + SDu $f26, $f27, 120, $sp, $t1 + SDu $f24, $f25, 112, $sp, $t1 + SDu $f22, $f23, 104, $sp, $t1 + SDu $f20, $f21, 96, $sp, $t1 + SDu $f18, $f19, 88, $sp, $t1 + SDu $f16, $f17, 80, $sp, $t1 + SDu $f14, $f15, 72, $sp, $t1 + SDu $f12, $f13, 64, $sp, $t1 + SDu $f10, $f11, 56, $sp, $t1 + SDu $f8, $f9, 48, $sp, $t1 + SDu $f6, $f7, 40, $sp, $t1 + SDu $f4, $f5, 32, $sp, $t1 + SDu $f2, $f3, 24, $sp, $t1 + SDu $f0, $f1, 16, $sp, $t1 + + # 3 words padding and 1 word for holding Method* + + lw $t0, %got(_ZN3art7Runtime9instance_E)($gp) + lw $t0, 0($t0) + lw $t0, RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET($t0) + sw $t0, 0($sp) # Place Method* at bottom of stack. + sw $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) # Place sp in Thread::Current()->top_quick_frame. + addiu $sp, $sp, -ARG_SLOT_SIZE # reserve argument slots on the stack + .cfi_adjust_cfa_offset ARG_SLOT_SIZE +.endm + +.macro RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + addiu $sp, $sp, ARG_SLOT_SIZE # remove argument slots on the stack + .cfi_adjust_cfa_offset -ARG_SLOT_SIZE + + LDu $f30, $f31, 136, $sp, $t1 + LDu $f28, $f29, 128, $sp, $t1 + LDu $f26, $f27, 120, $sp, $t1 + LDu $f24, $f25, 112, $sp, $t1 + LDu $f22, $f23, 104, $sp, $t1 + LDu $f20, $f21, 96, $sp, $t1 + LDu $f18, $f19, 88, $sp, $t1 + LDu $f16, $f17, 80, $sp, $t1 + LDu $f14, $f15, 72, $sp, $t1 + LDu $f12, $f13, 64, $sp, $t1 + LDu $f10, $f11, 56, $sp, $t1 + LDu $f8, $f9, 48, $sp, $t1 + LDu $f6, $f7, 40, $sp, $t1 + LDu $f4, $f5, 32, $sp, $t1 + LDu $f2, $f3, 24, $sp, $t1 + LDu $f0, $f1, 16, $sp, $t1 + + lw $ra, 252($sp) + .cfi_restore 31 + lw $fp, 248($sp) + .cfi_restore 30 + lw $gp, 244($sp) + .cfi_restore 28 + lw $t9, 240($sp) + .cfi_restore 25 + lw $t8, 236($sp) + .cfi_restore 24 + lw $s7, 232($sp) + .cfi_restore 23 + lw $s6, 228($sp) + .cfi_restore 22 + lw $s5, 224($sp) + .cfi_restore 21 + lw $s4, 220($sp) + .cfi_restore 20 + lw $s3, 216($sp) + .cfi_restore 19 + lw $s2, 212($sp) + .cfi_restore 18 + lw $s1, 208($sp) + .cfi_restore 17 + lw $s0, 204($sp) + .cfi_restore 16 + lw $t7, 200($sp) + .cfi_restore 15 + lw $t6, 196($sp) + .cfi_restore 14 + lw $t5, 192($sp) + .cfi_restore 13 + lw $t4, 188($sp) + .cfi_restore 12 + lw $t3, 184($sp) + .cfi_restore 11 + lw $t2, 180($sp) + .cfi_restore 10 + lw $t1, 176($sp) + .cfi_restore 9 + lw $t0, 172($sp) + .cfi_restore 8 + lw $a3, 168($sp) + .cfi_restore 7 + lw $a2, 164($sp) + .cfi_restore 6 + lw $a1, 160($sp) + .cfi_restore 5 + lw $a0, 156($sp) + .cfi_restore 4 + lw $v1, 152($sp) + .cfi_restore 3 + lw $v0, 148($sp) + .cfi_restore 2 + lw $at, 144($sp) + .cfi_restore 1 + + addiu $sp, $sp, 256 # pop frame + .cfi_adjust_cfa_offset -256 +.endm + + /* * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending * exception is Thread::Current()->exception_ */ @@ -1652,18 +1843,20 @@ ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeA * Called by managed code when the value in rSUSPEND has been decremented to 0. */ .extern artTestSuspendFromCode -ENTRY art_quick_test_suspend - lh $a0, THREAD_FLAGS_OFFSET(rSELF) - bnez $a0, 1f +ENTRY_NO_GP art_quick_test_suspend + lh rSUSPEND, THREAD_FLAGS_OFFSET(rSELF) + bnez rSUSPEND, 1f addiu rSUSPEND, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL jalr $zero, $ra nop 1: - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves for stack crawl + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME # save everything for stack crawl la $t9, artTestSuspendFromCode - jalr $t9 # (Thread*) + jalr $t9 # (Thread*) move $a0, rSELF - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + jalr $zero, $ra + nop END art_quick_test_suspend /* diff --git a/runtime/arch/mips/quick_method_frame_info_mips.h b/runtime/arch/mips/quick_method_frame_info_mips.h index f5d13c2b52..cce467e50c 100644 --- a/runtime/arch/mips/quick_method_frame_info_mips.h +++ b/runtime/arch/mips/quick_method_frame_info_mips.h @@ -34,6 +34,12 @@ static constexpr uint32_t kMipsCalleeSaveArgSpills = (1 << art::mips::A1) | (1 << art::mips::A2) | (1 << art::mips::A3); static constexpr uint32_t kMipsCalleeSaveAllSpills = (1 << art::mips::S0) | (1 << art::mips::S1); +static constexpr uint32_t kMipsCalleeSaveEverythingSpills = + (1 << art::mips::AT) | (1 << art::mips::V0) | (1 << art::mips::V1) | + (1 << art::mips::A0) | (1 << art::mips::A1) | (1 << art::mips::A2) | (1 << art::mips::A3) | + (1 << art::mips::T0) | (1 << art::mips::T1) | (1 << art::mips::T2) | (1 << art::mips::T3) | + (1 << art::mips::T4) | (1 << art::mips::T5) | (1 << art::mips::T6) | (1 << art::mips::T7) | + (1 << art::mips::S0) | (1 << art::mips::S1) | (1 << art::mips::T8) | (1 << art::mips::T9); static constexpr uint32_t kMipsCalleeSaveFpAlwaysSpills = 0; static constexpr uint32_t kMipsCalleeSaveFpRefSpills = 0; @@ -43,17 +49,28 @@ static constexpr uint32_t kMipsCalleeSaveAllFPSpills = (1 << art::mips::F20) | (1 << art::mips::F21) | (1 << art::mips::F22) | (1 << art::mips::F23) | (1 << art::mips::F24) | (1 << art::mips::F25) | (1 << art::mips::F26) | (1 << art::mips::F27) | (1 << art::mips::F28) | (1 << art::mips::F29) | (1 << art::mips::F30) | (1 << art::mips::F31); +static constexpr uint32_t kMipsCalleeSaveFpEverythingSpills = + (1 << art::mips::F0) | (1 << art::mips::F1) | (1 << art::mips::F2) | (1 << art::mips::F3) | + (1 << art::mips::F4) | (1 << art::mips::F5) | (1 << art::mips::F6) | (1 << art::mips::F7) | + (1 << art::mips::F8) | (1 << art::mips::F9) | (1 << art::mips::F10) | (1 << art::mips::F11) | + (1 << art::mips::F12) | (1 << art::mips::F13) | (1 << art::mips::F14) | (1 << art::mips::F15) | + (1 << art::mips::F16) | (1 << art::mips::F17) | (1 << art::mips::F18) | (1 << art::mips::F19) | + (1 << art::mips::F20) | (1 << art::mips::F21) | (1 << art::mips::F22) | (1 << art::mips::F23) | + (1 << art::mips::F24) | (1 << art::mips::F25) | (1 << art::mips::F26) | (1 << art::mips::F27) | + (1 << art::mips::F28) | (1 << art::mips::F29) | (1 << art::mips::F30) | (1 << art::mips::F31); constexpr uint32_t MipsCalleeSaveCoreSpills(Runtime::CalleeSaveType type) { return kMipsCalleeSaveAlwaysSpills | kMipsCalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kMipsCalleeSaveArgSpills : 0) | - (type == Runtime::kSaveAll ? kMipsCalleeSaveAllSpills : 0); + (type == Runtime::kSaveAll ? kMipsCalleeSaveAllSpills : 0) | + (type == Runtime::kSaveEverything ? kMipsCalleeSaveEverythingSpills : 0); } constexpr uint32_t MipsCalleeSaveFPSpills(Runtime::CalleeSaveType type) { return kMipsCalleeSaveFpAlwaysSpills | kMipsCalleeSaveFpRefSpills | (type == Runtime::kRefsAndArgs ? kMipsCalleeSaveFpArgSpills : 0) | - (type == Runtime::kSaveAll ? kMipsCalleeSaveAllFPSpills : 0); + (type == Runtime::kSaveAll ? kMipsCalleeSaveAllFPSpills : 0) | + (type == Runtime::kSaveEverything ? kMipsCalleeSaveFpEverythingSpills : 0); } constexpr uint32_t MipsCalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/arch/mips64/asm_support_mips64.h b/runtime/arch/mips64/asm_support_mips64.h index 995fcf37bf..2c16c2532d 100644 --- a/runtime/arch/mips64/asm_support_mips64.h +++ b/runtime/arch/mips64/asm_support_mips64.h @@ -25,5 +25,7 @@ #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 80 // $f12-$f19, $a1-$a7, $s2-$s7 + $gp + $s8 + $ra, 16 total + 1x8 bytes padding + method* #define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 208 +// $f0-$f31, $at, $v0-$v1, $a0-$a7, $t0-$t3, $s0-$s7, $t8-$t9, $gp, $s8, $ra + padding + method* +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE 496 #endif // ART_RUNTIME_ARCH_MIPS64_ASM_SUPPORT_MIPS64_H_ diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S index ae6962076b..0a379098f5 100644 --- a/runtime/arch/mips64/quick_entrypoints_mips64.S +++ b/runtime/arch/mips64/quick_entrypoints_mips64.S @@ -314,6 +314,227 @@ .endm /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything). + * callee-save: $at + $v0-$v1 + $a0-$a7 + $t0-$t3 + $s0-$s7 + $t8-$t9 + $gp + $s8 + $ra + $s8, + * $f0-$f31; 28(GPR)+ 32(FPR) + 1x8 bytes padding + method* + * This macro sets up $gp; entrypoints using it should start with ENTRY_NO_GP. + */ +.macro SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + daddiu $sp, $sp, -496 + .cfi_adjust_cfa_offset 496 + + // Ugly compile-time check, but we only have the preprocessor. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 496) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(MIPS64) size not as expected." +#endif + + // Save core registers. + sd $ra, 488($sp) + .cfi_rel_offset 31, 488 + sd $s8, 480($sp) + .cfi_rel_offset 30, 480 + sd $gp, 472($sp) + .cfi_rel_offset 28, 472 + sd $t9, 464($sp) + .cfi_rel_offset 25, 464 + sd $t8, 456($sp) + .cfi_rel_offset 24, 456 + sd $s7, 448($sp) + .cfi_rel_offset 23, 448 + sd $s6, 440($sp) + .cfi_rel_offset 22, 440 + sd $s5, 432($sp) + .cfi_rel_offset 21, 432 + sd $s4, 424($sp) + .cfi_rel_offset 20, 424 + sd $s3, 416($sp) + .cfi_rel_offset 19, 416 + sd $s2, 408($sp) + .cfi_rel_offset 18, 408 + sd $s1, 400($sp) + .cfi_rel_offset 17, 400 + sd $s0, 392($sp) + .cfi_rel_offset 16, 392 + sd $t3, 384($sp) + .cfi_rel_offset 15, 384 + sd $t2, 376($sp) + .cfi_rel_offset 14, 376 + sd $t1, 368($sp) + .cfi_rel_offset 13, 368 + sd $t0, 360($sp) + .cfi_rel_offset 12, 360 + sd $a7, 352($sp) + .cfi_rel_offset 11, 352 + sd $a6, 344($sp) + .cfi_rel_offset 10, 344 + sd $a5, 336($sp) + .cfi_rel_offset 9, 336 + sd $a4, 328($sp) + .cfi_rel_offset 8, 328 + sd $a3, 320($sp) + .cfi_rel_offset 7, 320 + sd $a2, 312($sp) + .cfi_rel_offset 6, 312 + sd $a1, 304($sp) + .cfi_rel_offset 5, 304 + sd $a0, 296($sp) + .cfi_rel_offset 4, 296 + sd $v1, 288($sp) + .cfi_rel_offset 3, 288 + sd $v0, 280($sp) + .cfi_rel_offset 2, 280 + + // Set up $gp, clobbering $ra and using the branch delay slot for a useful instruction. + bal 1f + sd $at, 272($sp) + .cfi_rel_offset 1, 272 +1: + // TODO: Can we avoid the unnecessary move $t8<-$gp? + .cpsetup $ra, $t8, 1b + + // Save FP registers. + s.d $f31, 264($sp) + s.d $f30, 256($sp) + s.d $f29, 248($sp) + s.d $f28, 240($sp) + s.d $f27, 232($sp) + s.d $f26, 224($sp) + s.d $f25, 216($sp) + s.d $f24, 208($sp) + s.d $f23, 200($sp) + s.d $f22, 192($sp) + s.d $f21, 184($sp) + s.d $f20, 176($sp) + s.d $f19, 168($sp) + s.d $f18, 160($sp) + s.d $f17, 152($sp) + s.d $f16, 144($sp) + s.d $f15, 136($sp) + s.d $f14, 128($sp) + s.d $f13, 120($sp) + s.d $f12, 112($sp) + s.d $f11, 104($sp) + s.d $f10, 96($sp) + s.d $f9, 88($sp) + s.d $f8, 80($sp) + s.d $f7, 72($sp) + s.d $f6, 64($sp) + s.d $f5, 56($sp) + s.d $f4, 48($sp) + s.d $f3, 40($sp) + s.d $f2, 32($sp) + s.d $f1, 24($sp) + s.d $f0, 16($sp) + + # load appropriate callee-save-method + ld $t1, %got(_ZN3art7Runtime9instance_E)($gp) + ld $t1, 0($t1) + ld $t1, RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET($t1) + sd $t1, 0($sp) # Place ArtMethod* at bottom of stack. + # Place sp in Thread::Current()->top_quick_frame. + sd $sp, THREAD_TOP_QUICK_FRAME_OFFSET(rSELF) +.endm + +.macro RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + // Restore FP registers. + l.d $f31, 264($sp) + l.d $f30, 256($sp) + l.d $f29, 248($sp) + l.d $f28, 240($sp) + l.d $f27, 232($sp) + l.d $f26, 224($sp) + l.d $f25, 216($sp) + l.d $f24, 208($sp) + l.d $f23, 200($sp) + l.d $f22, 192($sp) + l.d $f21, 184($sp) + l.d $f20, 176($sp) + l.d $f19, 168($sp) + l.d $f18, 160($sp) + l.d $f17, 152($sp) + l.d $f16, 144($sp) + l.d $f15, 136($sp) + l.d $f14, 128($sp) + l.d $f13, 120($sp) + l.d $f12, 112($sp) + l.d $f11, 104($sp) + l.d $f10, 96($sp) + l.d $f9, 88($sp) + l.d $f8, 80($sp) + l.d $f7, 72($sp) + l.d $f6, 64($sp) + l.d $f5, 56($sp) + l.d $f4, 48($sp) + l.d $f3, 40($sp) + l.d $f2, 32($sp) + l.d $f1, 24($sp) + l.d $f0, 16($sp) + + // Restore core registers. + ld $ra, 488($sp) + .cfi_restore 31 + ld $s8, 480($sp) + .cfi_restore 30 + ld $gp, 472($sp) + .cfi_restore 28 + ld $t9, 464($sp) + .cfi_restore 25 + ld $t8, 456($sp) + .cfi_restore 24 + ld $s7, 448($sp) + .cfi_restore 23 + ld $s6, 440($sp) + .cfi_restore 22 + ld $s5, 432($sp) + .cfi_restore 21 + ld $s4, 424($sp) + .cfi_restore 20 + ld $s3, 416($sp) + .cfi_restore 19 + ld $s2, 408($sp) + .cfi_restore 18 + ld $s1, 400($sp) + .cfi_restore 17 + ld $s0, 392($sp) + .cfi_restore 16 + ld $t3, 384($sp) + .cfi_restore 15 + ld $t2, 376($sp) + .cfi_restore 14 + ld $t1, 368($sp) + .cfi_restore 13 + ld $t0, 360($sp) + .cfi_restore 12 + ld $a7, 352($sp) + .cfi_restore 11 + ld $a6, 344($sp) + .cfi_restore 10 + ld $a5, 336($sp) + .cfi_restore 9 + ld $a4, 328($sp) + .cfi_restore 8 + ld $a3, 320($sp) + .cfi_restore 7 + ld $a2, 312($sp) + .cfi_restore 6 + ld $a1, 304($sp) + .cfi_restore 5 + ld $a0, 296($sp) + .cfi_restore 4 + ld $v1, 288($sp) + .cfi_restore 3 + ld $v0, 280($sp) + .cfi_restore 2 + ld $at, 272($sp) + .cfi_restore 1 + + .cpreturn + daddiu $sp, $sp, 496 + .cfi_adjust_cfa_offset -496 +.endm + + /* * Macro that set calls through to artDeliverPendingExceptionFromCode, * where the pending * exception is Thread::Current()->exception_ @@ -1673,17 +1894,19 @@ ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeA * Called by managed code when the value in rSUSPEND has been decremented to 0. */ .extern artTestSuspendFromCode -ENTRY art_quick_test_suspend - lh $a0, THREAD_FLAGS_OFFSET(rSELF) - bne $a0, $zero, 1f +ENTRY_NO_GP art_quick_test_suspend + lh rSUSPEND, THREAD_FLAGS_OFFSET(rSELF) + bne rSUSPEND, $zero, 1f daddiu rSUSPEND, $zero, SUSPEND_CHECK_INTERVAL # reset rSUSPEND to SUSPEND_CHECK_INTERVAL jalr $zero, $ra - .cpreturn # Restore gp from t8 in branch delay slot. + nop 1: - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME # save callee saves for stack crawl + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME # save everything for stack crawl jal artTestSuspendFromCode # (Thread*) move $a0, rSELF - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME_AND_RETURN + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME + jalr $zero, $ra + nop END art_quick_test_suspend /* diff --git a/runtime/arch/mips64/quick_method_frame_info_mips64.h b/runtime/arch/mips64/quick_method_frame_info_mips64.h index f967be0e4c..2bd2db08aa 100644 --- a/runtime/arch/mips64/quick_method_frame_info_mips64.h +++ b/runtime/arch/mips64/quick_method_frame_info_mips64.h @@ -25,6 +25,8 @@ namespace art { namespace mips64 { +static constexpr uint32_t kMips64CalleeSaveAlwaysSpills = + (1 << art::mips64::RA); static constexpr uint32_t kMips64CalleeSaveRefSpills = (1 << art::mips64::S2) | (1 << art::mips64::S3) | (1 << art::mips64::S4) | (1 << art::mips64::S5) | (1 << art::mips64::S6) | (1 << art::mips64::S7) | @@ -35,6 +37,14 @@ static constexpr uint32_t kMips64CalleeSaveArgSpills = (1 << art::mips64::A7); static constexpr uint32_t kMips64CalleeSaveAllSpills = (1 << art::mips64::S0) | (1 << art::mips64::S1); +static constexpr uint32_t kMips64CalleeSaveEverythingSpills = + (1 << art::mips64::AT) | (1 << art::mips64::V0) | (1 << art::mips64::V1) | + (1 << art::mips64::A0) | (1 << art::mips64::A1) | (1 << art::mips64::A2) | + (1 << art::mips64::A3) | (1 << art::mips64::A4) | (1 << art::mips64::A5) | + (1 << art::mips64::A6) | (1 << art::mips64::A7) | (1 << art::mips64::T0) | + (1 << art::mips64::T1) | (1 << art::mips64::T2) | (1 << art::mips64::T3) | + (1 << art::mips64::S0) | (1 << art::mips64::S1) | (1 << art::mips64::T8) | + (1 << art::mips64::T9); static constexpr uint32_t kMips64CalleeSaveFpRefSpills = 0; static constexpr uint32_t kMips64CalleeSaveFpArgSpills = @@ -46,17 +56,31 @@ static constexpr uint32_t kMips64CalleeSaveFpAllSpills = (1 << art::mips64::F24) | (1 << art::mips64::F25) | (1 << art::mips64::F26) | (1 << art::mips64::F27) | (1 << art::mips64::F28) | (1 << art::mips64::F29) | (1 << art::mips64::F30) | (1 << art::mips64::F31); +static constexpr uint32_t kMips64CalleeSaveFpEverythingSpills = + (1 << art::mips64::F0) | (1 << art::mips64::F1) | (1 << art::mips64::F2) | + (1 << art::mips64::F3) | (1 << art::mips64::F4) | (1 << art::mips64::F5) | + (1 << art::mips64::F6) | (1 << art::mips64::F7) | (1 << art::mips64::F8) | + (1 << art::mips64::F9) | (1 << art::mips64::F10) | (1 << art::mips64::F11) | + (1 << art::mips64::F12) | (1 << art::mips64::F13) | (1 << art::mips64::F14) | + (1 << art::mips64::F15) | (1 << art::mips64::F16) | (1 << art::mips64::F17) | + (1 << art::mips64::F18) | (1 << art::mips64::F19) | (1 << art::mips64::F20) | + (1 << art::mips64::F21) | (1 << art::mips64::F22) | (1 << art::mips64::F23) | + (1 << art::mips64::F24) | (1 << art::mips64::F25) | (1 << art::mips64::F26) | + (1 << art::mips64::F27) | (1 << art::mips64::F28) | (1 << art::mips64::F29) | + (1 << art::mips64::F30) | (1 << art::mips64::F31); constexpr uint32_t Mips64CalleeSaveCoreSpills(Runtime::CalleeSaveType type) { - return kMips64CalleeSaveRefSpills | + return kMips64CalleeSaveAlwaysSpills | kMips64CalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kMips64CalleeSaveArgSpills : 0) | - (type == Runtime::kSaveAll ? kMips64CalleeSaveAllSpills : 0) | (1 << art::mips64::RA); + (type == Runtime::kSaveAll ? kMips64CalleeSaveAllSpills : 0) | + (type == Runtime::kSaveEverything ? kMips64CalleeSaveEverythingSpills : 0); } constexpr uint32_t Mips64CalleeSaveFpSpills(Runtime::CalleeSaveType type) { return kMips64CalleeSaveFpRefSpills | (type == Runtime::kRefsAndArgs ? kMips64CalleeSaveFpArgSpills: 0) | - (type == Runtime::kSaveAll ? kMips64CalleeSaveFpAllSpills : 0); + (type == Runtime::kSaveAll ? kMips64CalleeSaveFpAllSpills : 0) | + (type == Runtime::kSaveEverything ? kMips64CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t Mips64CalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/arch/x86/asm_support_x86.h b/runtime/arch/x86/asm_support_x86.h index b0a6017b47..ba5fd997e8 100644 --- a/runtime/arch/x86/asm_support_x86.h +++ b/runtime/arch/x86/asm_support_x86.h @@ -21,8 +21,7 @@ #define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 32 #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 32 - -// 32 bytes for GPRs and 32 bytes for FPRs. #define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE (32 + 32) +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE (48 + 64) #endif // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_ diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index 77e04e7981..aa1af41de9 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -222,6 +222,74 @@ MACRO0(RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME_AND_JUMP) END_MACRO /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything) + */ +MACRO2(SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME, got_reg, temp_reg) + // Save core registers. + PUSH edi + PUSH esi + PUSH ebp + PUSH ebx + PUSH edx + PUSH ecx + PUSH eax + // Create space for FPR registers and stack alignment padding. + subl MACRO_LITERAL(12 + 8 * 8), %esp + CFI_ADJUST_CFA_OFFSET(12 + 8 * 8) + // Save FPRs. + movsd %xmm0, 12(%esp) + movsd %xmm1, 20(%esp) + movsd %xmm2, 28(%esp) + movsd %xmm3, 36(%esp) + movsd %xmm4, 44(%esp) + movsd %xmm5, 52(%esp) + movsd %xmm6, 60(%esp) + movsd %xmm7, 68(%esp) + + SETUP_GOT_NOSAVE RAW_VAR(got_reg) + // Load Runtime::instance_ from GOT. + movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) + movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) + // Push save everything callee-save method. + pushl RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET(REG_VAR(temp_reg)) + CFI_ADJUST_CFA_OFFSET(4) + // Store esp as the stop quick frame. + movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET + + // Ugly compile-time check, but we only have the preprocessor. + // Last +4: implicit return address pushed on stack when caller made call. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 7*4 + 8*8 + 12 + 4 + 4) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(X86) size not as expected." +#endif +END_MACRO + +MACRO0(RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME) + // Restore FPRs. Method and padding is still on the stack. + movsd 16(%esp), %xmm0 + movsd 24(%esp), %xmm1 + movsd 32(%esp), %xmm2 + movsd 40(%esp), %xmm3 + movsd 48(%esp), %xmm4 + movsd 56(%esp), %xmm5 + movsd 64(%esp), %xmm6 + movsd 72(%esp), %xmm7 + + // Remove save everything callee save method, stack alignment padding and FPRs. + addl MACRO_LITERAL(16 + 8 * 8), %esp + CFI_ADJUST_CFA_OFFSET(-(16 + 8 * 8)) + + // Restore core registers. + POP eax + POP ecx + POP edx + POP ebx + POP ebp + POP esi + POP edi +END_MACRO + + /* * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending * exception is Thread::Current()->exception_. */ @@ -661,22 +729,6 @@ DEFINE_FUNCTION art_quick_invoke_static_stub ret END_FUNCTION art_quick_invoke_static_stub -MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC - // Outgoing argument set up - subl MACRO_LITERAL(12), %esp // push padding - CFI_ADJUST_CFA_OFFSET(12) - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - call CALLVAR(cxx_name) // cxx_name(Thread*) - addl MACRO_LITERAL(16), %esp // pop arguments - CFI_ADJUST_CFA_OFFSET(-16) - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC @@ -1397,7 +1449,19 @@ DEFINE_FUNCTION art_quick_memcpy ret END_FUNCTION art_quick_memcpy -NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret +DEFINE_FUNCTION art_quick_test_suspend + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME ebx, ebx // save everything for GC + // Outgoing argument set up + subl MACRO_LITERAL(12), %esp // push padding + CFI_ADJUST_CFA_OFFSET(12) + pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() + CFI_ADJUST_CFA_OFFSET(4) + call artTestSuspendFromCode // artTestSuspendFromCode(Thread*) + addl MACRO_LITERAL(16), %esp // pop arguments + CFI_ADJUST_CFA_OFFSET(-16) + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME // restore frame up to return address + ret // return +END_FUNCTION art_quick_test_suspend DEFINE_FUNCTION art_quick_d2l subl LITERAL(12), %esp // alignment padding, room for argument diff --git a/runtime/arch/x86/quick_method_frame_info_x86.h b/runtime/arch/x86/quick_method_frame_info_x86.h index ed1d860850..b17119011e 100644 --- a/runtime/arch/x86/quick_method_frame_info_x86.h +++ b/runtime/arch/x86/quick_method_frame_info_x86.h @@ -36,21 +36,33 @@ enum XMM { XMM7 = 7, }; +static constexpr uint32_t kX86CalleeSaveAlwaysSpills = + (1 << art::x86::kNumberOfCpuRegisters); // Fake return address callee save. static constexpr uint32_t kX86CalleeSaveRefSpills = (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI); static constexpr uint32_t kX86CalleeSaveArgSpills = (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); +static constexpr uint32_t kX86CalleeSaveEverythingSpills = + (1 << art::x86::EAX) | (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); + static constexpr uint32_t kX86CalleeSaveFpArgSpills = (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | (1 << art::x86::XMM2) | (1 << art::x86::XMM3); +static constexpr uint32_t kX86CalleeSaveFpEverythingSpills = + (1 << art::x86::XMM0) | (1 << art::x86::XMM1) | + (1 << art::x86::XMM2) | (1 << art::x86::XMM3) | + (1 << art::x86::XMM4) | (1 << art::x86::XMM5) | + (1 << art::x86::XMM6) | (1 << art::x86::XMM7); constexpr uint32_t X86CalleeSaveCoreSpills(Runtime::CalleeSaveType type) { - return kX86CalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kX86CalleeSaveArgSpills : 0) | - (1 << art::x86::kNumberOfCpuRegisters); // fake return address callee save + return kX86CalleeSaveAlwaysSpills | kX86CalleeSaveRefSpills | + (type == Runtime::kRefsAndArgs ? kX86CalleeSaveArgSpills : 0) | + (type == Runtime::kSaveEverything ? kX86CalleeSaveEverythingSpills : 0); } constexpr uint32_t X86CalleeSaveFpSpills(Runtime::CalleeSaveType type) { - return type == Runtime::kRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0; + return (type == Runtime::kRefsAndArgs ? kX86CalleeSaveFpArgSpills : 0) | + (type == Runtime::kSaveEverything ? kX86CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t X86CalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/arch/x86_64/asm_support_x86_64.h b/runtime/arch/x86_64/asm_support_x86_64.h index 48bec73239..58dc2fe23a 100644 --- a/runtime/arch/x86_64/asm_support_x86_64.h +++ b/runtime/arch/x86_64/asm_support_x86_64.h @@ -21,6 +21,7 @@ #define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE (64 + 4*8) #define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE (64 + 4*8) -#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE (176 + 4*8) +#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE (112 + 12*8) +#define FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE (144 + 16*8) #endif // ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_ diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index 784ec394a8..a7c5e67f95 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -165,8 +165,8 @@ MACRO0(SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME) PUSH rdx // Quick arg 2. PUSH rcx // Quick arg 3. // Create space for FPR args and create 2 slots for ArtMethod*. - subq MACRO_LITERAL(80 + 4 * 8), %rsp - CFI_ADJUST_CFA_OFFSET(80 + 4 * 8) + subq MACRO_LITERAL(16 + 12 * 8), %rsp + CFI_ADJUST_CFA_OFFSET(16 + 12 * 8) // R10 := ArtMethod* for ref and args callee save frame method. movq RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET(%r10), %r10 // Save FPRs. @@ -189,7 +189,7 @@ MACRO0(SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME) // Ugly compile-time check, but we only have the preprocessor. // Last +8: implicit return address pushed on stack when caller made call. -#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 11 * 8 + 4 * 8 + 80 + 8) +#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 11 * 8 + 12 * 8 + 16 + 8) #error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(X86_64) size not as expected." #endif #endif // __APPLE__ @@ -260,6 +260,108 @@ MACRO0(RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME) POP r15 END_MACRO + /* + * Macro that sets up the callee save frame to conform with + * Runtime::CreateCalleeSaveMethod(kSaveEverything) + */ +MACRO0(SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME) +#if defined(__APPLE__) + int3 + int3 +#else + // Save core registers from highest to lowest to agree with core spills bitmap. + PUSH r15 + PUSH r14 + PUSH r13 + PUSH r12 + PUSH r11 + PUSH r10 + PUSH r9 + PUSH r8 + PUSH rdi + PUSH rsi + PUSH rbp + PUSH rbx + PUSH rdx + PUSH rcx + PUSH rax + // Create space for FPRs and stack alignment padding. + subq MACRO_LITERAL(8 + 16 * 8), %rsp + CFI_ADJUST_CFA_OFFSET(8 + 16 * 8) + // R10 := Runtime::Current() + movq _ZN3art7Runtime9instance_E@GOTPCREL(%rip), %r10 + movq (%r10), %r10 + // Save FPRs. + movq %xmm0, 8(%rsp) + movq %xmm1, 16(%rsp) + movq %xmm2, 24(%rsp) + movq %xmm3, 32(%rsp) + movq %xmm4, 40(%rsp) + movq %xmm5, 48(%rsp) + movq %xmm6, 56(%rsp) + movq %xmm7, 64(%rsp) + movq %xmm8, 72(%rsp) + movq %xmm9, 80(%rsp) + movq %xmm10, 88(%rsp) + movq %xmm11, 96(%rsp) + movq %xmm12, 104(%rsp) + movq %xmm13, 112(%rsp) + movq %xmm14, 120(%rsp) + movq %xmm15, 128(%rsp) + // Push ArtMethod* for save everything frame method. + pushq RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET(%r10) + CFI_ADJUST_CFA_OFFSET(8) + // Store rsp as the top quick frame. + movq %rsp, %gs:THREAD_TOP_QUICK_FRAME_OFFSET + + // Ugly compile-time check, but we only have the preprocessor. + // Last +8: implicit return address pushed on stack when caller made call. +#if (FRAME_SIZE_SAVE_EVERYTHING_CALLEE_SAVE != 15 * 8 + 16 * 8 + 16 + 8) +#error "SAVE_EVERYTHING_CALLEE_SAVE_FRAME(X86_64) size not as expected." +#endif +#endif // __APPLE__ +END_MACRO + +MACRO0(RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME) + // Restore FPRs. Method and padding is still on the stack. + movq 16(%rsp), %xmm0 + movq 24(%rsp), %xmm1 + movq 32(%rsp), %xmm2 + movq 40(%rsp), %xmm3 + movq 48(%rsp), %xmm4 + movq 56(%rsp), %xmm5 + movq 64(%rsp), %xmm6 + movq 72(%rsp), %xmm7 + movq 80(%rsp), %xmm8 + movq 88(%rsp), %xmm9 + movq 96(%rsp), %xmm10 + movq 104(%rsp), %xmm11 + movq 112(%rsp), %xmm12 + movq 120(%rsp), %xmm13 + movq 128(%rsp), %xmm14 + movq 136(%rsp), %xmm15 + + // Remove save everything callee save method, stack alignment padding and FPRs. + addq MACRO_LITERAL(16 + 16 * 8), %rsp + CFI_ADJUST_CFA_OFFSET(-(16 + 16 * 8)) + // Restore callee and GPR args, mixed together to agree with core spills bitmap. + POP rax + POP rcx + POP rdx + POP rbx + POP rbp + POP rsi + POP rdi + POP r8 + POP r9 + POP r10 + POP r11 + POP r12 + POP r13 + POP r14 + POP r15 +END_MACRO + /* * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending @@ -702,17 +804,6 @@ DEFINE_FUNCTION art_quick_do_long_jump #endif // __APPLE__ END_FUNCTION art_quick_do_long_jump -MACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_REFS_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC - // Outgoing argument set up - movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current() - call VAR(cxx_name) // cxx_name(Thread*) - RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - MACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) SETUP_REFS_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC @@ -1329,7 +1420,14 @@ DEFINE_FUNCTION art_quick_memcpy ret END_FUNCTION art_quick_memcpy -NO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret +DEFINE_FUNCTION art_quick_test_suspend + SETUP_SAVE_EVERYTHING_CALLEE_SAVE_FRAME // save everything for GC + // Outgoing argument set up + movq %gs:THREAD_SELF_OFFSET, %rdi // pass Thread::Current() + call artTestSuspendFromCode // artTestSuspendFromCode(Thread*) + RESTORE_SAVE_EVERYTHING_CALLEE_SAVE_FRAME // restore frame up to return address + ret +END_FUNCTION art_quick_test_suspend UNIMPLEMENTED art_quick_ldiv UNIMPLEMENTED art_quick_lmod diff --git a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h index 72d7e9913b..ce1844796c 100644 --- a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h +++ b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h @@ -25,12 +25,19 @@ namespace art { namespace x86_64 { +static constexpr uint32_t kX86_64CalleeSaveAlwaysSpills = + (1 << art::x86_64::kNumberOfCpuRegisters); // Fake return address callee save. static constexpr uint32_t kX86_64CalleeSaveRefSpills = (1 << art::x86_64::RBX) | (1 << art::x86_64::RBP) | (1 << art::x86_64::R12) | (1 << art::x86_64::R13) | (1 << art::x86_64::R14) | (1 << art::x86_64::R15); static constexpr uint32_t kX86_64CalleeSaveArgSpills = (1 << art::x86_64::RSI) | (1 << art::x86_64::RDX) | (1 << art::x86_64::RCX) | (1 << art::x86_64::R8) | (1 << art::x86_64::R9); +static constexpr uint32_t kX86_64CalleeSaveEverythingSpills = + (1 << art::x86_64::RAX) | (1 << art::x86_64::RCX) | (1 << art::x86_64::RDX) | + (1 << art::x86_64::RSI) | (1 << art::x86_64::RDI) | (1 << art::x86_64::R8) | + (1 << art::x86_64::R9) | (1 << art::x86_64::R10) | (1 << art::x86_64::R11); + static constexpr uint32_t kX86_64CalleeSaveFpArgSpills = (1 << art::x86_64::XMM0) | (1 << art::x86_64::XMM1) | (1 << art::x86_64::XMM2) | (1 << art::x86_64::XMM3) | (1 << art::x86_64::XMM4) | (1 << art::x86_64::XMM5) | @@ -38,16 +45,24 @@ static constexpr uint32_t kX86_64CalleeSaveFpArgSpills = static constexpr uint32_t kX86_64CalleeSaveFpSpills = (1 << art::x86_64::XMM12) | (1 << art::x86_64::XMM13) | (1 << art::x86_64::XMM14) | (1 << art::x86_64::XMM15); +static constexpr uint32_t kX86_64CalleeSaveFpEverythingSpills = + (1 << art::x86_64::XMM0) | (1 << art::x86_64::XMM1) | + (1 << art::x86_64::XMM2) | (1 << art::x86_64::XMM3) | + (1 << art::x86_64::XMM4) | (1 << art::x86_64::XMM5) | + (1 << art::x86_64::XMM6) | (1 << art::x86_64::XMM7) | + (1 << art::x86_64::XMM8) | (1 << art::x86_64::XMM9) | + (1 << art::x86_64::XMM10) | (1 << art::x86_64::XMM11); constexpr uint32_t X86_64CalleeSaveCoreSpills(Runtime::CalleeSaveType type) { - return kX86_64CalleeSaveRefSpills | + return kX86_64CalleeSaveAlwaysSpills | kX86_64CalleeSaveRefSpills | (type == Runtime::kRefsAndArgs ? kX86_64CalleeSaveArgSpills : 0) | - (1 << art::x86_64::kNumberOfCpuRegisters); // fake return address callee save; + (type == Runtime::kSaveEverything ? kX86_64CalleeSaveEverythingSpills : 0); } constexpr uint32_t X86_64CalleeSaveFpSpills(Runtime::CalleeSaveType type) { return kX86_64CalleeSaveFpSpills | - (type == Runtime::kRefsAndArgs ? kX86_64CalleeSaveFpArgSpills : 0); + (type == Runtime::kRefsAndArgs ? kX86_64CalleeSaveFpArgSpills : 0) | + (type == Runtime::kSaveEverything ? kX86_64CalleeSaveFpEverythingSpills : 0); } constexpr uint32_t X86_64CalleeSaveFrameSize(Runtime::CalleeSaveType type) { diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 8cadc2e0fc..0c38295651 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1435,6 +1435,8 @@ ImageSpace* ImageSpace::Init(const char* image_filename, image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod)); CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs), image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod)); + CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kSaveEverything), + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod)); } else if (!runtime->HasResolutionMethod()) { runtime->SetInstructionSet(space->oat_file_non_owned_->GetOatHeader().GetInstructionSet()); runtime->SetResolutionMethod(image_header->GetImageMethod(ImageHeader::kResolutionMethod)); @@ -1447,6 +1449,8 @@ ImageSpace* ImageSpace::Init(const char* image_filename, image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod), Runtime::kRefsOnly); runtime->SetCalleeSaveMethod( image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod), Runtime::kRefsAndArgs); + runtime->SetCalleeSaveMethod( + image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod), Runtime::kSaveEverything); } VLOG(image) << "ImageSpace::Init exiting " << *space.get(); diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h index a892eab984..ff70cbee7a 100644 --- a/runtime/generated/asm_support_gen.h +++ b/runtime/generated/asm_support_gen.h @@ -33,6 +33,8 @@ DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET), DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::Runtime:: kRefsOnly)))) #define RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 0x10 DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::Runtime:: kRefsAndArgs)))) +#define RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET 0x18 +DEFINE_CHECK_EQ(static_cast<size_t>(RUNTIME_SAVE_EVERYTHING_CALLEE_SAVE_FRAME_OFFSET), (static_cast<size_t>(art::Runtime::GetCalleeSaveMethodOffset(art::Runtime:: kSaveEverything)))) #define THREAD_FLAGS_OFFSET 0 DEFINE_CHECK_EQ(static_cast<int32_t>(THREAD_FLAGS_OFFSET), (static_cast<int32_t>(art::Thread:: ThreadFlagsOffset<sizeof(void*)>().Int32Value()))) #define THREAD_ID_OFFSET 12 diff --git a/runtime/image.h b/runtime/image.h index 06f06eed0e..96889f6a2d 100644 --- a/runtime/image.h +++ b/runtime/image.h @@ -181,6 +181,7 @@ class PACKED(4) ImageHeader { kCalleeSaveMethod, kRefsOnlySaveMethod, kRefsAndArgsSaveMethod, + kSaveEverythingMethod, kImageMethodsCount, // Number of elements in enum. }; diff --git a/runtime/oat.h b/runtime/oat.h index 2c5c3e636f..7c84fe90f9 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,7 +32,7 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - static constexpr uint8_t kOatVersion[] = { '0', '8', '5', '\0' }; + static constexpr uint8_t kOatVersion[] = { '0', '8', '6', '\0' }; static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h index bfa8c549bf..265587dc5c 100644 --- a/runtime/runtime-inl.h +++ b/runtime/runtime-inl.h @@ -45,9 +45,11 @@ inline QuickMethodFrameInfo Runtime::GetRuntimeMethodFrameInfo(ArtMethod* method return GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs); } else if (method == GetCalleeSaveMethodUnchecked(Runtime::kSaveAll)) { return GetCalleeSaveMethodFrameInfo(Runtime::kSaveAll); - } else { - DCHECK_EQ(method, GetCalleeSaveMethodUnchecked(Runtime::kRefsOnly)); + } else if (method == GetCalleeSaveMethodUnchecked(Runtime::kRefsOnly)) { return GetCalleeSaveMethodFrameInfo(Runtime::kRefsOnly); + } else { + DCHECK_EQ(method, GetCalleeSaveMethodUnchecked(Runtime::kSaveEverything)); + return GetCalleeSaveMethodFrameInfo(Runtime::kSaveEverything); } } diff --git a/runtime/runtime.h b/runtime/runtime.h index afa8e4818b..7e269af765 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -387,9 +387,10 @@ class Runtime { // Returns a special method that describes all callee saves being spilled to the stack. enum CalleeSaveType { - kSaveAll, + kSaveAll, // All callee-save registers. kRefsOnly, kRefsAndArgs, + kSaveEverything, // Even caller-save registers. kLastCalleeSaveType // Value used for iteration }; diff --git a/tools/cpp-define-generator/offset_runtime.def b/tools/cpp-define-generator/offset_runtime.def index b327ca3a96..123992f473 100644 --- a/tools/cpp-define-generator/offset_runtime.def +++ b/tools/cpp-define-generator/offset_runtime.def @@ -34,6 +34,8 @@ DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_ALL, kSaveAll) DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(REFS_ONLY, kRefsOnly) // Offset of field Runtime::callee_save_methods_[kRefsAndArgs] DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(REFS_AND_ARGS, kRefsAndArgs) +// Offset of field Runtime::callee_save_methods_[kSaveEverything] +DEFINE_RUNTIME_CALLEE_SAVE_OFFSET(SAVE_EVERYTHING, kSaveEverything) #undef DEFINE_RUNTIME_CALLEE_SAVE_OFFSET #include "common_undef.def" // undef DEFINE_OFFSET_EXPR |