xref: /aosp_15_r20/art/compiler/common_compiler_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "common_compiler_test.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
20*795d594fSAndroid Build Coastguard Worker #include <type_traits>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set_features.h"
23*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/callee_save_type.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/memfd.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
30*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
31*795d594fSAndroid Build Coastguard Worker #include "dex/descriptors_names.h"
32*795d594fSAndroid Build Coastguard Worker #include "driver/compiled_code_storage.h"
33*795d594fSAndroid Build Coastguard Worker #include "driver/compiler_options.h"
34*795d594fSAndroid Build Coastguard Worker #include "jni/java_vm_ext.h"
35*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter.h"
36*795d594fSAndroid Build Coastguard Worker #include "mirror/class-inl.h"
37*795d594fSAndroid Build Coastguard Worker #include "mirror/class_loader.h"
38*795d594fSAndroid Build Coastguard Worker #include "mirror/dex_cache.h"
39*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
40*795d594fSAndroid Build Coastguard Worker #include "oat/oat_quick_method_header.h"
41*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
42*795d594fSAndroid Build Coastguard Worker #include "thread-current-inl.h"
43*795d594fSAndroid Build Coastguard Worker #include "utils/atomic_dex_ref_map-inl.h"
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker class CommonCompilerTestImpl::CodeAndMetadata {
48*795d594fSAndroid Build Coastguard Worker  public:
49*795d594fSAndroid Build Coastguard Worker   CodeAndMetadata(CodeAndMetadata&& other) = default;
50*795d594fSAndroid Build Coastguard Worker 
CodeAndMetadata(ArrayRef<const uint8_t> code,ArrayRef<const uint8_t> vmap_table,InstructionSet instruction_set)51*795d594fSAndroid Build Coastguard Worker   CodeAndMetadata(ArrayRef<const uint8_t> code,
52*795d594fSAndroid Build Coastguard Worker                   ArrayRef<const uint8_t> vmap_table,
53*795d594fSAndroid Build Coastguard Worker                   InstructionSet instruction_set) {
54*795d594fSAndroid Build Coastguard Worker     const size_t page_size = MemMap::GetPageSize();
55*795d594fSAndroid Build Coastguard Worker     const uint32_t code_size = code.size();
56*795d594fSAndroid Build Coastguard Worker     CHECK_NE(code_size, 0u);
57*795d594fSAndroid Build Coastguard Worker     const uint32_t vmap_table_offset = vmap_table.empty() ? 0u
58*795d594fSAndroid Build Coastguard Worker         : sizeof(OatQuickMethodHeader) + vmap_table.size();
59*795d594fSAndroid Build Coastguard Worker     OatQuickMethodHeader method_header(vmap_table_offset);
60*795d594fSAndroid Build Coastguard Worker     const size_t code_alignment = GetInstructionSetCodeAlignment(instruction_set);
61*795d594fSAndroid Build Coastguard Worker     DCHECK_ALIGNED_PARAM(page_size, code_alignment);
62*795d594fSAndroid Build Coastguard Worker     const uint32_t code_offset = RoundUp(vmap_table.size() + sizeof(method_header), code_alignment);
63*795d594fSAndroid Build Coastguard Worker     const uint32_t capacity = RoundUp(code_offset + code_size, page_size);
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker     // Create a memfd handle with sufficient capacity.
66*795d594fSAndroid Build Coastguard Worker     android::base::unique_fd mem_fd(art::memfd_create_compat("test code", /*flags=*/ 0));
67*795d594fSAndroid Build Coastguard Worker     CHECK_GE(mem_fd.get(), 0);
68*795d594fSAndroid Build Coastguard Worker     int err = ftruncate(mem_fd, capacity);
69*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(err, 0);
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker     // Map the memfd contents for read/write.
72*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
73*795d594fSAndroid Build Coastguard Worker     rw_map_ = MemMap::MapFile(capacity,
74*795d594fSAndroid Build Coastguard Worker                               PROT_READ | PROT_WRITE,
75*795d594fSAndroid Build Coastguard Worker                               MAP_SHARED,
76*795d594fSAndroid Build Coastguard Worker                               mem_fd,
77*795d594fSAndroid Build Coastguard Worker                               /*start=*/ 0,
78*795d594fSAndroid Build Coastguard Worker                               /*low_4gb=*/ false,
79*795d594fSAndroid Build Coastguard Worker                               /*filename=*/ "test code",
80*795d594fSAndroid Build Coastguard Worker                               &error_msg);
81*795d594fSAndroid Build Coastguard Worker     CHECK(rw_map_.IsValid()) << error_msg;
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker     // Store data.
84*795d594fSAndroid Build Coastguard Worker     uint8_t* code_addr = rw_map_.Begin() + code_offset;
85*795d594fSAndroid Build Coastguard Worker     CHECK_ALIGNED_PARAM(code_addr, code_alignment);
86*795d594fSAndroid Build Coastguard Worker     CHECK_LE(vmap_table_offset, code_offset);
87*795d594fSAndroid Build Coastguard Worker     memcpy(code_addr - vmap_table_offset, vmap_table.data(), vmap_table.size());
88*795d594fSAndroid Build Coastguard Worker     static_assert(std::is_trivially_copyable<OatQuickMethodHeader>::value, "Cannot use memcpy");
89*795d594fSAndroid Build Coastguard Worker     CHECK_LE(sizeof(method_header), code_offset);
90*795d594fSAndroid Build Coastguard Worker     memcpy(code_addr - sizeof(method_header), &method_header, sizeof(method_header));
91*795d594fSAndroid Build Coastguard Worker     CHECK_LE(code_size, static_cast<size_t>(rw_map_.End() - code_addr));
92*795d594fSAndroid Build Coastguard Worker     memcpy(code_addr, code.data(), code_size);
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker     // Sync data.
95*795d594fSAndroid Build Coastguard Worker     bool success = rw_map_.Sync();
96*795d594fSAndroid Build Coastguard Worker     CHECK(success);
97*795d594fSAndroid Build Coastguard Worker     success = FlushCpuCaches(rw_map_.Begin(), rw_map_.End());
98*795d594fSAndroid Build Coastguard Worker     CHECK(success);
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker     // Map the data as read/executable.
101*795d594fSAndroid Build Coastguard Worker     rx_map_ = MemMap::MapFile(capacity,
102*795d594fSAndroid Build Coastguard Worker                               PROT_READ | PROT_EXEC,
103*795d594fSAndroid Build Coastguard Worker                               MAP_SHARED,
104*795d594fSAndroid Build Coastguard Worker                               mem_fd,
105*795d594fSAndroid Build Coastguard Worker                               /*start=*/ 0,
106*795d594fSAndroid Build Coastguard Worker                               /*low_4gb=*/ false,
107*795d594fSAndroid Build Coastguard Worker                               /*filename=*/ "test code",
108*795d594fSAndroid Build Coastguard Worker                               &error_msg);
109*795d594fSAndroid Build Coastguard Worker     CHECK(rx_map_.IsValid()) << error_msg;
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker     DCHECK_LT(code_offset, rx_map_.Size());
112*795d594fSAndroid Build Coastguard Worker     size_t adjustment = GetInstructionSetEntryPointAdjustment(instruction_set);
113*795d594fSAndroid Build Coastguard Worker     entry_point_ = rx_map_.Begin() + code_offset + adjustment;
114*795d594fSAndroid Build Coastguard Worker   }
115*795d594fSAndroid Build Coastguard Worker 
GetEntryPoint() const116*795d594fSAndroid Build Coastguard Worker   const void* GetEntryPoint() const {
117*795d594fSAndroid Build Coastguard Worker     DCHECK(rx_map_.IsValid());
118*795d594fSAndroid Build Coastguard Worker     return entry_point_;
119*795d594fSAndroid Build Coastguard Worker   }
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker  private:
122*795d594fSAndroid Build Coastguard Worker   MemMap rw_map_;
123*795d594fSAndroid Build Coastguard Worker   MemMap rx_map_;
124*795d594fSAndroid Build Coastguard Worker   const void* entry_point_;
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(CodeAndMetadata);
127*795d594fSAndroid Build Coastguard Worker };
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker class CommonCompilerTestImpl::OneCompiledMethodStorage final : public CompiledCodeStorage {
130*795d594fSAndroid Build Coastguard Worker  public:
OneCompiledMethodStorage()131*795d594fSAndroid Build Coastguard Worker   OneCompiledMethodStorage() {}
~OneCompiledMethodStorage()132*795d594fSAndroid Build Coastguard Worker   ~OneCompiledMethodStorage() {}
133*795d594fSAndroid Build Coastguard Worker 
CreateCompiledMethod(InstructionSet instruction_set,ArrayRef<const uint8_t> code,ArrayRef<const uint8_t> stack_map,ArrayRef<const uint8_t> cfi,ArrayRef<const linker::LinkerPatch> patches,bool is_intrinsic)134*795d594fSAndroid Build Coastguard Worker   CompiledMethod* CreateCompiledMethod(InstructionSet instruction_set,
135*795d594fSAndroid Build Coastguard Worker                                        ArrayRef<const uint8_t> code,
136*795d594fSAndroid Build Coastguard Worker                                        ArrayRef<const uint8_t> stack_map,
137*795d594fSAndroid Build Coastguard Worker                                        [[maybe_unused]] ArrayRef<const uint8_t> cfi,
138*795d594fSAndroid Build Coastguard Worker                                        ArrayRef<const linker::LinkerPatch> patches,
139*795d594fSAndroid Build Coastguard Worker                                        [[maybe_unused]] bool is_intrinsic) override {
140*795d594fSAndroid Build Coastguard Worker     // Supports only one method at a time.
141*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(instruction_set_, InstructionSet::kNone);
142*795d594fSAndroid Build Coastguard Worker     CHECK_NE(instruction_set, InstructionSet::kNone);
143*795d594fSAndroid Build Coastguard Worker     instruction_set_ = instruction_set;
144*795d594fSAndroid Build Coastguard Worker     CHECK(code_.empty());
145*795d594fSAndroid Build Coastguard Worker     CHECK(!code.empty());
146*795d594fSAndroid Build Coastguard Worker     code_.assign(code.begin(), code.end());
147*795d594fSAndroid Build Coastguard Worker     CHECK(stack_map_.empty());
148*795d594fSAndroid Build Coastguard Worker     CHECK(!stack_map.empty());
149*795d594fSAndroid Build Coastguard Worker     stack_map_.assign(stack_map.begin(), stack_map.end());
150*795d594fSAndroid Build Coastguard Worker     CHECK(patches.empty()) << "Linker patches are unsupported for compiler gtests.";
151*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<CompiledMethod*>(this);
152*795d594fSAndroid Build Coastguard Worker   }
153*795d594fSAndroid Build Coastguard Worker 
GetThunkCode(const linker::LinkerPatch & patch,std::string * debug_name)154*795d594fSAndroid Build Coastguard Worker   ArrayRef<const uint8_t> GetThunkCode([[maybe_unused]] const linker::LinkerPatch& patch,
155*795d594fSAndroid Build Coastguard Worker                                        [[maybe_unused]] /*out*/ std::string* debug_name) override {
156*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unsupported.";
157*795d594fSAndroid Build Coastguard Worker     UNREACHABLE();
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
SetThunkCode(const linker::LinkerPatch & patch,ArrayRef<const uint8_t> code,const std::string & debug_name)160*795d594fSAndroid Build Coastguard Worker   void SetThunkCode([[maybe_unused]] const linker::LinkerPatch& patch,
161*795d594fSAndroid Build Coastguard Worker                     [[maybe_unused]] ArrayRef<const uint8_t> code,
162*795d594fSAndroid Build Coastguard Worker                     [[maybe_unused]] const std::string& debug_name) override {
163*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Unsupported.";
164*795d594fSAndroid Build Coastguard Worker     UNREACHABLE();
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker 
GetInstructionSet() const167*795d594fSAndroid Build Coastguard Worker   InstructionSet GetInstructionSet() const {
168*795d594fSAndroid Build Coastguard Worker     CHECK_NE(instruction_set_, InstructionSet::kNone);
169*795d594fSAndroid Build Coastguard Worker     return instruction_set_;
170*795d594fSAndroid Build Coastguard Worker   }
171*795d594fSAndroid Build Coastguard Worker 
GetCode() const172*795d594fSAndroid Build Coastguard Worker   ArrayRef<const uint8_t> GetCode() const {
173*795d594fSAndroid Build Coastguard Worker     CHECK(!code_.empty());
174*795d594fSAndroid Build Coastguard Worker     return ArrayRef<const uint8_t>(code_);
175*795d594fSAndroid Build Coastguard Worker   }
176*795d594fSAndroid Build Coastguard Worker 
GetStackMap() const177*795d594fSAndroid Build Coastguard Worker   ArrayRef<const uint8_t> GetStackMap() const {
178*795d594fSAndroid Build Coastguard Worker     CHECK(!stack_map_.empty());
179*795d594fSAndroid Build Coastguard Worker     return ArrayRef<const uint8_t>(stack_map_);
180*795d594fSAndroid Build Coastguard Worker   }
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker  private:
183*795d594fSAndroid Build Coastguard Worker   InstructionSet instruction_set_ = InstructionSet::kNone;
184*795d594fSAndroid Build Coastguard Worker   std::vector<uint8_t> code_;
185*795d594fSAndroid Build Coastguard Worker   std::vector<uint8_t> stack_map_;
186*795d594fSAndroid Build Coastguard Worker };
187*795d594fSAndroid Build Coastguard Worker 
CreateCompilerOptions(InstructionSet instruction_set,const std::string & variant,const std::optional<std::string> & extra_features)188*795d594fSAndroid Build Coastguard Worker std::unique_ptr<CompilerOptions> CommonCompilerTestImpl::CreateCompilerOptions(
189*795d594fSAndroid Build Coastguard Worker     InstructionSet instruction_set,
190*795d594fSAndroid Build Coastguard Worker     const std::string& variant,
191*795d594fSAndroid Build Coastguard Worker     const std::optional<std::string>& extra_features) {
192*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<CompilerOptions> compiler_options = std::make_unique<CompilerOptions>();
193*795d594fSAndroid Build Coastguard Worker   compiler_options->emit_read_barrier_ = gUseReadBarrier;
194*795d594fSAndroid Build Coastguard Worker   compiler_options->instruction_set_ = instruction_set;
195*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
196*795d594fSAndroid Build Coastguard Worker   compiler_options->instruction_set_features_ =
197*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromVariant(instruction_set, variant, &error_msg);
198*795d594fSAndroid Build Coastguard Worker   CHECK(compiler_options->instruction_set_features_ != nullptr) << error_msg;
199*795d594fSAndroid Build Coastguard Worker   if (extra_features) {
200*795d594fSAndroid Build Coastguard Worker     compiler_options->instruction_set_features_ =
201*795d594fSAndroid Build Coastguard Worker         compiler_options->instruction_set_features_->AddFeaturesFromString(*extra_features,
202*795d594fSAndroid Build Coastguard Worker                                                                            &error_msg);
203*795d594fSAndroid Build Coastguard Worker     CHECK_NE(compiler_options->instruction_set_features_, nullptr) << error_msg;
204*795d594fSAndroid Build Coastguard Worker   }
205*795d594fSAndroid Build Coastguard Worker   return compiler_options;
206*795d594fSAndroid Build Coastguard Worker }
207*795d594fSAndroid Build Coastguard Worker 
CommonCompilerTestImpl()208*795d594fSAndroid Build Coastguard Worker CommonCompilerTestImpl::CommonCompilerTestImpl() {}
~CommonCompilerTestImpl()209*795d594fSAndroid Build Coastguard Worker CommonCompilerTestImpl::~CommonCompilerTestImpl() {}
210*795d594fSAndroid Build Coastguard Worker 
MakeExecutable(ArrayRef<const uint8_t> code,ArrayRef<const uint8_t> vmap_table,InstructionSet instruction_set)211*795d594fSAndroid Build Coastguard Worker const void* CommonCompilerTestImpl::MakeExecutable(ArrayRef<const uint8_t> code,
212*795d594fSAndroid Build Coastguard Worker                                                    ArrayRef<const uint8_t> vmap_table,
213*795d594fSAndroid Build Coastguard Worker                                                    InstructionSet instruction_set) {
214*795d594fSAndroid Build Coastguard Worker   CHECK_NE(code.size(), 0u);
215*795d594fSAndroid Build Coastguard Worker   code_and_metadata_.emplace_back(code, vmap_table, instruction_set);
216*795d594fSAndroid Build Coastguard Worker   return code_and_metadata_.back().GetEntryPoint();
217*795d594fSAndroid Build Coastguard Worker }
218*795d594fSAndroid Build Coastguard Worker 
SetUp()219*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::SetUp() {
220*795d594fSAndroid Build Coastguard Worker   {
221*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(Thread::Current());
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker     Runtime* runtime = GetRuntime();
224*795d594fSAndroid Build Coastguard Worker     runtime->SetInstructionSet(instruction_set_);
225*795d594fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) {
226*795d594fSAndroid Build Coastguard Worker       CalleeSaveType type = CalleeSaveType(i);
227*795d594fSAndroid Build Coastguard Worker       if (!runtime->HasCalleeSaveMethod(type)) {
228*795d594fSAndroid Build Coastguard Worker         runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(), type);
229*795d594fSAndroid Build Coastguard Worker       }
230*795d594fSAndroid Build Coastguard Worker     }
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker 
ApplyInstructionSet()234*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::ApplyInstructionSet() {
235*795d594fSAndroid Build Coastguard Worker   // Copy local instruction_set_ and instruction_set_features_ to *compiler_options_;
236*795d594fSAndroid Build Coastguard Worker   CHECK(instruction_set_features_ != nullptr);
237*795d594fSAndroid Build Coastguard Worker   if (instruction_set_ == InstructionSet::kThumb2) {
238*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(InstructionSet::kArm, instruction_set_features_->GetInstructionSet());
239*795d594fSAndroid Build Coastguard Worker   } else {
240*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(instruction_set_, instruction_set_features_->GetInstructionSet());
241*795d594fSAndroid Build Coastguard Worker   }
242*795d594fSAndroid Build Coastguard Worker   compiler_options_->instruction_set_ = instruction_set_;
243*795d594fSAndroid Build Coastguard Worker   compiler_options_->instruction_set_features_ =
244*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromBitmap(instruction_set_, instruction_set_features_->AsBitmap());
245*795d594fSAndroid Build Coastguard Worker   CHECK(compiler_options_->instruction_set_features_->Equals(instruction_set_features_.get()));
246*795d594fSAndroid Build Coastguard Worker }
247*795d594fSAndroid Build Coastguard Worker 
OverrideInstructionSetFeatures(InstructionSet instruction_set,const std::string & variant)248*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::OverrideInstructionSetFeatures(InstructionSet instruction_set,
249*795d594fSAndroid Build Coastguard Worker                                                             const std::string& variant) {
250*795d594fSAndroid Build Coastguard Worker   instruction_set_ = instruction_set;
251*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
252*795d594fSAndroid Build Coastguard Worker   instruction_set_features_ =
253*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromVariant(instruction_set, variant, &error_msg);
254*795d594fSAndroid Build Coastguard Worker   CHECK(instruction_set_features_ != nullptr) << error_msg;
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker   if (compiler_options_ != nullptr) {
257*795d594fSAndroid Build Coastguard Worker     ApplyInstructionSet();
258*795d594fSAndroid Build Coastguard Worker   }
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker 
SetUpRuntimeOptionsImpl()261*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::SetUpRuntimeOptionsImpl() {
262*795d594fSAndroid Build Coastguard Worker   compiler_options_ = CreateCompilerOptions(instruction_set_, "default");
263*795d594fSAndroid Build Coastguard Worker   ApplyInstructionSet();
264*795d594fSAndroid Build Coastguard Worker }
265*795d594fSAndroid Build Coastguard Worker 
TearDown()266*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::TearDown() {
267*795d594fSAndroid Build Coastguard Worker   code_and_metadata_.clear();
268*795d594fSAndroid Build Coastguard Worker   compiler_options_.reset();
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker 
CompileMethod(ArtMethod * method)271*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::CompileMethod(ArtMethod* method) {
272*795d594fSAndroid Build Coastguard Worker   CHECK(method != nullptr);
273*795d594fSAndroid Build Coastguard Worker   TimingLogger timings("CommonCompilerTestImpl::CompileMethod", false, false);
274*795d594fSAndroid Build Coastguard Worker   TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
275*795d594fSAndroid Build Coastguard Worker   OneCompiledMethodStorage storage;
276*795d594fSAndroid Build Coastguard Worker   CompiledMethod* compiled_method = nullptr;
277*795d594fSAndroid Build Coastguard Worker   {
278*795d594fSAndroid Build Coastguard Worker     DCHECK(!Runtime::Current()->IsStarted());
279*795d594fSAndroid Build Coastguard Worker     Thread* self = Thread::Current();
280*795d594fSAndroid Build Coastguard Worker     StackHandleScope<2> hs(self);
281*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<Compiler> compiler(Compiler::Create(*compiler_options_, &storage));
282*795d594fSAndroid Build Coastguard Worker     const DexFile& dex_file = *method->GetDexFile();
283*795d594fSAndroid Build Coastguard Worker     Handle<mirror::DexCache> dex_cache =
284*795d594fSAndroid Build Coastguard Worker         hs.NewHandle(GetClassLinker()->FindDexCache(self, dex_file));
285*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ClassLoader> class_loader = hs.NewHandle(method->GetClassLoader());
286*795d594fSAndroid Build Coastguard Worker     if (method->IsNative()) {
287*795d594fSAndroid Build Coastguard Worker       compiled_method = compiler->JniCompile(method->GetAccessFlags(),
288*795d594fSAndroid Build Coastguard Worker                                              method->GetDexMethodIndex(),
289*795d594fSAndroid Build Coastguard Worker                                              dex_file,
290*795d594fSAndroid Build Coastguard Worker                                              dex_cache);
291*795d594fSAndroid Build Coastguard Worker     } else {
292*795d594fSAndroid Build Coastguard Worker       compiled_method = compiler->Compile(method->GetCodeItem(),
293*795d594fSAndroid Build Coastguard Worker                                           method->GetAccessFlags(),
294*795d594fSAndroid Build Coastguard Worker                                           method->GetClassDefIndex(),
295*795d594fSAndroid Build Coastguard Worker                                           method->GetDexMethodIndex(),
296*795d594fSAndroid Build Coastguard Worker                                           class_loader,
297*795d594fSAndroid Build Coastguard Worker                                           dex_file,
298*795d594fSAndroid Build Coastguard Worker                                           dex_cache);
299*795d594fSAndroid Build Coastguard Worker     }
300*795d594fSAndroid Build Coastguard Worker     CHECK(compiled_method != nullptr) << "Failed to compile " << method->PrettyMethod();
301*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(reinterpret_cast<OneCompiledMethodStorage*>(compiled_method), &storage);
302*795d594fSAndroid Build Coastguard Worker   }
303*795d594fSAndroid Build Coastguard Worker   {
304*795d594fSAndroid Build Coastguard Worker     TimingLogger::ScopedTiming t2("MakeExecutable", &timings);
305*795d594fSAndroid Build Coastguard Worker     const void* method_code = MakeExecutable(storage.GetCode(),
306*795d594fSAndroid Build Coastguard Worker                                              storage.GetStackMap(),
307*795d594fSAndroid Build Coastguard Worker                                              storage.GetInstructionSet());
308*795d594fSAndroid Build Coastguard Worker     LOG(INFO) << "MakeExecutable " << method->PrettyMethod() << " code=" << method_code;
309*795d594fSAndroid Build Coastguard Worker     GetRuntime()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ method_code);
310*795d594fSAndroid Build Coastguard Worker   }
311*795d594fSAndroid Build Coastguard Worker }
312*795d594fSAndroid Build Coastguard Worker 
JniCompileCode(ArtMethod * method)313*795d594fSAndroid Build Coastguard Worker std::vector<uint8_t> CommonCompilerTestImpl::JniCompileCode(ArtMethod* method) {
314*795d594fSAndroid Build Coastguard Worker   CHECK(method->IsNative());
315*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
316*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
317*795d594fSAndroid Build Coastguard Worker   const DexFile& dex_file = *method->GetDexFile();
318*795d594fSAndroid Build Coastguard Worker   Handle<mirror::DexCache> dex_cache =
319*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(GetClassLinker()->FindDexCache(self, dex_file));
320*795d594fSAndroid Build Coastguard Worker   OneCompiledMethodStorage storage;
321*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<Compiler> compiler(Compiler::Create(*compiler_options_, &storage));
322*795d594fSAndroid Build Coastguard Worker   compiler->JniCompile(method->GetAccessFlags(),
323*795d594fSAndroid Build Coastguard Worker                        method->GetDexMethodIndex(),
324*795d594fSAndroid Build Coastguard Worker                        dex_file,
325*795d594fSAndroid Build Coastguard Worker                        dex_cache);
326*795d594fSAndroid Build Coastguard Worker   ArrayRef<const uint8_t> code = storage.GetCode();
327*795d594fSAndroid Build Coastguard Worker   return std::vector<uint8_t>(code.begin(), code.end());
328*795d594fSAndroid Build Coastguard Worker }
329*795d594fSAndroid Build Coastguard Worker 
ClearBootImageOption()330*795d594fSAndroid Build Coastguard Worker void CommonCompilerTestImpl::ClearBootImageOption() {
331*795d594fSAndroid Build Coastguard Worker   compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
332*795d594fSAndroid Build Coastguard Worker }
333*795d594fSAndroid Build Coastguard Worker 
334*795d594fSAndroid Build Coastguard Worker }  // namespace art
335