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 #ifndef ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_
18 #define ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_
19 
20 #include "jni_macro_assembler.h"
21 
22 #include "assembler_test_base.h"
23 #include "base/malloc_arena_pool.h"
24 #include "common_runtime_test.h"  // For ScratchFile
25 
26 #include <sys/stat.h>
27 
28 #include <cstdio>
29 #include <cstdlib>
30 #include <fstream>
31 #include <iterator>
32 
33 namespace art {
34 
35 template<typename Ass>
36 class JNIMacroAssemblerTest : public AssemblerTestBase {
37  public:
GetAssembler()38   Ass* GetAssembler() {
39     return assembler_.get();
40   }
41 
42   typedef std::string (*TestFn)(JNIMacroAssemblerTest* assembler_test, Ass* assembler);
43 
DriverFn(TestFn f,const std::string & test_name)44   void DriverFn(TestFn f, const std::string& test_name) {
45     DriverWrapper(f(this, assembler_.get()), test_name);
46   }
47 
48   // This driver assumes the assembler has already been called.
DriverStr(const std::string & assembly_string,const std::string & test_name)49   void DriverStr(const std::string& assembly_string, const std::string& test_name) {
50     DriverWrapper(assembly_string, test_name);
51   }
52 
53  protected:
JNIMacroAssemblerTest()54   JNIMacroAssemblerTest() {}
55 
SetUp()56   void SetUp() override {
57     AssemblerTestBase::SetUp();
58     allocator_.reset(new ArenaAllocator(&pool_));
59     assembler_.reset(CreateAssembler(allocator_.get()));
60     SetUpHelpers();
61   }
62 
TearDown()63   void TearDown() override {
64     AssemblerTestBase::TearDown();
65     assembler_.reset();
66     allocator_.reset();
67   }
68 
69   // Override this to set up any architecture-specific things, e.g., CPU revision.
CreateAssembler(ArenaAllocator * allocator)70   virtual Ass* CreateAssembler(ArenaAllocator* allocator) {
71     return new (allocator) Ass(allocator);
72   }
73 
74   // Override this to set up any architecture-specific things, e.g., register vectors.
SetUpHelpers()75   virtual void SetUpHelpers() {}
76 
77  private:
78   // Override this to pad the code with NOPs to a certain size if needed.
Pad(std::vector<uint8_t> & data ATTRIBUTE_UNUSED)79   virtual void Pad(std::vector<uint8_t>& data ATTRIBUTE_UNUSED) {
80   }
81 
DriverWrapper(const std::string & assembly_text,const std::string & test_name)82   void DriverWrapper(const std::string& assembly_text, const std::string& test_name) {
83     assembler_->FinalizeCode();
84     size_t cs = assembler_->CodeSize();
85     std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>(cs));
86     MemoryRegion code(&(*data)[0], data->size());
87     assembler_->FinalizeInstructions(code);
88     Pad(*data);
89     Driver(*data, assembly_text, test_name);
90   }
91 
92   MallocArenaPool pool_;
93   std::unique_ptr<ArenaAllocator> allocator_;
94   std::unique_ptr<Ass> assembler_;
95 
96   DISALLOW_COPY_AND_ASSIGN(JNIMacroAssemblerTest);
97 };
98 
99 }  // namespace art
100 
101 #endif  // ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_
102