diff options
Diffstat (limited to 'compiler/dex/mir_method_info.cc')
-rw-r--r-- | compiler/dex/mir_method_info.cc | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc deleted file mode 100644 index c250bd9fd2..0000000000 --- a/compiler/dex/mir_method_info.cc +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -# include "mir_method_info.h" - -#include "dex/compiler_ir.h" -#include "dex/quick/dex_file_method_inliner.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" -#include "dex/verified_method.h" -#include "driver/compiler_driver.h" -#include "driver/dex_compilation_unit.h" -#include "driver/compiler_driver-inl.h" -#include "driver/compiler_options.h" -#include "mirror/class_loader.h" // Only to allow casts in Handle<ClassLoader>. -#include "mirror/dex_cache.h" // Only to allow casts in Handle<DexCache>. -#include "scoped_thread_state_change.h" -#include "handle_scope-inl.h" - -namespace art { - -void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver, - const DexCompilationUnit* mUnit, - MirMethodLoweringInfo* method_infos, size_t count) { - if (kIsDebugBuild) { - DCHECK(method_infos != nullptr); - DCHECK_NE(count, 0u); - for (auto it = method_infos, end = method_infos + count; it != end; ++it) { - MirMethodLoweringInfo unresolved(it->MethodIndex(), it->GetInvokeType(), it->IsQuickened()); - unresolved.declaring_dex_file_ = it->declaring_dex_file_; - unresolved.vtable_idx_ = it->vtable_idx_; - if (it->target_dex_file_ != nullptr) { - unresolved.target_dex_file_ = it->target_dex_file_; - unresolved.target_method_idx_ = it->target_method_idx_; - } - if (kIsDebugBuild) { - unresolved.CheckEquals(*it); - } - } - } - - // We're going to resolve methods and check access in a tight loop. It's better to hold - // the lock and needed references once than re-acquiring them again and again. - ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<4> hs(soa.Self()); - Handle<mirror::DexCache> dex_cache(hs.NewHandle(compiler_driver->GetDexCache(mUnit))); - Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(compiler_driver->GetClassLoader(soa, mUnit))); - Handle<mirror::Class> referrer_class(hs.NewHandle( - compiler_driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit))); - auto current_dex_cache(hs.NewHandle<mirror::DexCache>(nullptr)); - // Even if the referrer class is unresolved (i.e. we're compiling a method without class - // definition) we still want to resolve methods and record all available info. - Runtime* const runtime = Runtime::Current(); - const DexFile* const dex_file = mUnit->GetDexFile(); - const bool use_jit = runtime->UseJit(); - const VerifiedMethod* const verified_method = mUnit->GetVerifiedMethod(); - DexFileToMethodInlinerMap* inliner_map = compiler_driver->GetMethodInlinerMap(); - DexFileMethodInliner* default_inliner = - (inliner_map != nullptr) ? inliner_map->GetMethodInliner(dex_file) : nullptr; - - for (auto it = method_infos, end = method_infos + count; it != end; ++it) { - // For quickened invokes, the dex method idx is actually the mir offset. - if (it->IsQuickened()) { - const auto* dequicken_ref = verified_method->GetDequickenIndex(it->method_idx_); - CHECK(dequicken_ref != nullptr); - it->target_dex_file_ = dequicken_ref->dex_file; - it->target_method_idx_ = dequicken_ref->index; - } - // Remember devirtualized invoke target and set the called method to the default. - MethodReference devirt_ref(it->target_dex_file_, it->target_method_idx_); - MethodReference* devirt_target = (it->target_dex_file_ != nullptr) ? &devirt_ref : nullptr; - InvokeType invoke_type = it->GetInvokeType(); - ArtMethod* resolved_method = nullptr; - - bool string_init = false; - if (default_inliner->IsStringInitMethodIndex(it->MethodIndex())) { - string_init = true; - invoke_type = kDirect; - } - - if (!it->IsQuickened()) { - it->target_dex_file_ = dex_file; - it->target_method_idx_ = it->MethodIndex(); - current_dex_cache.Assign(dex_cache.Get()); - resolved_method = compiler_driver->ResolveMethod(soa, dex_cache, class_loader, mUnit, - it->target_method_idx_, invoke_type, true); - } else { - // The method index is actually the dex PC in this case. - // Calculate the proper dex file and target method idx. - - // We must be in JIT mode if we get here. - CHECK(use_jit); - - // The invoke type better be virtual, except for the string init special case above. - CHECK_EQ(invoke_type, string_init ? kDirect : kVirtual); - // Don't devirt if we are in a different dex file since we can't have direct invokes in - // another dex file unless we always put a direct / patch pointer. - devirt_target = nullptr; - current_dex_cache.Assign(runtime->GetClassLinker()->FindDexCache( - soa.Self(), *it->target_dex_file_)); - CHECK(current_dex_cache.Get() != nullptr); - DexCompilationUnit cu( - mUnit->GetCompilationUnit(), mUnit->GetClassLoader(), mUnit->GetClassLinker(), - *it->target_dex_file_, nullptr /* code_item not used */, 0u /* class_def_idx not used */, - it->target_method_idx_, 0u /* access_flags not used */, - nullptr /* verified_method not used */, - current_dex_cache); - resolved_method = compiler_driver->ResolveMethod(soa, current_dex_cache, class_loader, &cu, - it->target_method_idx_, invoke_type, false); - if (resolved_method == nullptr) { - // If the method is null then it should be a miranda method, in this case try - // re-loading it, this time as an interface method. The actual miranda method is in the - // vtable, but it will resolve to an interface method. - resolved_method = compiler_driver->ResolveMethod( - soa, current_dex_cache, class_loader, &cu, it->target_method_idx_, kInterface, false); - CHECK(resolved_method != nullptr); - } - if (resolved_method != nullptr) { - // Since this was a dequickened virtual, it is guaranteed to be resolved. However, it may be - // resolved to an interface method. If this is the case then change the invoke type to - // interface with the assumption that sharp_type will be kVirtual. - if (resolved_method->GetInvokeType() == kInterface) { - it->flags_ = (it->flags_ & ~(kInvokeTypeMask << kBitInvokeTypeBegin)) | - (static_cast<uint16_t>(kInterface) << kBitInvokeTypeBegin); - } - } - } - if (UNLIKELY(resolved_method == nullptr)) { - continue; - } - - compiler_driver->GetResolvedMethodDexFileLocation(resolved_method, - &it->declaring_dex_file_, &it->declaring_class_idx_, &it->declaring_method_idx_); - if (!it->IsQuickened()) { - // For quickened invoke virtuals we may have desharpened to an interface method which - // wont give us the right method index, in this case blindly dispatch or else we can't - // compile the method. Converting the invoke to interface dispatch doesn't work since we - // have no way to get the dex method index for quickened invoke virtuals in the interface - // trampolines. - it->vtable_idx_ = - compiler_driver->GetResolvedMethodVTableIndex(resolved_method, invoke_type); - } - - MethodReference target_method(it->target_dex_file_, it->target_method_idx_); - int fast_path_flags = compiler_driver->IsFastInvoke( - soa, current_dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method, - &invoke_type, &target_method, devirt_target, &it->direct_code_, &it->direct_method_); - const bool is_referrers_class = referrer_class.Get() == resolved_method->GetDeclaringClass(); - const bool is_class_initialized = - compiler_driver->IsMethodsClassInitialized(referrer_class.Get(), resolved_method); - - // Check if the target method is intrinsic or special. - InlineMethodFlags is_intrinsic_or_special = kNoInlineMethodFlags; - if (inliner_map != nullptr) { - auto* inliner = (target_method.dex_file == dex_file) - ? default_inliner - : inliner_map->GetMethodInliner(target_method.dex_file); - is_intrinsic_or_special = inliner->IsIntrinsicOrSpecial(target_method.dex_method_index); - } - - uint16_t other_flags = it->flags_ & - ~(kFlagFastPath | kFlagIsIntrinsic | kFlagIsSpecial | kFlagClassIsInitialized | - (kInvokeTypeMask << kBitSharpTypeBegin)); - it->flags_ = other_flags | - // String init path is a special always-fast path. - (fast_path_flags != 0 || string_init ? kFlagFastPath : 0u) | - ((is_intrinsic_or_special & kInlineIntrinsic) != 0 ? kFlagIsIntrinsic : 0u) | - ((is_intrinsic_or_special & kInlineSpecial) != 0 ? kFlagIsSpecial : 0u) | - (static_cast<uint16_t>(invoke_type) << kBitSharpTypeBegin) | - (is_referrers_class ? kFlagIsReferrersClass : 0u) | - (is_class_initialized ? kFlagClassIsInitialized : 0u); - it->target_dex_file_ = target_method.dex_file; - it->target_method_idx_ = target_method.dex_method_index; - it->stats_flags_ = fast_path_flags; - if (string_init) { - it->direct_code_ = 0; - } - } -} - -} // namespace art |