jni_cfi_test.cc revision 217488a9ddf351033c1688198c492b9c40c36d8a
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 32namespace art { 33 34// Run the tests only on host. 35#ifndef ART_TARGET_ANDROID 36 37class 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 arena(&pool); 66 67 std::unique_ptr<JniCallingConvention> jni_conv( 68 JniCallingConvention::Create(&arena, 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(&arena, is_static, is_synchronized, shorty, isa)); 76 const int frame_size(jni_conv->FrameSize()); 77 ArrayRef<const ManagedRegister> callee_save_regs = jni_conv->CalleeSaveRegisters(); 78 79 // Assemble the method. 80 std::unique_ptr<JNIMacroAssembler<kPointerSize>> jni_asm( 81 JNIMacroAssembler<kPointerSize>::Create(&arena, isa)); 82 jni_asm->cfi().SetEnabled(true); 83 jni_asm->BuildFrame(frame_size, mr_conv->MethodRegister(), 84 callee_save_regs, mr_conv->EntrySpills()); 85 jni_asm->IncreaseFrameSize(32); 86 jni_asm->DecreaseFrameSize(32); 87 jni_asm->RemoveFrame(frame_size, callee_save_regs); 88 jni_asm->FinalizeCode(); 89 std::vector<uint8_t> actual_asm(jni_asm->CodeSize()); 90 MemoryRegion code(&actual_asm[0], actual_asm.size()); 91 jni_asm->FinalizeInstructions(code); 92 ASSERT_EQ(jni_asm->cfi().GetCurrentCFAOffset(), frame_size); 93 const std::vector<uint8_t>& actual_cfi = *(jni_asm->cfi().data()); 94 95 if (kGenerateExpected) { 96 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi); 97 } else { 98 EXPECT_EQ(expected_asm, actual_asm); 99 EXPECT_EQ(expected_cfi, actual_cfi); 100 } 101 } 102}; 103 104#define TEST_ISA(isa) \ 105 TEST_F(JNICFITest, isa) { \ 106 std::vector<uint8_t> expected_asm(expected_asm_##isa, \ 107 expected_asm_##isa + arraysize(expected_asm_##isa)); \ 108 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \ 109 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \ 110 TestImpl(isa, #isa, expected_asm, expected_cfi); \ 111 } 112 113#ifdef ART_ENABLE_CODEGEN_arm 114// Run the tests for ARM only with Baker read barriers, as the 115// expected generated code contains a Marking Register refresh 116// instruction. 117#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 118TEST_ISA(kThumb2) 119#endif 120#endif 121 122#ifdef ART_ENABLE_CODEGEN_arm64 123// Run the tests for ARM64 only with Baker read barriers, as the 124// expected generated code contains a Marking Register refresh 125// instruction. 126#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 127TEST_ISA(kArm64) 128#endif 129#endif 130 131#ifdef ART_ENABLE_CODEGEN_x86 132TEST_ISA(kX86) 133#endif 134 135#ifdef ART_ENABLE_CODEGEN_x86_64 136TEST_ISA(kX86_64) 137#endif 138 139#ifdef ART_ENABLE_CODEGEN_mips 140TEST_ISA(kMips) 141#endif 142 143#ifdef ART_ENABLE_CODEGEN_mips64 144TEST_ISA(kMips64) 145#endif 146 147#endif // ART_TARGET_ANDROID 148 149} // namespace art 150