diff options
Diffstat (limited to 'compiler/driver')
-rw-r--r-- | compiler/driver/compiler_driver-inl.h | 52 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 113 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 18 | ||||
-rw-r--r-- | compiler/driver/compiler_driver_test.cc | 29 |
4 files changed, 109 insertions, 103 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index e54cbf6fb6..b25e967609 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -20,8 +20,9 @@ #include "compiler_driver.h" #include "art_field-inl.h" +#include "art_method-inl.h" +#include "class_linker-inl.h" #include "dex_compilation_unit.h" -#include "mirror/art_method-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" #include "scoped_thread_state_change.h" @@ -133,7 +134,7 @@ inline bool CompilerDriver::CanAccessResolvedMember(mirror::Class* referrer_clas ArtMember* member ATTRIBUTE_UNUSED, mirror::DexCache* dex_cache ATTRIBUTE_UNUSED, uint32_t field_idx ATTRIBUTE_UNUSED) { - // Not defined for ArtMember values other than ArtField or mirror::ArtMethod. + // Not defined for ArtMember values other than ArtField or ArtMethod. UNREACHABLE(); } @@ -147,10 +148,10 @@ inline bool CompilerDriver::CanAccessResolvedMember<ArtField>(mirror::Class* ref } template <> -inline bool CompilerDriver::CanAccessResolvedMember<mirror::ArtMethod>( +inline bool CompilerDriver::CanAccessResolvedMember<ArtMethod>( mirror::Class* referrer_class, mirror::Class* access_to, - mirror::ArtMethod* method, + ArtMethod* method, mirror::DexCache* dex_cache, uint32_t field_idx) { return referrer_class->CanAccessResolvedMethod(access_to, method, dex_cache, field_idx); @@ -217,7 +218,7 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField( inline bool CompilerDriver::IsClassOfStaticMethodAvailableToReferrer( mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtMethod* resolved_method, uint16_t method_idx, uint32_t* storage_index) { + ArtMethod* resolved_method, uint16_t method_idx, uint32_t* storage_index) { std::pair<bool, bool> result = IsClassOfStaticMemberAvailableToReferrer( dex_cache, referrer_class, resolved_method, method_idx, storage_index); // Only the first member of `result` is meaningful, as there is no @@ -239,15 +240,14 @@ inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referr return fields_class == referrer_class || fields_class->IsInitialized(); } -inline mirror::ArtMethod* CompilerDriver::ResolveMethod( +inline ArtMethod* CompilerDriver::ResolveMethod( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); - mirror::ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod( - *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), - invoke_type); + ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod( + *mUnit->GetDexFile(), method_idx, dex_cache, class_loader, nullptr, invoke_type); DCHECK_EQ(resolved_method == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(resolved_method == nullptr)) { // Clean up any exception left by type resolution. @@ -263,7 +263,7 @@ inline mirror::ArtMethod* CompilerDriver::ResolveMethod( } inline void CompilerDriver::GetResolvedMethodDexFileLocation( - mirror::ArtMethod* resolved_method, const DexFile** declaring_dex_file, + ArtMethod* resolved_method, const DexFile** declaring_dex_file, uint16_t* declaring_class_idx, uint16_t* declaring_method_idx) { mirror::Class* declaring_class = resolved_method->GetDeclaringClass(); *declaring_dex_file = declaring_class->GetDexCache()->GetDexFile(); @@ -272,7 +272,7 @@ inline void CompilerDriver::GetResolvedMethodDexFileLocation( } inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex( - mirror::ArtMethod* resolved_method, InvokeType type) { + ArtMethod* resolved_method, InvokeType type) { if (type == kVirtual || type == kSuper) { return resolved_method->GetMethodIndex(); } else if (type == kInterface) { @@ -285,7 +285,7 @@ inline uint16_t CompilerDriver::GetResolvedMethodVTableIndex( inline int CompilerDriver::IsFastInvoke( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, - mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type, + mirror::Class* referrer_class, ArtMethod* resolved_method, InvokeType* invoke_type, MethodReference* target_method, const MethodReference* devirt_target, uintptr_t* direct_code, uintptr_t* direct_method) { // Don't try to fast-path if we don't understand the caller's class. @@ -305,10 +305,12 @@ inline int CompilerDriver::IsFastInvoke( (*invoke_type == kVirtual) && (resolved_method->IsFinal() || methods_class->IsFinal()); // For invoke-super, ensure the vtable index will be correct to dispatch in the vtable of // the super class. + const size_t pointer_size = InstructionSetPointerSize(GetInstructionSet()); bool can_sharpen_super_based_on_type = same_dex_file && (*invoke_type == kSuper) && (referrer_class != methods_class) && referrer_class->IsSubClass(methods_class) && resolved_method->GetMethodIndex() < methods_class->GetVTableLength() && - (methods_class->GetVTableEntry(resolved_method->GetMethodIndex()) == resolved_method) && + (methods_class->GetVTableEntry( + resolved_method->GetMethodIndex(), pointer_size) == resolved_method) && !resolved_method->IsAbstract(); if (can_sharpen_virtual_based_on_type || can_sharpen_super_based_on_type) { @@ -316,7 +318,8 @@ inline int CompilerDriver::IsFastInvoke( // dex cache, check that this resolved method is where we expect it. CHECK_EQ(target_method->dex_file, mUnit->GetDexFile()); DCHECK_EQ(dex_cache.Get(), mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())); - CHECK_EQ(referrer_class->GetDexCache()->GetResolvedMethod(target_method->dex_method_index), + CHECK_EQ(referrer_class->GetDexCache()->GetResolvedMethod( + target_method->dex_method_index, pointer_size), resolved_method) << PrettyMethod(resolved_method); int stats_flags = kFlagMethodResolved; GetCodeAndMethodForDirectCall(/*out*/invoke_type, @@ -336,21 +339,18 @@ inline int CompilerDriver::IsFastInvoke( if ((*invoke_type == kVirtual || *invoke_type == kInterface) && devirt_target != nullptr) { // Post-verification callback recorded a more precise invoke target based on its type info. - mirror::ArtMethod* called_method; + ArtMethod* called_method; ClassLinker* class_linker = mUnit->GetClassLinker(); if (LIKELY(devirt_target->dex_file == mUnit->GetDexFile())) { - called_method = class_linker->ResolveMethod(*devirt_target->dex_file, - devirt_target->dex_method_index, dex_cache, - class_loader, NullHandle<mirror::ArtMethod>(), - kVirtual); + called_method = class_linker->ResolveMethod( + *devirt_target->dex_file, devirt_target->dex_method_index, dex_cache, class_loader, + nullptr, kVirtual); } else { StackHandleScope<1> hs(soa.Self()); - Handle<mirror::DexCache> target_dex_cache( - hs.NewHandle(class_linker->FindDexCache(*devirt_target->dex_file))); - called_method = class_linker->ResolveMethod(*devirt_target->dex_file, - devirt_target->dex_method_index, - target_dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), kVirtual); + auto target_dex_cache(hs.NewHandle(class_linker->FindDexCache(*devirt_target->dex_file))); + called_method = class_linker->ResolveMethod( + *devirt_target->dex_file, devirt_target->dex_method_index, target_dex_cache, + class_loader, nullptr, kVirtual); } CHECK(called_method != nullptr); CHECK(!called_method->IsAbstract()); @@ -389,7 +389,7 @@ inline int CompilerDriver::IsFastInvoke( } inline bool CompilerDriver::IsMethodsClassInitialized(mirror::Class* referrer_class, - mirror::ArtMethod* resolved_method) { + ArtMethod* resolved_method) { if (!resolved_method->IsStatic()) { return true; } diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 7cc5aae8c7..e963c12402 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -28,6 +28,7 @@ #endif #include "art_field-inl.h" +#include "art_method-inl.h" #include "base/stl_util.h" #include "base/time_utils.h" #include "base/timing_logger.h" @@ -50,8 +51,8 @@ #include "runtime.h" #include "gc/accounting/card_table-inl.h" #include "gc/accounting/heap_bitmap.h" +#include "gc/space/image_space.h" #include "gc/space/space.h" -#include "mirror/art_method-inl.h" #include "mirror/class_loader.h" #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" @@ -542,7 +543,7 @@ DexToDexCompilationLevel CompilerDriver::GetDexToDexCompilationlevel( } } -void CompilerDriver::CompileOne(Thread* self, mirror::ArtMethod* method, TimingLogger* timings) { +void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings) { DCHECK(!Runtime::Current()->IsStarted()); jobject jclass_loader; const DexFile* dex_file; @@ -586,7 +587,7 @@ void CompilerDriver::CompileOne(Thread* self, mirror::ArtMethod* method, TimingL self->TransitionFromSuspendedToRunnable(); } -CompiledMethod* CompilerDriver::CompileMethod(Thread* self, mirror::ArtMethod* method) { +CompiledMethod* CompilerDriver::CompileMethod(Thread* self, ArtMethod* method) { const uint32_t method_idx = method->GetDexMethodIndex(); const uint32_t access_flags = method->GetAccessFlags(); const InvokeType invoke_type = method->GetInvokeType(); @@ -688,8 +689,8 @@ bool CompilerDriver::IsMethodToCompile(const MethodReference& method_ref) const return methods_to_compile_->find(tmp.c_str()) != methods_to_compile_->end(); } -static void ResolveExceptionsForMethod(MutableHandle<mirror::ArtMethod> method_handle, - std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve) +static void ResolveExceptionsForMethod( + ArtMethod* method_handle, std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { const DexFile::CodeItem* code_item = method_handle->GetCodeItem(); if (code_item == nullptr) { @@ -728,17 +729,14 @@ static void ResolveExceptionsForMethod(MutableHandle<mirror::ArtMethod> method_h static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - std::set<std::pair<uint16_t, const DexFile*>>* exceptions_to_resolve = + auto* exceptions_to_resolve = reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*>>*>(arg); - StackHandleScope<1> hs(Thread::Current()); - MutableHandle<mirror::ArtMethod> method_handle(hs.NewHandle<mirror::ArtMethod>(nullptr)); - for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { - method_handle.Assign(c->GetVirtualMethod(i)); - ResolveExceptionsForMethod(method_handle, *exceptions_to_resolve); + const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + for (auto& m : c->GetVirtualMethods(pointer_size)) { + ResolveExceptionsForMethod(&m, *exceptions_to_resolve); } - for (size_t i = 0; i < c->NumDirectMethods(); ++i) { - method_handle.Assign(c->GetDirectMethod(i)); - ResolveExceptionsForMethod(method_handle, *exceptions_to_resolve); + for (auto& m : c->GetDirectMethods(pointer_size)) { + ResolveExceptionsForMethod(&m, *exceptions_to_resolve); } return true; } @@ -826,6 +824,7 @@ static void MaybeAddToImageClasses(Handle<mirror::Class> c, // Make a copy of the handle so that we don't clobber it doing Assign. MutableHandle<mirror::Class> klass(hs.NewHandle(c.Get())); std::string temp; + const size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); while (!klass->IsObjectClass()) { const char* descriptor = klass->GetDescriptor(&temp); std::pair<std::unordered_set<std::string>::iterator, bool> result = @@ -839,6 +838,12 @@ static void MaybeAddToImageClasses(Handle<mirror::Class> c, MaybeAddToImageClasses(hs2.NewHandle(mirror::Class::GetDirectInterface(self, klass, i)), image_classes); } + for (auto& m : c->GetVirtualMethods(pointer_size)) { + if (m.IsMiranda() || (true)) { + StackHandleScope<1> hs2(self); + MaybeAddToImageClasses(hs2.NewHandle(m.GetDeclaringClass()), image_classes); + } + } if (klass->IsArrayClass()) { StackHandleScope<1> hs2(self); MaybeAddToImageClasses(hs2.NewHandle(klass->GetComponentType()), image_classes); @@ -855,10 +860,7 @@ class ClinitImageUpdate { Thread* self, ClassLinker* linker, std::string* error_msg) { std::unique_ptr<ClinitImageUpdate> res(new ClinitImageUpdate(image_class_descriptors, self, linker)); - if (res->art_method_class_ == nullptr) { - *error_msg = "Could not find ArtMethod class."; - return nullptr; - } else if (res->dex_cache_class_ == nullptr) { + if (res->dex_cache_class_ == nullptr) { *error_msg = "Could not find DexCache class."; return nullptr; } @@ -903,8 +905,6 @@ class ClinitImageUpdate { old_cause_ = self->StartAssertNoThreadSuspension("Boot image closure"); // Find the interesting classes. - art_method_class_ = linker->LookupClass(self, "Ljava/lang/reflect/ArtMethod;", - ComputeModifiedUtf8Hash("Ljava/lang/reflect/ArtMethod;"), nullptr); dex_cache_class_ = linker->LookupClass(self, "Ljava/lang/DexCache;", ComputeModifiedUtf8Hash("Ljava/lang/DexCache;"), nullptr); @@ -922,7 +922,8 @@ class ClinitImageUpdate { data->image_classes_.push_back(klass); } else { // Check whether it is initialized and has a clinit. They must be kept, too. - if (klass->IsInitialized() && klass->FindClassInitializer() != nullptr) { + if (klass->IsInitialized() && klass->FindClassInitializer( + Runtime::Current()->GetClassLinker()->GetImagePointerSize()) != nullptr) { data->image_classes_.push_back(klass); } } @@ -950,9 +951,9 @@ class ClinitImageUpdate { VisitClinitClassesObject(object->GetClass()); } - // If it is not a dex cache or an ArtMethod, visit all references. + // If it is not a DexCache, visit all references. mirror::Class* klass = object->GetClass(); - if (klass != art_method_class_ && klass != dex_cache_class_) { + if (klass != dex_cache_class_) { object->VisitReferences<false /* visit class */>(*this, *this); } } @@ -960,7 +961,6 @@ class ClinitImageUpdate { mutable std::unordered_set<mirror::Object*> marked_objects_; std::unordered_set<std::string>* const image_class_descriptors_; std::vector<mirror::Class*> image_classes_; - const mirror::Class* art_method_class_; const mirror::Class* dex_cache_class_; Thread* const self_; const char* old_cause_; @@ -1334,7 +1334,7 @@ bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompila void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type, bool no_guarantee_of_dex_cache_entry, const mirror::Class* referrer_class, - mirror::ArtMethod* method, + ArtMethod* method, int* stats_flags, MethodReference* target_method, uintptr_t* direct_code, @@ -1347,6 +1347,8 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType *direct_method = 0; Runtime* const runtime = Runtime::Current(); gc::Heap* const heap = runtime->GetHeap(); + auto* cl = runtime->GetClassLinker(); + const auto pointer_size = cl->GetImagePointerSize(); bool use_dex_cache = GetCompilerOptions().GetCompilePic(); // Off by default const bool compiling_boot = heap->IsCompilingBoot(); // TODO This is somewhat hacky. We should refactor all of this invoke codepath. @@ -1375,7 +1377,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType if (runtime->UseJit()) { // If we are the JIT, then don't allow a direct call to the interpreter bridge since this will // never be updated even after we compile the method. - if (runtime->GetClassLinker()->IsQuickToInterpreterBridge( + if (cl->IsQuickToInterpreterBridge( reinterpret_cast<const void*>(compiler_->GetEntryPointOf(method)))) { use_dex_cache = true; } @@ -1389,8 +1391,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType is_in_image = IsImageClass(method->GetDeclaringClassDescriptor()); } else { is_in_image = instruction_set_ != kX86 && instruction_set_ != kX86_64 && - Runtime::Current()->GetHeap()->FindSpaceFromObject(method->GetDeclaringClass(), - false)->IsImageSpace(); + heap->FindSpaceFromObject(method->GetDeclaringClass(), false)->IsImageSpace(); } if (!is_in_image) { // We can only branch directly to Methods that are resolved in the DexCache. @@ -1403,14 +1404,14 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType bool must_use_direct_pointers = false; mirror::DexCache* dex_cache = declaring_class->GetDexCache(); if (target_method->dex_file == dex_cache->GetDexFile() && - !(runtime->UseJit() && dex_cache->GetResolvedMethod(method->GetDexMethodIndex()) == nullptr)) { + !(runtime->UseJit() && dex_cache->GetResolvedMethod( + method->GetDexMethodIndex(), pointer_size) == nullptr)) { target_method->dex_method_index = method->GetDexMethodIndex(); } else { if (no_guarantee_of_dex_cache_entry) { // See if the method is also declared in this dex cache. - uint32_t dex_method_idx = - method->FindDexMethodIndexInOtherDexFile(*target_method->dex_file, - target_method->dex_method_index); + uint32_t dex_method_idx = method->FindDexMethodIndexInOtherDexFile( + *target_method->dex_file, target_method->dex_method_index); if (dex_method_idx != DexFile::kDexNoIndex) { target_method->dex_method_index = dex_method_idx; } else { @@ -1431,7 +1432,13 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType *type = sharp_type; } } else { - bool method_in_image = heap->FindSpaceFromObject(method, false)->IsImageSpace(); + auto* image_space = heap->GetImageSpace(); + bool method_in_image = false; + if (image_space != nullptr) { + const auto& method_section = image_space->GetImageHeader().GetMethodsSection(); + method_in_image = method_section.Contains( + reinterpret_cast<uint8_t*>(method) - image_space->Begin()); + } if (method_in_image || compiling_boot || runtime->UseJit()) { // We know we must be able to get to the method in the image, so use that pointer. // In the case where we are the JIT, we can always use direct pointers since we know where @@ -1469,21 +1476,16 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui int stats_flags = 0; ScopedObjectAccess soa(Thread::Current()); // Try to resolve the method and compiling method's class. - mirror::ArtMethod* resolved_method; - mirror::Class* referrer_class; StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()))); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()))); - { - uint32_t method_idx = target_method->dex_method_index; - Handle<mirror::ArtMethod> resolved_method_handle(hs.NewHandle( - ResolveMethod(soa, dex_cache, class_loader, mUnit, method_idx, orig_invoke_type))); - referrer_class = (resolved_method_handle.Get() != nullptr) - ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr; - resolved_method = resolved_method_handle.Get(); - } + uint32_t method_idx = target_method->dex_method_index; + ArtMethod* resolved_method = ResolveMethod( + soa, dex_cache, class_loader, mUnit, method_idx, orig_invoke_type); + auto h_referrer_class = hs.NewHandle(resolved_method != nullptr ? + ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr); bool result = false; if (resolved_method != nullptr) { *vtable_idx = GetResolvedMethodVTableIndex(resolved_method, orig_invoke_type); @@ -1492,13 +1494,13 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui const MethodReference* devirt_target = mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc); stats_flags = IsFastInvoke( - soa, dex_cache, class_loader, mUnit, referrer_class, resolved_method, + soa, dex_cache, class_loader, mUnit, h_referrer_class.Get(), resolved_method, invoke_type, target_method, devirt_target, direct_code, direct_method); result = stats_flags != 0; } else { // Devirtualization not enabled. Inline IsFastInvoke(), dropping the devirtualization parts. - if (UNLIKELY(referrer_class == nullptr) || - UNLIKELY(!referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(), + if (UNLIKELY(h_referrer_class.Get() == nullptr) || + UNLIKELY(!h_referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(), resolved_method, dex_cache.Get(), target_method->dex_method_index)) || *invoke_type == kSuper) { @@ -1506,8 +1508,9 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui } else { // Sharpening failed so generate a regular resolved method dispatch. stats_flags = kFlagMethodResolved; - GetCodeAndMethodForDirectCall(invoke_type, *invoke_type, false, referrer_class, resolved_method, - &stats_flags, target_method, direct_code, direct_method); + GetCodeAndMethodForDirectCall( + invoke_type, *invoke_type, false, h_referrer_class.Get(), resolved_method, &stats_flags, + target_method, direct_code, direct_method); result = true; } } @@ -1773,20 +1776,18 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag } if (resolve_fields_and_methods) { while (it.HasNextDirectMethod()) { - mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), - dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), - it.GetMethodInvokeType(class_def)); + ArtMethod* method = class_linker->ResolveMethod( + dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr, + it.GetMethodInvokeType(class_def)); if (method == nullptr) { CheckAndClearResolveException(soa.Self()); } it.Next(); } while (it.HasNextVirtualMethod()) { - mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), - dex_cache, class_loader, - NullHandle<mirror::ArtMethod>(), - it.GetMethodInvokeType(class_def)); + ArtMethod* method = class_linker->ResolveMethod( + dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr, + it.GetMethodInvokeType(class_def)); if (method == nullptr) { CheckAndClearResolveException(soa.Self()); } diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 2cc2409a34..68c905eb22 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -116,11 +116,11 @@ class CompilerDriver { TimingLogger* timings) LOCKS_EXCLUDED(Locks::mutator_lock_); - CompiledMethod* CompileMethod(Thread* self, mirror::ArtMethod*) + CompiledMethod* CompileMethod(Thread* self, ArtMethod*) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) WARN_UNUSED; // Compile a single Method. - void CompileOne(Thread* self, mirror::ArtMethod* method, TimingLogger* timings) + void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); VerificationResults* GetVerificationResults() const { @@ -288,7 +288,7 @@ class CompilerDriver { // return DexFile::kDexNoIndex through `storage_index`. bool IsClassOfStaticMethodAvailableToReferrer(mirror::DexCache* dex_cache, mirror::Class* referrer_class, - mirror::ArtMethod* resolved_method, + ArtMethod* resolved_method, uint16_t method_idx, uint32_t* storage_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -303,7 +303,7 @@ class CompilerDriver { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Resolve a method. Returns null on failure, including incompatible class change. - mirror::ArtMethod* ResolveMethod( + ArtMethod* ResolveMethod( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true) @@ -311,13 +311,13 @@ class CompilerDriver { // Get declaration location of a resolved field. void GetResolvedMethodDexFileLocation( - mirror::ArtMethod* resolved_method, const DexFile** declaring_dex_file, + ArtMethod* resolved_method, const DexFile** declaring_dex_file, uint16_t* declaring_class_idx, uint16_t* declaring_method_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get the index in the vtable of the method. uint16_t GetResolvedMethodVTableIndex( - mirror::ArtMethod* resolved_method, InvokeType type) + ArtMethod* resolved_method, InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Can we fast-path an INVOKE? If no, returns 0. If yes, returns a non-zero opaque flags value @@ -325,7 +325,7 @@ class CompilerDriver { int IsFastInvoke( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, - mirror::Class* referrer_class, mirror::ArtMethod* resolved_method, InvokeType* invoke_type, + mirror::Class* referrer_class, ArtMethod* resolved_method, InvokeType* invoke_type, MethodReference* target_method, const MethodReference* devirt_target, uintptr_t* direct_code, uintptr_t* direct_method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -333,7 +333,7 @@ class CompilerDriver { // Is method's class initialized for an invoke? // For static invokes to determine whether we need to consider potential call to <clinit>(). // For non-static invokes, assuming a non-null reference, the class is always initialized. - bool IsMethodsClassInitialized(mirror::Class* referrer_class, mirror::ArtMethod* resolved_method) + bool IsMethodsClassInitialized(mirror::Class* referrer_class, ArtMethod* resolved_method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Get the layout of dex cache arrays for a dex file. Returns invalid layout if the @@ -526,7 +526,7 @@ class CompilerDriver { InvokeType sharp_type, bool no_guarantee_of_dex_cache_entry, const mirror::Class* referrer_class, - mirror::ArtMethod* method, + ArtMethod* method, /*out*/int* stats_flags, MethodReference* target_method, uintptr_t* direct_code, uintptr_t* direct_method) diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index 5085f32aec..ba03f5a5d4 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -20,11 +20,11 @@ #include <stdio.h> #include <memory> +#include "art_method-inl.h" #include "class_linker-inl.h" #include "common_compiler_test.h" #include "dex_file.h" #include "gc/heap.h" -#include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" @@ -85,11 +85,12 @@ class CompilerDriverTest : public CommonCompilerTest { hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader); CHECK(c != nullptr); - for (size_t j = 0; j < c->NumDirectMethods(); j++) { - MakeExecutable(c->GetDirectMethod(j)); + const auto pointer_size = class_linker->GetImagePointerSize(); + for (auto& m : c->GetDirectMethods(pointer_size)) { + MakeExecutable(&m); } - for (size_t j = 0; j < c->NumVirtualMethods(); j++) { - MakeExecutable(c->GetVirtualMethod(j)); + for (auto& m : c->GetVirtualMethods(pointer_size)) { + MakeExecutable(&m); } } } @@ -120,8 +121,10 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { << " " << dex.GetTypeDescriptor(dex.GetTypeId(i)); } EXPECT_EQ(dex.NumMethodIds(), dex_cache->NumResolvedMethods()); + auto* cl = Runtime::Current()->GetClassLinker(); + auto pointer_size = cl->GetImagePointerSize(); for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { - mirror::ArtMethod* method = dex_cache->GetResolvedMethod(i); + ArtMethod* method = dex_cache->GetResolvedMethod(i, pointer_size); EXPECT_TRUE(method != nullptr) << "method_idx=" << i << " " << dex.GetMethodDeclaringClassDescriptor(dex.GetMethodId(i)) << " " << dex.GetMethodName(dex.GetMethodId(i)); @@ -131,7 +134,7 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) { } EXPECT_EQ(dex.NumFieldIds(), dex_cache->NumResolvedFields()); for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) { - ArtField* field = Runtime::Current()->GetClassLinker()->GetResolvedField(i, dex_cache); + ArtField* field = cl->GetResolvedField(i, dex_cache); EXPECT_TRUE(field != nullptr) << "field_idx=" << i << " " << dex.GetFieldDeclaringClassDescriptor(dex.GetFieldId(i)) << " " << dex.GetFieldName(dex.GetFieldId(i)); @@ -157,12 +160,15 @@ TEST_F(CompilerDriverTest, AbstractMethodErrorStub) { // Create a jobj_ of ConcreteClass, NOT AbstractClass. jclass c_class = env_->FindClass("ConcreteClass"); + jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V"); + jobject jobj_ = env_->NewObject(c_class, constructor); ASSERT_TRUE(jobj_ != nullptr); // Force non-virtual call to AbstractClass foo, will throw AbstractMethodError exception. env_->CallNonvirtualVoidMethod(jobj_, class_, mid_); + EXPECT_EQ(env_->ExceptionCheck(), JNI_TRUE); jthrowable exception = env_->ExceptionOccurred(); env_->ExceptionClear(); @@ -212,11 +218,10 @@ TEST_F(CompilerDriverMethodsTest, Selection) { std::unique_ptr<std::unordered_set<std::string>> expected(GetCompiledMethods()); - for (int32_t i = 0; static_cast<uint32_t>(i) < klass->NumDirectMethods(); i++) { - mirror::ArtMethod* m = klass->GetDirectMethod(i); - std::string name = PrettyMethod(m, true); - const void* code = - m->GetEntryPointFromQuickCompiledCodePtrSize(InstructionSetPointerSize(kRuntimeISA)); + const auto pointer_size = class_linker->GetImagePointerSize(); + for (auto& m : klass->GetDirectMethods(pointer_size)) { + std::string name = PrettyMethod(&m, true); + const void* code = m.GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); ASSERT_NE(code, nullptr); if (expected->find(name) != expected->end()) { expected->erase(name); |