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 "art_method-inl.h"
     20 #include "base/callee_save_type.h"
     21 #include "common_runtime_test.h"
     22 #include "quick/quick_method_frame_info.h"
     23 
     24 
     25 // asm_support.h declares tests next to the #defines. We use asm_support_check.h to (safely)
     26 // generate CheckAsmSupportOffsetsAndSizes using gtest's EXPECT for the tests. We also use the
     27 // RETURN_TYPE, HEADER and FOOTER defines from asm_support_check.h to try to ensure that any
     28 // tests are actually generated.
     29 
     30 // Let CheckAsmSupportOffsetsAndSizes return a size_t (the count).
     31 #define ASM_SUPPORT_CHECK_RETURN_TYPE size_t
     32 
     33 // Declare the counter that will be updated per test.
     34 #define ASM_SUPPORT_CHECK_HEADER size_t count = 0;
     35 
     36 // Use EXPECT_EQ for tests, and increment the counter.
     37 #define ADD_TEST_EQ(x, y) EXPECT_EQ(x, y); count++;
     38 
     39 // Return the counter at the end of CheckAsmSupportOffsetsAndSizes.
     40 #define ASM_SUPPORT_CHECK_FOOTER return count;
     41 
     42 // Generate CheckAsmSupportOffsetsAndSizes().
     43 #include "asm_support_check.h"
     44 
     45 namespace art {
     46 
     47 class ArchTest : public CommonRuntimeTest {
     48  protected:
     49   void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE {
     50     // Use 64-bit ISA for runtime setup to make method size potentially larger
     51     // than necessary (rather than smaller) during CreateCalleeSaveMethod
     52     options->push_back(std::make_pair("imageinstructionset", "x86_64"));
     53   }
     54 
     55   // Do not do any of the finalization. We don't want to run any code, we don't need the heap
     56   // prepared, it actually will be a problem with setting the instruction set to x86_64 in
     57   // SetUpRuntimeOptions.
     58   void FinalizeSetup() OVERRIDE {
     59     ASSERT_EQ(InstructionSet::kX86_64, Runtime::Current()->GetInstructionSet());
     60   }
     61 
     62   static void CheckFrameSize(InstructionSet isa, CalleeSaveType type, uint32_t save_size)
     63       NO_THREAD_SAFETY_ANALYSIS {
     64     Runtime* const runtime = Runtime::Current();
     65     Thread* const self = Thread::Current();
     66     ScopedObjectAccess soa(self);  // So we can create callee-save methods.
     67 
     68     runtime->SetInstructionSet(isa);
     69     ArtMethod* save_method = runtime->CreateCalleeSaveMethod();
     70     runtime->SetCalleeSaveMethod(save_method, type);
     71     QuickMethodFrameInfo frame_info =  runtime->GetRuntimeMethodFrameInfo(save_method);
     72     EXPECT_EQ(frame_info.FrameSizeInBytes(), save_size) << "Expected and real size differs for "
     73         << type << " core spills=" << std::hex << frame_info.CoreSpillMask() << " fp spills="
     74         << frame_info.FpSpillMask() << std::dec;
     75   }
     76 };
     77 
     78 TEST_F(ArchTest, CheckCommonOffsetsAndSizes) {
     79   size_t test_count = CheckAsmSupportOffsetsAndSizes();
     80   EXPECT_GT(test_count, 0u);
     81 }
     82 
     83 // Grab architecture specific constants.
     84 namespace arm {
     85 #include "arch/arm/asm_support_arm.h"
     86 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
     87 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
     88 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
     89 #undef FRAME_SIZE_SAVE_REFS_ONLY
     90 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
     91 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
     92 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
     93 #undef FRAME_SIZE_SAVE_EVERYTHING
     94 #undef BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_ENTRYPOINT_OFFSET
     95 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_WIDE_ENTRYPOINT_OFFSET
     96 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_NARROW_ENTRYPOINT_OFFSET
     97 #undef BAKER_MARK_INTROSPECTION_ARRAY_SWITCH_OFFSET
     98 #undef BAKER_MARK_INTROSPECTION_FIELD_LDR_WIDE_OFFSET
     99 #undef BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_OFFSET
    100 #undef BAKER_MARK_INTROSPECTION_ARRAY_LDR_OFFSET
    101 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_WIDE_OFFSET
    102 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_NARROW_OFFSET
    103 }  // namespace arm
    104 
    105 namespace arm64 {
    106 #include "arch/arm64/asm_support_arm64.h"
    107 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
    108 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    109 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
    110 #undef FRAME_SIZE_SAVE_REFS_ONLY
    111 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
    112 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
    113 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
    114 #undef FRAME_SIZE_SAVE_EVERYTHING
    115 #undef BAKER_MARK_INTROSPECTION_ARRAY_SWITCH_OFFSET
    116 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_ENTRYPOINT_OFFSET
    117 #undef BAKER_MARK_INTROSPECTION_FIELD_LDR_OFFSET
    118 #undef BAKER_MARK_INTROSPECTION_ARRAY_LDR_OFFSET
    119 #undef BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_OFFSET
    120 }  // namespace arm64
    121 
    122 namespace mips {
    123 #include "arch/mips/asm_support_mips.h"
    124 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
    125 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    126 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
    127 #undef FRAME_SIZE_SAVE_REFS_ONLY
    128 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
    129 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
    130 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
    131 #undef FRAME_SIZE_SAVE_EVERYTHING
    132 }  // namespace mips
    133 
    134 namespace mips64 {
    135 #include "arch/mips64/asm_support_mips64.h"
    136 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
    137 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    138 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
    139 #undef FRAME_SIZE_SAVE_REFS_ONLY
    140 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
    141 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
    142 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
    143 #undef FRAME_SIZE_SAVE_EVERYTHING
    144 }  // namespace mips64
    145 
    146 namespace x86 {
    147 #include "arch/x86/asm_support_x86.h"
    148 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
    149 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    150 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
    151 #undef FRAME_SIZE_SAVE_REFS_ONLY
    152 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
    153 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
    154 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
    155 #undef FRAME_SIZE_SAVE_EVERYTHING
    156 }  // namespace x86
    157 
    158 namespace x86_64 {
    159 #include "arch/x86_64/asm_support_x86_64.h"
    160 static constexpr size_t kFrameSizeSaveAllCalleeSaves = FRAME_SIZE_SAVE_ALL_CALLEE_SAVES;
    161 #undef FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
    162 static constexpr size_t kFrameSizeSaveRefsOnly = FRAME_SIZE_SAVE_REFS_ONLY;
    163 #undef FRAME_SIZE_SAVE_REFS_ONLY
    164 static constexpr size_t kFrameSizeSaveRefsAndArgs = FRAME_SIZE_SAVE_REFS_AND_ARGS;
    165 #undef FRAME_SIZE_SAVE_REFS_AND_ARGS
    166 static constexpr size_t kFrameSizeSaveEverything = FRAME_SIZE_SAVE_EVERYTHING;
    167 #undef FRAME_SIZE_SAVE_EVERYTHING
    168 }  // namespace x86_64
    169 
    170 // Check architecture specific constants are sound.
    171 #define TEST_ARCH(Arch, arch)                             \
    172   TEST_F(ArchTest, Arch) {                                \
    173     CheckFrameSize(InstructionSet::k##Arch,               \
    174                    CalleeSaveType::kSaveAllCalleeSaves,   \
    175                    arch::kFrameSizeSaveAllCalleeSaves);   \
    176     CheckFrameSize(InstructionSet::k##Arch,               \
    177                    CalleeSaveType::kSaveRefsOnly,         \
    178                    arch::kFrameSizeSaveRefsOnly);         \
    179     CheckFrameSize(InstructionSet::k##Arch,               \
    180                    CalleeSaveType::kSaveRefsAndArgs,      \
    181                    arch::kFrameSizeSaveRefsAndArgs);      \
    182     CheckFrameSize(InstructionSet::k##Arch,               \
    183                    CalleeSaveType::kSaveEverything,       \
    184                    arch::kFrameSizeSaveEverything);       \
    185   }
    186 TEST_ARCH(Arm, arm)
    187 TEST_ARCH(Arm64, arm64)
    188 TEST_ARCH(Mips, mips)
    189 TEST_ARCH(Mips64, mips64)
    190 TEST_ARCH(X86, x86)
    191 TEST_ARCH(X86_64, x86_64)
    192 
    193 }  // namespace art
    194