1 /* 2 * Copyright (C) 2015 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 <memory> 18 #include <vector> 19 20 #include "arch/instruction_set.h" 21 #include "base/arena_allocator.h" 22 #include "base/enums.h" 23 #include "cfi_test.h" 24 #include "gtest/gtest.h" 25 #include "jni/quick/calling_convention.h" 26 #include "read_barrier_config.h" 27 #include "utils/assembler.h" 28 #include "utils/jni_macro_assembler.h" 29 30 #include "jni/jni_cfi_test_expected.inc" 31 32 namespace art { 33 34 // Run the tests only on host. 35 #ifndef ART_TARGET_ANDROID 36 37 class JNICFITest : public CFITest { 38 public: 39 // Enable this flag to generate the expected outputs. 40 static constexpr bool kGenerateExpected = false; 41 42 void TestImpl(InstructionSet isa, 43 const char* isa_str, 44 const std::vector<uint8_t>& expected_asm, 45 const std::vector<uint8_t>& expected_cfi) { 46 if (Is64BitInstructionSet(isa)) { 47 TestImplSized<PointerSize::k64>(isa, isa_str, expected_asm, expected_cfi); 48 } else { 49 TestImplSized<PointerSize::k32>(isa, isa_str, expected_asm, expected_cfi); 50 } 51 } 52 53 private: 54 template <PointerSize kPointerSize> 55 void TestImplSized(InstructionSet isa, 56 const char* isa_str, 57 const std::vector<uint8_t>& expected_asm, 58 const std::vector<uint8_t>& expected_cfi) { 59 // Description of simple method. 60 const bool is_static = true; 61 const bool is_synchronized = false; 62 const char* shorty = "IIFII"; 63 64 ArenaPool pool; 65 ArenaAllocator allocator(&pool); 66 67 std::unique_ptr<JniCallingConvention> jni_conv( 68 JniCallingConvention::Create(&allocator, 69 is_static, 70 is_synchronized, 71 /*is_critical_native*/false, 72 shorty, 73 isa)); 74 std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv( 75 ManagedRuntimeCallingConvention::Create( 76 &allocator, is_static, is_synchronized, shorty, isa)); 77 const int frame_size(jni_conv->FrameSize()); 78 ArrayRef<const ManagedRegister> callee_save_regs = jni_conv->CalleeSaveRegisters(); 79 80 // Assemble the method. 81 std::unique_ptr<JNIMacroAssembler<kPointerSize>> jni_asm( 82 JNIMacroAssembler<kPointerSize>::Create(&allocator, isa)); 83 jni_asm->cfi().SetEnabled(true); 84 jni_asm->BuildFrame(frame_size, mr_conv->MethodRegister(), 85 callee_save_regs, mr_conv->EntrySpills()); 86 jni_asm->IncreaseFrameSize(32); 87 jni_asm->DecreaseFrameSize(32); 88 jni_asm->RemoveFrame(frame_size, callee_save_regs, /* may_suspend */ true); 89 jni_asm->FinalizeCode(); 90 std::vector<uint8_t> actual_asm(jni_asm->CodeSize()); 91 MemoryRegion code(&actual_asm[0], actual_asm.size()); 92 jni_asm->FinalizeInstructions(code); 93 ASSERT_EQ(jni_asm->cfi().GetCurrentCFAOffset(), frame_size); 94 const std::vector<uint8_t>& actual_cfi = *(jni_asm->cfi().data()); 95 96 if (kGenerateExpected) { 97 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi); 98 } else { 99 EXPECT_EQ(expected_asm, actual_asm); 100 EXPECT_EQ(expected_cfi, actual_cfi); 101 } 102 } 103 }; 104 105 #define TEST_ISA(isa) \ 106 TEST_F(JNICFITest, isa) { \ 107 std::vector<uint8_t> expected_asm(expected_asm_##isa, \ 108 expected_asm_##isa + arraysize(expected_asm_##isa)); \ 109 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \ 110 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \ 111 TestImpl(InstructionSet::isa, #isa, expected_asm, expected_cfi); \ 112 } 113 114 #ifdef ART_ENABLE_CODEGEN_arm 115 // Run the tests for ARM only with Baker read barriers, as the 116 // expected generated code contains a Marking Register refresh 117 // instruction. 118 #if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 119 TEST_ISA(kThumb2) 120 #endif 121 #endif 122 123 #ifdef ART_ENABLE_CODEGEN_arm64 124 // Run the tests for ARM64 only with Baker read barriers, as the 125 // expected generated code contains a Marking Register refresh 126 // instruction. 127 #if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 128 TEST_ISA(kArm64) 129 #endif 130 #endif 131 132 #ifdef ART_ENABLE_CODEGEN_x86 133 TEST_ISA(kX86) 134 #endif 135 136 #ifdef ART_ENABLE_CODEGEN_x86_64 137 TEST_ISA(kX86_64) 138 #endif 139 140 #ifdef ART_ENABLE_CODEGEN_mips 141 TEST_ISA(kMips) 142 #endif 143 144 #ifdef ART_ENABLE_CODEGEN_mips64 145 TEST_ISA(kMips64) 146 #endif 147 148 #endif // ART_TARGET_ANDROID 149 150 } // namespace art 151