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