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
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 063eb11..0f6944a 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1377,6 +1377,8 @@
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 3269dc6..94ecb1c 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -765,16 +765,24 @@
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 124a61f..62f3ee9 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -119,11 +119,9 @@
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 efeef7b..21ca506 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -398,11 +398,9 @@
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 334d30d..bdd75b6 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -351,14 +351,12 @@
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 29b8c20..e16abc5 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -300,13 +300,11 @@
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 528e94f..3fb4fe8 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -192,13 +192,11 @@
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 0f0129b..b0c3caa 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -149,13 +149,11 @@
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 64349b5..532bccf 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -76,6 +76,7 @@
"kCalleeSaveMethod",
"kRefsOnlySaveMethod",
"kRefsAndArgsSaveMethod",
+ "kSaveEverythingMethod",
};
const char* image_roots_descriptions_[] = {
diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc
index ee31c58..6d80eb6 100644
--- a/runtime/arch/arch_test.cc
+++ b/runtime/arch/arch_test.cc
@@ -69,7 +69,9 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
#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 @@
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 1fa566b..67f6f7a 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 34d3158..ee59068 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 @@
.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 5580ee4..3e726e0 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 @@
(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 @@
(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 989ecc6..68d12e9 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 a5be52d..971b843 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 @@
*/
.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 b525309..46ddf68 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 @@
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 @@
(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 @@
(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 453056d..2ef45f5 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 c1b8044..b926bdf 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 @@
* 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 f5d13c2..cce467e 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 @@
(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 @@
(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 995fcf3..2c16c25 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 ae69620..0a37909 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 @@
* 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 f967be0..2bd2db0 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 @@
(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 @@
(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 b0a6017..ba5fd99 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 77e04e7..aa1af41 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -222,6 +222,74 @@
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 @@
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 @@
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 ed1d860..b171190 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 @@
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 48bec73..58dc2fe 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 784ec39..a7c5e67 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 @@
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 @@
// 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 @@
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 @@
#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 @@
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 72d7e99..ce18447 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_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 8cadc2e..0c38295 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1435,6 +1435,8 @@
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 @@
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 a892eab..ff70cbe 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_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 06f06ee..96889f6 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -181,6 +181,7 @@
kCalleeSaveMethod,
kRefsOnlySaveMethod,
kRefsAndArgsSaveMethod,
+ kSaveEverythingMethod,
kImageMethodsCount, // Number of elements in enum.
};
diff --git a/runtime/oat.h b/runtime/oat.h
index 2c5c3e6..7c84fe9 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
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 bfa8c54..265587d 100644
--- a/runtime/runtime-inl.h
+++ b/runtime/runtime-inl.h
@@ -45,9 +45,11 @@
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 afa8e48..7e269af 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -387,9 +387,10 @@
// 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 b327ca3..123992f 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(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