| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2011 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 "common_compiler_test.h" | 
 | 18 |  | 
| Andreas Gampe | b68ed2c | 2018-06-20 10:39:31 -0700 | [diff] [blame] | 19 | #include <type_traits> | 
 | 20 |  | 
| Ian Rogers | d582fa4 | 2014-11-05 23:46:43 -0800 | [diff] [blame] | 21 | #include "arch/instruction_set_features.h" | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 22 | #include "art_field-inl.h" | 
| Andreas Gampe | c6ea7d0 | 2017-02-01 16:46:28 -0800 | [diff] [blame] | 23 | #include "art_method-inl.h" | 
| Andreas Gampe | 8228cdf | 2017-05-30 15:03:54 -0700 | [diff] [blame] | 24 | #include "base/callee_save_type.h" | 
| Andreas Gampe | 542451c | 2016-07-26 09:02:02 -0700 | [diff] [blame] | 25 | #include "base/enums.h" | 
| David Sehr | c431b9d | 2018-03-02 12:01:51 -0800 | [diff] [blame] | 26 | #include "base/utils.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 27 | #include "class_linker.h" | 
| Vladimir Marko | d8dbc8d | 2017-09-20 13:37:47 +0100 | [diff] [blame] | 28 | #include "compiled_method-inl.h" | 
| David Sehr | b2ec9f5 | 2018-02-21 13:20:31 -0800 | [diff] [blame] | 29 | #include "dex/descriptors_names.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 30 | #include "dex/quick_compiler_callbacks.h" | 
| Mathieu Chartier | 5bdab12 | 2015-01-26 18:30:19 -0800 | [diff] [blame] | 31 | #include "dex/verification_results.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 32 | #include "driver/compiler_driver.h" | 
| Vladimir Marko | 20f8559 | 2015-03-19 10:07:02 +0000 | [diff] [blame] | 33 | #include "driver/compiler_options.h" | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 34 | #include "jni/java_vm_ext.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 35 | #include "interpreter/interpreter.h" | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 36 | #include "mirror/class-inl.h" | 
| Andreas Gampe | 8cf9cb3 | 2017-07-19 09:28:38 -0700 | [diff] [blame] | 37 | #include "mirror/class_loader.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 38 | #include "mirror/dex_cache.h" | 
 | 39 | #include "mirror/object-inl.h" | 
| Nicolas Geoffray | 524e7ea | 2015-10-16 17:13:34 +0100 | [diff] [blame] | 40 | #include "oat_quick_method_header.h" | 
| Mathieu Chartier | 0795f23 | 2016-09-27 18:43:30 -0700 | [diff] [blame] | 41 | #include "scoped_thread_state_change-inl.h" | 
| Andreas Gampe | b486a98 | 2017-06-01 13:45:54 -0700 | [diff] [blame] | 42 | #include "thread-current-inl.h" | 
| Vladimir Marko | 213ee2d | 2018-06-22 11:56:34 +0100 | [diff] [blame] | 43 | #include "utils/atomic_dex_ref_map-inl.h" | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 44 |  | 
 | 45 | namespace art { | 
 | 46 |  | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 47 | CommonCompilerTest::CommonCompilerTest() {} | 
 | 48 | CommonCompilerTest::~CommonCompilerTest() {} | 
 | 49 |  | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 50 | void CommonCompilerTest::MakeExecutable(ArtMethod* method) { | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 51 |   CHECK(method != nullptr); | 
 | 52 |  | 
 | 53 |   const CompiledMethod* compiled_method = nullptr; | 
 | 54 |   if (!method->IsAbstract()) { | 
 | 55 |     mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); | 
 | 56 |     const DexFile& dex_file = *dex_cache->GetDexFile(); | 
 | 57 |     compiled_method = | 
 | 58 |         compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, | 
 | 59 |                                                             method->GetDexMethodIndex())); | 
 | 60 |   } | 
| Calin Juravle | e0ac115 | 2017-02-13 19:03:47 -0800 | [diff] [blame] | 61 |   // If the code size is 0 it means the method was skipped due to profile guided compilation. | 
 | 62 |   if (compiled_method != nullptr && compiled_method->GetQuickCode().size() != 0u) { | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 63 |     ArrayRef<const uint8_t> code = compiled_method->GetQuickCode(); | 
| Mathieu Chartier | cbcedbf | 2017-03-12 22:24:50 -0700 | [diff] [blame] | 64 |     const uint32_t code_size = code.size(); | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 65 |     ArrayRef<const uint8_t> vmap_table = compiled_method->GetVmapTable(); | 
| Mathieu Chartier | cbcedbf | 2017-03-12 22:24:50 -0700 | [diff] [blame] | 66 |     const uint32_t vmap_table_offset = vmap_table.empty() ? 0u | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 67 |         : sizeof(OatQuickMethodHeader) + vmap_table.size(); | 
| David Srbecky | 8cd5454 | 2018-07-15 23:58:44 +0100 | [diff] [blame] | 68 |     OatQuickMethodHeader method_header(vmap_table_offset, code_size); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 69 |  | 
| Elliott Hughes | 956af0f | 2014-12-11 14:34:28 -0800 | [diff] [blame] | 70 |     header_code_and_maps_chunks_.push_back(std::vector<uint8_t>()); | 
 | 71 |     std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back(); | 
| Vladimir Marko | 562ff44 | 2015-10-27 18:51:20 +0000 | [diff] [blame] | 72 |     const size_t max_padding = GetInstructionSetAlignment(compiled_method->GetInstructionSet()); | 
| David Srbecky | 8cd5454 | 2018-07-15 23:58:44 +0100 | [diff] [blame] | 73 |     const size_t size = vmap_table.size() + sizeof(method_header) + code_size; | 
| Vladimir Marko | 562ff44 | 2015-10-27 18:51:20 +0000 | [diff] [blame] | 74 |     chunk->reserve(size + max_padding); | 
| Elliott Hughes | 956af0f | 2014-12-11 14:34:28 -0800 | [diff] [blame] | 75 |     chunk->resize(sizeof(method_header)); | 
| Andreas Gampe | b68ed2c | 2018-06-20 10:39:31 -0700 | [diff] [blame] | 76 |     static_assert(std::is_trivially_copyable<OatQuickMethodHeader>::value, "Cannot use memcpy"); | 
| Elliott Hughes | 956af0f | 2014-12-11 14:34:28 -0800 | [diff] [blame] | 77 |     memcpy(&(*chunk)[0], &method_header, sizeof(method_header)); | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 78 |     chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end()); | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 79 |     chunk->insert(chunk->end(), code.begin(), code.end()); | 
| Vladimir Marko | 562ff44 | 2015-10-27 18:51:20 +0000 | [diff] [blame] | 80 |     CHECK_EQ(chunk->size(), size); | 
 | 81 |     const void* unaligned_code_ptr = chunk->data() + (size - code_size); | 
 | 82 |     size_t offset = dchecked_integral_cast<size_t>(reinterpret_cast<uintptr_t>(unaligned_code_ptr)); | 
 | 83 |     size_t padding = compiled_method->AlignCode(offset) - offset; | 
 | 84 |     // Make sure no resizing takes place. | 
 | 85 |     CHECK_GE(chunk->capacity(), chunk->size() + padding); | 
 | 86 |     chunk->insert(chunk->begin(), padding, 0); | 
 | 87 |     const void* code_ptr = reinterpret_cast<const uint8_t*>(unaligned_code_ptr) + padding; | 
 | 88 |     CHECK_EQ(code_ptr, static_cast<const void*>(chunk->data() + (chunk->size() - code_size))); | 
| Vladimir Marko | 35831e8 | 2015-09-11 11:59:18 +0100 | [diff] [blame] | 89 |     MakeExecutable(code_ptr, code.size()); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 90 |     const void* method_code = CompiledMethod::CodePointer(code_ptr, | 
 | 91 |                                                           compiled_method->GetInstructionSet()); | 
| David Sehr | 709b070 | 2016-10-13 09:12:37 -0700 | [diff] [blame] | 92 |     LOG(INFO) << "MakeExecutable " << method->PrettyMethod() << " code=" << method_code; | 
| Vladimir Marko | fbfc394 | 2017-07-27 16:51:35 +0100 | [diff] [blame] | 93 |     method->SetEntryPointFromQuickCompiledCode(method_code); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 94 |   } else { | 
 | 95 |     // No code? You must mean to go into the interpreter. | 
 | 96 |     // Or the generic JNI... | 
| Ian Rogers | 6f3dbba | 2014-10-14 17:41:57 -0700 | [diff] [blame] | 97 |     class_linker_->SetEntryPointsToInterpreter(method); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 98 |   } | 
 | 99 | } | 
 | 100 |  | 
 | 101 | void CommonCompilerTest::MakeExecutable(const void* code_start, size_t code_length) { | 
 | 102 |   CHECK(code_start != nullptr); | 
 | 103 |   CHECK_NE(code_length, 0U); | 
 | 104 |   uintptr_t data = reinterpret_cast<uintptr_t>(code_start); | 
 | 105 |   uintptr_t base = RoundDown(data, kPageSize); | 
 | 106 |   uintptr_t limit = RoundUp(data + code_length, kPageSize); | 
 | 107 |   uintptr_t len = limit - base; | 
 | 108 |   int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC); | 
 | 109 |   CHECK_EQ(result, 0); | 
 | 110 |  | 
| Orion Hodson | 38d29fd | 2018-09-07 12:58:37 +0100 | [diff] [blame] | 111 |   FlushInstructionCache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len)); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 112 | } | 
 | 113 |  | 
| Mathieu Chartier | 0795f23 | 2016-09-27 18:43:30 -0700 | [diff] [blame] | 114 | void CommonCompilerTest::MakeExecutable(ObjPtr<mirror::ClassLoader> class_loader, | 
 | 115 |                                         const char* class_name) { | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 116 |   std::string class_descriptor(DotToDescriptor(class_name)); | 
 | 117 |   Thread* self = Thread::Current(); | 
 | 118 |   StackHandleScope<1> hs(self); | 
 | 119 |   Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader)); | 
| Vladimir Marko | e9987b0 | 2018-05-22 16:26:43 +0100 | [diff] [blame] | 120 |   ObjPtr<mirror::Class> klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 121 |   CHECK(klass != nullptr) << "Class not found " << class_name; | 
| Andreas Gampe | 542451c | 2016-07-26 09:02:02 -0700 | [diff] [blame] | 122 |   PointerSize pointer_size = class_linker_->GetImagePointerSize(); | 
| Alex Light | e64300b | 2015-12-15 15:02:47 -0800 | [diff] [blame] | 123 |   for (auto& m : klass->GetMethods(pointer_size)) { | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 124 |     MakeExecutable(&m); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 125 |   } | 
 | 126 | } | 
 | 127 |  | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 128 | // Get the set of image classes given to the compiler options in SetUp. | 
| Vladimir Marko | 54159c6 | 2018-06-20 14:30:08 +0100 | [diff] [blame] | 129 | std::unique_ptr<HashSet<std::string>> CommonCompilerTest::GetImageClasses() { | 
| Andreas Gampe | 70bef0d | 2015-04-15 02:37:28 -0700 | [diff] [blame] | 130 |   // Empty set: by default no classes are retained in the image. | 
| Vladimir Marko | 54159c6 | 2018-06-20 14:30:08 +0100 | [diff] [blame] | 131 |   return std::make_unique<HashSet<std::string>>(); | 
| Andreas Gampe | 70bef0d | 2015-04-15 02:37:28 -0700 | [diff] [blame] | 132 | } | 
 | 133 |  | 
| Calin Juravle | 877fd96 | 2016-01-05 14:29:29 +0000 | [diff] [blame] | 134 | // Get ProfileCompilationInfo that should be passed to the driver. | 
 | 135 | ProfileCompilationInfo* CommonCompilerTest::GetProfileCompilationInfo() { | 
 | 136 |   // Null, profile information will not be taken into account. | 
 | 137 |   return nullptr; | 
 | 138 | } | 
 | 139 |  | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 140 | void CommonCompilerTest::SetUp() { | 
 | 141 |   CommonRuntimeTest::SetUp(); | 
 | 142 |   { | 
 | 143 |     ScopedObjectAccess soa(Thread::Current()); | 
 | 144 |  | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 145 |     runtime_->SetInstructionSet(instruction_set_); | 
| Andreas Gampe | 8228cdf | 2017-05-30 15:03:54 -0700 | [diff] [blame] | 146 |     for (uint32_t i = 0; i < static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType); ++i) { | 
 | 147 |       CalleeSaveType type = CalleeSaveType(i); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 148 |       if (!runtime_->HasCalleeSaveMethod(type)) { | 
| Ian Rogers | 6a3c1fc | 2014-10-31 00:33:20 -0700 | [diff] [blame] | 149 |         runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(), type); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 150 |       } | 
 | 151 |     } | 
 | 152 |  | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 153 |     CreateCompilerDriver(); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 154 |   } | 
| Mathieu Chartier | ceb07b3 | 2015-12-10 09:33:21 -0800 | [diff] [blame] | 155 | } | 
 | 156 |  | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 157 | void CommonCompilerTest::ApplyInstructionSet() { | 
 | 158 |   // Copy local instruction_set_ and instruction_set_features_ to *compiler_options_; | 
 | 159 |   CHECK(instruction_set_features_ != nullptr); | 
 | 160 |   if (instruction_set_ == InstructionSet::kThumb2) { | 
 | 161 |     CHECK_EQ(InstructionSet::kArm, instruction_set_features_->GetInstructionSet()); | 
 | 162 |   } else { | 
 | 163 |     CHECK_EQ(instruction_set_, instruction_set_features_->GetInstructionSet()); | 
 | 164 |   } | 
 | 165 |   compiler_options_->instruction_set_ = instruction_set_; | 
 | 166 |   compiler_options_->instruction_set_features_ = | 
 | 167 |       InstructionSetFeatures::FromBitmap(instruction_set_, instruction_set_features_->AsBitmap()); | 
 | 168 |   CHECK(compiler_options_->instruction_set_features_->Equals(instruction_set_features_.get())); | 
 | 169 | } | 
 | 170 |  | 
 | 171 | void CommonCompilerTest::OverrideInstructionSetFeatures(InstructionSet instruction_set, | 
 | 172 |                                                         const std::string& variant) { | 
 | 173 |   instruction_set_ = instruction_set; | 
 | 174 |   std::string error_msg; | 
 | 175 |   instruction_set_features_ = | 
 | 176 |       InstructionSetFeatures::FromVariant(instruction_set, variant, &error_msg); | 
 | 177 |   CHECK(instruction_set_features_ != nullptr) << error_msg; | 
 | 178 |  | 
 | 179 |   if (compiler_options_ != nullptr) { | 
 | 180 |     ApplyInstructionSet(); | 
 | 181 |   } | 
 | 182 | } | 
 | 183 |  | 
 | 184 | void CommonCompilerTest::CreateCompilerDriver() { | 
 | 185 |   ApplyInstructionSet(); | 
 | 186 |  | 
| Vladimir Marko | 9c4b970 | 2018-11-14 15:09:02 +0000 | [diff] [blame] | 187 |   compiler_options_->image_type_ = CompilerOptions::ImageType::kBootImage; | 
| Vladimir Marko | bb089b6 | 2018-06-28 17:30:16 +0100 | [diff] [blame] | 188 |   compiler_options_->compile_pic_ = false;  // Non-PIC boot image is a test configuration. | 
| Mathieu Chartier | d0af56c | 2017-02-17 12:56:25 -0800 | [diff] [blame] | 189 |   compiler_options_->SetCompilerFilter(GetCompilerFilter()); | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 190 |   compiler_options_->image_classes_.swap(*GetImageClasses()); | 
| Vladimir Marko | 1a2a5cd | 2018-11-07 15:39:48 +0000 | [diff] [blame] | 191 |   compiler_options_->profile_compilation_info_ = GetProfileCompilationInfo(); | 
| Mathieu Chartier | ceb07b3 | 2015-12-10 09:33:21 -0800 | [diff] [blame] | 192 |   compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), | 
 | 193 |                                             verification_results_.get(), | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 194 |                                             compiler_kind_, | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 195 |                                             &compiler_options_->image_classes_, | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 196 |                                             number_of_threads_, | 
| Vladimir Marko | 1a2a5cd | 2018-11-07 15:39:48 +0000 | [diff] [blame] | 197 |                                             /* swap_fd */ -1)); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 198 | } | 
 | 199 |  | 
 | 200 | void CommonCompilerTest::SetUpRuntimeOptions(RuntimeOptions* options) { | 
 | 201 |   CommonRuntimeTest::SetUpRuntimeOptions(options); | 
 | 202 |  | 
 | 203 |   compiler_options_.reset(new CompilerOptions); | 
 | 204 |   verification_results_.reset(new VerificationResults(compiler_options_.get())); | 
| Mathieu Chartier | e01b6f6 | 2017-07-19 16:55:04 -0700 | [diff] [blame] | 205 |   QuickCompilerCallbacks* callbacks = | 
 | 206 |       new QuickCompilerCallbacks(CompilerCallbacks::CallbackMode::kCompileApp); | 
 | 207 |   callbacks->SetVerificationResults(verification_results_.get()); | 
 | 208 |   callbacks_.reset(callbacks); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 209 | } | 
 | 210 |  | 
| Roland Levillain | bbcc01a | 2015-06-30 14:16:48 +0100 | [diff] [blame] | 211 | Compiler::Kind CommonCompilerTest::GetCompilerKind() const { | 
 | 212 |   return compiler_kind_; | 
 | 213 | } | 
 | 214 |  | 
 | 215 | void CommonCompilerTest::SetCompilerKind(Compiler::Kind compiler_kind) { | 
 | 216 |   compiler_kind_ = compiler_kind; | 
 | 217 | } | 
 | 218 |  | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 219 | void CommonCompilerTest::TearDown() { | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 220 |   compiler_driver_.reset(); | 
 | 221 |   callbacks_.reset(); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 222 |   verification_results_.reset(); | 
 | 223 |   compiler_options_.reset(); | 
| Vladimir Marko | c34bebf | 2018-08-16 16:12:49 +0100 | [diff] [blame] | 224 |   image_reservation_.Reset(); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 225 |  | 
 | 226 |   CommonRuntimeTest::TearDown(); | 
 | 227 | } | 
 | 228 |  | 
 | 229 | void CommonCompilerTest::CompileClass(mirror::ClassLoader* class_loader, const char* class_name) { | 
 | 230 |   std::string class_descriptor(DotToDescriptor(class_name)); | 
 | 231 |   Thread* self = Thread::Current(); | 
 | 232 |   StackHandleScope<1> hs(self); | 
 | 233 |   Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader)); | 
| Vladimir Marko | e9987b0 | 2018-05-22 16:26:43 +0100 | [diff] [blame] | 234 |   ObjPtr<mirror::Class> klass = class_linker_->FindClass(self, class_descriptor.c_str(), loader); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 235 |   CHECK(klass != nullptr) << "Class not found " << class_name; | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 236 |   auto pointer_size = class_linker_->GetImagePointerSize(); | 
| Alex Light | e64300b | 2015-12-15 15:02:47 -0800 | [diff] [blame] | 237 |   for (auto& m : klass->GetMethods(pointer_size)) { | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 238 |     CompileMethod(&m); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 239 |   } | 
 | 240 | } | 
 | 241 |  | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 242 | void CommonCompilerTest::CompileMethod(ArtMethod* method) { | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 243 |   CHECK(method != nullptr); | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 244 |   TimingLogger timings("CommonCompilerTest::CompileMethod", false, false); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 245 |   TimingLogger::ScopedTiming t(__FUNCTION__, &timings); | 
| Vladimir Marko | dc4bcce | 2018-06-21 16:15:42 +0100 | [diff] [blame] | 246 |   { | 
 | 247 |     Thread* self = Thread::Current(); | 
 | 248 |     jobject class_loader = self->GetJniEnv()->GetVm()->AddGlobalRef(self, method->GetClassLoader()); | 
 | 249 |  | 
 | 250 |     DCHECK(!Runtime::Current()->IsStarted()); | 
 | 251 |     const DexFile* dex_file = method->GetDexFile(); | 
 | 252 |     uint16_t class_def_idx = method->GetClassDefIndex(); | 
 | 253 |     uint32_t method_idx = method->GetDexMethodIndex(); | 
 | 254 |     uint32_t access_flags = method->GetAccessFlags(); | 
 | 255 |     InvokeType invoke_type = method->GetInvokeType(); | 
 | 256 |     StackHandleScope<2> hs(self); | 
 | 257 |     Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache())); | 
 | 258 |     Handle<mirror::ClassLoader> h_class_loader = hs.NewHandle( | 
 | 259 |         self->DecodeJObject(class_loader)->AsClassLoader()); | 
 | 260 |     const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); | 
 | 261 |  | 
 | 262 |     std::vector<const DexFile*> dex_files; | 
 | 263 |     dex_files.push_back(dex_file); | 
 | 264 |  | 
 | 265 |     // Go to native so that we don't block GC during compilation. | 
 | 266 |     ScopedThreadSuspension sts(self, kNative); | 
 | 267 |  | 
 | 268 |     compiler_driver_->InitializeThreadPools(); | 
 | 269 |  | 
 | 270 |     compiler_driver_->PreCompile(class_loader, dex_files, &timings); | 
 | 271 |  | 
 | 272 |     compiler_driver_->CompileOne(self, | 
 | 273 |                                  class_loader, | 
 | 274 |                                  *dex_file, | 
 | 275 |                                  class_def_idx, | 
 | 276 |                                  method_idx, | 
 | 277 |                                  access_flags, | 
 | 278 |                                  invoke_type, | 
 | 279 |                                  code_item, | 
 | 280 |                                  dex_cache, | 
 | 281 |                                  h_class_loader); | 
 | 282 |  | 
 | 283 |     compiler_driver_->FreeThreadPools(); | 
 | 284 |  | 
 | 285 |     self->GetJniEnv()->DeleteGlobalRef(class_loader); | 
 | 286 |   } | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 287 |   TimingLogger::ScopedTiming t2("MakeExecutable", &timings); | 
 | 288 |   MakeExecutable(method); | 
 | 289 | } | 
 | 290 |  | 
| Andreas Gampe | 5a4b8a2 | 2014-09-11 08:30:08 -0700 | [diff] [blame] | 291 | void CommonCompilerTest::CompileDirectMethod(Handle<mirror::ClassLoader> class_loader, | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 292 |                                              const char* class_name, const char* method_name, | 
 | 293 |                                              const char* signature) { | 
 | 294 |   std::string class_descriptor(DotToDescriptor(class_name)); | 
 | 295 |   Thread* self = Thread::Current(); | 
| Vladimir Marko | e9987b0 | 2018-05-22 16:26:43 +0100 | [diff] [blame] | 296 |   ObjPtr<mirror::Class> klass = | 
 | 297 |       class_linker_->FindClass(self, class_descriptor.c_str(), class_loader); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 298 |   CHECK(klass != nullptr) << "Class not found " << class_name; | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 299 |   auto pointer_size = class_linker_->GetImagePointerSize(); | 
| Vladimir Marko | ba11882 | 2017-06-12 15:41:56 +0100 | [diff] [blame] | 300 |   ArtMethod* method = klass->FindClassMethod(method_name, signature, pointer_size); | 
 | 301 |   CHECK(method != nullptr && method->IsDirect()) << "Direct method not found: " | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 302 |       << class_name << "." << method_name << signature; | 
 | 303 |   CompileMethod(method); | 
 | 304 | } | 
 | 305 |  | 
| Andreas Gampe | 5a4b8a2 | 2014-09-11 08:30:08 -0700 | [diff] [blame] | 306 | void CommonCompilerTest::CompileVirtualMethod(Handle<mirror::ClassLoader> class_loader, | 
| Mathieu Chartier | bf99f77 | 2014-08-23 16:37:27 -0700 | [diff] [blame] | 307 |                                               const char* class_name, const char* method_name, | 
 | 308 |                                               const char* signature) { | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 309 |   std::string class_descriptor(DotToDescriptor(class_name)); | 
 | 310 |   Thread* self = Thread::Current(); | 
| Vladimir Marko | e9987b0 | 2018-05-22 16:26:43 +0100 | [diff] [blame] | 311 |   ObjPtr<mirror::Class> klass = | 
 | 312 |       class_linker_->FindClass(self, class_descriptor.c_str(), class_loader); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 313 |   CHECK(klass != nullptr) << "Class not found " << class_name; | 
| Mathieu Chartier | e401d14 | 2015-04-22 13:56:20 -0700 | [diff] [blame] | 314 |   auto pointer_size = class_linker_->GetImagePointerSize(); | 
| Vladimir Marko | ba11882 | 2017-06-12 15:41:56 +0100 | [diff] [blame] | 315 |   ArtMethod* method = klass->FindClassMethod(method_name, signature, pointer_size); | 
 | 316 |   CHECK(method != nullptr && !method->IsDirect()) << "Virtual method not found: " | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 317 |       << class_name << "." << method_name << signature; | 
 | 318 |   CompileMethod(method); | 
 | 319 | } | 
 | 320 |  | 
 | 321 | void CommonCompilerTest::ReserveImageSpace() { | 
 | 322 |   // Reserve where the image will be loaded up front so that other parts of test set up don't | 
 | 323 |   // accidentally end up colliding with the fixed memory address when we need to load the image. | 
 | 324 |   std::string error_msg; | 
| Mathieu Chartier | 6e88ef6 | 2014-10-14 15:01:24 -0700 | [diff] [blame] | 325 |   MemMap::Init(); | 
| Vladimir Marko | c34bebf | 2018-08-16 16:12:49 +0100 | [diff] [blame] | 326 |   image_reservation_ = MemMap::MapAnonymous("image reservation", | 
 | 327 |                                             reinterpret_cast<uint8_t*>(ART_BASE_ADDRESS), | 
 | 328 |                                             (size_t)120 * 1024 * 1024,  // 120MB | 
 | 329 |                                             PROT_NONE, | 
 | 330 |                                             false /* no need for 4gb flag with fixed mmap */, | 
| Vladimir Marko | 1130659 | 2018-10-26 14:22:59 +0100 | [diff] [blame] | 331 |                                             /*reuse=*/ false, | 
 | 332 |                                             /*reservation=*/ nullptr, | 
| Vladimir Marko | c34bebf | 2018-08-16 16:12:49 +0100 | [diff] [blame] | 333 |                                             &error_msg); | 
 | 334 |   CHECK(image_reservation_.IsValid()) << error_msg; | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 335 | } | 
 | 336 |  | 
 | 337 | void CommonCompilerTest::UnreserveImageSpace() { | 
| Vladimir Marko | c34bebf | 2018-08-16 16:12:49 +0100 | [diff] [blame] | 338 |   image_reservation_.Reset(); | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 339 | } | 
 | 340 |  | 
| Vladimir Marko | 213ee2d | 2018-06-22 11:56:34 +0100 | [diff] [blame] | 341 | void CommonCompilerTest::SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files) { | 
 | 342 |   compiler_options_->dex_files_for_oat_file_ = dex_files; | 
 | 343 |   compiler_driver_->compiled_classes_.AddDexFiles(dex_files); | 
 | 344 |   compiler_driver_->dex_to_dex_compiler_.SetDexFiles(dex_files); | 
 | 345 | } | 
 | 346 |  | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 347 | void CommonCompilerTest::ClearBootImageOption() { | 
| Vladimir Marko | 9c4b970 | 2018-11-14 15:09:02 +0000 | [diff] [blame] | 348 |   compiler_options_->image_type_ = CompilerOptions::ImageType::kNone; | 
| Vladimir Marko | a043111 | 2018-06-25 09:32:54 +0100 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Ian Rogers | e63db27 | 2014-07-15 15:36:11 -0700 | [diff] [blame] | 351 | }  // namespace art |