diff options
| -rw-r--r-- | runtime/art_method-inl.h | 16 | ||||
| -rw-r--r-- | runtime/art_method.h | 15 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 54 | ||||
| -rw-r--r-- | runtime/class_linker.h | 10 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.cc | 1 | ||||
| -rw-r--r-- | runtime/jit/jit_code_cache.h | 3 |
6 files changed, 26 insertions, 73 deletions
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 50e91447a9..0f5ffa0c49 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -388,17 +388,11 @@ inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(PointerSize pointer_size) if (LIKELY(!IsProxyMethod())) { return this; } - uint32_t method_index = GetDexMethodIndex(); - uint32_t slot_idx = method_index % mirror::DexCache::kDexCacheMethodCacheSize; - mirror::MethodDexCachePair pair = mirror::DexCache::GetNativePairPtrSize( - GetDexCacheResolvedMethods(pointer_size), slot_idx, pointer_size); - ArtMethod* interface_method = pair.GetObjectForIndex(method_index); - if (LIKELY(interface_method != nullptr)) { - DCHECK_EQ(interface_method, Runtime::Current()->GetClassLinker()->FindMethodForProxy(this)); - } else { - interface_method = Runtime::Current()->GetClassLinker()->FindMethodForProxy(this); - DCHECK(interface_method != nullptr); - } + ArtMethod* interface_method = reinterpret_cast<ArtMethod*>(GetDataPtrSize(pointer_size)); + // We can check that the proxy class implements the interface only if the proxy class + // is resolved, otherwise the interface table is not yet initialized. + DCHECK(!GetDeclaringClass()->IsResolved() || + interface_method->GetDeclaringClass()->IsAssignableFrom(GetDeclaringClass())); return interface_method; } diff --git a/runtime/art_method.h b/runtime/art_method.h index cac40e011a..7ffd585f1a 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -458,12 +458,15 @@ class ArtMethod FINAL { SetDataPtrSize(table, pointer_size); } - ProfilingInfo* GetProfilingInfo(PointerSize pointer_size) { + ProfilingInfo* GetProfilingInfo(PointerSize pointer_size) REQUIRES_SHARED(Locks::mutator_lock_) { // Don't do a read barrier in the DCHECK, as GetProfilingInfo is called in places // where the declaring class is treated as a weak reference (accessing it with // a read barrier would either prevent unloading the class, or crash the runtime if // the GC wants to unload it). DCHECK(!IsNative<kWithoutReadBarrier>()); + if (UNLIKELY(IsProxyMethod())) { + return nullptr; + } return reinterpret_cast<ProfilingInfo*>(GetDataPtrSize(pointer_size)); } @@ -726,9 +729,13 @@ class ArtMethod FINAL { // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. mirror::MethodDexCacheType* dex_cache_resolved_methods_; - // Pointer to JNI function registered to this method, or a function to resolve the JNI function, - // or the profiling data for non-native methods, or an ImtConflictTable, or the - // single-implementation of an abstract/interface method. + // Depending on the method type, the data is + // - native method: pointer to the JNI function registered to this method + // or a function to resolve the JNI function, + // - conflict method: ImtConflictTable, + // - abstract/interface method: the single-implementation if any, + // - proxy method: the original interface method or constructor, + // - other methods: the profiling data. void* data_; // Method dispatch from quick compiled code invokes this pointer which may cause bridging into diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 845bd6d5ff..0efc004b48 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -3552,7 +3552,6 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, DexCacheData data; data.weak_root = dex_cache_jweak; data.dex_file = dex_cache->GetDexFile(); - data.resolved_methods = dex_cache->GetResolvedMethods(); data.class_table = ClassTableForClassLoader(class_loader); DCHECK(data.class_table != nullptr); // Make sure to hold the dex cache live in the class table. This case happens for the boot class @@ -4668,6 +4667,9 @@ void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* kAccPublic | kAccCompileDontBother); out->SetDeclaringClass(klass.Get()); + + // Set the original constructor method. + out->SetDataPtrSize(proxy_constructor, image_pointer_size_); } void ClassLinker::CheckProxyConstructor(ArtMethod* constructor) const { @@ -4708,6 +4710,9 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot // method they copy might (if it's a default method). out->SetCodeItemOffset(0); + // Set the original interface method. + out->SetDataPtrSize(prototype, image_pointer_size_); + // At runtime the method looks like a reference and argument saving method, clone the code // related parameters from this method. out->SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler()); @@ -9031,53 +9036,6 @@ mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) { ifcount * mirror::IfTable::kMax)); } -ArtMethod* ClassLinker::FindMethodForProxy(ArtMethod* proxy_method) { - DCHECK(proxy_method->IsProxyMethod()); - { - uint32_t method_index = proxy_method->GetDexMethodIndex(); - PointerSize pointer_size = image_pointer_size_; - Thread* const self = Thread::Current(); - ReaderMutexLock mu(self, *Locks::dex_lock_); - // Locate the dex cache of the original interface/Object - for (const DexCacheData& data : dex_caches_) { - if (!self->IsJWeakCleared(data.weak_root) && - proxy_method->HasSameDexCacheResolvedMethods(data.resolved_methods, pointer_size)) { - ObjPtr<mirror::DexCache> dex_cache = - ObjPtr<mirror::DexCache>::DownCast(self->DecodeJObject(data.weak_root)); - if (dex_cache != nullptr) { - // Lookup up the method. Instead of going through LookupResolvedMethod() - // and thus LookupResolvedType(), use the ClassTable from the DexCacheData. - ArtMethod* resolved_method = dex_cache->GetResolvedMethod(method_index, pointer_size); - if (resolved_method == nullptr) { - const DexFile::MethodId& method_id = data.dex_file->GetMethodId(method_index); - ObjPtr<mirror::Class> klass = dex_cache->GetResolvedType(method_id.class_idx_); - if (klass == nullptr) { - const char* descriptor = data.dex_file->StringByTypeIdx(method_id.class_idx_); - klass = data.class_table->Lookup(descriptor, ComputeModifiedUtf8Hash(descriptor)); - DCHECK(klass != nullptr); - dex_cache->SetResolvedType(method_id.class_idx_, klass); - } - if (klass->IsInterface()) { - resolved_method = klass->FindInterfaceMethod(dex_cache, method_index, pointer_size); - } else { - DCHECK( - klass == WellKnownClasses::ToClass(WellKnownClasses::java_lang_reflect_Proxy) || - klass == WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object)); - resolved_method = klass->FindClassMethod(dex_cache, method_index, pointer_size); - } - CHECK(resolved_method != nullptr); - dex_cache->SetResolvedMethod(method_index, resolved_method, pointer_size); - } - return resolved_method; - } - } - } - } - // Note: Do not use proxy_method->PrettyMethod() as it can call back here. - LOG(FATAL) << "Didn't find dex cache for " << proxy_method->GetDeclaringClass()->PrettyClass(); - UNREACHABLE(); -} - // Instantiate ResolveMethod. template ArtMethod* ClassLinker::ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>( const DexFile& dex_file, diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 66bcbe091f..783ec745cf 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -479,9 +479,6 @@ class ClassLinker { REQUIRES_SHARED(Locks::mutator_lock_); std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class) REQUIRES_SHARED(Locks::mutator_lock_); - ArtMethod* FindMethodForProxy(ArtMethod* proxy_method) - REQUIRES(!Locks::dex_lock_) - REQUIRES_SHARED(Locks::mutator_lock_); // Get the oat code for a method when its class isn't yet initialized. const void* GetQuickOatCodeFor(ArtMethod* method) @@ -675,7 +672,6 @@ class ClassLinker { DexCacheData() : weak_root(nullptr), dex_file(nullptr), - resolved_methods(nullptr), class_table(nullptr) { } // Check if the data is valid. @@ -686,11 +682,9 @@ class ClassLinker { // Weak root to the DexCache. Note: Do not decode this unnecessarily or else class unloading may // not work properly. jweak weak_root; - // The following two fields are caches to the DexCache's fields and here to avoid unnecessary - // jweak decode that triggers read barriers (and mark them alive unnecessarily and mess with - // class unloading.) + // The following field caches the DexCache's field here to avoid unnecessary jweak decode that + // triggers read barriers (and marks them alive unnecessarily and messes with class unloading.) const DexFile* dex_file; - mirror::MethodDexCacheType* resolved_methods; // Identify the associated class loader's class table. This is used to make sure that // the Java call to native DexCache.setResolvedType() inserts the resolved type in that // class table. It is also used to make sure we don't register the same dex cache with diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 47ace7fa71..40a5212629 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -1169,7 +1169,6 @@ void JitCodeCache::DoCollection(Thread* self, bool collect_profiling_info) { RemoveUnmarkedCode(self); if (collect_profiling_info) { - ScopedThreadSuspension sts(self, kSuspended); MutexLock mu(self, lock_); // Free all profiling infos of methods not compiled nor being compiled. auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(), diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h index daa1d616a6..9790e3aa43 100644 --- a/runtime/jit/jit_code_cache.h +++ b/runtime/jit/jit_code_cache.h @@ -323,7 +323,8 @@ class JitCodeCache { REQUIRES_SHARED(Locks::mutator_lock_); bool CheckLiveCompiledCodeHasProfilingInfo() - REQUIRES(lock_); + REQUIRES(lock_) + REQUIRES_SHARED(Locks::mutator_lock_); void FreeCode(uint8_t* code) REQUIRES(lock_); uint8_t* AllocateCode(size_t code_size) REQUIRES(lock_); |