1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdint.h> 18 19 #include "art_method-inl.h" 20 #include "common_runtime_test.h" 21 #include "quick/quick_method_frame_info.h" 22 23 namespace art { 24 25 class ArchTest : public CommonRuntimeTest { 26 protected: 27 void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE { 28 // Use 64-bit ISA for runtime setup to make method size potentially larger 29 // than necessary (rather than smaller) during CreateCalleeSaveMethod 30 options->push_back(std::make_pair("imageinstructionset", "x86_64")); 31 } 32 33 static void CheckFrameSize(InstructionSet isa, Runtime::CalleeSaveType type, uint32_t save_size) 34 NO_THREAD_SAFETY_ANALYSIS { 35 Runtime* r = Runtime::Current(); 36 37 Thread* t = Thread::Current(); 38 t->TransitionFromSuspendedToRunnable(); // So we can create callee-save methods. 39 40 r->SetInstructionSet(isa); 41 ArtMethod* save_method = r->CreateCalleeSaveMethod(); 42 r->SetCalleeSaveMethod(save_method, type); 43 QuickMethodFrameInfo frame_info = save_method->GetQuickFrameInfo(); 44 EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for " 45 << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills=" 46 << frame_info.FpSpillMask() << std::dec; 47 48 t->TransitionFromRunnableToSuspended(ThreadState::kNative); // So we can shut down. 49 } 50 }; 51 52 // Common tests are declared next to the constants. 53 #define ADD_TEST_EQ(x, y) EXPECT_EQ(x, y); 54 #include "asm_support.h" 55 56 TEST_F(ArchTest, CheckCommonOffsetsAndSizes) { 57 CheckAsmSupportOffsetsAndSizes(); 58 } 59 60 // Grab architecture specific constants. 61 namespace arm { 62 #include "arch/arm/asm_support_arm.h" 63 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 64 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 65 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 66 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 67 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 68 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 69 } 70 71 namespace arm64 { 72 #include "arch/arm64/asm_support_arm64.h" 73 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 74 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 75 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 76 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 77 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 78 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 79 } 80 81 namespace mips { 82 #include "arch/mips/asm_support_mips.h" 83 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 84 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 85 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 86 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 87 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 88 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 89 } 90 91 namespace mips64 { 92 #include "arch/mips64/asm_support_mips64.h" 93 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 94 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 95 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 96 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 97 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 98 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 99 } 100 101 namespace x86 { 102 #include "arch/x86/asm_support_x86.h" 103 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 104 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 105 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 106 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 107 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 108 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 109 } 110 111 namespace x86_64 { 112 #include "arch/x86_64/asm_support_x86_64.h" 113 static constexpr size_t kFrameSizeSaveAllCalleeSave = FRAME_SIZE_SAVE_ALL_CALLEE_SAVE; 114 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 115 static constexpr size_t kFrameSizeRefsOnlyCalleeSave = FRAME_SIZE_REFS_ONLY_CALLEE_SAVE; 116 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 117 static constexpr size_t kFrameSizeRefsAndArgsCalleeSave = FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE; 118 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 119 } 120 121 // Check architecture specific constants are sound. 122 TEST_F(ArchTest, ARM) { 123 CheckFrameSize(InstructionSet::kArm, Runtime::kSaveAll, arm::kFrameSizeSaveAllCalleeSave); 124 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsOnly, arm::kFrameSizeRefsOnlyCalleeSave); 125 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsAndArgs, arm::kFrameSizeRefsAndArgsCalleeSave); 126 } 127 128 129 TEST_F(ArchTest, ARM64) { 130 CheckFrameSize(InstructionSet::kArm64, Runtime::kSaveAll, arm64::kFrameSizeSaveAllCalleeSave); 131 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsOnly, arm64::kFrameSizeRefsOnlyCalleeSave); 132 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsAndArgs, 133 arm64::kFrameSizeRefsAndArgsCalleeSave); 134 } 135 136 TEST_F(ArchTest, MIPS) { 137 CheckFrameSize(InstructionSet::kMips, Runtime::kSaveAll, mips::kFrameSizeSaveAllCalleeSave); 138 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsOnly, mips::kFrameSizeRefsOnlyCalleeSave); 139 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsAndArgs, 140 mips::kFrameSizeRefsAndArgsCalleeSave); 141 } 142 143 TEST_F(ArchTest, MIPS64) { 144 CheckFrameSize(InstructionSet::kMips64, Runtime::kSaveAll, mips64::kFrameSizeSaveAllCalleeSave); 145 CheckFrameSize(InstructionSet::kMips64, Runtime::kRefsOnly, mips64::kFrameSizeRefsOnlyCalleeSave); 146 CheckFrameSize(InstructionSet::kMips64, Runtime::kRefsAndArgs, 147 mips64::kFrameSizeRefsAndArgsCalleeSave); 148 } 149 150 TEST_F(ArchTest, X86) { 151 CheckFrameSize(InstructionSet::kX86, Runtime::kSaveAll, x86::kFrameSizeSaveAllCalleeSave); 152 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsOnly, x86::kFrameSizeRefsOnlyCalleeSave); 153 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsAndArgs, x86::kFrameSizeRefsAndArgsCalleeSave); 154 } 155 156 TEST_F(ArchTest, X86_64) { 157 CheckFrameSize(InstructionSet::kX86_64, Runtime::kSaveAll, x86_64::kFrameSizeSaveAllCalleeSave); 158 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsOnly, x86_64::kFrameSizeRefsOnlyCalleeSave); 159 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsAndArgs, 160 x86_64::kFrameSizeRefsAndArgsCalleeSave); 161 } 162 163 } // namespace art 164