diff options
-rw-r--r-- | compiler/optimizing/inliner.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 5 | ||||
-rw-r--r-- | runtime/art_method.cc | 106 | ||||
-rw-r--r-- | runtime/art_method.h | 6 | ||||
-rw-r--r-- | runtime/class_linker.cc | 162 | ||||
-rw-r--r-- | runtime/class_linker.h | 37 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 5 | ||||
-rw-r--r-- | runtime/oat_file.cc | 14 | ||||
-rw-r--r-- | runtime/oat_file.h | 11 | ||||
-rw-r--r-- | runtime/openjdkjvmti/transform.cc | 1 | ||||
-rw-r--r-- | runtime/runtime.cc | 1 | ||||
-rw-r--r-- | test/117-nopatchoat/nopatchoat.cc | 1 | ||||
-rw-r--r-- | test/common/stack_inspect.cc | 1 |
13 files changed, 174 insertions, 178 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index af2fe9cb1f..6080551900 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1138,7 +1138,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, *code_item, compiler_driver_, inline_stats.get(), - resolved_method->GetQuickenedInfo(), + resolved_method->GetQuickenedInfo(class_linker->GetImagePointerSize()), dex_cache, handles_); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 52d6e0b3f1..d6f8307ac2 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -872,9 +872,10 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, return nullptr; } + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); DexCompilationUnit dex_compilation_unit( class_loader, - Runtime::Current()->GetClassLinker(), + class_linker, dex_file, code_item, class_def_idx, @@ -913,7 +914,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, if (method != nullptr) { graph->SetArtMethod(method); ScopedObjectAccess soa(Thread::Current()); - interpreter_metadata = method->GetQuickenedInfo(); + interpreter_metadata = method->GetQuickenedInfo(class_linker->GetImagePointerSize()); uint16_t type_index = method->GetDeclaringClass()->GetDexTypeIndex(); // Update the dex cache if the type is not in it yet. Note that under AOT, diff --git a/runtime/art_method.cc b/runtime/art_method.cc index c97c32837d..937dcee473 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -283,7 +283,9 @@ void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* // 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 @@ bool ArtMethod::IsAnnotatedWith(jclass klass, uint32_t visibility) { 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 @@ bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> param 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 @@ const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) { } // 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 @@ const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) { // 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 @@ const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) { 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 7a8f479d19..0d0bf2056a 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -600,13 +600,17 @@ class ArtMethod FINAL { 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 d67e1118bb..bb62f2d55f 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2750,104 +2750,15 @@ uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file, 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 @@ const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) { 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 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { 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 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { // 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 @@ void ClassLinker::LinkCode(ArtMethod* method, const OatFile::OatClass* oat_class // 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 @@ void ClassLinker::LinkCode(ArtMethod* method, const OatFile::OatClass* oat_class // 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 @@ void ClassLinker::LoadClass(Thread* self, 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 @@ LinearAlloc* ClassLinker::GetOrCreateAllocatorForClassLoader(mirror::ClassLoader 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 @@ void ClassLinker::LoadClassMembers(Thread* self, 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 @@ void ClassLinker::LoadClassMembers(Thread* self, 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 @@ void ClassLinker::LoadClassMembers(Thread* self, 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 @@ bool ClassLinker::LinkInterfaceMethods( // 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 f69a5767e2..63389d8130 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 @@ namespace mirror { 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 @@ class ClassLinker { 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 @@ class ClassLinker { // 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 @@ class ClassLinker { 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 @@ class ClassLinker { 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 @@ class ClassLinker { 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 @@ class ClassLinker { 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 ff433890a9..a73970b138 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -887,11 +887,10 @@ void Instrumentation::DisableMethodTracing(const char* key) { } 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 @@ const void* Instrumentation::GetQuickCodeFor(ArtMethod* method, PointerSize poin 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 5f37b82a98..f164a92c92 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -53,6 +53,7 @@ #include "utf-inl.h" #include "utils.h" #include "utils/dex_cache_arrays_layout-inl.h" +#include "vdex_file.h" namespace art { @@ -1534,4 +1535,17 @@ bool OatFile::GetDexLocationsFromDependencies(const char* dex_dependencies, 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 c3188cbb09..b99bcb5f7d 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -24,16 +24,14 @@ #include "base/array_ref.h" #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 { @@ -44,6 +42,7 @@ class MemMap; class OatMethodOffsets; class OatHeader; class OatDexFile; +class VdexFile; namespace gc { namespace collector { @@ -202,7 +201,7 @@ class OatFile { 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); @@ -298,6 +297,10 @@ class OatFile { 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 9c42b2ff85..f59e01e3db 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 d5f592078b..7d9d506a1b 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" diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc index 56c0dcd41b..3236bde5a2 100644 --- a/test/117-nopatchoat/nopatchoat.cc +++ b/test/117-nopatchoat/nopatchoat.cc @@ -19,6 +19,7 @@ #include "gc/heap.h" #include "gc/space/image_space.h" #include "mirror/class-inl.h" +#include "oat_file.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc index d2aacf0562..4df2d470ec 100644 --- a/test/common/stack_inspect.cc +++ b/test/common/stack_inspect.cc @@ -20,6 +20,7 @@ #include "dex_file-inl.h" #include "mirror/class-inl.h" #include "nth_caller_visitor.h" +#include "oat_file.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "stack.h" |