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