diff options
| author | 2018-01-25 18:44:30 +0000 | |
|---|---|---|
| committer | 2018-01-25 18:44:30 +0000 | |
| commit | 816ca4d083ae9c439be587a0192906fe1510a123 (patch) | |
| tree | c928fcb0c57e3e277bf004ba24b0f893c8915b09 /compiler/driver/compiler_driver.cc | |
| parent | b7b2957f79a33fc15ee48ff6709e9b080a266b07 (diff) | |
| parent | bff7a52e2c6c9e988c3ed1f12a2da0fa5fd37cfb (diff) | |
Merge "Revert "Compiler changes for bitstring based type checks.""
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 114 | 
1 files changed, 12 insertions, 102 deletions
| diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 3720dda0f8..60537fd5c8 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -680,8 +680,7 @@ void CompilerDriver::Resolve(jobject class_loader,  // TODO: Collect the relevant string indices in parallel, then allocate them sequentially in a  //       stable order. -static void ResolveConstStrings(ClassLinker* class_linker, -                                Handle<mirror::DexCache> dex_cache, +static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache,                                  const DexFile& dex_file,                                  const DexFile::CodeItem* code_item)        REQUIRES_SHARED(Locks::mutator_lock_) { @@ -690,6 +689,7 @@ static void ResolveConstStrings(ClassLinker* class_linker,      return;    } +  ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();    for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) {      switch (inst->Opcode()) {        case Instruction::CONST_STRING: @@ -737,105 +737,22 @@ static void ResolveConstStrings(CompilerDriver* driver,            dex_file->StringByTypeIdx(class_def.class_idx_));        if (!compilation_enabled) {          // Compilation is skipped, do not resolve const-string in code of this class. -        // FIXME: Make sure that inlining honors this. b/26687569 +        // TODO: Make sure that inlining honors this.          continue;        }        // Direct and virtual methods. +      int64_t previous_method_idx = -1;        while (it.HasNextMethod()) { -        ResolveConstStrings(class_linker, dex_cache, *dex_file, it.GetMethodCodeItem()); -        it.Next(); -      } -      DCHECK(!it.HasNext()); -    } -  } -} - -// Initialize type check bit strings for check-cast and instance-of in the code. Done to have -// deterministic allocation behavior. Right now this is single-threaded for simplicity. -// TODO: Collect the relevant type indices in parallel, then process them sequentially in a -//       stable order. - -static void InitializeTypeCheckBitstrings(CompilerDriver* driver, -                                          ClassLinker* class_linker, -                                          Handle<mirror::DexCache> dex_cache, -                                          const DexFile& dex_file, -                                          const DexFile::CodeItem* code_item) -      REQUIRES_SHARED(Locks::mutator_lock_) { -  if (code_item == nullptr) { -    // Abstract or native method. -    return; -  } - -  for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) { -    switch (inst->Opcode()) { -      case Instruction::CHECK_CAST: -      case Instruction::INSTANCE_OF: { -        dex::TypeIndex type_index( -            (inst->Opcode() == Instruction::CHECK_CAST) ? inst->VRegB_21c() : inst->VRegC_22c()); -        const char* descriptor = dex_file.StringByTypeIdx(type_index); -        // We currently do not use the bitstring type check for array or final (including -        // primitive) classes. We may reconsider this in future if it's deemed to be beneficial. -        // And we cannot use it for classes outside the boot image as we do not know the runtime -        // value of their bitstring when compiling (it may not even get assigned at runtime). -        if (descriptor[0] == 'L' && driver->IsImageClass(descriptor)) { -          ObjPtr<mirror::Class> klass = -              class_linker->LookupResolvedType(type_index, -                                               dex_cache.Get(), -                                               /* class_loader */ nullptr); -          CHECK(klass != nullptr) << descriptor << " should have been previously resolved."; -          // Now assign the bitstring if the class is not final. Keep this in sync with sharpening. -          if (!klass->IsFinal()) { -            MutexLock subtype_check_lock(Thread::Current(), *Locks::subtype_check_lock_); -            SubtypeCheck<ObjPtr<mirror::Class>>::EnsureAssigned(klass); -          } +        uint32_t method_idx = it.GetMemberIndex(); +        if (method_idx == previous_method_idx) { +          // smali can create dex files with two encoded_methods sharing the same method_idx +          // http://code.google.com/p/smali/issues/detail?id=119 +          it.Next(); +          continue;          } -        break; -      } - -      default: -        break; -    } -  } -} - -static void InitializeTypeCheckBitstrings(CompilerDriver* driver, -                                          const std::vector<const DexFile*>& dex_files, -                                          TimingLogger* timings) { -  ScopedObjectAccess soa(Thread::Current()); -  StackHandleScope<1> hs(soa.Self()); -  ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); -  MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr)); - -  for (const DexFile* dex_file : dex_files) { -    dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file)); -    TimingLogger::ScopedTiming t("Initialize type check bitstrings", timings); - -    size_t class_def_count = dex_file->NumClassDefs(); -    for (size_t class_def_index = 0; class_def_index < class_def_count; ++class_def_index) { -      const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); - -      const uint8_t* class_data = dex_file->GetClassData(class_def); -      if (class_data == nullptr) { -        // empty class, probably a marker interface -        continue; -      } - -      ClassDataItemIterator it(*dex_file, class_data); -      it.SkipAllFields(); - -      bool compilation_enabled = driver->IsClassToCompile( -          dex_file->StringByTypeIdx(class_def.class_idx_)); -      if (!compilation_enabled) { -        // Compilation is skipped, do not look for type checks in code of this class. -        // FIXME: Make sure that inlining honors this. b/26687569 -        continue; -      } - -      // Direct and virtual methods. -      while (it.HasNextMethod()) { -        InitializeTypeCheckBitstrings( -            driver, class_linker, dex_cache, *dex_file, it.GetMethodCodeItem()); +        previous_method_idx = method_idx; +        ResolveConstStrings(dex_cache, *dex_file, it.GetMethodCodeItem());          it.Next();        }        DCHECK(!it.HasNext()); @@ -937,13 +854,6 @@ void CompilerDriver::PreCompile(jobject class_loader,    UpdateImageClasses(timings);    VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString(false); - -  if (GetCompilerOptions().IsForceDeterminism() && GetCompilerOptions().IsBootImage()) { -    // Initialize type check bit string used by check-cast and instanceof. -    // Do this now to have a deterministic image. -    // Note: This is done after UpdateImageClasses() at it relies on the image classes to be final. -    InitializeTypeCheckBitstrings(this, dex_files, timings); -  }  }  bool CompilerDriver::IsImageClass(const char* descriptor) const { |