summaryrefslogtreecommitdiffstats
path: root/compiler/driver
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/driver')
-rw-r--r--compiler/driver/compiler_driver-inl.h52
-rw-r--r--compiler/driver/compiler_driver.cc113
-rw-r--r--compiler/driver/compiler_driver.h18
-rw-r--r--compiler/driver/compiler_driver_test.cc29
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);