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