Home | History | Annotate | Download | only in arch
      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