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