Home | History | Annotate | Download | only in driver
      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 <unordered_set>
     23 #include <vector>
     24 
     25 #include "arch/instruction_set.h"
     26 #include "base/arena_allocator.h"
     27 #include "base/array_ref.h"
     28 #include "base/bit_utils.h"
     29 #include "base/mutex.h"
     30 #include "base/timing_logger.h"
     31 #include "class_reference.h"
     32 #include "compiler.h"
     33 #include "dex_file.h"
     34 #include "dex_file_types.h"
     35 #include "driver/compiled_method_storage.h"
     36 #include "jit/profile_compilation_info.h"
     37 #include "invoke_type.h"
     38 #include "method_reference.h"
     39 #include "mirror/class.h"  // For mirror::Class::Status.
     40 #include "os.h"
     41 #include "runtime.h"
     42 #include "safe_map.h"
     43 #include "thread_pool.h"
     44 #include "utils/atomic_method_ref_map.h"
     45 #include "utils/dex_cache_arrays_layout.h"
     46 
     47 namespace art {
     48 
     49 namespace mirror {
     50 class DexCache;
     51 }  // namespace mirror
     52 
     53 namespace verifier {
     54 class MethodVerifier;
     55 class VerifierDepsTest;
     56 }  // namespace verifier
     57 
     58 class BitVector;
     59 class CompiledClass;
     60 class CompiledMethod;
     61 class CompilerOptions;
     62 class DexCompilationUnit;
     63 struct InlineIGetIPutData;
     64 class InstructionSetFeatures;
     65 class ParallelCompilationManager;
     66 class ScopedObjectAccess;
     67 template <class Allocator> class SrcMap;
     68 template<class T> class Handle;
     69 class TimingLogger;
     70 class VdexFile;
     71 class VerificationResults;
     72 class VerifiedMethod;
     73 
     74 enum EntryPointCallingConvention {
     75   // ABI of invocations to a method's interpreter entry point.
     76   kInterpreterAbi,
     77   // ABI of calls to a method's native code, only used for native methods.
     78   kJniAbi,
     79   // ABI of calls to a method's quick code entry point.
     80   kQuickAbi
     81 };
     82 
     83 class CompilerDriver {
     84  public:
     85   // Create a compiler targeting the requested "instruction_set".
     86   // "image" should be true if image specific optimizations should be
     87   // enabled.  "image_classes" lets the compiler know what classes it
     88   // can assume will be in the image, with null implying all available
     89   // classes.
     90   CompilerDriver(const CompilerOptions* compiler_options,
     91                  VerificationResults* verification_results,
     92                  Compiler::Kind compiler_kind,
     93                  InstructionSet instruction_set,
     94                  const InstructionSetFeatures* instruction_set_features,
     95                  std::unordered_set<std::string>* image_classes,
     96                  std::unordered_set<std::string>* compiled_classes,
     97                  std::unordered_set<std::string>* compiled_methods,
     98                  size_t thread_count,
     99                  bool dump_stats,
    100                  bool dump_passes,
    101                  CumulativeLogger* timer,
    102                  int swap_fd,
    103                  const ProfileCompilationInfo* profile_compilation_info);
    104 
    105   ~CompilerDriver();
    106 
    107   // Set dex files that will be stored in the oat file after being compiled.
    108   void SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files) {
    109     dex_files_for_oat_file_ = &dex_files;
    110   }
    111 
    112   // Get dex file that will be stored in the oat file after being compiled.
    113   ArrayRef<const DexFile* const> GetDexFilesForOatFile() const {
    114     return (dex_files_for_oat_file_ != nullptr)
    115         ? ArrayRef<const DexFile* const>(*dex_files_for_oat_file_)
    116         : ArrayRef<const DexFile* const>();
    117   }
    118 
    119   void CompileAll(jobject class_loader,
    120                   const std::vector<const DexFile*>& dex_files,
    121                   TimingLogger* timings)
    122       REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
    123 
    124   void CompileAll(jobject class_loader,
    125                   const std::vector<const DexFile*>& dex_files,
    126                   VdexFile* vdex_file,
    127                   TimingLogger* timings)
    128       REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_, !dex_to_dex_references_lock_);
    129 
    130   // Compile a single Method.
    131   void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings)
    132       REQUIRES_SHARED(Locks::mutator_lock_)
    133       REQUIRES(!compiled_classes_lock_, !dex_to_dex_references_lock_);
    134 
    135   VerificationResults* GetVerificationResults() const {
    136     DCHECK(Runtime::Current()->IsAotCompiler());
    137     return verification_results_;
    138   }
    139 
    140   InstructionSet GetInstructionSet() const {
    141     return instruction_set_;
    142   }
    143 
    144   const InstructionSetFeatures* GetInstructionSetFeatures() const {
    145     return instruction_set_features_;
    146   }
    147 
    148   const CompilerOptions& GetCompilerOptions() const {
    149     return *compiler_options_;
    150   }
    151 
    152   Compiler* GetCompiler() const {
    153     return compiler_.get();
    154   }
    155 
    156   const std::unordered_set<std::string>* GetImageClasses() const {
    157     return image_classes_.get();
    158   }
    159 
    160   // Generate the trampolines that are invoked by unresolved direct methods.
    161   std::unique_ptr<const std::vector<uint8_t>> CreateJniDlsymLookup() const;
    162   std::unique_ptr<const std::vector<uint8_t>> CreateQuickGenericJniTrampoline() const;
    163   std::unique_ptr<const std::vector<uint8_t>> CreateQuickImtConflictTrampoline() const;
    164   std::unique_ptr<const std::vector<uint8_t>> CreateQuickResolutionTrampoline() const;
    165   std::unique_ptr<const std::vector<uint8_t>> CreateQuickToInterpreterBridge() const;
    166 
    167   CompiledClass* GetCompiledClass(ClassReference ref) const
    168       REQUIRES(!compiled_classes_lock_);
    169 
    170   CompiledMethod* GetCompiledMethod(MethodReference ref) const;
    171   size_t GetNonRelativeLinkerPatchCount() const;
    172   // Add a compiled method.
    173   void AddCompiledMethod(const MethodReference& method_ref,
    174                          CompiledMethod* const compiled_method,
    175                          size_t non_relative_linker_patch_count);
    176 
    177   void SetRequiresConstructorBarrier(Thread* self,
    178                                      const DexFile* dex_file,
    179                                      uint16_t class_def_index,
    180                                      bool requires)
    181       REQUIRES(!requires_constructor_barrier_lock_);
    182   bool RequiresConstructorBarrier(Thread* self,
    183                                   const DexFile* dex_file,
    184                                   uint16_t class_def_index)
    185       REQUIRES(!requires_constructor_barrier_lock_);
    186 
    187   // Are runtime access checks necessary in the compiled code?
    188   bool CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
    189                                   ObjPtr<mirror::Class> resolved_class)
    190       REQUIRES_SHARED(Locks::mutator_lock_);
    191 
    192   // Are runtime access and instantiable checks necessary in the code?
    193   // out_is_finalizable is set to whether the type is finalizable.
    194   bool CanAccessInstantiableTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
    195                                               ObjPtr<mirror::Class> resolved_class,
    196                                               bool* out_is_finalizable)
    197       REQUIRES_SHARED(Locks::mutator_lock_);
    198 
    199   // Resolve compiling method's class. Returns null on failure.
    200   mirror::Class* ResolveCompilingMethodsClass(
    201       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
    202       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit)
    203       REQUIRES_SHARED(Locks::mutator_lock_);
    204 
    205   mirror::Class* ResolveClass(
    206       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
    207       Handle<mirror::ClassLoader> class_loader, dex::TypeIndex type_index,
    208       const DexCompilationUnit* mUnit)
    209       REQUIRES_SHARED(Locks::mutator_lock_);
    210 
    211   // Resolve a field. Returns null on failure, including incompatible class change.
    212   // NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static.
    213   ArtField* ResolveField(
    214       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
    215       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
    216       uint32_t field_idx, bool is_static)
    217       REQUIRES_SHARED(Locks::mutator_lock_);
    218 
    219   // Resolve a field with a given dex file.
    220   ArtField* ResolveFieldWithDexFile(
    221       const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
    222       Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
    223       uint32_t field_idx, bool is_static)
    224       REQUIRES_SHARED(Locks::mutator_lock_);
    225 
    226   // Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
    227   std::pair<bool, bool> IsFastInstanceField(
    228       mirror::DexCache* dex_cache, mirror::Class* referrer_class,
    229       ArtField* resolved_field, uint16_t field_idx)
    230       REQUIRES_SHARED(Locks::mutator_lock_);
    231 
    232   // Resolve a method. Returns null on failure, including incompatible class change.
    233   ArtMethod* ResolveMethod(
    234       ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
    235       Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
    236       uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
    237       REQUIRES_SHARED(Locks::mutator_lock_);
    238 
    239   void ProcessedInstanceField(bool resolved);
    240   void ProcessedStaticField(bool resolved, bool local);
    241 
    242   // Can we fast path instance field access? Computes field's offset and volatility.
    243   bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
    244                                 MemberOffset* field_offset, bool* is_volatile)
    245       REQUIRES(!Locks::mutator_lock_);
    246 
    247   ArtField* ComputeInstanceFieldInfo(uint32_t field_idx,
    248                                              const DexCompilationUnit* mUnit,
    249                                              bool is_put,
    250                                              const ScopedObjectAccess& soa)
    251       REQUIRES_SHARED(Locks::mutator_lock_);
    252 
    253 
    254   const VerifiedMethod* GetVerifiedMethod(const DexFile* dex_file, uint32_t method_idx) const;
    255   bool IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc);
    256 
    257   bool GetSupportBootImageFixup() const {
    258     return support_boot_image_fixup_;
    259   }
    260 
    261   void SetSupportBootImageFixup(bool support_boot_image_fixup) {
    262     support_boot_image_fixup_ = support_boot_image_fixup;
    263   }
    264 
    265   void SetCompilerContext(void* compiler_context) {
    266     compiler_context_ = compiler_context;
    267   }
    268 
    269   void* GetCompilerContext() const {
    270     return compiler_context_;
    271   }
    272 
    273   size_t GetThreadCount() const {
    274     return parallel_thread_count_;
    275   }
    276 
    277   bool GetDumpStats() const {
    278     return dump_stats_;
    279   }
    280 
    281   bool GetDumpPasses() const {
    282     return dump_passes_;
    283   }
    284 
    285   CumulativeLogger* GetTimingsLogger() const {
    286     return timings_logger_;
    287   }
    288 
    289   void SetDedupeEnabled(bool dedupe_enabled) {
    290     compiled_method_storage_.SetDedupeEnabled(dedupe_enabled);
    291   }
    292 
    293   bool DedupeEnabled() const {
    294     return compiled_method_storage_.DedupeEnabled();
    295   }
    296 
    297   // Checks if class specified by type_idx is one of the image_classes_
    298   bool IsImageClass(const char* descriptor) const;
    299 
    300   // Checks whether the provided class should be compiled, i.e., is in classes_to_compile_.
    301   bool IsClassToCompile(const char* descriptor) const;
    302 
    303   // Checks whether the provided method should be compiled, i.e., is in method_to_compile_.
    304   bool IsMethodToCompile(const MethodReference& method_ref) const;
    305 
    306   // Checks whether profile guided compilation is enabled and if the method should be compiled
    307   // according to the profile file.
    308   bool ShouldCompileBasedOnProfile(const MethodReference& method_ref) const;
    309 
    310   // Checks whether profile guided verification is enabled and if the method should be verified
    311   // according to the profile file.
    312   bool ShouldVerifyClassBasedOnProfile(const DexFile& dex_file, uint16_t class_idx) const;
    313 
    314   void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
    315       REQUIRES(!compiled_classes_lock_);
    316 
    317   // Checks if the specified method has been verified without failures. Returns
    318   // false if the method is not in the verification results (GetVerificationResults).
    319   bool IsMethodVerifiedWithoutFailures(uint32_t method_idx,
    320                                        uint16_t class_def_idx,
    321                                        const DexFile& dex_file) const;
    322 
    323   // Get memory usage during compilation.
    324   std::string GetMemoryUsageString(bool extended) const;
    325 
    326   void SetHadHardVerifierFailure() {
    327     had_hard_verifier_failure_ = true;
    328   }
    329 
    330   Compiler::Kind GetCompilerKind() {
    331     return compiler_kind_;
    332   }
    333 
    334   CompiledMethodStorage* GetCompiledMethodStorage() {
    335     return &compiled_method_storage_;
    336   }
    337 
    338   // Can we assume that the klass is loaded?
    339   bool CanAssumeClassIsLoaded(mirror::Class* klass)
    340       REQUIRES_SHARED(Locks::mutator_lock_);
    341 
    342   bool MayInline(const DexFile* inlined_from, const DexFile* inlined_into) const {
    343     if (!kIsTargetBuild) {
    344       return MayInlineInternal(inlined_from, inlined_into);
    345     }
    346     return true;
    347   }
    348 
    349   void MarkForDexToDexCompilation(Thread* self, const MethodReference& method_ref)
    350       REQUIRES(!dex_to_dex_references_lock_);
    351 
    352   const BitVector* GetCurrentDexToDexMethods() const {
    353     return current_dex_to_dex_methods_;
    354   }
    355 
    356   const ProfileCompilationInfo* GetProfileCompilationInfo() const {
    357     return profile_compilation_info_;
    358   }
    359 
    360  private:
    361   // Can `referrer_class` access the resolved `member`?
    362   // Dispatch call to mirror::Class::CanAccessResolvedField or
    363   // mirror::Class::CanAccessResolvedMember depending on the value of
    364   // ArtMember.
    365   template <typename ArtMember>
    366   static bool CanAccessResolvedMember(mirror::Class* referrer_class,
    367                                       mirror::Class* access_to,
    368                                       ArtMember* member,
    369                                       mirror::DexCache* dex_cache,
    370                                       uint32_t field_idx)
    371       REQUIRES_SHARED(Locks::mutator_lock_);
    372 
    373  private:
    374   void PreCompile(jobject class_loader,
    375                   const std::vector<const DexFile*>& dex_files,
    376                   TimingLogger* timings)
    377       REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
    378 
    379   void LoadImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
    380 
    381   // Attempt to resolve all type, methods, fields, and strings
    382   // referenced from code in the dex file following PathClassLoader
    383   // ordering semantics.
    384   void Resolve(jobject class_loader,
    385                const std::vector<const DexFile*>& dex_files,
    386                TimingLogger* timings)
    387       REQUIRES(!Locks::mutator_lock_);
    388   void ResolveDexFile(jobject class_loader,
    389                       const DexFile& dex_file,
    390                       const std::vector<const DexFile*>& dex_files,
    391                       ThreadPool* thread_pool,
    392                       size_t thread_count,
    393                       TimingLogger* timings)
    394       REQUIRES(!Locks::mutator_lock_);
    395 
    396   // Do fast verification through VerifierDeps if possible. Return whether
    397   // verification was successful.
    398   // NO_THREAD_SAFETY_ANALYSIS as the method accesses a guarded value in a
    399   // single-threaded way.
    400   bool FastVerify(jobject class_loader,
    401                   const std::vector<const DexFile*>& dex_files,
    402                   TimingLogger* timings)
    403       NO_THREAD_SAFETY_ANALYSIS;
    404 
    405   void Verify(jobject class_loader,
    406               const std::vector<const DexFile*>& dex_files,
    407               TimingLogger* timings);
    408 
    409   void VerifyDexFile(jobject class_loader,
    410                      const DexFile& dex_file,
    411                      const std::vector<const DexFile*>& dex_files,
    412                      ThreadPool* thread_pool,
    413                      size_t thread_count,
    414                      TimingLogger* timings)
    415       REQUIRES(!Locks::mutator_lock_);
    416 
    417   void SetVerified(jobject class_loader,
    418                    const std::vector<const DexFile*>& dex_files,
    419                    TimingLogger* timings);
    420   void SetVerifiedDexFile(jobject class_loader,
    421                           const DexFile& dex_file,
    422                           const std::vector<const DexFile*>& dex_files,
    423                           ThreadPool* thread_pool,
    424                           size_t thread_count,
    425                           TimingLogger* timings)
    426       REQUIRES(!Locks::mutator_lock_);
    427 
    428   void InitializeClasses(jobject class_loader,
    429                          const std::vector<const DexFile*>& dex_files,
    430                          TimingLogger* timings)
    431       REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
    432   void InitializeClasses(jobject class_loader,
    433                          const DexFile& dex_file,
    434                          const std::vector<const DexFile*>& dex_files,
    435                          TimingLogger* timings)
    436       REQUIRES(!Locks::mutator_lock_, !compiled_classes_lock_);
    437 
    438   void UpdateImageClasses(TimingLogger* timings) REQUIRES(!Locks::mutator_lock_);
    439 
    440   void Compile(jobject class_loader,
    441                const std::vector<const DexFile*>& dex_files,
    442                TimingLogger* timings) REQUIRES(!dex_to_dex_references_lock_);
    443   void CompileDexFile(jobject class_loader,
    444                       const DexFile& dex_file,
    445                       const std::vector<const DexFile*>& dex_files,
    446                       ThreadPool* thread_pool,
    447                       size_t thread_count,
    448                       TimingLogger* timings)
    449       REQUIRES(!Locks::mutator_lock_);
    450 
    451   bool MayInlineInternal(const DexFile* inlined_from, const DexFile* inlined_into) const;
    452 
    453   void InitializeThreadPools();
    454   void FreeThreadPools();
    455   void CheckThreadPools();
    456 
    457   bool RequiresConstructorBarrier(const DexFile& dex_file, uint16_t class_def_idx) const;
    458 
    459   const CompilerOptions* const compiler_options_;
    460   VerificationResults* const verification_results_;
    461 
    462   std::unique_ptr<Compiler> compiler_;
    463   Compiler::Kind compiler_kind_;
    464 
    465   const InstructionSet instruction_set_;
    466   const InstructionSetFeatures* const instruction_set_features_;
    467 
    468   // All class references that require constructor barriers. If the class reference is not in the
    469   // set then the result has not yet been computed.
    470   mutable ReaderWriterMutex requires_constructor_barrier_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    471   std::map<ClassReference, bool> requires_constructor_barrier_
    472       GUARDED_BY(requires_constructor_barrier_lock_);
    473 
    474   typedef SafeMap<const ClassReference, CompiledClass*> ClassTable;
    475   // All class references that this compiler has compiled.
    476   mutable Mutex compiled_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    477   ClassTable compiled_classes_ GUARDED_BY(compiled_classes_lock_);
    478 
    479   typedef AtomicMethodRefMap<CompiledMethod*> MethodTable;
    480 
    481  private:
    482   // All method references that this compiler has compiled.
    483   MethodTable compiled_methods_;
    484 
    485   // Number of non-relative patches in all compiled methods. These patches need space
    486   // in the .oat_patches ELF section if requested in the compiler options.
    487   Atomic<size_t> non_relative_linker_patch_count_;
    488 
    489   // If image_ is true, specifies the classes that will be included in the image.
    490   // Note if image_classes_ is null, all classes are included in the image.
    491   std::unique_ptr<std::unordered_set<std::string>> image_classes_;
    492 
    493   // Specifies the classes that will be compiled. Note that if classes_to_compile_ is null,
    494   // all classes are eligible for compilation (duplication filters etc. will still apply).
    495   // This option may be restricted to the boot image, depending on a flag in the implementation.
    496   std::unique_ptr<std::unordered_set<std::string>> classes_to_compile_;
    497 
    498   // Specifies the methods that will be compiled. Note that if methods_to_compile_ is null,
    499   // all methods are eligible for compilation (compilation filters etc. will still apply).
    500   // This option may be restricted to the boot image, depending on a flag in the implementation.
    501   std::unique_ptr<std::unordered_set<std::string>> methods_to_compile_;
    502 
    503   bool had_hard_verifier_failure_;
    504 
    505   // A thread pool that can (potentially) run tasks in parallel.
    506   std::unique_ptr<ThreadPool> parallel_thread_pool_;
    507   size_t parallel_thread_count_;
    508 
    509   // A thread pool that guarantees running single-threaded on the main thread.
    510   std::unique_ptr<ThreadPool> single_thread_pool_;
    511 
    512   class AOTCompilationStats;
    513   std::unique_ptr<AOTCompilationStats> stats_;
    514 
    515   bool dump_stats_;
    516   const bool dump_passes_;
    517 
    518   CumulativeLogger* const timings_logger_;
    519 
    520   typedef void (*CompilerCallbackFn)(CompilerDriver& driver);
    521   typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver);
    522 
    523   void* compiler_context_;
    524 
    525   bool support_boot_image_fixup_;
    526 
    527   // List of dex files that will be stored in the oat file.
    528   const std::vector<const DexFile*>* dex_files_for_oat_file_;
    529 
    530   CompiledMethodStorage compiled_method_storage_;
    531 
    532   // Info for profile guided compilation.
    533   const ProfileCompilationInfo* const profile_compilation_info_;
    534 
    535   size_t max_arena_alloc_;
    536 
    537   // Data for delaying dex-to-dex compilation.
    538   Mutex dex_to_dex_references_lock_;
    539   // In the first phase, dex_to_dex_references_ collects methods for dex-to-dex compilation.
    540   class DexFileMethodSet;
    541   std::vector<DexFileMethodSet> dex_to_dex_references_ GUARDED_BY(dex_to_dex_references_lock_);
    542   // In the second phase, current_dex_to_dex_methods_ points to the BitVector with method
    543   // indexes for dex-to-dex compilation in the current dex file.
    544   const BitVector* current_dex_to_dex_methods_;
    545 
    546   friend class CompileClassVisitor;
    547   friend class DexToDexDecompilerTest;
    548   friend class verifier::VerifierDepsTest;
    549   DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
    550 };
    551 
    552 }  // namespace art
    553 
    554 #endif  // ART_COMPILER_DRIVER_COMPILER_DRIVER_H_
    555