compiler_driver.h revision d54f3a6219bca6ae018f4395fa0f1254bd4459be
15912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/* 25912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Copyright (C) 2011 The Android Open Source Project 35912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 45912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 55912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * you may not use this file except in compliance with the License. 65912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * You may obtain a copy of the License at 75912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 85912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 95912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * 105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Unless required by applicable law or agreed to in writing, software 115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * See the License for the specific language governing permissions and 145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * limitations under the License. 155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */ 165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#ifndef ART_COMPILER_DRIVER_COMPILER_DRIVER_H_ 185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define ART_COMPILER_DRIVER_COMPILER_DRIVER_H_ 195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <set> 215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <string> 225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <vector> 235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 24872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright#include "base/mutex.h" 255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "base/timing_logger.h" 266071da7ef84c60645572654504813d492b8b21d5Elliott Hughes#include "class_reference.h" 275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "compiled_class.h" 285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "compiled_method.h" 295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "compiler_backend.h" 305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "dex_file.h" 315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "instruction_set.h" 325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "invoke_type.h" 335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "method_reference.h" 345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "os.h" 355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "runtime.h" 365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "safe_map.h" 375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "thread_pool.h" 385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "utils/arena_allocator.h" 395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include "utils/dedupe_set.h" 405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace art { 425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace verifier { 445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass MethodVerifier; 455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace verifier 46872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright 47872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightclass AOTCompilationStats; 485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass CompilerOptions; 495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass DexCompilationUnit; 50872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightclass DexFileToMethodInlinerMap; 51872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightstruct InlineIGetIPutData; 525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass OatWriter; 535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass ParallelCompilationManager; 545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass ScopedObjectAccess; 555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Browntemplate<class T> class SirtRef; 565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass TimingLogger; 575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass VerificationResults; 585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass VerifiedMethod; 595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownenum EntryPointCallingConvention { 615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // ABI of invocations to a method's interpreter entry point. 625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kInterpreterAbi, 635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // ABI of calls to a method's native code, only used for native methods. 645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kJniAbi, 655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // ABI of calls to a method's portable code entry point. 665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kPortableAbi, 675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // ABI of calls to a method's quick code entry point. 685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kQuickAbi 695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}; 705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownenum DexToDexCompilationLevel { 725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kDontDexToDexCompile, // Only meaning wrt image time interpretation. 735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kRequired, // Dex-to-dex compilation required for correctness. 745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown kOptimize // Perform required transformation and peep-hole optimizations. 755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}; 765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Thread-local storage compiler worker threads 785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass CompilerTls { 795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown public: 805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CompilerTls() : llvm_info_(NULL) {} 815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ~CompilerTls() {} 825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void* GetLLVMInfo() { return llvm_info_; } 845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void SetLLVMInfo(void* llvm_info) { llvm_info_ = llvm_info; } 865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown private: 885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void* llvm_info_; 895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}; 905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass CompilerDriver { 9238dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright public: 935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown typedef std::set<std::string> DescriptorSet; 945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 9538dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright // Create a compiler targeting the requested "instruction_set". 965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // "image" should be true if image specific optimizations should be 975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // enabled. "image_classes" lets the compiler know what classes it 985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // can assume will be in the image, with NULL implying all available 995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // classes. 1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown explicit CompilerDriver(const CompilerOptions* compiler_options, 1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown VerificationResults* verification_results, 1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DexFileToMethodInlinerMap* method_inliner_map, 10338dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright CompilerBackend::Kind compiler_backend_kind, 10438dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright InstructionSet instruction_set, 1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InstructionSetFeatures instruction_set_features, 1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool image, DescriptorSet* image_classes, 1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t thread_count, bool dump_stats, bool dump_passes, 10838dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright CumulativeLogger* timer, 10938dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright std::string profile_file = ""); 1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ~CompilerDriver(); 1125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, 11438dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright TimingLogger* timings) 1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Compile a single Method. 1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void CompileOne(mirror::ArtMethod* method, TimingLogger* timings) 11938dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown VerificationResults* GetVerificationResults() const { 1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return verification_results_; 1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DexFileToMethodInlinerMap* GetMethodInlinerMap() const { 1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return method_inliner_map_; 1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InstructionSet GetInstructionSet() const { 1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return instruction_set_; 1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InstructionSetFeatures GetInstructionSetFeatures() const { 1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return instruction_set_features_; 1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const CompilerOptions& GetCompilerOptions() const { 1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return *compiler_options_; 1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CompilerBackend* GetCompilerBackend() const { 142f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown return compiler_backend_.get(); 143f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown } 144f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown 145f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown bool ProfilePresent() const { 146f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown return profile_ok_; 1476071da7ef84c60645572654504813d492b8b21d5Elliott Hughes } 1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Are we compiling and creating an image file? 1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsImage() const { 15138dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright return image_; 1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DescriptorSet* GetImageClasses() const { 1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return image_classes_.get(); 1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CompilerTls* GetTls(); 1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Generate the trampolines that are invoked by unresolved direct methods. 1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateInterpreterToInterpreterBridge() const 1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateInterpreterToCompiledCodeBridge() const 1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 16538dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright const std::vector<uint8_t>* CreateJniDlsymLookup() const 1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreatePortableImtConflictTrampoline() const 1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreatePortableResolutionTrampoline() const 1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreatePortableToInterpreterBridge() const 1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateQuickGenericJniTrampoline() const 1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateQuickImtConflictTrampoline() const 1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateQuickResolutionTrampoline() const 1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<uint8_t>* CreateQuickToInterpreterBridge() const 1805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 18238dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright CompiledClass* GetCompiledClass(ClassReference ref) const 1835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_classes_lock_); 1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CompiledMethod* GetCompiledMethod(MethodReference ref) const 1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_methods_lock_); 1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file, 1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t class_def_index); 1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, uint16_t class_def_index); 1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Callbacks from compiler to see what runtime checks must be generated. 19338dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright 1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx); 1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, uint32_t string_idx) 1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Are runtime access checks necessary in the compiled code? 2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, 2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t type_idx, bool* type_known_final = NULL, 2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool* type_known_abstract = NULL, 2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool* equals_referrers_class = NULL) 2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Are runtime access and instantiable checks necessary in the code? 2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file, 2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t type_idx) 2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx, 2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool* is_type_initialized, bool* use_direct_type_ptr, 2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uintptr_t* direct_type_ptr); 2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Get the DexCache for the 2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit) 2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2197b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright mirror::ClassLoader* GetClassLoader(ScopedObjectAccess& soa, const DexCompilationUnit* mUnit) 2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Resolve compiling method's class. Returns nullptr on failure. 2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::Class* ResolveCompilingMethodsClass( 2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ScopedObjectAccess& soa, const SirtRef<mirror::DexCache>& dex_cache, 2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const SirtRef<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit) 2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Resolve a field. Returns nullptr on failure, including incompatible class change. 2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static. 2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::ArtField* ResolveField( 2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ScopedObjectAccess& soa, const SirtRef<mirror::DexCache>& dex_cache, 2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const SirtRef<mirror::ClassLoader>& class_loader, const DexCompilationUnit* mUnit, 2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t field_idx, bool is_static) 2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2357b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright 2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Get declaration location of a resolved field. 2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void GetResolvedFieldDexFileLocation( 2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::ArtField* resolved_field, const DexFile** declaring_dex_file, 2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) 2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsFieldVolatile(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset. 2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::pair<bool, bool> IsFastInstanceField( 2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::DexCache* dex_cache, mirror::Class* referrer_class, 2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::ArtField* resolved_field, uint16_t field_idx, MemberOffset* field_offset) 2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fast-path an SGET/SPUT access to a static field? If yes, compute the field offset, 2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // the type index of the declaring class in the referrer's dex file and whether the declaring 2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // class is the referrer's class or at least can be assumed to be initialized. 2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::pair<bool, bool> IsFastStaticField( 2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown mirror::DexCache* dex_cache, mirror::Class* referrer_class, 2557b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright mirror::ArtField* resolved_field, uint16_t field_idx, MemberOffset* field_offset, 2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t* storage_index, bool* is_referrers_class, bool* is_initialized) 2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void ProcessedInstanceField(bool resolved); 2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void ProcessedStaticField(bool resolved, bool local); 2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fast path instance field access in a verified accessor? 2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // If yes, computes field's offset and volatility and whether the method is static or not. 2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown static bool ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put, 2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown verifier::MethodVerifier* verifier, 2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InlineIGetIPutData* result) 2675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 2685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fast path instance field access? Computes field's offset and volatility. 2705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put, 2715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown MemberOffset* field_offset, bool* is_volatile) 2725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 2735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fastpath static field access? Computes field's offset, volatility and whether the 2755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // field is within the referrer (which can avoid checking class initialization). 2765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put, 2775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown MemberOffset* field_offset, uint32_t* storage_index, 2785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool* is_referrers_class, bool* is_volatile, bool* is_initialized) 2795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 2805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Can we fastpath a interface, super class or virtual method call? Computes method's vtable 2825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // index. 2835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc, 2845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool update_stats, bool enable_devirtualization, 2855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType* type, MethodReference* target_method, int* vtable_idx, 2865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uintptr_t* direct_code, uintptr_t* direct_method) 2875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(Locks::mutator_lock_); 2885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const; 2905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc); 2915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 2925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Record patch information for later fix up. 2935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void AddCodePatch(const DexFile* dex_file, 2945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 2955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 2965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType referrer_invoke_type, 2975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 2985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType target_invoke_type, 2995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 3005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_methods_lock_); 3015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void AddRelativeCodePatch(const DexFile* dex_file, 3025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 3035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 3045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType referrer_invoke_type, 3055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 3065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType target_invoke_type, 3075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset, 3085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown int32_t pc_relative_offset) 3095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_methods_lock_); 3105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void AddMethodPatch(const DexFile* dex_file, 3115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 3125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 3135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType referrer_invoke_type, 3145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 3155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType target_invoke_type, 3165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 3175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_methods_lock_); 3185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void AddClassPatch(const DexFile* dex_file, 3195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 3205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 3215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 3225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 3235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_methods_lock_); 3245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool GetSupportBootImageFixup() const { 3265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return support_boot_image_fixup_; 3275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void SetSupportBootImageFixup(bool support_boot_image_fixup) { 3305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown support_boot_image_fixup_ = support_boot_image_fixup; 3315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ArenaPool* GetArenaPool() { 3345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return &arena_pool_; 3355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool WriteElf(const std::string& android_root, 3385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool is_host, 3395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const std::vector<const DexFile*>& dex_files, 3405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown OatWriter* oat_writer, 3415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown File* file); 3425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // TODO: move to a common home for llvm helpers once quick/portable are merged. 3445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown static void InstructionSetToLLVMTarget(InstructionSet instruction_set, 3455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::string* target_triple, 3465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::string* target_cpu, 3475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::string* target_attr); 3485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void SetCompilerContext(void* compiler_context) { 3505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown compiler_context_ = compiler_context; 3515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void* GetCompilerContext() const { 3545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return compiler_context_; 3555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3565a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 3575a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown size_t GetThreadCount() const { 3585a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return thread_count_; 3595a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 3605a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 3615a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown class CallPatchInformation; 3625a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown class TypePatchInformation; 3635a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 3645a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown bool GetDumpPasses() const { 3655a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return dump_passes_; 3665a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 3675a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 3685a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown CumulativeLogger* GetTimingsLogger() const { 3695a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return timings_logger_; 3705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3725a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown class PatchInformation { 3735a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown public: 3745a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown const DexFile& GetDexFile() const { 3755a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return *dex_file_; 3765a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 3775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t GetReferrerClassDefIdx() const { 3785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return referrer_class_def_idx_; 3795a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 3805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t GetReferrerMethodIdx() const { 3815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return referrer_method_idx_; 3825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t GetLiteralOffset() const { 3845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return literal_offset_; 3855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 3875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown virtual bool IsCall() const { 3885a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return false; 3895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown virtual bool IsType() const { 3915a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return false; 3925a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 3935a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown virtual const CallPatchInformation* AsCall() const { 3945a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown LOG(FATAL) << "Unreachable"; 3955a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return nullptr; 3965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 3975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown virtual const TypePatchInformation* AsType() const { 3985a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown LOG(FATAL) << "Unreachable"; 3995a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown return nullptr; 4005a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown } 4015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4025a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown protected: 4035a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown PatchInformation(const DexFile* dex_file, 4045a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown uint16_t referrer_class_def_idx, 4055a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown uint32_t referrer_method_idx, 4065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 4075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown : dex_file_(dex_file), 4085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_class_def_idx_(referrer_class_def_idx), 4095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_method_idx_(referrer_method_idx), 4105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown literal_offset_(literal_offset) { 4115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CHECK(dex_file_ != NULL); 4125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4135a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown virtual ~PatchInformation() {} 4145a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 4155a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown const DexFile* const dex_file_; 4165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const uint16_t referrer_class_def_idx_; 4175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const uint32_t referrer_method_idx_; 4185a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown const size_t literal_offset_; 4195a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown 4205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown friend class CompilerDriver; 4215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown }; 4225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4236071da7ef84c60645572654504813d492b8b21d5Elliott Hughes class CallPatchInformation : public PatchInformation { 4245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown public: 4255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType GetReferrerInvokeType() const { 4265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return referrer_invoke_type_; 427552a8a5d8df32f659b8d11311a244cdc6d3b7733Flanker } 428552a8a5d8df32f659b8d11311a244cdc6d3b7733Flanker uint32_t GetTargetMethodIdx() const { 4295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return target_method_idx_; 4305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType GetTargetInvokeType() const { 4325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return target_invoke_type_; 4335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4357b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright const CallPatchInformation* AsCall() const { 4365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return this; 4375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsCall() const { 4395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return true; 4405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown virtual bool IsRelative() const { 4425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return false; 4435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown virtual int RelativeOffset() const { 4455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return 0; 4465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown protected: 4495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown CallPatchInformation(const DexFile* dex_file, 4505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 4515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 4525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType referrer_invoke_type, 4535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 4545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType target_invoke_type, 4555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 4565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown : PatchInformation(dex_file, referrer_class_def_idx, 4575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_method_idx, literal_offset), 4585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_invoke_type_(referrer_invoke_type), 4595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown target_method_idx_(target_method_idx), 460c94fc45bc5c07724e63e4da5151cfea90bd87986Dan Austin target_invoke_type_(target_invoke_type) { 461c94fc45bc5c07724e63e4da5151cfea90bd87986Dan Austin } 4625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown private: 4645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const InvokeType referrer_invoke_type_; 4655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const uint32_t target_method_idx_; 4665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const InvokeType target_invoke_type_; 4675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown friend class CompilerDriver; 4695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DISALLOW_COPY_AND_ASSIGN(CallPatchInformation); 4705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown }; 4715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown class RelativeCallPatchInformation : public CallPatchInformation { 4735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown public: 4745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsRelative() const { 4755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return true; 4765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown int RelativeOffset() const { 4785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return offset_; 4795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown private: 4825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown RelativeCallPatchInformation(const DexFile* dex_file, 4835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 4847b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright uint32_t referrer_method_idx, 4855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType referrer_invoke_type, 4865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_method_idx, 4875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown InvokeType target_invoke_type, 4885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset, 4895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown int32_t pc_relative_offset) 4905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown : CallPatchInformation(dex_file, referrer_class_def_idx, 4915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_method_idx, referrer_invoke_type, 4925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown target_method_idx, target_invoke_type, literal_offset), 4935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown offset_(pc_relative_offset) { 4945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 4955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const int offset_; 4975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 4985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown friend class CompilerDriver; 4995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DISALLOW_COPY_AND_ASSIGN(RelativeCallPatchInformation); 5005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown }; 5015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown class TypePatchInformation : public PatchInformation { 5035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown public: 5045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t GetTargetTypeIdx() const { 5055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return target_type_idx_; 5065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsType() const { 5095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return true; 5105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const TypePatchInformation* AsType() const { 5125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return this; 5135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown private: 5165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown TypePatchInformation(const DexFile* dex_file, 5175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint16_t referrer_class_def_idx, 5185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t referrer_method_idx, 5195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t target_type_idx, 5205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown size_t literal_offset) 5215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown : PatchInformation(dex_file, referrer_class_def_idx, 5225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown referrer_method_idx, literal_offset), 5235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown target_type_idx_(target_type_idx) { 5245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown const uint32_t target_type_idx_; 5275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown friend class CompilerDriver; 5295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown DISALLOW_COPY_AND_ASSIGN(TypePatchInformation); 5305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown }; 5315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 532872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright const std::vector<const CallPatchInformation*>& GetCodeToPatch() const { 533872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright return code_to_patch_; 534872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright } 535872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright const std::vector<const CallPatchInformation*>& GetMethodsToPatch() const { 536872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright return methods_to_patch_; 537872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright } 538872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright const std::vector<const TypePatchInformation*>& GetClassesToPatch() const { 539872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright return classes_to_patch_; 5405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Checks if class specified by type_idx is one of the image_classes_ 5435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsImageClass(const char* descriptor) const; 5445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown void RecordClassStatus(ClassReference ref, mirror::Class::Status status) 5465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown LOCKS_EXCLUDED(compiled_classes_lock_); 5475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* DeduplicateCode(const std::vector<uint8_t>& code); 5495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* DeduplicateMappingTable(const std::vector<uint8_t>& code); 5505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* DeduplicateVMapTable(const std::vector<uint8_t>& code); 5515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* DeduplicateGCMap(const std::vector<uint8_t>& code); 5525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* DeduplicateCFIInfo(const std::vector<uint8_t>* cfi_info); 5535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown /* 5555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * @brief return the pointer to the Call Frame Information. 5565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * @return pointer to call frame information for this compilation. 5575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */ 5585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::vector<uint8_t>* GetCallFrameInformation() const { 5595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown return cfi_info_.get(); 5605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Profile data. This is generated from previous runs of the program and stored 5635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // in a file. It is used to determine whether to compile a particular method or not. 5645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown class ProfileData { 5655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown public: 5665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ProfileData() : count_(0), method_size_(0), percent_(0) {} 5675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ProfileData(std::string method_name, uint32_t count, uint32_t method_size, double percent) : 5685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown method_name_(method_name), count_(count), method_size_(method_size), percent_(percent) { 5695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown } 5705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool IsAbove(double v) const { return percent_ >= v; } 5725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown double GetPercent() const { return percent_; } 5735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown private: 5755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown std::string method_name_; // Method name. 5765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t count_; // Number number of times it has been called. 5775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown uint32_t method_size_; // Size of the method on dex instructions. 5785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown double percent_; // Percentage of time spent in this method. 5795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown }; 5805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Profile data is stored in a map, indexed by the full method name. 5825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown typedef std::map<const std::string, ProfileData> ProfileMap; 5835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown ProfileMap profile_map_; 5845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool profile_ok_; 5855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Read the profile data from the given file. Calculates the percentage for each method. 5875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Returns false if there was no profile file or it was malformed. 5885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool ReadProfile(const std::string& filename); 5895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 5905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown // Should the compiler run on this method given profile information? 5915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown bool SkipCompilation(const std::string& method_name); 5925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown 593 private: 594 // Compute constant code and method pointers when possible 595 void GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type, 596 bool no_guarantee_of_dex_cache_entry, 597 mirror::Class* referrer_class, 598 mirror::ArtMethod* method, 599 bool update_stats, 600 MethodReference* target_method, 601 uintptr_t* direct_code, uintptr_t* direct_method) 602 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 603 604 void PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 605 ThreadPool* thread_pool, TimingLogger* timings) 606 LOCKS_EXCLUDED(Locks::mutator_lock_); 607 608 void LoadImageClasses(TimingLogger* timings); 609 610 // Attempt to resolve all type, methods, fields, and strings 611 // referenced from code in the dex file following PathClassLoader 612 // ordering semantics. 613 void Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files, 614 ThreadPool* thread_pool, TimingLogger* timings) 615 LOCKS_EXCLUDED(Locks::mutator_lock_); 616 void ResolveDexFile(jobject class_loader, const DexFile& dex_file, 617 ThreadPool* thread_pool, TimingLogger* timings) 618 LOCKS_EXCLUDED(Locks::mutator_lock_); 619 620 void Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files, 621 ThreadPool* thread_pool, TimingLogger* timings); 622 void VerifyDexFile(jobject class_loader, const DexFile& dex_file, 623 ThreadPool* thread_pool, TimingLogger* timings) 624 LOCKS_EXCLUDED(Locks::mutator_lock_); 625 626 void InitializeClasses(jobject class_loader, const std::vector<const DexFile*>& dex_files, 627 ThreadPool* thread_pool, TimingLogger* timings) 628 LOCKS_EXCLUDED(Locks::mutator_lock_); 629 void InitializeClasses(jobject class_loader, const DexFile& dex_file, 630 ThreadPool* thread_pool, TimingLogger* timings) 631 LOCKS_EXCLUDED(Locks::mutator_lock_, compiled_classes_lock_); 632 633 void UpdateImageClasses(TimingLogger* timings) LOCKS_EXCLUDED(Locks::mutator_lock_); 634 static void FindClinitImageClassesCallback(mirror::Object* object, void* arg) 635 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 636 637 void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, 638 ThreadPool* thread_pool, TimingLogger* timings); 639 void CompileDexFile(jobject class_loader, const DexFile& dex_file, 640 ThreadPool* thread_pool, TimingLogger* timings) 641 LOCKS_EXCLUDED(Locks::mutator_lock_); 642 void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 643 InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, 644 jobject class_loader, const DexFile& dex_file, 645 DexToDexCompilationLevel dex_to_dex_compilation_level) 646 LOCKS_EXCLUDED(compiled_methods_lock_); 647 648 static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index) 649 LOCKS_EXCLUDED(Locks::mutator_lock_); 650 651 std::vector<const CallPatchInformation*> code_to_patch_; 652 std::vector<const CallPatchInformation*> methods_to_patch_; 653 std::vector<const TypePatchInformation*> classes_to_patch_; 654 655 const CompilerOptions* const compiler_options_; 656 VerificationResults* const verification_results_; 657 DexFileToMethodInlinerMap* const method_inliner_map_; 658 659 UniquePtr<CompilerBackend> compiler_backend_; 660 661 const InstructionSet instruction_set_; 662 const InstructionSetFeatures instruction_set_features_; 663 664 // All class references that require 665 mutable ReaderWriterMutex freezing_constructor_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 666 std::set<ClassReference> freezing_constructor_classes_ GUARDED_BY(freezing_constructor_lock_); 667 668 typedef SafeMap<const ClassReference, CompiledClass*> ClassTable; 669 // All class references that this compiler has compiled. 670 mutable Mutex compiled_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 671 ClassTable compiled_classes_ GUARDED_BY(compiled_classes_lock_); 672 673 typedef SafeMap<const MethodReference, CompiledMethod*, MethodReferenceComparator> MethodTable; 674 // All method references that this compiler has compiled. 675 mutable Mutex compiled_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 676 MethodTable compiled_methods_ GUARDED_BY(compiled_methods_lock_); 677 678 const bool image_; 679 680 // If image_ is true, specifies the classes that will be included in 681 // the image. Note if image_classes_ is NULL, all classes are 682 // included in the image. 683 UniquePtr<DescriptorSet> image_classes_; 684 685 size_t thread_count_; 686 uint64_t start_ns_; 687 688 UniquePtr<AOTCompilationStats> stats_; 689 690 bool dump_stats_; 691 const bool dump_passes_; 692 693 CumulativeLogger* const timings_logger_; 694 695 typedef void (*CompilerCallbackFn)(CompilerDriver& driver); 696 typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver); 697 698 void* compiler_library_; 699 700 typedef void (*DexToDexCompilerFn)(CompilerDriver& driver, 701 const DexFile::CodeItem* code_item, 702 uint32_t access_flags, InvokeType invoke_type, 703 uint32_t class_dex_idx, uint32_t method_idx, 704 jobject class_loader, const DexFile& dex_file, 705 DexToDexCompilationLevel dex_to_dex_compilation_level); 706 DexToDexCompilerFn dex_to_dex_compiler_; 707 708 void* compiler_context_; 709 710 pthread_key_t tls_key_; 711 712 // Arena pool used by the compiler. 713 ArenaPool arena_pool_; 714 715 typedef void (*CompilerEnableAutoElfLoadingFn)(CompilerDriver& driver); 716 CompilerEnableAutoElfLoadingFn compiler_enable_auto_elf_loading_; 717 718 typedef const void* (*CompilerGetMethodCodeAddrFn) 719 (const CompilerDriver& driver, const CompiledMethod* cm, const mirror::ArtMethod* method); 720 CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_; 721 722 bool support_boot_image_fixup_; 723 724 // Call Frame Information, which might be generated to help stack tracebacks. 725 UniquePtr<std::vector<uint8_t> > cfi_info_; 726 727 // DeDuplication data structures, these own the corresponding byte arrays. 728 class DedupeHashFunc { 729 public: 730 size_t operator()(const std::vector<uint8_t>& array) const { 731 // For small arrays compute a hash using every byte. 732 static const size_t kSmallArrayThreshold = 16; 733 size_t hash = 0x811c9dc5; 734 if (array.size() <= kSmallArrayThreshold) { 735 for (uint8_t b : array) { 736 hash = (hash * 16777619) ^ b; 737 } 738 } else { 739 // For larger arrays use the 2 bytes at 6 bytes (the location of a push registers 740 // instruction field for quick generated code on ARM) and then select a number of other 741 // values at random. 742 static const size_t kRandomHashCount = 16; 743 for (size_t i = 0; i < 2; ++i) { 744 uint8_t b = array[i + 6]; 745 hash = (hash * 16777619) ^ b; 746 } 747 for (size_t i = 2; i < kRandomHashCount; ++i) { 748 size_t r = i * 1103515245 + 12345; 749 uint8_t b = array[r % array.size()]; 750 hash = (hash * 16777619) ^ b; 751 } 752 } 753 hash += hash << 13; 754 hash ^= hash >> 7; 755 hash += hash << 3; 756 hash ^= hash >> 17; 757 hash += hash << 5; 758 return hash; 759 } 760 }; 761 DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_code_; 762 DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_mapping_table_; 763 DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_vmap_table_; 764 DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_gc_map_; 765 DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_cfi_info_; 766 767 DISALLOW_COPY_AND_ASSIGN(CompilerDriver); 768}; 769 770} // namespace art 771 772#endif // ART_COMPILER_DRIVER_COMPILER_DRIVER_H_ 773