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 23namespace art { 24 25class 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 47TEST_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 105TEST_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 163TEST_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 221TEST_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 279TEST_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 360TEST_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 398TEST_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 422TEST_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 431TEST_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