From 5cb328362a633302ca0fcdbaa0da7d94069df051 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Thu, 17 Apr 2014 14:05:19 +0100 Subject: 64bit changes to the stack walker for the Quick ABI. - Spill registers have different sizes. - The ArtMethod at the bottom of the stack is always of kWordSize. Change-Id: I92f67ff928477970c393c7146980255d08e8e6af --- runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 11 ----------- runtime/instruction_set.h | 10 ++++++++++ runtime/stack.h | 11 ++++++----- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'runtime') diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 2b29591..741b7dd 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -34,12 +34,6 @@ namespace art { // Visits the arguments as saved to the stack by a Runtime::kRefAndArgs callee save frame. class QuickArgumentVisitor { - // Size of each spilled GPR. -#ifdef __LP64__ - static constexpr size_t kBytesPerGprSpillLocation = 8; -#else - static constexpr size_t kBytesPerGprSpillLocation = 4; -#endif // Number of bytes for each out register in the caller method's frame. static constexpr size_t kBytesStackArgLocation = 4; #if defined(__arm__) @@ -61,7 +55,6 @@ class QuickArgumentVisitor { static constexpr bool kQuickSoftFloatAbi = true; // This is a soft float ABI. static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 0; // 0 arguments passed in FPRs. - static constexpr size_t kBytesPerFprSpillLocation = 4; // FPR spill size is 4 bytes. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 0; // Offset of first FPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 8; // Offset of first GPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 44; // Offset of return address. @@ -93,7 +86,6 @@ class QuickArgumentVisitor { static constexpr bool kQuickSoftFloatAbi = false; // This is a hard float ABI. static constexpr size_t kNumQuickGprArgs = 7; // 7 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 8; // 8 arguments passed in FPRs. - static constexpr size_t kBytesPerFprSpillLocation = 8; // FPR spill size is 8 bytes. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset =16; // Offset of first FPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 144; // Offset of first GPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 296; // Offset of return address. @@ -119,7 +111,6 @@ class QuickArgumentVisitor { static constexpr bool kQuickSoftFloatAbi = true; // This is a soft float ABI. static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 0; // 0 arguments passed in FPRs. - static constexpr size_t kBytesPerFprSpillLocation = 4; // FPR spill size is 4 bytes. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 0; // Offset of first FPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 4; // Offset of first GPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 60; // Offset of return address. @@ -145,7 +136,6 @@ class QuickArgumentVisitor { static constexpr bool kQuickSoftFloatAbi = true; // This is a soft float ABI. static constexpr size_t kNumQuickGprArgs = 3; // 3 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 0; // 0 arguments passed in FPRs. - static constexpr size_t kBytesPerFprSpillLocation = 8; // FPR spill size is 8 bytes. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 0; // Offset of first FPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 4; // Offset of first GPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 28; // Offset of return address. @@ -184,7 +174,6 @@ class QuickArgumentVisitor { static constexpr bool kQuickSoftFloatAbi = false; // This is a hard float ABI. static constexpr size_t kNumQuickGprArgs = 5; // 3 arguments passed in GPRs. static constexpr size_t kNumQuickFprArgs = 8; // 0 arguments passed in FPRs. - static constexpr size_t kBytesPerFprSpillLocation = 8; // FPR spill size is 8 bytes. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Fpr1Offset = 16; // Offset of first FPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset = 80; // Offset of first GPR arg. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_LrOffset = 168; // Offset of return address. diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h index c746e06..4eebaa6 100644 --- a/runtime/instruction_set.h +++ b/runtime/instruction_set.h @@ -41,14 +41,24 @@ bool Is64BitInstructionSet(InstructionSet isa); #if defined(__arm__) static constexpr InstructionSet kRuntimeISA = kArm; +static constexpr size_t kBytesPerGprSpillLocation = 4; +static constexpr size_t kBytesPerFprSpillLocation = 4; #elif defined(__aarch64__) static constexpr InstructionSet kRuntimeISA = kArm64; +static constexpr size_t kBytesPerGprSpillLocation = 8; +static constexpr size_t kBytesPerFprSpillLocation = 8; #elif defined(__mips__) static constexpr InstructionSet kRuntimeISA = kMips; +static constexpr size_t kBytesPerGprSpillLocation = 4; +static constexpr size_t kBytesPerFprSpillLocation = 4; #elif defined(__i386__) static constexpr InstructionSet kRuntimeISA = kX86; +static constexpr size_t kBytesPerGprSpillLocation = 4; +static constexpr size_t kBytesPerFprSpillLocation = 8; #elif defined(__x86_64__) static constexpr InstructionSet kRuntimeISA = kX86_64; +static constexpr size_t kBytesPerGprSpillLocation = 8; +static constexpr size_t kBytesPerFprSpillLocation = 8; #else static constexpr InstructionSet kRuntimeISA = kNone; #endif diff --git a/runtime/stack.h b/runtime/stack.h index ab903d6..deba389 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -637,11 +637,12 @@ class StackVisitor { size_t frame_size, int reg) { DCHECK_EQ(frame_size & (kStackAlignment - 1), 0U); DCHECK_NE(reg, static_cast(kVRegInvalid)); - - int num_spills = __builtin_popcount(core_spills) + __builtin_popcount(fp_spills) + 1; // Filler. + int spills = __builtin_popcount(core_spills) * kBytesPerGprSpillLocation + + __builtin_popcount(fp_spills) * kBytesPerFprSpillLocation + + sizeof(uint32_t); // Filler. int num_ins = code_item->ins_size_; int num_regs = code_item->registers_size_ - num_ins; - int locals_start = frame_size - ((num_spills + num_regs) * sizeof(uint32_t)); + int locals_start = frame_size - spills - num_regs * sizeof(uint32_t); if (reg == static_cast(kVRegMethodPtrBaseReg)) { // The current method pointer corresponds to special location on stack. return 0; @@ -660,13 +661,13 @@ class StackVisitor { return locals_start + (reg * sizeof(uint32_t)); } else { // Handle ins. - return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(StackReference); + return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + kWordSize; } } static int GetOutVROffset(uint16_t out_num) { // According to stack model, the first out is above the Method ptr. - return sizeof(StackReference) + (out_num * sizeof(uint32_t)); + return kWordSize + (out_num * sizeof(uint32_t)); } uintptr_t GetCurrentQuickFramePc() const { -- cgit v1.1