diff options
author | 2015-12-01 16:28:10 +0000 | |
---|---|---|
committer | 2015-12-01 16:28:10 +0000 | |
commit | c88ef3a10c474045a3476a02ae75d07ddd3230b7 (patch) | |
tree | cd23e1e0a3cea10cc9a9ae8269a01f75ada8ef0e /compiler/optimizing/builder.cc | |
parent | 4db0bf9c4db6a09716c3388b7d2f88d534470339 (diff) |
Revert "Don't use the compiler driver for method resolution."
Fails 425 in debuggable mode.
This reverts commit 4db0bf9c4db6a09716c3388b7d2f88d534470339.
Change-Id: I346df8f75674564fc4fb241c60f23e250fc7f0a7
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r-- | compiler/optimizing/builder.cc | 150 |
1 files changed, 43 insertions, 107 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 8e75bdcdc9..d7754e8ea9 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -735,79 +735,6 @@ static InvokeType GetInvokeTypeFromOpCode(Instruction::Code opcode) { } } -ArtMethod* HGraphBuilder::ResolveMethod(uint16_t method_idx, InvokeType invoke_type) { - ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<2> hs(soa.Self()); - - ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); - Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); - - ArtMethod* resolved_method = class_linker->ResolveMethod( - *dex_compilation_unit_->GetDexFile(), - method_idx, - dex_compilation_unit_->GetDexCache(), - class_loader, - /* referrer */ nullptr, - invoke_type); - - if (UNLIKELY(resolved_method == nullptr)) { - // Clean up any exception left by type resolution. - soa.Self()->ClearException(); - return nullptr; - } - - // Check access. The class linker has a fast path for looking into the dex cache - // and does not check the access if it hits it. - if (compiling_class.Get() == nullptr) { - if (!resolved_method->IsPublic()) { - return nullptr; - } - } else if (!compiling_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(), - resolved_method, - dex_compilation_unit_->GetDexCache().Get(), - method_idx)) { - return nullptr; - } - - // We have to special case the invoke-super case, as ClassLinker::ResolveMethod does not. - // We need to look at the referrer's super class vtable. - if (invoke_type == kSuper) { - if (compiling_class.Get() == nullptr) { - // Invoking a super method requires knowing the actual super class. If we did not resolve - // the compiling method's declaring class (which only happens for ahead of time compilation), - // bail out. - DCHECK(Runtime::Current()->IsAotCompiler()); - return nullptr; - } - uint16_t vtable_index = resolved_method->GetMethodIndex(); - ArtMethod* actual_method = compiling_class->GetSuperClass()->GetVTableEntry( - vtable_index, class_linker->GetImagePointerSize()); - if (actual_method != resolved_method && - !IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) { - // TODO: The actual method could still be referenced in the current dex file, so we - // could try locating it. - // TODO: Remove the dex_file restriction. - return nullptr; - } - if (!actual_method->IsInvokable()) { - // Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub - // could resolve the callee to the wrong method. - return nullptr; - } - resolved_method = actual_method; - } - - // Check for incompatible class changes. The class linker has a fast path for - // looking into the dex cache and does not check incompatible class changes if it hits it. - if (resolved_method->CheckIncompatibleClassChange(invoke_type)) { - return nullptr; - } - - return resolved_method; -} - bool HGraphBuilder::BuildInvoke(const Instruction& instruction, uint32_t dex_pc, uint32_t method_idx, @@ -815,18 +742,22 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, bool is_range, uint32_t* args, uint32_t register_index) { - InvokeType invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode()); + InvokeType original_invoke_type = GetInvokeTypeFromOpCode(instruction.Opcode()); + InvokeType optimized_invoke_type = original_invoke_type; const char* descriptor = dex_file_->GetMethodShorty(method_idx); Primitive::Type return_type = Primitive::GetType(descriptor[0]); // Remove the return type from the 'proto'. size_t number_of_arguments = strlen(descriptor) - 1; - if (invoke_type != kStatic) { // instance call + if (original_invoke_type != kStatic) { // instance call // One extra argument for 'this'. number_of_arguments++; } MethodReference target_method(dex_file_, method_idx); + int32_t table_index = 0; + uintptr_t direct_code = 0; + uintptr_t direct_method = 0; // Special handling for string init. int32_t string_init_offset = 0; @@ -849,7 +780,7 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, method_idx, target_method, dispatch_info, - invoke_type, + original_invoke_type, kStatic /* optimized_invoke_type */, HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit); return HandleStringInit(invoke, @@ -860,16 +791,23 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, descriptor); } - ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type); - - if (resolved_method == nullptr) { + // Handle unresolved methods. + if (!compiler_driver_->ComputeInvokeInfo(dex_compilation_unit_, + dex_pc, + true /* update_stats */, + true /* enable_devirtualization */, + &optimized_invoke_type, + &target_method, + &table_index, + &direct_code, + &direct_method)) { MaybeRecordStat(MethodCompilationStat::kUnresolvedMethod); HInvoke* invoke = new (arena_) HInvokeUnresolved(arena_, number_of_arguments, return_type, dex_pc, method_idx, - invoke_type); + original_invoke_type); return HandleInvoke(invoke, number_of_vreg_arguments, args, @@ -879,26 +817,21 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, nullptr /* clinit_check */); } + // Handle resolved methods (non string init). + + DCHECK(optimized_invoke_type != kSuper); + // Potential class initialization check, in the case of a static method call. HClinitCheck* clinit_check = nullptr; HInvoke* invoke = nullptr; - if (invoke_type == kDirect || invoke_type == kStatic || invoke_type == kSuper) { + if (optimized_invoke_type == kDirect || optimized_invoke_type == kStatic) { // By default, consider that the called method implicitly requires // an initialization check of its declaring method. HInvokeStaticOrDirect::ClinitCheckRequirement clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit; - ScopedObjectAccess soa(Thread::Current()); - if (invoke_type == kStatic) { - clinit_check = ProcessClinitCheckForInvoke( - dex_pc, resolved_method, method_idx, &clinit_check_requirement); - } else if (invoke_type == kSuper) { - if (IsSameDexFile(*resolved_method->GetDexFile(), *dex_compilation_unit_->GetDexFile())) { - // Update the target method to the one resolved. Note that this may be a no-op if - // we resolved to the method referenced by the instruction. - method_idx = resolved_method->GetDexMethodIndex(); - target_method = MethodReference(dex_file_, method_idx); - } + if (optimized_invoke_type == kStatic) { + clinit_check = ProcessClinitCheckForInvoke(dex_pc, method_idx, &clinit_check_requirement); } HInvokeStaticOrDirect::DispatchInfo dispatch_info = { @@ -914,26 +847,24 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, method_idx, target_method, dispatch_info, - invoke_type, - invoke_type, + original_invoke_type, + optimized_invoke_type, clinit_check_requirement); - } else if (invoke_type == kVirtual) { - ScopedObjectAccess soa(Thread::Current()); // Needed for the method index + } else if (optimized_invoke_type == kVirtual) { invoke = new (arena_) HInvokeVirtual(arena_, number_of_arguments, return_type, dex_pc, method_idx, - resolved_method->GetMethodIndex()); + table_index); } else { - DCHECK_EQ(invoke_type, kInterface); - ScopedObjectAccess soa(Thread::Current()); // Needed for the method index + DCHECK_EQ(optimized_invoke_type, kInterface); invoke = new (arena_) HInvokeInterface(arena_, number_of_arguments, return_type, dex_pc, method_idx, - resolved_method->GetDexMethodIndex()); + table_index); } return HandleInvoke(invoke, @@ -1031,18 +962,23 @@ bool HGraphBuilder::IsInitialized(Handle<mirror::Class> cls) const { HClinitCheck* HGraphBuilder::ProcessClinitCheckForInvoke( uint32_t dex_pc, - ArtMethod* resolved_method, uint32_t method_idx, HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement) { - const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); - Thread* self = Thread::Current(); - StackHandleScope<4> hs(self); + ScopedObjectAccess soa(Thread::Current()); + StackHandleScope<5> hs(soa.Self()); Handle<mirror::DexCache> dex_cache(hs.NewHandle( dex_compilation_unit_->GetClassLinker()->FindDexCache( - self, *dex_compilation_unit_->GetDexFile()))); + soa.Self(), *dex_compilation_unit_->GetDexFile()))); + Handle<mirror::ClassLoader> class_loader(hs.NewHandle( + soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); + ArtMethod* resolved_method = compiler_driver_->ResolveMethod( + soa, dex_cache, class_loader, dex_compilation_unit_, method_idx, InvokeType::kStatic); + + DCHECK(resolved_method != nullptr); + + const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); Handle<mirror::DexCache> outer_dex_cache(hs.NewHandle( - outer_compilation_unit_->GetClassLinker()->FindDexCache( - self, outer_dex_file))); + outer_compilation_unit_->GetClassLinker()->FindDexCache(soa.Self(), outer_dex_file))); Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); Handle<mirror::Class> resolved_method_class(hs.NewHandle(resolved_method->GetDeclaringClass())); |