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