compiler.cc revision b34f69ab43aaf7a6e6045c95f398baf566ef5023
1b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray/* 2b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project 3b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 4b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * you may not use this file except in compliance with the License. 6b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * You may obtain a copy of the License at 7b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 8b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * 10b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * See the License for the specific language governing permissions and 14b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray * limitations under the License. 15b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray */ 16b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 17b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "compiler.h" 18b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "compilers.h" 19b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "driver/compiler_driver.h" 20b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "mirror/art_method-inl.h" 21b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 22b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#ifdef ART_USE_PORTABLE_COMPILER 23b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "dex/portable/mir_to_gbc.h" 24b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "elf_writer_mclinker.h" 25b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#endif 26b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 27b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffraynamespace art { 28b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 29b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#ifdef ART_SEA_IR_MODE 30b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" art::CompiledMethod* SeaIrCompileMethod(art::CompilerDriver& driver, 31b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile::CodeItem* code_item, 32b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 33b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray art::InvokeType invoke_type, 34b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint16_t class_def_idx, 35b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 36b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray jobject class_loader, 37b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile& dex_file); 38b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#endif 39b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 40b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 41b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas GeoffrayCompiledMethod* Compiler::TryCompileWithSeaIR(art::CompilerDriver& driver, 42b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile::CodeItem* code_item, 43b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 44b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray art::InvokeType invoke_type, 45b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint16_t class_def_idx, 46b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 47b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray jobject class_loader, 48b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile& dex_file) { 49b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#ifdef ART_SEA_IR_MODE 50b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray bool use_sea = Runtime::Current()->IsSeaIRMode(); 51b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray use_sea = use_sea && 52b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci")); 53b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray if (use_sea) { 54b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray LOG(INFO) << "Using SEA IR to compile..." << std::endl; 55b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return SeaIrCompileMethod(compiler, 56b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray code_item, 57b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray access_flags, 58b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray invoke_type, 59b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_def_idx, 60b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray method_idx, 61b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_loader, 62b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray dex_file); 63b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 64b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#endif 65b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return nullptr; 66b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray} 67b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 68b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 69b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#ifdef ART_USE_PORTABLE_COMPILER 70b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 71b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" void ArtInitCompilerContext(art::CompilerDriver& driver); 72b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 73b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver); 74b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 75b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver, 76b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile::CodeItem* code_item, 77b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 78b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray art::InvokeType invoke_type, 79b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint16_t class_def_idx, 80b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 81b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray jobject class_loader, 82b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile& dex_file); 83b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 84b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& driver, 85b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, uint32_t method_idx, 86b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const art::DexFile& dex_file); 87b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 88b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayextern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver& driver, 89b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray std::string const& filename); 90b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 91b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 92b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffrayclass LLVMCompiler : public Compiler { 93b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray public: 94b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray LLVMCompiler() : Compiler(1000) {} 95b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 96b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray void Init(CompilerDriver& driver) const { 97b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray ArtInitCompilerContext(driver); 98b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 99b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 100b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray void UnInit(CompilerDriver& driver) const { 101b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray ArtUnInitCompilerContext(driver); 102b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 103b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 104b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray CompiledMethod* Compile(CompilerDriver& driver, 105b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const DexFile::CodeItem* code_item, 106b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 107b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray InvokeType invoke_type, 108b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint16_t class_def_idx, 109b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 110b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray jobject class_loader, 111b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const DexFile& dex_file) const { 112b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray CompiledMethod* method = TryCompileWithSeaIR(driver, 113b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray code_item, 114b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray access_flags, 115b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray invoke_type, 116b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_def_idx, 117b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray method_idx, 118b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_loader, 119b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray dex_file); 120b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray if (method != nullptr) return method; 121b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 122b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return ArtCompileMethod(compiler, 123b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray code_item, 124b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray access_flags, 125b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray invoke_type, 126b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_def_idx, 127b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray method_idx, 128b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray class_loader, 129b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray dex_file); 130b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 131b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 132b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray CompiledMethod* JniCompile(CompilerDriver& driver, 133b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t access_flags, 134b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uint32_t method_idx, 135b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const DexFile& dex_file) const { 136b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return ArtLLVMJniCompileMethod(driver, access_flags, method_idx, dex_file); 137b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 138b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 139b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const { 140b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode()); 141b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 142b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 143b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray bool WriteElf(art::File* file, 144b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray OatWriter* oat_writer, 145b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const std::vector<const art::DexFile*>& dex_files, 146b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray const std::string& android_root, 147b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray bool is_host, const CompilerDriver& driver) const 148b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray OVERRIDE 149b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 150b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return art::ElfWriterMclinker::Create( 151b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray file, oat_writer, dex_files, android_root, is_host, driver); 152b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 153b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 154b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const { 155b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return PortableCodeGenerator( 156b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray cu, cu->mir_graph.get(), &cu->arena, 157b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray reinterpret_cast<art::llvm::LlvmCompilationUnit*>(compilation_unit)); 158b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 159b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 160b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray void InitCompilationUnit(CompilationUnit& cu) const { 161b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray // Fused long branches not currently useful in bitcode. 162b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray cu.disable_opt |= 163b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray (1 << kBranchFusing) | 164b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray (1 << kSuppressExceptionEdges); 165b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 166b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 167b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray bool IsPortable() const OVERRIDE { 168b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return true; 169b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 170b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 171b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) { 172b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray typedef void (*SetBitcodeFileNameFn)(const CompilerDriver&, const std::string&); 173b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 174b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray SetBitcodeFileNameFn set_bitcode_file_name = 175b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray reinterpret_cast<SetBitcodeFileNameFn>(compilerLLVMSetBitcodeFileName); 176b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 177b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray set_bitcode_file_name(driver, filename); 178b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 179b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 180b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray private: 181b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(LLVMCompiler); 182b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray}; 183b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#endif 184b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 185b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas GeoffrayCompiler* Compiler::Create(Compiler::Kind kind) { 186b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray switch (kind) { 187b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray case kQuick: 188b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return new QuickCompiler(); 189b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray break; 190b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray case kOptimizing: 191b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return new OptimizingCompiler(); 192b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray break; 193b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray case kPortable: 194b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#ifdef ART_USE_PORTABLE_COMPILER 195b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return new LLVMCompiler(); 196b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#else 197b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray LOG(FATAL) << "Portable compiler not compiled"; 198b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#endif 199b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray break; 200b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray default: 201b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray LOG(FATAL) << "UNREACHABLE"; 202b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray } 203b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray return nullptr; 204b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray} 205b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray 206b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray} // namespace art 207