diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-22 11:03:52 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-05-02 10:44:52 +0100 |
commit | 42fcd9838a87abaf7a2ef86853a5287f86dbe391 (patch) | |
tree | d8ffcfcb9c1997c06c6ef93b551abaa900ebcf8e /runtime | |
parent | 608168b380b741e2c7e1a2b0b568c0738986166b (diff) | |
download | art-42fcd9838a87abaf7a2ef86853a5287f86dbe391.zip art-42fcd9838a87abaf7a2ef86853a5287f86dbe391.tar.gz art-42fcd9838a87abaf7a2ef86853a5287f86dbe391.tar.bz2 |
Revert "Revert "64bit changes to the stack walker for the Quick ABI.""
This reverts commit 8d5ead52a92675c258113d3dfa71bf8fceba5d9f.
Change-Id: I6b4774a9bd180de33551975e106322ba1192e6ab
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 46 | ||||
-rw-r--r-- | runtime/instruction_set.cc | 46 | ||||
-rw-r--r-- | runtime/instruction_set.h | 2 | ||||
-rw-r--r-- | runtime/stack.cc | 2 | ||||
-rw-r--r-- | runtime/stack.h | 23 |
5 files changed, 80 insertions, 39 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 2b29591..680ffbe 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,13 +55,12 @@ 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. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = 48; // Frame size. static size_t GprIndexToGprOffset(uint32_t gpr_index) { - return gpr_index * kBytesPerGprSpillLocation; + return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } #elif defined(__aarch64__) // The callee save frame is pointed to by SP. @@ -93,13 +86,12 @@ 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. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = 304; // Frame size. static size_t GprIndexToGprOffset(uint32_t gpr_index) { - return gpr_index * kBytesPerGprSpillLocation; + return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } #elif defined(__mips__) // The callee save frame is pointed to by SP. @@ -119,13 +111,12 @@ 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. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = 64; // Frame size. static size_t GprIndexToGprOffset(uint32_t gpr_index) { - return gpr_index * kBytesPerGprSpillLocation; + return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } #elif defined(__i386__) // The callee save frame is pointed to by SP. @@ -145,13 +136,12 @@ 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. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = 32; // Frame size. static size_t GprIndexToGprOffset(uint32_t gpr_index) { - return gpr_index * kBytesPerGprSpillLocation; + return gpr_index * GetBytesPerGprSpillLocation(kRuntimeISA); } #elif defined(__x86_64__) // The callee save frame is pointed to by SP. @@ -184,18 +174,17 @@ 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. static constexpr size_t kQuickCalleeSaveFrame_RefAndArgs_FrameSize = 176; // Frame size. static size_t GprIndexToGprOffset(uint32_t gpr_index) { switch (gpr_index) { - case 0: return (4 * kBytesPerGprSpillLocation); - case 1: return (1 * kBytesPerGprSpillLocation); - case 2: return (0 * kBytesPerGprSpillLocation); - case 3: return (5 * kBytesPerGprSpillLocation); - case 4: return (6 * kBytesPerGprSpillLocation); + case 0: return (4 * GetBytesPerGprSpillLocation(kRuntimeISA)); + case 1: return (1 * GetBytesPerGprSpillLocation(kRuntimeISA)); + case 2: return (0 * GetBytesPerGprSpillLocation(kRuntimeISA)); + case 3: return (5 * GetBytesPerGprSpillLocation(kRuntimeISA)); + case 4: return (6 * GetBytesPerGprSpillLocation(kRuntimeISA)); default: LOG(FATAL) << "Unexpected GPR index: " << gpr_index; return 0; @@ -248,7 +237,7 @@ class QuickArgumentVisitor { Primitive::Type type = GetParamPrimitiveType(); if (UNLIKELY((type == Primitive::kPrimDouble) || (type == Primitive::kPrimFloat))) { if ((kNumQuickFprArgs != 0) && (fpr_index_ + 1 < kNumQuickFprArgs + 1)) { - return fpr_args_ + (fpr_index_ * kBytesPerFprSpillLocation); + return fpr_args_ + (fpr_index_ * GetBytesPerFprSpillLocation(kRuntimeISA)); } return stack_args_ + (stack_index_ * kBytesStackArgLocation); } @@ -260,7 +249,7 @@ class QuickArgumentVisitor { } bool IsSplitLongOrDouble() const { - if ((kBytesPerGprSpillLocation == 4) || (kBytesPerFprSpillLocation == 4)) { + if ((GetBytesPerGprSpillLocation(kRuntimeISA) == 4) || (GetBytesPerFprSpillLocation(kRuntimeISA) == 4)) { return is_split_long_or_double_; } else { return false; // An optimization for when GPR and FPRs are 64bit. @@ -341,7 +330,7 @@ class QuickArgumentVisitor { case Primitive::kPrimDouble: case Primitive::kPrimLong: if (kQuickSoftFloatAbi || (cur_type_ == Primitive::kPrimLong)) { - is_split_long_or_double_ = (kBytesPerGprSpillLocation == 4) && + is_split_long_or_double_ = (GetBytesPerGprSpillLocation(kRuntimeISA) == 4) && ((gpr_index_ + 1) == kNumQuickGprArgs); Visit(); if (!kQuickSoftFloatAbi || kNumQuickGprArgs == gpr_index_) { @@ -354,7 +343,7 @@ class QuickArgumentVisitor { } if (gpr_index_ < kNumQuickGprArgs) { gpr_index_++; - if (kBytesPerGprSpillLocation == 4) { + if (GetBytesPerGprSpillLocation(kRuntimeISA) == 4) { if (gpr_index_ < kNumQuickGprArgs) { gpr_index_++; } else if (kQuickSoftFloatAbi) { @@ -363,12 +352,12 @@ class QuickArgumentVisitor { } } } else { - is_split_long_or_double_ = (kBytesPerFprSpillLocation == 4) && + is_split_long_or_double_ = (GetBytesPerFprSpillLocation(kRuntimeISA) == 4) && ((fpr_index_ + 1) == kNumQuickFprArgs); Visit(); if ((kNumQuickFprArgs != 0) && (fpr_index_ + 1 < kNumQuickFprArgs + 1)) { fpr_index_++; - if (kBytesPerFprSpillLocation == 4) { + if (GetBytesPerFprSpillLocation(kRuntimeISA) == 4) { if ((kNumQuickFprArgs != 0) && (fpr_index_ + 1 < kNumQuickFprArgs + 1)) { fpr_index_++; } @@ -393,12 +382,13 @@ class QuickArgumentVisitor { uint32_t shorty_len) { if (kQuickSoftFloatAbi) { CHECK_EQ(kNumQuickFprArgs, 0U); - return (kNumQuickGprArgs * kBytesPerGprSpillLocation) + kBytesPerGprSpillLocation /* ArtMethod* */; + return (kNumQuickGprArgs * GetBytesPerGprSpillLocation(kRuntimeISA)) + + GetBytesPerGprSpillLocation(kRuntimeISA) /* ArtMethod* */; } else { // For now, there is no reg-spill area for the targets with // hard float ABI. So, the offset pointing to the first method's // parameter ('this' for non-static methods) should be returned. - return kBytesPerGprSpillLocation; // Skip Method*. + return GetBytesPerGprSpillLocation(kRuntimeISA); // Skip Method*. } } diff --git a/runtime/instruction_set.cc b/runtime/instruction_set.cc index cbcd2e0..c1931a9 100644 --- a/runtime/instruction_set.cc +++ b/runtime/instruction_set.cc @@ -86,6 +86,52 @@ size_t GetInstructionSetPointerSize(InstructionSet isa) { } } +size_t GetBytesPerGprSpillLocation(InstructionSet isa) { + switch (isa) { + case kArm: + // Fall-through. + case kThumb2: + return 4; + case kArm64: + return 8; + case kX86: + return 4; + case kX86_64: + return 8; + case kMips: + return 4; + case kNone: + LOG(FATAL) << "ISA kNone does not have spills."; + return 0; + default: + LOG(FATAL) << "Unknown ISA " << isa; + return 0; + } +} + +size_t GetBytesPerFprSpillLocation(InstructionSet isa) { + switch (isa) { + case kArm: + // Fall-through. + case kThumb2: + return 4; + case kArm64: + return 8; + case kX86: + return 8; + case kX86_64: + return 8; + case kMips: + return 4; + case kNone: + LOG(FATAL) << "ISA kNone does not have spills."; + return 0; + default: + LOG(FATAL) << "Unknown ISA " << isa; + return 0; + } +} + size_t GetInstructionSetAlignment(InstructionSet isa) { switch (isa) { case kArm: diff --git a/runtime/instruction_set.h b/runtime/instruction_set.h index 4bc35a7..bfbbbd6 100644 --- a/runtime/instruction_set.h +++ b/runtime/instruction_set.h @@ -41,6 +41,8 @@ InstructionSet GetInstructionSetFromString(const char* instruction_set); size_t GetInstructionSetPointerSize(InstructionSet isa); size_t GetInstructionSetAlignment(InstructionSet isa); bool Is64BitInstructionSet(InstructionSet isa); +size_t GetBytesPerGprSpillLocation(InstructionSet isa); +size_t GetBytesPerFprSpillLocation(InstructionSet isa); #if defined(__arm__) static constexpr InstructionSet kRuntimeISA = kArm; diff --git a/runtime/stack.cc b/runtime/stack.cc index ab3bd85..9c709ae 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -187,7 +187,7 @@ void StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val uint32_t core_spills = m->GetCoreSpillMask(); uint32_t fp_spills = m->GetFpSpillMask(); size_t frame_size = m->GetFrameSizeInBytes(); - int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg); + int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg, kRuntimeISA); byte* vreg_addr = reinterpret_cast<byte*>(GetCurrentQuickFrame()) + offset; *reinterpret_cast<uint32_t*>(vreg_addr) = new_value; } diff --git a/runtime/stack.h b/runtime/stack.h index ab903d6..afc4f25 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -19,9 +19,10 @@ #include "dex_file.h" #include "instrumentation.h" +#include "arch/context.h" #include "base/casts.h" #include "base/macros.h" -#include "arch/context.h" +#include "instruction_set.h" #include "mirror/object.h" #include "mirror/object_reference.h" #include "verify_object.h" @@ -577,7 +578,7 @@ class StackVisitor { uint32_t* GetVRegAddr(mirror::ArtMethod** cur_quick_frame, const DexFile::CodeItem* code_item, uint32_t core_spills, uint32_t fp_spills, size_t frame_size, uint16_t vreg) const { - int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg); + int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg, kRuntimeISA); DCHECK_EQ(cur_quick_frame, GetCurrentQuickFrame()); byte* vreg_addr = reinterpret_cast<byte*>(cur_quick_frame) + offset; return reinterpret_cast<uint32_t*>(vreg_addr); @@ -634,14 +635,15 @@ class StackVisitor { */ static int GetVRegOffset(const DexFile::CodeItem* code_item, uint32_t core_spills, uint32_t fp_spills, - size_t frame_size, int reg) { + size_t frame_size, int reg, InstructionSet isa) { DCHECK_EQ(frame_size & (kStackAlignment - 1), 0U); DCHECK_NE(reg, static_cast<int>(kVRegInvalid)); - - int num_spills = __builtin_popcount(core_spills) + __builtin_popcount(fp_spills) + 1; // Filler. + int spill_size = __builtin_popcount(core_spills) * GetBytesPerGprSpillLocation(isa) + + __builtin_popcount(fp_spills) * GetBytesPerFprSpillLocation(isa) + + 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 - spill_size - num_regs * sizeof(uint32_t); if (reg == static_cast<int>(kVRegMethodPtrBaseReg)) { // The current method pointer corresponds to special location on stack. return 0; @@ -654,19 +656,20 @@ class StackVisitor { * temp is at offset -4 bytes from locals, the second is at -8 bytes from locals, * and so on. */ - int relative_offset = (reg + std::abs(static_cast<int>(kVRegNonSpecialTempBaseReg)) - 1) * sizeof(uint32_t); + int relative_offset = + (reg + std::abs(static_cast<int>(kVRegNonSpecialTempBaseReg)) - 1) * sizeof(uint32_t); return locals_start + relative_offset; } else if (reg < num_regs) { return locals_start + (reg * sizeof(uint32_t)); } else { // Handle ins. - return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(StackReference<mirror::ArtMethod>); + return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + GetBytesPerGprSpillLocation(isa); } } - static int GetOutVROffset(uint16_t out_num) { + static int GetOutVROffset(uint16_t out_num, InstructionSet isa) { // According to stack model, the first out is above the Method ptr. - return sizeof(StackReference<mirror::ArtMethod>) + (out_num * sizeof(uint32_t)); + return GetBytesPerGprSpillLocation(isa) + (out_num * sizeof(uint32_t)); } uintptr_t GetCurrentQuickFramePc() const { |