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