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 "common_runtime_test.h" 20 #include "mirror/art_method-inl.h" 21 #include "quick/quick_method_frame_info.h" 22 23 namespace art { 24 25 class ArchTest : public CommonRuntimeTest { 26 protected: 27 static void CheckFrameSize(InstructionSet isa, Runtime::CalleeSaveType type, uint32_t save_size) 28 NO_THREAD_SAFETY_ANALYSIS { 29 Runtime* r = Runtime::Current(); 30 31 Thread* t = Thread::Current(); 32 t->TransitionFromSuspendedToRunnable(); // So we can create callee-save methods. 33 34 r->SetInstructionSet(isa); 35 mirror::ArtMethod* save_method = r->CreateCalleeSaveMethod(type); 36 r->SetCalleeSaveMethod(save_method, type); 37 QuickMethodFrameInfo frame_info = save_method->GetQuickFrameInfo(); 38 EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for " 39 << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills=" 40 << frame_info.FpSpillMask() << std::dec; 41 42 t->TransitionFromRunnableToSuspended(ThreadState::kNative); // So we can shut down. 43 } 44 }; 45 46 47 TEST_F(ArchTest, ARM) { 48 #include "arch/arm/asm_support_arm.h" 49 #undef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_H_ 50 51 52 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 53 CheckFrameSize(InstructionSet::kArm, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE); 54 #else 55 LOG(WARNING) << "No frame size for SaveAll"; 56 #endif 57 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 58 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE); 59 #else 60 LOG(WARNING) << "No frame size for RefsOnly"; 61 #endif 62 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 63 CheckFrameSize(InstructionSet::kArm, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE); 64 #else 65 LOG(WARNING) << "No frame size for RefsAndArgs"; 66 #endif 67 68 69 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 70 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 71 #endif 72 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 73 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 74 #endif 75 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 76 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 77 #endif 78 #ifdef THREAD_SELF_OFFSET 79 #undef THREAD_SELF_OFFSET 80 #endif 81 #ifdef THREAD_CARD_TABLE_OFFSET 82 #undef THREAD_CARD_TABLE_OFFSET 83 #endif 84 #ifdef THREAD_EXCEPTION_OFFSET 85 #undef THREAD_EXCEPTION_OFFSET 86 #endif 87 #ifdef THREAD_ID_OFFSET 88 #undef THREAD_ID_OFFSET 89 #endif 90 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 91 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 92 #endif 93 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 94 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 95 #endif 96 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 97 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 98 #endif 99 #ifdef HEAP_REFERENCE_SIZE 100 #undef HEAP_REFERENCE_SIZE 101 #endif 102 } 103 104 105 TEST_F(ArchTest, ARM64) { 106 #include "arch/arm64/asm_support_arm64.h" 107 #undef ART_RUNTIME_ARCH_ARM64_ASM_SUPPORT_ARM64_H_ 108 109 110 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 111 CheckFrameSize(InstructionSet::kArm64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE); 112 #else 113 LOG(WARNING) << "No frame size for SaveAll"; 114 #endif 115 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 116 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE); 117 #else 118 LOG(WARNING) << "No frame size for RefsOnly"; 119 #endif 120 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 121 CheckFrameSize(InstructionSet::kArm64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE); 122 #else 123 LOG(WARNING) << "No frame size for RefsAndArgs"; 124 #endif 125 126 127 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 128 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 129 #endif 130 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 131 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 132 #endif 133 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 134 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 135 #endif 136 #ifdef THREAD_SELF_OFFSET 137 #undef THREAD_SELF_OFFSET 138 #endif 139 #ifdef THREAD_CARD_TABLE_OFFSET 140 #undef THREAD_CARD_TABLE_OFFSET 141 #endif 142 #ifdef THREAD_EXCEPTION_OFFSET 143 #undef THREAD_EXCEPTION_OFFSET 144 #endif 145 #ifdef THREAD_ID_OFFSET 146 #undef THREAD_ID_OFFSET 147 #endif 148 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 149 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 150 #endif 151 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 152 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 153 #endif 154 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 155 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 156 #endif 157 #ifdef HEAP_REFERENCE_SIZE 158 #undef HEAP_REFERENCE_SIZE 159 #endif 160 } 161 162 163 TEST_F(ArchTest, MIPS) { 164 #include "arch/mips/asm_support_mips.h" 165 #undef ART_RUNTIME_ARCH_MIPS_ASM_SUPPORT_MIPS_H_ 166 167 168 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 169 CheckFrameSize(InstructionSet::kMips, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE); 170 #else 171 LOG(WARNING) << "No frame size for SaveAll"; 172 #endif 173 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 174 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE); 175 #else 176 LOG(WARNING) << "No frame size for RefsOnly"; 177 #endif 178 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 179 CheckFrameSize(InstructionSet::kMips, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE); 180 #else 181 LOG(WARNING) << "No frame size for RefsAndArgs"; 182 #endif 183 184 185 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 186 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 187 #endif 188 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 189 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 190 #endif 191 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 192 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 193 #endif 194 #ifdef THREAD_SELF_OFFSET 195 #undef THREAD_SELF_OFFSET 196 #endif 197 #ifdef THREAD_CARD_TABLE_OFFSET 198 #undef THREAD_CARD_TABLE_OFFSET 199 #endif 200 #ifdef THREAD_EXCEPTION_OFFSET 201 #undef THREAD_EXCEPTION_OFFSET 202 #endif 203 #ifdef THREAD_ID_OFFSET 204 #undef THREAD_ID_OFFSET 205 #endif 206 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 207 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 208 #endif 209 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 210 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 211 #endif 212 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 213 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 214 #endif 215 #ifdef HEAP_REFERENCE_SIZE 216 #undef HEAP_REFERENCE_SIZE 217 #endif 218 } 219 220 221 TEST_F(ArchTest, X86) { 222 #include "arch/x86/asm_support_x86.h" 223 #undef ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_H_ 224 225 226 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 227 CheckFrameSize(InstructionSet::kX86, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE); 228 #else 229 LOG(WARNING) << "No frame size for SaveAll"; 230 #endif 231 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 232 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE); 233 #else 234 LOG(WARNING) << "No frame size for RefsOnly"; 235 #endif 236 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 237 CheckFrameSize(InstructionSet::kX86, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE); 238 #else 239 LOG(WARNING) << "No frame size for RefsAndArgs"; 240 #endif 241 242 243 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 244 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 245 #endif 246 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 247 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 248 #endif 249 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 250 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 251 #endif 252 #ifdef THREAD_SELF_OFFSET 253 #undef THREAD_SELF_OFFSET 254 #endif 255 #ifdef THREAD_CARD_TABLE_OFFSET 256 #undef THREAD_CARD_TABLE_OFFSET 257 #endif 258 #ifdef THREAD_EXCEPTION_OFFSET 259 #undef THREAD_EXCEPTION_OFFSET 260 #endif 261 #ifdef THREAD_ID_OFFSET 262 #undef THREAD_ID_OFFSET 263 #endif 264 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 265 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 266 #endif 267 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 268 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 269 #endif 270 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 271 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 272 #endif 273 #ifdef HEAP_REFERENCE_SIZE 274 #undef HEAP_REFERENCE_SIZE 275 #endif 276 } 277 278 279 TEST_F(ArchTest, X86_64) { 280 #include "arch/x86_64/asm_support_x86_64.h" 281 #undef ART_RUNTIME_ARCH_X86_64_ASM_SUPPORT_X86_64_H_ 282 283 284 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 285 CheckFrameSize(InstructionSet::kX86_64, Runtime::kSaveAll, FRAME_SIZE_SAVE_ALL_CALLEE_SAVE); 286 #else 287 LOG(WARNING) << "No frame size for SaveAll"; 288 #endif 289 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 290 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsOnly, FRAME_SIZE_REFS_ONLY_CALLEE_SAVE); 291 #else 292 LOG(WARNING) << "No frame size for RefsOnly"; 293 #endif 294 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 295 CheckFrameSize(InstructionSet::kX86_64, Runtime::kRefsAndArgs, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE); 296 #else 297 LOG(WARNING) << "No frame size for RefsAndArgs"; 298 #endif 299 300 301 #ifdef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 302 #undef RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET 303 #endif 304 #ifdef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 305 #undef RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET 306 #endif 307 #ifdef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 308 #undef RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET 309 #endif 310 #ifdef THREAD_SELF_OFFSET 311 #undef THREAD_SELF_OFFSET 312 #endif 313 #ifdef THREAD_CARD_TABLE_OFFSET 314 #undef THREAD_CARD_TABLE_OFFSET 315 #endif 316 #ifdef THREAD_EXCEPTION_OFFSET 317 #undef THREAD_EXCEPTION_OFFSET 318 #endif 319 #ifdef THREAD_ID_OFFSET 320 #undef THREAD_ID_OFFSET 321 #endif 322 #ifdef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 323 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 324 #endif 325 #ifdef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 326 #undef FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 327 #endif 328 #ifdef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 329 #undef FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 330 #endif 331 #ifdef HEAP_REFERENCE_SIZE 332 #undef HEAP_REFERENCE_SIZE 333 #endif 334 } 335 336 337 // The following tests are all for the running architecture. So we get away 338 // with just including it and not undefining it every time. 339 340 #if defined(__arm__) 341 #include "arch/arm/asm_support_arm.h" 342 #elif defined(__aarch64__) 343 #include "arch/arm64/asm_support_arm64.h" 344 #elif defined(__mips__) 345 #include "arch/mips/asm_support_mips.h" 346 #elif defined(__i386__) 347 #include "arch/x86/asm_support_x86.h" 348 #elif defined(__x86_64__) 349 #include "arch/x86_64/asm_support_x86_64.h" 350 #else 351 // This happens for the host test. 352 #ifdef __LP64__ 353 #include "arch/x86_64/asm_support_x86_64.h" 354 #else 355 #include "arch/x86/asm_support_x86.h" 356 #endif 357 #endif 358 359 360 TEST_F(ArchTest, ThreadOffsets) { 361 // Ugly hack, change when possible. 362 #ifdef __LP64__ 363 #define POINTER_SIZE 8 364 #else 365 #define POINTER_SIZE 4 366 #endif 367 368 #if defined(THREAD_SELF_OFFSET) 369 ThreadOffset<POINTER_SIZE> self_offset = Thread::SelfOffset<POINTER_SIZE>(); 370 EXPECT_EQ(self_offset.Int32Value(), THREAD_SELF_OFFSET); 371 #else 372 LOG(INFO) << "No Thread Self Offset found."; 373 #endif 374 375 #if defined(THREAD_CARD_TABLE_OFFSET) 376 ThreadOffset<POINTER_SIZE> card_offset = Thread::CardTableOffset<POINTER_SIZE>(); 377 EXPECT_EQ(card_offset.Int32Value(), THREAD_CARD_TABLE_OFFSET); 378 #else 379 LOG(INFO) << "No Thread Card Table Offset found."; 380 #endif 381 382 #if defined(THREAD_EXCEPTION_OFFSET) 383 ThreadOffset<POINTER_SIZE> exc_offset = Thread::ExceptionOffset<POINTER_SIZE>(); 384 EXPECT_EQ(exc_offset.Int32Value(), THREAD_EXCEPTION_OFFSET); 385 #else 386 LOG(INFO) << "No Thread Exception Offset found."; 387 #endif 388 389 #if defined(THREAD_ID_OFFSET) 390 ThreadOffset<POINTER_SIZE> id_offset = Thread::ThinLockIdOffset<POINTER_SIZE>(); 391 EXPECT_EQ(id_offset.Int32Value(), THREAD_ID_OFFSET); 392 #else 393 LOG(INFO) << "No Thread ID Offset found."; 394 #endif 395 } 396 397 398 TEST_F(ArchTest, CalleeSaveMethodOffsets) { 399 #if defined(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET) 400 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kSaveAll), 401 static_cast<size_t>(RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET)); 402 #else 403 LOG(INFO) << "No Runtime Save-all Offset found."; 404 #endif 405 406 #if defined(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET) 407 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsOnly), 408 static_cast<size_t>(RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET)); 409 #else 410 LOG(INFO) << "No Runtime Refs-only Offset found."; 411 #endif 412 413 #if defined(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET) 414 EXPECT_EQ(Runtime::GetCalleeSaveMethodOffset(Runtime::kRefsAndArgs), 415 static_cast<size_t>(RUNTIME_REF_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET)); 416 #else 417 LOG(INFO) << "No Runtime Refs-and-Args Offset found."; 418 #endif 419 } 420 421 422 TEST_F(ArchTest, HeapReferenceSize) { 423 #if defined(HEAP_REFERENCE_SIZE) 424 EXPECT_EQ(sizeof(mirror::HeapReference<mirror::Object>), 425 static_cast<size_t>(HEAP_REFERENCE_SIZE)); 426 #else 427 LOG(INFO) << "No expected HeapReference Size found."; 428 #endif 429 } 430 431 TEST_F(ArchTest, StackReferenceSize) { 432 #if defined(STACK_REFERENCE_SIZE) 433 EXPECT_EQ(sizeof(StackReference<mirror::Object>), 434 static_cast<size_t>(STACK_REFERENCE_SIZE)); 435 #else 436 LOG(INFO) << "No expected StackReference Size #define found."; 437 #endif 438 } 439 440 } // namespace art 441