compiler_driver.h revision ae7083dac2db59dcdef869e35ac44a039d888ee9
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_DRIVER_COMPILER_DRIVER_H_
18#define ART_COMPILER_DRIVER_COMPILER_DRIVER_H_
19
20#include <set>
21#include <string>
22#include <vector>
23
24#include "base/mutex.h"
25#include "base/timing_logger.h"
26#include "class_reference.h"
27#include "compiled_class.h"
28#include "compiled_method.h"
29#include "compiler_backend.h"
30#include "dex_file.h"
31#include "instruction_set.h"
32#include "invoke_type.h"
33#include "method_reference.h"
34#include "os.h"
35#include "runtime.h"
36#include "safe_map.h"
37#include "thread_pool.h"
38#include "utils/arena_allocator.h"
39#include "utils/dedupe_set.h"
40
41namespace art {
42
43namespace verifier {
44class MethodVerifier;
45}  // namespace verifier
46
47class AOTCompilationStats;
48class CompilerOptions;
49class DexCompilationUnit;
50class DexFileToMethodInlinerMap;
51class InlineIGetIPutData;
52class OatWriter;
53class ParallelCompilationManager;
54class TimingLogger;
55class VerificationResults;
56class VerifiedMethod;
57
58enum EntryPointCallingConvention {
59  // ABI of invocations to a method's interpreter entry point.
60  kInterpreterAbi,
61  // ABI of calls to a method's native code, only used for native methods.
62  kJniAbi,
63  // ABI of calls to a method's portable code entry point.
64  kPortableAbi,
65  // ABI of calls to a method's quick code entry point.
66  kQuickAbi
67};
68
69enum DexToDexCompilationLevel {
70  kDontDexToDexCompile,   // Only meaning wrt image time interpretation.
71  kRequired,              // Dex-to-dex compilation required for correctness.
72  kOptimize               // Perform required transformation and peep-hole optimizations.
73};
74
75// Thread-local storage compiler worker threads
76class CompilerTls {
77  public:
78    CompilerTls() : llvm_info_(NULL) {}
79    ~CompilerTls() {}
80
81    void* GetLLVMInfo() { return llvm_info_; }
82
83    void SetLLVMInfo(void* llvm_info) { llvm_info_ = llvm_info; }
84
85  private:
86    void* llvm_info_;
87};
88
89class CompilerDriver {
90 public:
91  typedef std::set<std::string> DescriptorSet;
92
93  // Create a compiler targeting the requested "instruction_set".
94  // "image" should be true if image specific optimizations should be
95  // enabled.  "image_classes" lets the compiler know what classes it
96  // can assume will be in the image, with NULL implying all available
97  // classes.
98  explicit CompilerDriver(const CompilerOptions* compiler_options,
99                          VerificationResults* verification_results,
100                          DexFileToMethodInlinerMap* method_inliner_map,
101                          CompilerBackend::Kind compiler_backend_kind,
102                          InstructionSet instruction_set,
103                          InstructionSetFeatures instruction_set_features,
104                          bool image, DescriptorSet* image_classes,
105                          size_t thread_count, bool dump_stats, bool dump_passes,
106                          CumulativeLogger* timer);
107
108  ~CompilerDriver();
109
110  void CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files,
111                  TimingLogger& timings)
112      LOCKS_EXCLUDED(Locks::mutator_lock_);
113
114  // Compile a single Method.
115  void CompileOne(mirror::ArtMethod* method, TimingLogger& timings)
116      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
117
118  VerificationResults* GetVerificationResults() const {
119    return verification_results_;
120  }
121
122  DexFileToMethodInlinerMap* GetMethodInlinerMap() const {
123    return method_inliner_map_;
124  }
125
126  const InstructionSet& GetInstructionSet() const {
127    return instruction_set_;
128  }
129
130  const InstructionSetFeatures& GetInstructionSetFeatures() const {
131    return instruction_set_features_;
132  }
133
134  const CompilerOptions& GetCompilerOptions() const {
135    DCHECK(compiler_options_ != nullptr);
136    return *compiler_options_;
137  }
138
139  CompilerBackend* GetCompilerBackend() const {
140    return compiler_backend_.get();
141  }
142
143  // Are we compiling and creating an image file?
144  bool IsImage() const {
145    return image_;
146  }
147
148  DescriptorSet* GetImageClasses() const {
149    return image_classes_.get();
150  }
151
152  CompilerTls* GetTls();
153
154  // Generate the trampolines that are invoked by unresolved direct methods.
155  const std::vector<uint8_t>* CreateInterpreterToInterpreterBridge() const
156      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
157  const std::vector<uint8_t>* CreateInterpreterToCompiledCodeBridge() const
158      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
159  const std::vector<uint8_t>* CreateJniDlsymLookup() const
160      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
161  const std::vector<uint8_t>* CreatePortableImtConflictTrampoline() const
162      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
163  const std::vector<uint8_t>* CreatePortableResolutionTrampoline() const
164      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
165  const std::vector<uint8_t>* CreatePortableToInterpreterBridge() const
166      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
167  const std::vector<uint8_t>* CreateQuickImtConflictTrampoline() const
168      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
169  const std::vector<uint8_t>* CreateQuickResolutionTrampoline() const
170      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
171  const std::vector<uint8_t>* CreateQuickToInterpreterBridge() const
172      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
173
174  CompiledClass* GetCompiledClass(ClassReference ref) const
175      LOCKS_EXCLUDED(compiled_classes_lock_);
176
177  CompiledMethod* GetCompiledMethod(MethodReference ref) const
178      LOCKS_EXCLUDED(compiled_methods_lock_);
179
180  void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
181                                     uint16_t class_def_index);
182  bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, uint16_t class_def_index);
183
184  // Callbacks from compiler to see what runtime checks must be generated.
185
186  bool CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx);
187
188  bool CanAssumeStringIsPresentInDexCache(const DexFile& dex_file, uint32_t string_idx)
189      LOCKS_EXCLUDED(Locks::mutator_lock_);
190
191  // Are runtime access checks necessary in the compiled code?
192  bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
193                                  uint32_t type_idx, bool* type_known_final = NULL,
194                                  bool* type_known_abstract = NULL,
195                                  bool* equals_referrers_class = NULL)
196      LOCKS_EXCLUDED(Locks::mutator_lock_);
197
198  // Are runtime access and instantiable checks necessary in the code?
199  bool CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
200                                              uint32_t type_idx)
201     LOCKS_EXCLUDED(Locks::mutator_lock_);
202
203  bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
204                          bool* is_type_initialized, bool* use_direct_type_ptr,
205                          uintptr_t* direct_type_ptr);
206
207  // Can we fast path instance field access in a verified accessor?
208  // If yes, computes field's offset and volatility and whether the method is static or not.
209  static bool ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put,
210                                         verifier::MethodVerifier* verifier,
211                                         InlineIGetIPutData* result)
212      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
213
214  // Can we fast path instance field access? Computes field's offset and volatility.
215  bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
216                                int* field_offset, bool* is_volatile)
217      LOCKS_EXCLUDED(Locks::mutator_lock_);
218
219  // Can we fastpath static field access? Computes field's offset, volatility and whether the
220  // field is within the referrer (which can avoid checking class initialization).
221  bool ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
222                              int* field_offset, int* storage_index,
223                              bool* is_referrers_class, bool* is_volatile, bool* is_initialized)
224      LOCKS_EXCLUDED(Locks::mutator_lock_);
225
226  // Can we fastpath a interface, super class or virtual method call? Computes method's vtable
227  // index.
228  bool ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
229                         bool update_stats, bool enable_devirtualization,
230                         InvokeType* type, MethodReference* target_method, int* vtable_idx,
231                         uintptr_t* direct_code, uintptr_t* direct_method)
232      LOCKS_EXCLUDED(Locks::mutator_lock_);
233
234  const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
235  bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc);
236
237  // Record patch information for later fix up.
238  void AddCodePatch(const DexFile* dex_file,
239                    uint16_t referrer_class_def_idx,
240                    uint32_t referrer_method_idx,
241                    InvokeType referrer_invoke_type,
242                    uint32_t target_method_idx,
243                    InvokeType target_invoke_type,
244                    size_t literal_offset)
245      LOCKS_EXCLUDED(compiled_methods_lock_);
246  void AddRelativeCodePatch(const DexFile* dex_file,
247                            uint16_t referrer_class_def_idx,
248                            uint32_t referrer_method_idx,
249                            InvokeType referrer_invoke_type,
250                            uint32_t target_method_idx,
251                            InvokeType target_invoke_type,
252                            size_t literal_offset,
253                            int32_t pc_relative_offset)
254      LOCKS_EXCLUDED(compiled_methods_lock_);
255  void AddMethodPatch(const DexFile* dex_file,
256                      uint16_t referrer_class_def_idx,
257                      uint32_t referrer_method_idx,
258                      InvokeType referrer_invoke_type,
259                      uint32_t target_method_idx,
260                      InvokeType target_invoke_type,
261                      size_t literal_offset)
262      LOCKS_EXCLUDED(compiled_methods_lock_);
263  void AddClassPatch(const DexFile* dex_file,
264                     uint16_t referrer_class_def_idx,
265                     uint32_t referrer_method_idx,
266                     uint32_t target_method_idx,
267                     size_t literal_offset)
268      LOCKS_EXCLUDED(compiled_methods_lock_);
269
270  bool GetSupportBootImageFixup() const {
271    return support_boot_image_fixup_;
272  }
273
274  void SetSupportBootImageFixup(bool support_boot_image_fixup) {
275    support_boot_image_fixup_ = support_boot_image_fixup;
276  }
277
278  ArenaPool& GetArenaPool() {
279    return arena_pool_;
280  }
281
282  bool WriteElf(const std::string& android_root,
283                bool is_host,
284                const std::vector<const DexFile*>& dex_files,
285                OatWriter& oat_writer,
286                File* file);
287
288  // TODO: move to a common home for llvm helpers once quick/portable are merged
289  static void InstructionSetToLLVMTarget(InstructionSet instruction_set,
290                                         std::string& target_triple,
291                                         std::string& target_cpu,
292                                         std::string& target_attr);
293
294  void SetCompilerContext(void* compiler_context) {
295    compiler_context_ = compiler_context;
296  }
297
298  void* GetCompilerContext() const {
299    return compiler_context_;
300  }
301
302  size_t GetThreadCount() const {
303    return thread_count_;
304  }
305
306  class CallPatchInformation;
307  class TypePatchInformation;
308
309  bool GetDumpPasses() const {
310    return dump_passes_;
311  }
312
313  CumulativeLogger& GetTimingsLogger() const {
314    return *timings_logger_;
315  }
316
317  class PatchInformation {
318   public:
319    const DexFile& GetDexFile() const {
320      return *dex_file_;
321    }
322    uint16_t GetReferrerClassDefIdx() const {
323      return referrer_class_def_idx_;
324    }
325    uint32_t GetReferrerMethodIdx() const {
326      return referrer_method_idx_;
327    }
328    size_t GetLiteralOffset() const {
329      return literal_offset_;
330    }
331
332    virtual bool IsCall() const {
333      return false;
334    }
335    virtual bool IsType() const {
336      return false;
337    }
338    virtual const CallPatchInformation* AsCall() const {
339      LOG(FATAL) << "Unreachable";
340      return nullptr;
341    }
342    virtual const TypePatchInformation* AsType() const {
343      LOG(FATAL) << "Unreachable";
344      return nullptr;
345    }
346
347   protected:
348    PatchInformation(const DexFile* dex_file,
349                     uint16_t referrer_class_def_idx,
350                     uint32_t referrer_method_idx,
351                     size_t literal_offset)
352      : dex_file_(dex_file),
353        referrer_class_def_idx_(referrer_class_def_idx),
354        referrer_method_idx_(referrer_method_idx),
355        literal_offset_(literal_offset) {
356      CHECK(dex_file_ != NULL);
357    }
358    virtual ~PatchInformation() {}
359
360    const DexFile* const dex_file_;
361    const uint16_t referrer_class_def_idx_;
362    const uint32_t referrer_method_idx_;
363    const size_t literal_offset_;
364
365    friend class CompilerDriver;
366  };
367
368  class CallPatchInformation : public PatchInformation {
369   public:
370    InvokeType GetReferrerInvokeType() const {
371      return referrer_invoke_type_;
372    }
373    uint32_t GetTargetMethodIdx() const {
374      return target_method_idx_;
375    }
376    InvokeType GetTargetInvokeType() const {
377      return target_invoke_type_;
378    }
379
380    const CallPatchInformation* AsCall() const {
381      return this;
382    }
383    bool IsCall() const {
384      return true;
385    }
386    virtual bool IsRelative() const {
387      return false;
388    }
389    virtual int RelativeOffset() const {
390      return 0;
391    }
392
393   protected:
394    CallPatchInformation(const DexFile* dex_file,
395                         uint16_t referrer_class_def_idx,
396                         uint32_t referrer_method_idx,
397                         InvokeType referrer_invoke_type,
398                         uint32_t target_method_idx,
399                         InvokeType target_invoke_type,
400                         size_t literal_offset)
401        : PatchInformation(dex_file, referrer_class_def_idx,
402                           referrer_method_idx, literal_offset),
403          referrer_invoke_type_(referrer_invoke_type),
404          target_method_idx_(target_method_idx),
405          target_invoke_type_(target_invoke_type) {
406    }
407
408   private:
409    const InvokeType referrer_invoke_type_;
410    const uint32_t target_method_idx_;
411    const InvokeType target_invoke_type_;
412
413    friend class CompilerDriver;
414    DISALLOW_COPY_AND_ASSIGN(CallPatchInformation);
415  };
416
417  class RelativeCallPatchInformation : public CallPatchInformation {
418   public:
419    bool IsRelative() const {
420      return true;
421    }
422    int RelativeOffset() const {
423      return offset_;
424    }
425
426   private:
427    RelativeCallPatchInformation(const DexFile* dex_file,
428                                 uint16_t referrer_class_def_idx,
429                                 uint32_t referrer_method_idx,
430                                 InvokeType referrer_invoke_type,
431                                 uint32_t target_method_idx,
432                                 InvokeType target_invoke_type,
433                                 size_t literal_offset,
434                                 int32_t pc_relative_offset)
435        : CallPatchInformation(dex_file, referrer_class_def_idx,
436                           referrer_method_idx, referrer_invoke_type,
437                           target_method_idx, target_invoke_type, literal_offset),
438          offset_(pc_relative_offset) {
439    }
440
441    const int offset_;
442
443    friend class CompilerDriver;
444    DISALLOW_COPY_AND_ASSIGN(RelativeCallPatchInformation);
445  };
446
447  class TypePatchInformation : public PatchInformation {
448   public:
449    uint32_t GetTargetTypeIdx() const {
450      return target_type_idx_;
451    }
452
453    bool IsType() const {
454      return true;
455    }
456    const TypePatchInformation* AsType() const {
457      return this;
458    }
459
460   private:
461    TypePatchInformation(const DexFile* dex_file,
462                         uint16_t referrer_class_def_idx,
463                         uint32_t referrer_method_idx,
464                         uint32_t target_type_idx,
465                         size_t literal_offset)
466        : PatchInformation(dex_file, referrer_class_def_idx,
467                           referrer_method_idx, literal_offset),
468          target_type_idx_(target_type_idx) {
469    }
470
471    const uint32_t target_type_idx_;
472
473    friend class CompilerDriver;
474    DISALLOW_COPY_AND_ASSIGN(TypePatchInformation);
475  };
476
477  const std::vector<const CallPatchInformation*>& GetCodeToPatch() const {
478    return code_to_patch_;
479  }
480  const std::vector<const CallPatchInformation*>& GetMethodsToPatch() const {
481    return methods_to_patch_;
482  }
483  const std::vector<const TypePatchInformation*>& GetClassesToPatch() const {
484    return classes_to_patch_;
485  }
486
487  // Checks if class specified by type_idx is one of the image_classes_
488  bool IsImageClass(const char* descriptor) const;
489
490  void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
491      LOCKS_EXCLUDED(compiled_classes_lock_);
492
493  std::vector<uint8_t>* DeduplicateCode(const std::vector<uint8_t>& code);
494  std::vector<uint8_t>* DeduplicateMappingTable(const std::vector<uint8_t>& code);
495  std::vector<uint8_t>* DeduplicateVMapTable(const std::vector<uint8_t>& code);
496  std::vector<uint8_t>* DeduplicateGCMap(const std::vector<uint8_t>& code);
497
498 private:
499  // Compute constant code and method pointers when possible
500  void GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,
501                                     bool no_guarantee_of_dex_cache_entry,
502                                     mirror::Class* referrer_class,
503                                     mirror::ArtMethod* method,
504                                     bool update_stats,
505                                     MethodReference* target_method,
506                                     uintptr_t* direct_code, uintptr_t* direct_method)
507      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
508
509  void PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
510                  ThreadPool& thread_pool, TimingLogger& timings)
511      LOCKS_EXCLUDED(Locks::mutator_lock_);
512
513  void LoadImageClasses(TimingLogger& timings);
514
515  // Attempt to resolve all type, methods, fields, and strings
516  // referenced from code in the dex file following PathClassLoader
517  // ordering semantics.
518  void Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
519               ThreadPool& thread_pool, TimingLogger& timings)
520      LOCKS_EXCLUDED(Locks::mutator_lock_);
521  void ResolveDexFile(jobject class_loader, const DexFile& dex_file,
522                      ThreadPool& thread_pool, TimingLogger& timings)
523      LOCKS_EXCLUDED(Locks::mutator_lock_);
524
525  void Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
526              ThreadPool& thread_pool, TimingLogger& timings);
527  void VerifyDexFile(jobject class_loader, const DexFile& dex_file,
528                     ThreadPool& thread_pool, TimingLogger& timings)
529      LOCKS_EXCLUDED(Locks::mutator_lock_);
530
531  void InitializeClasses(jobject class_loader, const std::vector<const DexFile*>& dex_files,
532                         ThreadPool& thread_pool, TimingLogger& timings)
533      LOCKS_EXCLUDED(Locks::mutator_lock_);
534  void InitializeClasses(jobject class_loader, const DexFile& dex_file,
535                         ThreadPool& thread_pool, TimingLogger& timings)
536      LOCKS_EXCLUDED(Locks::mutator_lock_, compiled_classes_lock_);
537
538  void UpdateImageClasses(TimingLogger& timings)
539      LOCKS_EXCLUDED(Locks::mutator_lock_);
540  static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
541      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
542
543  void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
544               ThreadPool& thread_pool, TimingLogger& timings);
545  void CompileDexFile(jobject class_loader, const DexFile& dex_file,
546                      ThreadPool& thread_pool, TimingLogger& timings)
547      LOCKS_EXCLUDED(Locks::mutator_lock_);
548  void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
549                     InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx,
550                     jobject class_loader, const DexFile& dex_file,
551                     DexToDexCompilationLevel dex_to_dex_compilation_level)
552      LOCKS_EXCLUDED(compiled_methods_lock_);
553
554  static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index)
555      LOCKS_EXCLUDED(Locks::mutator_lock_);
556
557  std::vector<const CallPatchInformation*> code_to_patch_;
558  std::vector<const CallPatchInformation*> methods_to_patch_;
559  std::vector<const TypePatchInformation*> classes_to_patch_;
560
561  const CompilerOptions* const compiler_options_;
562  VerificationResults* const verification_results_;
563  DexFileToMethodInlinerMap* const method_inliner_map_;
564
565  UniquePtr<CompilerBackend> compiler_backend_;
566
567  const InstructionSet instruction_set_;
568  const InstructionSetFeatures instruction_set_features_;
569
570  // All class references that require
571  mutable ReaderWriterMutex freezing_constructor_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
572  std::set<ClassReference> freezing_constructor_classes_ GUARDED_BY(freezing_constructor_lock_);
573
574  typedef SafeMap<const ClassReference, CompiledClass*> ClassTable;
575  // All class references that this compiler has compiled.
576  mutable Mutex compiled_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
577  ClassTable compiled_classes_ GUARDED_BY(compiled_classes_lock_);
578
579  typedef SafeMap<const MethodReference, CompiledMethod*, MethodReferenceComparator> MethodTable;
580  // All method references that this compiler has compiled.
581  mutable Mutex compiled_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
582  MethodTable compiled_methods_ GUARDED_BY(compiled_methods_lock_);
583
584  const bool image_;
585
586  // If image_ is true, specifies the classes that will be included in
587  // the image. Note if image_classes_ is NULL, all classes are
588  // included in the image.
589  UniquePtr<DescriptorSet> image_classes_;
590
591  size_t thread_count_;
592  uint64_t start_ns_;
593
594  UniquePtr<AOTCompilationStats> stats_;
595
596  bool dump_stats_;
597  const bool dump_passes_;
598
599  CumulativeLogger* const timings_logger_;
600
601  typedef void (*CompilerCallbackFn)(CompilerDriver& driver);
602  typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver);
603
604  void* compiler_library_;
605
606  typedef void (*DexToDexCompilerFn)(CompilerDriver& driver,
607                                     const DexFile::CodeItem* code_item,
608                                     uint32_t access_flags, InvokeType invoke_type,
609                                     uint32_t class_dex_idx, uint32_t method_idx,
610                                     jobject class_loader, const DexFile& dex_file,
611                                     DexToDexCompilationLevel dex_to_dex_compilation_level);
612  DexToDexCompilerFn dex_to_dex_compiler_;
613
614  void* compiler_context_;
615
616  pthread_key_t tls_key_;
617
618  // Arena pool used by the compiler.
619  ArenaPool arena_pool_;
620
621  typedef void (*CompilerEnableAutoElfLoadingFn)(CompilerDriver& driver);
622  CompilerEnableAutoElfLoadingFn compiler_enable_auto_elf_loading_;
623
624  typedef const void* (*CompilerGetMethodCodeAddrFn)
625      (const CompilerDriver& driver, const CompiledMethod* cm, const mirror::ArtMethod* method);
626  CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_;
627
628  bool support_boot_image_fixup_;
629
630  // DeDuplication data structures, these own the corresponding byte arrays.
631  class DedupeHashFunc {
632   public:
633    size_t operator()(const std::vector<uint8_t>& array) const {
634      // For small arrays compute a hash using every byte.
635      static const size_t kSmallArrayThreshold = 16;
636      size_t hash = 0x811c9dc5;
637      if (array.size() <= kSmallArrayThreshold) {
638        for (uint8_t b : array) {
639          hash = (hash * 16777619) ^ b;
640        }
641      } else {
642        // For larger arrays use the 2 bytes at 6 bytes (the location of a push registers
643        // instruction field for quick generated code on ARM) and then select a number of other
644        // values at random.
645        static const size_t kRandomHashCount = 16;
646        for (size_t i = 0; i < 2; ++i) {
647          uint8_t b = array[i + 6];
648          hash = (hash * 16777619) ^ b;
649        }
650        for (size_t i = 2; i < kRandomHashCount; ++i) {
651          size_t r = i * 1103515245 + 12345;
652          uint8_t b = array[r % array.size()];
653          hash = (hash * 16777619) ^ b;
654        }
655      }
656      hash += hash << 13;
657      hash ^= hash >> 7;
658      hash += hash << 3;
659      hash ^= hash >> 17;
660      hash += hash << 5;
661      return hash;
662    }
663  };
664  DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_code_;
665  DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_mapping_table_;
666  DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_vmap_table_;
667  DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_gc_map_;
668
669  DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
670};
671
672}  // namespace art
673
674#endif  // ART_COMPILER_DRIVER_COMPILER_DRIVER_H_
675