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