Remove #include "oat_file.h" from class_linker.h .
Refactor the OatClass and OatMethod related functions from
ClassLinker to OatFile and ArtMethod, respectively. Refactor
the remaining ClassLinker dependencies on OatFile to break
the #include dependency and reduce incremental build times.
Test: m test-art-host
Change-Id: Iebc5b9f81b48fbcf79821cc827a5d7c4a0261bf6
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index c97c328..937dcee 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -283,7 +283,9 @@
// Ensure that we won't be accidentally calling quick compiled code when -Xint.
if (kIsDebugBuild && runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
CHECK(!runtime->UseJitCompilation());
- const void* oat_quick_code = runtime->GetClassLinker()->GetOatMethodQuickCodeFor(this);
+ const void* oat_quick_code = (IsNative() || !IsInvokable() || IsProxyMethod())
+ ? nullptr
+ : GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize());
CHECK(oat_quick_code == nullptr || oat_quick_code != GetEntryPointFromQuickCompiledCode())
<< "Don't call compiled code when -Xint " << PrettyMethod(this);
}
@@ -360,6 +362,80 @@
return annotations::IsMethodAnnotationPresent(this, annotation_handle, visibility);
}
+static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
+ uint16_t class_def_idx,
+ uint32_t method_idx) {
+ const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
+ const uint8_t* class_data = dex_file.GetClassData(class_def);
+ CHECK(class_data != nullptr);
+ ClassDataItemIterator it(dex_file, class_data);
+ // Skip fields
+ while (it.HasNextStaticField()) {
+ it.Next();
+ }
+ while (it.HasNextInstanceField()) {
+ it.Next();
+ }
+ // Process methods
+ size_t class_def_method_index = 0;
+ while (it.HasNextDirectMethod()) {
+ if (it.GetMemberIndex() == method_idx) {
+ return class_def_method_index;
+ }
+ class_def_method_index++;
+ it.Next();
+ }
+ while (it.HasNextVirtualMethod()) {
+ if (it.GetMemberIndex() == method_idx) {
+ return class_def_method_index;
+ }
+ class_def_method_index++;
+ it.Next();
+ }
+ DCHECK(!it.HasNext());
+ LOG(FATAL) << "Failed to find method index " << method_idx << " in " << dex_file.GetLocation();
+ UNREACHABLE();
+}
+
+static const OatFile::OatMethod FindOatMethodFor(ArtMethod* method,
+ PointerSize pointer_size,
+ bool* found)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
+ // method for direct methods (or virtual methods made direct).
+ mirror::Class* declaring_class = method->GetDeclaringClass();
+ size_t oat_method_index;
+ if (method->IsStatic() || method->IsDirect()) {
+ // Simple case where the oat method index was stashed at load time.
+ oat_method_index = method->GetMethodIndex();
+ } else {
+ // Compute the oat_method_index by search for its position in the declared virtual methods.
+ oat_method_index = declaring_class->NumDirectMethods();
+ bool found_virtual = false;
+ for (ArtMethod& art_method : declaring_class->GetVirtualMethods(pointer_size)) {
+ // Check method index instead of identity in case of duplicate method definitions.
+ if (method->GetDexMethodIndex() == art_method.GetDexMethodIndex()) {
+ found_virtual = true;
+ break;
+ }
+ oat_method_index++;
+ }
+ CHECK(found_virtual) << "Didn't find oat method index for virtual method: "
+ << PrettyMethod(method);
+ }
+ DCHECK_EQ(oat_method_index,
+ GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
+ method->GetDeclaringClass()->GetDexClassDefIndex(),
+ method->GetDexMethodIndex()));
+ OatFile::OatClass oat_class = OatFile::FindOatClass(*declaring_class->GetDexCache()->GetDexFile(),
+ declaring_class->GetDexClassDefIndex(),
+ found);
+ if (!(*found)) {
+ return OatFile::OatMethod::Invalid();
+ }
+ return oat_class.GetOatMethod(oat_method_index);
+}
+
bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params) {
auto* dex_cache = GetDexCache();
auto* dex_file = dex_cache->GetDexFile();
@@ -386,10 +462,9 @@
return true;
}
-const uint8_t* ArtMethod::GetQuickenedInfo() {
+const uint8_t* ArtMethod::GetQuickenedInfo(PointerSize pointer_size) {
bool found = false;
- OatFile::OatMethod oat_method =
- Runtime::Current()->GetClassLinker()->FindOatMethodFor(this, &found);
+ OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
if (!found || (oat_method.GetQuickCode() != nullptr)) {
return nullptr;
}
@@ -433,7 +508,7 @@
}
// Check whether the pc is in the JIT code cache.
- jit::Jit* jit = Runtime::Current()->GetJit();
+ jit::Jit* jit = runtime->GetJit();
if (jit != nullptr) {
jit::JitCodeCache* code_cache = jit->GetCodeCache();
OatQuickMethodHeader* method_header = code_cache->LookupMethodHeader(pc, this);
@@ -452,7 +527,8 @@
// The code has to be in an oat file.
bool found;
- OatFile::OatMethod oat_method = class_linker->FindOatMethodFor(this, &found);
+ OatFile::OatMethod oat_method =
+ FindOatMethodFor(this, class_linker->GetImagePointerSize(), &found);
if (!found) {
if (class_linker->IsQuickResolutionStub(existing_entry_point)) {
// We are running the generic jni stub, but the entry point of the method has not
@@ -491,15 +567,29 @@
return method_header;
}
+const void* ArtMethod::GetOatMethodQuickCode(PointerSize pointer_size) {
+ bool found;
+ OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
+ if (found) {
+ return oat_method.GetQuickCode();
+ }
+ return nullptr;
+}
+
bool ArtMethod::HasAnyCompiledCode() {
+ if (IsNative() || !IsInvokable() || IsProxyMethod()) {
+ return false;
+ }
+
// Check whether the JIT has compiled it.
- jit::Jit* jit = Runtime::Current()->GetJit();
+ Runtime* runtime = Runtime::Current();
+ jit::Jit* jit = runtime->GetJit();
if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(this)) {
return true;
}
// Check whether we have AOT code.
- return Runtime::Current()->GetClassLinker()->GetOatMethodQuickCodeFor(this) != nullptr;
+ return GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize()) != nullptr;
}
void ArtMethod::CopyFrom(ArtMethod* src, PointerSize image_pointer_size) {
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 7a8f479..0d0bf20 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -600,13 +600,17 @@
return hotness_count_;
}
- const uint8_t* GetQuickenedInfo() REQUIRES_SHARED(Locks::mutator_lock_);
+ const uint8_t* GetQuickenedInfo(PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the method header for the compiled code containing 'pc'. Note that runtime
// methods will return null for this method, as they are not oat based.
const OatQuickMethodHeader* GetOatQuickMethodHeader(uintptr_t pc)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // Get compiled code for the method, return null if no code exists.
+ const void* GetOatMethodQuickCode(PointerSize pointer_size)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Returns whether the method has any compiled code, JIT or AOT.
bool HasAnyCompiledCode() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0d3c012..6f24568 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2750,104 +2750,15 @@
image_pointer_size_);
}
-OatFile::OatClass ClassLinker::FindOatClass(const DexFile& dex_file,
- uint16_t class_def_idx,
- bool* found) {
- DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
- const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
- if (oat_dex_file == nullptr) {
- *found = false;
- return OatFile::OatClass::Invalid();
- }
- *found = true;
- return oat_dex_file->GetOatClass(class_def_idx);
-}
-
-static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
- uint16_t class_def_idx,
- uint32_t method_idx) {
- const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
- const uint8_t* class_data = dex_file.GetClassData(class_def);
- CHECK(class_data != nullptr);
- ClassDataItemIterator it(dex_file, class_data);
- // Skip fields
- while (it.HasNextStaticField()) {
- it.Next();
- }
- while (it.HasNextInstanceField()) {
- it.Next();
- }
- // Process methods
- size_t class_def_method_index = 0;
- while (it.HasNextDirectMethod()) {
- if (it.GetMemberIndex() == method_idx) {
- return class_def_method_index;
- }
- class_def_method_index++;
- it.Next();
- }
- while (it.HasNextVirtualMethod()) {
- if (it.GetMemberIndex() == method_idx) {
- return class_def_method_index;
- }
- class_def_method_index++;
- it.Next();
- }
- DCHECK(!it.HasNext());
- LOG(FATAL) << "Failed to find method index " << method_idx << " in " << dex_file.GetLocation();
- UNREACHABLE();
-}
-
-const OatFile::OatMethod ClassLinker::FindOatMethodFor(ArtMethod* method, bool* found) {
- // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
- // method for direct methods (or virtual methods made direct).
- mirror::Class* declaring_class = method->GetDeclaringClass();
- size_t oat_method_index;
- if (method->IsStatic() || method->IsDirect()) {
- // Simple case where the oat method index was stashed at load time.
- oat_method_index = method->GetMethodIndex();
- } else {
- // We're invoking a virtual method directly (thanks to sharpening), compute the oat_method_index
- // by search for its position in the declared virtual methods.
- oat_method_index = declaring_class->NumDirectMethods();
- bool found_virtual = false;
- for (ArtMethod& art_method : declaring_class->GetVirtualMethods(image_pointer_size_)) {
- // Check method index instead of identity in case of duplicate method definitions.
- if (method->GetDexMethodIndex() == art_method.GetDexMethodIndex()) {
- found_virtual = true;
- break;
- }
- oat_method_index++;
- }
- CHECK(found_virtual) << "Didn't find oat method index for virtual method: "
- << PrettyMethod(method);
- }
- DCHECK_EQ(oat_method_index,
- GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
- method->GetDeclaringClass()->GetDexClassDefIndex(),
- method->GetDexMethodIndex()));
- OatFile::OatClass oat_class = FindOatClass(*declaring_class->GetDexCache()->GetDexFile(),
- declaring_class->GetDexClassDefIndex(),
- found);
- if (!(*found)) {
- return OatFile::OatMethod::Invalid();
- }
- return oat_class.GetOatMethod(oat_method_index);
-}
-
// Special case to get oat code without overwriting a trampoline.
const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) {
CHECK(method->IsInvokable()) << PrettyMethod(method);
if (method->IsProxyMethod()) {
return GetQuickProxyInvokeHandler();
}
- bool found;
- OatFile::OatMethod oat_method = FindOatMethodFor(method, &found);
- if (found) {
- auto* code = oat_method.GetQuickCode();
- if (code != nullptr) {
- return code;
- }
+ auto* code = method->GetOatMethodQuickCode(GetImagePointerSize());
+ if (code != nullptr) {
+ return code;
}
if (method->IsNative()) {
// No code and native? Use generic trampoline.
@@ -2856,18 +2767,6 @@
return GetQuickToInterpreterBridge();
}
-const void* ClassLinker::GetOatMethodQuickCodeFor(ArtMethod* method) {
- if (method->IsNative() || !method->IsInvokable() || method->IsProxyMethod()) {
- return nullptr;
- }
- bool found;
- OatFile::OatMethod oat_method = FindOatMethodFor(method, &found);
- if (found) {
- return oat_method.GetQuickCode();
- }
- return nullptr;
-}
-
bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void* quick_code) {
if (UNLIKELY(method->IsNative() || method->IsProxyMethod())) {
return false;
@@ -2938,9 +2837,9 @@
it.Next();
}
bool has_oat_class;
- OatFile::OatClass oat_class = FindOatClass(dex_file,
- klass->GetDexClassDefIndex(),
- &has_oat_class);
+ OatFile::OatClass oat_class = OatFile::FindOatClass(dex_file,
+ klass->GetDexClassDefIndex(),
+ &has_oat_class);
// Link the code of methods skipped by LinkCode.
for (size_t method_index = 0; it.HasNextDirectMethod(); ++method_index, it.Next()) {
ArtMethod* method = klass->GetDirectMethod(method_index, image_pointer_size_);
@@ -2965,15 +2864,20 @@
// Ignore virtual methods on the iterator.
}
-void ClassLinker::EnsureThrowsInvocationError(ArtMethod* method) {
+// Does anything needed to make sure that the compiler will not generate a direct invoke to this
+// method. Should only be called on non-invokable methods.
+inline void EnsureThrowsInvocationError(ClassLinker* class_linker, ArtMethod* method) {
DCHECK(method != nullptr);
DCHECK(!method->IsInvokable());
- method->SetEntryPointFromQuickCompiledCodePtrSize(quick_to_interpreter_bridge_trampoline_,
- image_pointer_size_);
+ method->SetEntryPointFromQuickCompiledCodePtrSize(
+ class_linker->GetQuickToInterpreterBridgeTrampoline(),
+ class_linker->GetImagePointerSize());
}
-void ClassLinker::LinkCode(ArtMethod* method, const OatFile::OatClass* oat_class,
- uint32_t class_def_method_index) {
+static void LinkCode(ClassLinker* class_linker,
+ ArtMethod* method,
+ const OatFile::OatClass* oat_class,
+ uint32_t class_def_method_index) REQUIRES_SHARED(Locks::mutator_lock_) {
Runtime* const runtime = Runtime::Current();
if (runtime->IsAotCompiler()) {
// The following code only applies to a non-compiler runtime.
@@ -2990,10 +2894,10 @@
// Install entry point from interpreter.
const void* quick_code = method->GetEntryPointFromQuickCompiledCode();
- bool enter_interpreter = ShouldUseInterpreterEntrypoint(method, quick_code);
+ bool enter_interpreter = class_linker->ShouldUseInterpreterEntrypoint(method, quick_code);
if (!method->IsInvokable()) {
- EnsureThrowsInvocationError(method);
+ EnsureThrowsInvocationError(class_linker, method);
return;
}
@@ -3018,7 +2922,8 @@
// trampoline as entrypoint (non-static), or the resolution trampoline (static).
// TODO: this doesn't handle all the cases where trampolines may be installed.
const void* entry_point = method->GetEntryPointFromQuickCompiledCode();
- DCHECK(IsQuickGenericJniStub(entry_point) || IsQuickResolutionStub(entry_point));
+ DCHECK(class_linker->IsQuickGenericJniStub(entry_point) ||
+ class_linker->IsQuickResolutionStub(entry_point));
}
}
}
@@ -3054,17 +2959,7 @@
if (class_data == nullptr) {
return; // no fields or methods - for example a marker interface
}
- bool has_oat_class = false;
- if (Runtime::Current()->IsStarted() && !Runtime::Current()->IsAotCompiler()) {
- OatFile::OatClass oat_class = FindOatClass(dex_file, klass->GetDexClassDefIndex(),
- &has_oat_class);
- if (has_oat_class) {
- LoadClassMembers(self, dex_file, class_data, klass, &oat_class);
- }
- }
- if (!has_oat_class) {
- LoadClassMembers(self, dex_file, class_data, klass, nullptr);
- }
+ LoadClassMembers(self, dex_file, class_data, klass);
}
LengthPrefixedArray<ArtField>* ClassLinker::AllocArtFieldArray(Thread* self,
@@ -3128,8 +3023,7 @@
void ClassLinker::LoadClassMembers(Thread* self,
const DexFile& dex_file,
const uint8_t* class_data,
- Handle<mirror::Class> klass,
- const OatFile::OatClass* oat_class) {
+ Handle<mirror::Class> klass) {
{
// Note: We cannot have thread suspension until the field and method arrays are setup or else
// Class::VisitFieldRoots may miss some fields or methods.
@@ -3189,6 +3083,12 @@
klass->SetIFieldsPtr(ifields);
DCHECK_EQ(klass->NumInstanceFields(), num_ifields);
// Load methods.
+ bool has_oat_class = false;
+ const OatFile::OatClass oat_class =
+ (Runtime::Current()->IsStarted() && !Runtime::Current()->IsAotCompiler())
+ ? OatFile::FindOatClass(dex_file, klass->GetDexClassDefIndex(), &has_oat_class)
+ : OatFile::OatClass::Invalid();
+ const OatFile::OatClass* oat_class_ptr = has_oat_class ? &oat_class : nullptr;
klass->SetMethodsPtr(
AllocArtMethodArray(self, allocator, it.NumDirectMethods() + it.NumVirtualMethods()),
it.NumDirectMethods(),
@@ -3200,7 +3100,7 @@
for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
ArtMethod* method = klass->GetDirectMethodUnchecked(i, image_pointer_size_);
LoadMethod(dex_file, it, klass, method);
- LinkCode(method, oat_class, class_def_method_index);
+ LinkCode(this, method, oat_class_ptr, class_def_method_index);
uint32_t it_method_index = it.GetMemberIndex();
if (last_dex_method_index == it_method_index) {
// duplicate case
@@ -3216,7 +3116,7 @@
ArtMethod* method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
LoadMethod(dex_file, it, klass, method);
DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
- LinkCode(method, oat_class, class_def_method_index);
+ LinkCode(this, method, oat_class_ptr, class_def_method_index);
class_def_method_index++;
}
DCHECK(!it.HasNext());
@@ -7185,7 +7085,7 @@
// The actual method might or might not be marked abstract since we just copied it from a
// (possibly default) interface method. We need to set it entry point to be the bridge so
// that the compiler will not invoke the implementation of whatever method we copied from.
- EnsureThrowsInvocationError(&new_method);
+ EnsureThrowsInvocationError(this, &new_method);
move_table.emplace(conf_method, &new_method);
++out;
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index f69a576..63389d8 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -34,7 +34,7 @@
#include "dex_file.h"
#include "gc_root.h"
#include "jni.h"
-#include "oat_file.h"
+#include "mirror/class.h"
#include "object_callbacks.h"
#include "verifier/verifier_log_mode.h"
@@ -57,8 +57,9 @@
class StackTraceElement;
} // namespace mirror
-class ImtConflictTable;
template<class T> class Handle;
+class ImtConflictTable;
+template<typename T> class LengthPrefixedArray;
template<class T> class MutableHandle;
class InternTable;
template<class T> class ObjectLock;
@@ -511,19 +512,10 @@
REQUIRES(!dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get the oat code for a method when its class isn't yet initialized
+ // Get the oat code for a method when its class isn't yet initialized.
const void* GetQuickOatCodeFor(ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get compiled code for a method, return null if no code
- // exists. This is unlike Get..OatCodeFor which will return a bridge
- // or interpreter entrypoint.
- const void* GetOatMethodQuickCodeFor(ArtMethod* method)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- const OatFile::OatMethod FindOatMethodFor(ArtMethod* method, bool* found)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
@@ -540,6 +532,10 @@
// Is the given entry point quick code to run the generic JNI stub?
bool IsQuickGenericJniStub(const void* entry_point) const;
+ const void* GetQuickToInterpreterBridgeTrampoline() const {
+ return quick_to_interpreter_bridge_trampoline_;
+ }
+
InternTable* GetInternTable() const {
return intern_table_;
}
@@ -783,8 +779,7 @@
void LoadClassMembers(Thread* self,
const DexFile& dex_file,
const uint8_t* class_data,
- Handle<mirror::Class> klass,
- const OatFile::OatClass* oat_class)
+ Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
void LoadField(const ClassDataItemIterator& it, Handle<mirror::Class> klass, ArtField* dst)
@@ -797,11 +792,6 @@
void FixupStaticTrampolines(mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_);
- // Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on
- // error and sets found to false.
- OatFile::OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
void RegisterDexFileLocked(const DexFile& dex_file, Handle<mirror::DexCache> dex_cache)
REQUIRES(dex_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
@@ -861,11 +851,6 @@
ArtMethod** out_imt)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Does anything needed to make sure that the compiler will not generate a direct invoke to this
- // method. Should only be called on non-invokable methods.
- void EnsureThrowsInvocationError(ArtMethod* method)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// A wrapper class representing the result of a method translation used for linking methods and
// updating superclass default methods. For each method in a classes vtable there are 4 states it
// could be in:
@@ -1015,10 +1000,6 @@
REQUIRES_SHARED(Locks::mutator_lock_);
bool LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_static, size_t* class_size)
REQUIRES_SHARED(Locks::mutator_lock_);
- void LinkCode(ArtMethod* method,
- const OatFile::OatClass* oat_class,
- uint32_t class_def_method_index)
- REQUIRES_SHARED(Locks::mutator_lock_);
void CreateReferenceInstanceOffsets(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index ff43389..a73970b 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -887,11 +887,10 @@
}
const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const {
- Runtime* runtime = Runtime::Current();
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (LIKELY(!instrumentation_stubs_installed_)) {
const void* code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
DCHECK(code != nullptr);
- ClassLinker* class_linker = runtime->GetClassLinker();
if (LIKELY(!class_linker->IsQuickResolutionStub(code) &&
!class_linker->IsQuickToInterpreterBridge(code)) &&
!class_linker->IsQuickResolutionStub(code) &&
@@ -899,7 +898,7 @@
return code;
}
}
- return runtime->GetClassLinker()->GetQuickOatCodeFor(method);
+ return class_linker->GetQuickOatCodeFor(method);
}
void Instrumentation::MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index ea692cd..b05d7ac 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -52,6 +52,7 @@
#include "utf-inl.h"
#include "utils.h"
#include "utils/dex_cache_arrays_layout-inl.h"
+#include "vdex_file.h"
namespace art {
@@ -1497,4 +1498,17 @@
return true;
}
+OatFile::OatClass OatFile::FindOatClass(const DexFile& dex_file,
+ uint16_t class_def_idx,
+ bool* found) {
+ DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
+ const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
+ if (oat_dex_file == nullptr) {
+ *found = false;
+ return OatFile::OatClass::Invalid();
+ }
+ *found = true;
+ return oat_dex_file->GetOatClass(class_def_idx);
+}
+
} // namespace art
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index a61b941..fb6250a 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -23,16 +23,14 @@
#include "base/mutex.h"
#include "base/stringpiece.h"
+#include "compiler_filter.h"
#include "dex_file.h"
-#include "invoke_type.h"
-#include "mem_map.h"
#include "mirror/class.h"
#include "oat.h"
#include "os.h"
#include "type_lookup_table.h"
#include "utf.h"
#include "utils.h"
-#include "vdex_file.h"
namespace art {
@@ -42,6 +40,7 @@
class OatMethodOffsets;
class OatHeader;
class OatDexFile;
+class VdexFile;
namespace gc {
namespace collector {
@@ -200,7 +199,7 @@
uint32_t GetOatMethodOffsetsOffset(uint32_t method_index) const;
// A representation of an invalid OatClass, used when an OatClass can't be found.
- // See ClassLinker::FindOatClass.
+ // See FindOatClass().
static OatClass Invalid() {
return OatClass(nullptr, mirror::Class::kStatusError, kOatClassNoneCompiled, 0, nullptr,
nullptr);
@@ -290,6 +289,10 @@
static bool GetDexLocationsFromDependencies(const char* dex_dependencies,
std::vector<std::string>* locations);
+ // Finds the associated oat class for a dex_file and descriptor. Returns an invalid OatClass on
+ // error and sets found to false.
+ static OatClass FindOatClass(const DexFile& dex_file, uint16_t class_def_idx, bool* found);
+
protected:
OatFile(const std::string& filename, bool executable);
diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc
index 9c42b2f..f59e01e 100644
--- a/runtime/openjdkjvmti/transform.cc
+++ b/runtime/openjdkjvmti/transform.cc
@@ -43,6 +43,7 @@
#include "mirror/class-inl.h"
#include "mirror/class_loader-inl.h"
#include "mirror/string-inl.h"
+#include "oat_file.h"
#include "scoped_thread_state_change-inl.h"
#include "thread_list.h"
#include "transform.h"
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index df0dca0..3d74af4 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -143,6 +143,7 @@
#include "trace.h"
#include "transaction.h"
#include "utils.h"
+#include "vdex_file.h"
#include "verifier/method_verifier.h"
#include "well_known_classes.h"