diff options
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 { |