diff options
| -rw-r--r-- | compiler/image_writer.cc | 3 | ||||
| -rw-r--r-- | runtime/Android.bp | 1 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 4 | ||||
| -rw-r--r-- | runtime/class_linker_test.cc | 1 | ||||
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 2 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 47 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime_list.h | 1 | ||||
| -rw-r--r-- | runtime/mirror/class-inl.h | 6 | ||||
| -rw-r--r-- | runtime/mirror/class.cc | 2 | ||||
| -rw-r--r-- | runtime/mirror/class.h | 6 | ||||
| -rw-r--r-- | runtime/mirror/dex_cache-inl.h | 2 | ||||
| -rw-r--r-- | runtime/mirror/dex_cache.h | 10 | ||||
| -rw-r--r-- | runtime/native/java_lang_Class.cc | 52 | ||||
| -rw-r--r-- | runtime/native/java_lang_DexCache.cc | 109 | ||||
| -rw-r--r-- | runtime/native/java_lang_DexCache.h | 28 | ||||
| -rw-r--r-- | runtime/native/java_lang_reflect_Executable.cc | 140 | ||||
| -rw-r--r-- | runtime/native/java_lang_reflect_Field.cc | 8 | ||||
| -rw-r--r-- | runtime/native/java_lang_reflect_Method.cc | 3 | ||||
| -rw-r--r-- | runtime/runtime.cc | 2 | ||||
| -rw-r--r-- | runtime/well_known_classes.cc | 2 | ||||
| -rw-r--r-- | runtime/well_known_classes.h | 1 |
21 files changed, 207 insertions, 223 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index aa734561b6..aefdb548ff 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -976,9 +976,6 @@ void ImageWriter::PruneNonImageClasses() { dex_cache->ClearResolvedField(pair.index, target_ptr_size_); } } - // Clean the dex field. It might have been populated during the initialization phase, but - // contains data only valid during a real run. - dex_cache->SetFieldObject<false>(mirror::DexCache::DexOffset(), nullptr); } // Drop the array class cache in the ClassLinker, as these are roots holding those classes live. diff --git a/runtime/Android.bp b/runtime/Android.bp index d075c58d27..6c3bc0450b 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -149,7 +149,6 @@ cc_defaults { "native/dalvik_system_VMStack.cc", "native/dalvik_system_ZygoteHooks.cc", "native/java_lang_Class.cc", - "native/java_lang_DexCache.cc", "native/java_lang_Object.cc", "native/java_lang_String.cc", "native/java_lang_StringFactory.cc", diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index eb7d7bd9a3..746cace8a6 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4409,9 +4409,9 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& decoded_name->ToModifiedUtf8().c_str())); CHECK_EQ(ArtField::PrettyField(klass->GetStaticField(1)), throws_field_name); - CHECK_EQ(klass.Get()->GetInterfaces(), + CHECK_EQ(klass.Get()->GetProxyInterfaces(), soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces)); - CHECK_EQ(klass.Get()->GetThrows(), + CHECK_EQ(klass.Get()->GetProxyThrows(), soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>>(throws)); } return klass.Get(); diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index e5722a13a7..9f04e598eb 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -668,7 +668,6 @@ struct ProxyOffsets : public CheckOffsets<mirror::Proxy> { struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> { DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") { - addOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_), "dex"); addOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_file_), "dexFile"); addOffset(OFFSETOF_MEMBER(mirror::DexCache, location_), "location"); addOffset(OFFSETOF_MEMBER(mirror::DexCache, num_resolved_call_sites_), "numResolvedCallSites"); diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 6301362e09..9c453ec9ba 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -138,7 +138,7 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons reinterpret_cast<uintptr_t>(&virtual_methods.At(0))) / method_size; CHECK_LT(throws_index, static_cast<int>(num_virtuals)); mirror::ObjectArray<mirror::Class>* declared_exceptions = - proxy_class->GetThrows()->Get(throws_index); + proxy_class->GetProxyThrows()->Get(throws_index); mirror::Class* exception_class = exception->GetClass(); for (int32_t i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) { mirror::Class* declared_exception = declared_exceptions->Get(i); diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index eb0a9d161a..420fa85a46 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -1131,53 +1131,6 @@ void UnstartedRuntime::UnstartedDoubleDoubleToRawLongBits( result->SetJ(bit_cast<int64_t, double>(in)); } -static ObjPtr<mirror::Object> GetDexFromDexCache(Thread* self, mirror::DexCache* dex_cache) - REQUIRES_SHARED(Locks::mutator_lock_) { - const DexFile* dex_file = dex_cache->GetDexFile(); - if (dex_file == nullptr) { - return nullptr; - } - - // Create the direct byte buffer. - JNIEnv* env = self->GetJniEnv(); - DCHECK(env != nullptr); - void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin())); - ScopedLocalRef<jobject> byte_buffer(env, env->NewDirectByteBuffer(address, dex_file->Size())); - if (byte_buffer.get() == nullptr) { - DCHECK(self->IsExceptionPending()); - return nullptr; - } - - jvalue args[1]; - args[0].l = byte_buffer.get(); - - ScopedLocalRef<jobject> dex(env, env->CallStaticObjectMethodA( - WellKnownClasses::com_android_dex_Dex, - WellKnownClasses::com_android_dex_Dex_create, - args)); - - return self->DecodeJObject(dex.get()); -} - -void UnstartedRuntime::UnstartedDexCacheGetDexNative( - Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { - // We will create the Dex object, but the image writer will release it before creating the - // art file. - mirror::Object* src = shadow_frame->GetVRegReference(arg_offset); - bool have_dex = false; - if (src != nullptr) { - ObjPtr<mirror::Object> dex = GetDexFromDexCache(self, src->AsDexCache()); - if (dex != nullptr) { - have_dex = true; - result->SetL(dex); - } - } - if (!have_dex) { - self->ClearException(); - Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Could not create Dex object"); - } -} - static void UnstartedMemoryPeek( Primitive::Type type, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { int64_t address = shadow_frame->GetVRegLong(arg_offset); diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h index 2560a92f8f..47910357d5 100644 --- a/runtime/interpreter/unstarted_runtime_list.h +++ b/runtime/interpreter/unstarted_runtime_list.h @@ -52,7 +52,6 @@ V(MathPow, "double java.lang.Math.pow(double, double)") \ V(ObjectHashCode, "int java.lang.Object.hashCode()") \ V(DoubleDoubleToRawLongBits, "long java.lang.Double.doubleToRawLongBits(double)") \ - V(DexCacheGetDexNative, "com.android.dex.Dex java.lang.DexCache.getDexNative()") \ V(MemoryPeekByte, "byte libcore.io.Memory.peekByte(long)") \ V(MemoryPeekShort, "short libcore.io.Memory.peekShortNative(long)") \ V(MemoryPeekInt, "int libcore.io.Memory.peekIntNative(long)") \ diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 2cff47e8b4..f6dc551b6f 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -841,7 +841,7 @@ inline void Class::AssertInitializedOrInitializingInThread(Thread* self) { } } -inline ObjectArray<Class>* Class::GetInterfaces() { +inline ObjectArray<Class>* Class::GetProxyInterfaces() { CHECK(IsProxyClass()); // First static field. auto* field = GetStaticField(0); @@ -850,7 +850,7 @@ inline ObjectArray<Class>* Class::GetInterfaces() { return GetFieldObject<ObjectArray<Class>>(field_offset); } -inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() { +inline ObjectArray<ObjectArray<Class>>* Class::GetProxyThrows() { CHECK(IsProxyClass()); // Second static field. auto* field = GetStaticField(1); @@ -920,7 +920,7 @@ inline uint32_t Class::NumDirectInterfaces() { } else if (IsArrayClass()) { return 2; } else if (IsProxyClass()) { - ObjectArray<Class>* interfaces = GetInterfaces(); + ObjectArray<Class>* interfaces = GetProxyInterfaces(); return interfaces != nullptr ? interfaces->GetLength() : 0; } else { const DexFile::TypeList* interfaces = GetInterfaceTypeList(); diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index eb2ec9b3c8..efb87104c2 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -946,7 +946,7 @@ ObjPtr<Class> Class::GetDirectInterface(Thread* self, ObjPtr<Class> klass, uint3 DCHECK(interface != nullptr); return interface; } else if (klass->IsProxyClass()) { - ObjPtr<ObjectArray<Class>> interfaces = klass->GetInterfaces(); + ObjPtr<ObjectArray<Class>> interfaces = klass->GetProxyInterfaces(); DCHECK(interfaces != nullptr); return interfaces->Get(idx); } else { diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index c52b66affe..34d5bf3715 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -595,7 +595,7 @@ class MANAGED Class FINAL : public Object { // The size of java.lang.Class.class. static uint32_t ClassClassSize(PointerSize pointer_size) { // The number of vtable entries in java.lang.Class. - uint32_t vtable_entries = Object::kVTableLength + 70; + uint32_t vtable_entries = Object::kVTableLength + 67; return ComputeClassSize(true, vtable_entries, 0, 0, 4, 1, 0, pointer_size); } @@ -1262,10 +1262,10 @@ class MANAGED Class FINAL : public Object { REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); // For proxy class only. - ObjectArray<Class>* GetInterfaces() REQUIRES_SHARED(Locks::mutator_lock_); + ObjectArray<Class>* GetProxyInterfaces() REQUIRES_SHARED(Locks::mutator_lock_); // For proxy class only. - ObjectArray<ObjectArray<Class>>* GetThrows() REQUIRES_SHARED(Locks::mutator_lock_); + ObjectArray<ObjectArray<Class>>* GetProxyThrows() REQUIRES_SHARED(Locks::mutator_lock_); // For reference class only. MemberOffset GetDisableIntrinsicFlagOffset() REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index 582ecb23e5..5d3af5071a 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -47,7 +47,7 @@ inline void NativeDexCachePair<T>::Initialize(std::atomic<NativeDexCachePair<T>> } inline uint32_t DexCache::ClassSize(PointerSize pointer_size) { - uint32_t vtable_entries = Object::kVTableLength + 5; + const uint32_t vtable_entries = Object::kVTableLength; return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size); } diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 35707ef4e9..48a9ecd992 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -212,10 +212,6 @@ class MANAGED DexCache FINAL : public Object { return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); } - static MemberOffset DexOffset() { - return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_); - } - static MemberOffset StringsOffset() { return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_); } @@ -516,8 +512,11 @@ class MANAGED DexCache FINAL : public Object { static void AtomicStoreRelease16B(std::atomic<ConversionPair64>* target, ConversionPair64 value); #endif - HeapReference<Object> dex_; HeapReference<String> location_; + // Number of elements in the call_sites_ array. Note that this appears here + // because of our packing logic for 32 bit fields. + uint32_t num_resolved_call_sites_; + uint64_t dex_file_; // const DexFile* uint64_t resolved_call_sites_; // GcRoot<CallSite>* array with num_resolved_call_sites_ // elements. @@ -530,7 +529,6 @@ class MANAGED DexCache FINAL : public Object { uint64_t strings_; // std::atomic<StringDexCachePair>*, array with num_strings_ // elements. - uint32_t num_resolved_call_sites_; // Number of elements in the call_sites_ array. uint32_t num_resolved_fields_; // Number of elements in the resolved_fields_ array. uint32_t num_resolved_method_types_; // Number of elements in the resolved_method_types_ array. uint32_t num_resolved_methods_; // Number of elements in the resolved_methods_ array. diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index c8431c0519..381dc7beb0 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -108,10 +108,50 @@ static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) { return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c))); } -static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) { +// TODO: Move this to mirror::Class ? Other mirror types that commonly appear +// as arrays have a GetArrayClass() method. +static ObjPtr<mirror::Class> GetClassArrayClass(Thread* self) + REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); + return Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_class); +} + +static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::Class> c = DecodeClass(soa, javaThis); - return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self())); + StackHandleScope<4> hs(soa.Self()); + Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis)); + + if (klass->IsProxyClass()) { + return soa.AddLocalReference<jobjectArray>(klass->GetProxyInterfaces()->Clone(soa.Self())); + } + + const DexFile::TypeList* iface_list = klass->GetInterfaceTypeList(); + if (iface_list == nullptr) { + return nullptr; + } + + const uint32_t num_ifaces = iface_list->Size(); + Handle<mirror::Class> class_array_class = hs.NewHandle(GetClassArrayClass(soa.Self())); + Handle<mirror::ObjectArray<mirror::Class>> ifaces = hs.NewHandle( + mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class.Get(), num_ifaces)); + if (ifaces.IsNull()) { + DCHECK(soa.Self()->IsExceptionPending()); + return nullptr; + } + + // Check that we aren't in an active transaction, we call SetWithoutChecks + // with kActiveTransaction == false. + DCHECK(!Runtime::Current()->IsActiveTransaction()); + + MutableHandle<mirror::Class> interface(hs.NewHandle<mirror::Class>(nullptr)); + for (uint32_t i = 0; i < num_ifaces; ++i) { + const dex::TypeIndex type_idx = iface_list->GetTypeItem(i).type_idx_; + interface.Assign(ClassLinker::LookupResolvedType( + type_idx, klass->GetDexCache(), klass->GetClassLoader())); + ifaces->SetWithoutChecks<false>(i, interface.Get()); + } + + return soa.AddLocalReference<jobjectArray>(ifaces.Get()); } static mirror::ObjectArray<mirror::Field>* GetDeclaredFields( @@ -501,9 +541,7 @@ static jobjectArray Class_getDeclaredClasses(JNIEnv* env, jobject javaThis) { // Pending exception from GetDeclaredClasses. return nullptr; } - ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); - ObjPtr<mirror::Class> class_array_class = - Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class); + ObjPtr<mirror::Class> class_array_class = GetClassArrayClass(soa.Self()); if (class_array_class == nullptr) { return nullptr; } @@ -736,8 +774,8 @@ static JNINativeMethod gMethods[] = { FAST_NATIVE_METHOD(Class, getEnclosingMethodNative, "()Ljava/lang/reflect/Method;"), FAST_NATIVE_METHOD(Class, getInnerClassFlags, "(I)I"), FAST_NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"), + FAST_NATIVE_METHOD(Class, getInterfacesInternal, "()[Ljava/lang/Class;"), FAST_NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"), - FAST_NATIVE_METHOD(Class, getProxyInterfaces, "()[Ljava/lang/Class;"), FAST_NATIVE_METHOD(Class, getPublicDeclaredFields, "()[Ljava/lang/reflect/Field;"), FAST_NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/String;"), FAST_NATIVE_METHOD(Class, isAnonymousClass, "()Z"), diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc deleted file mode 100644 index 8fda4dfaaf..0000000000 --- a/runtime/native/java_lang_DexCache.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "java_lang_DexCache.h" - -#include "dex_file.h" -#include "dex_file_types.h" -#include "jni_internal.h" -#include "mirror/class-inl.h" -#include "mirror/dex_cache-inl.h" -#include "mirror/object-inl.h" -#include "scoped_fast_native_object_access-inl.h" -#include "well_known_classes.h" - -namespace art { - -static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) { - ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - // Should only be called while holding the lock on the dex cache. - DCHECK_EQ(dex_cache->GetLockOwnerThreadId(), soa.Self()->GetThreadId()); - const DexFile* dex_file = dex_cache->GetDexFile(); - if (dex_file == nullptr) { - return nullptr; - } - void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin())); - jobject byte_buffer = env->NewDirectByteBuffer(address, dex_file->Size()); - if (byte_buffer == nullptr) { - DCHECK(soa.Self()->IsExceptionPending()); - return nullptr; - } - - jvalue args[1]; - args[0].l = byte_buffer; - return env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex, - WellKnownClasses::com_android_dex_Dex_create, - args); -} - -static jobject DexCache_getResolvedType(JNIEnv* env, jobject javaDexCache, jint type_index) { - ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - CHECK_LT(static_cast<size_t>(type_index), dex_cache->GetDexFile()->NumTypeIds()); - return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(dex::TypeIndex(type_index))); -} - -static jobject DexCache_getResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index) { - ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds()); - return soa.AddLocalReference<jobject>( - dex_cache->GetResolvedString(dex::StringIndex(string_index))); -} - -static void DexCache_setResolvedType(JNIEnv* env, - jobject javaDexCache, - jint type_index, - jobject type) { - ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - const DexFile& dex_file = *dex_cache->GetDexFile(); - CHECK_LT(static_cast<size_t>(type_index), dex_file.NumTypeIds()); - ObjPtr<mirror::Class> t = soa.Decode<mirror::Class>(type); - if (t != nullptr && t->DescriptorEquals(dex_file.StringByTypeIdx(dex::TypeIndex(type_index)))) { - ClassTable* table = - Runtime::Current()->GetClassLinker()->FindClassTable(soa.Self(), dex_cache); - if (table != nullptr && table->TryInsert(t) == t) { - dex_cache->SetResolvedType(dex::TypeIndex(type_index), t); - } - } -} - -static void DexCache_setResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index, - jobject string) { - ScopedFastNativeObjectAccess soa(env); - ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); - CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds()); - ObjPtr<mirror::String> s = soa.Decode<mirror::String>(string); - if (s != nullptr) { - dex_cache->SetResolvedString(dex::StringIndex(string_index), s); - } -} - -static JNINativeMethod gMethods[] = { - FAST_NATIVE_METHOD(DexCache, getDexNative, "()Lcom/android/dex/Dex;"), - FAST_NATIVE_METHOD(DexCache, getResolvedType, "(I)Ljava/lang/Class;"), - FAST_NATIVE_METHOD(DexCache, getResolvedString, "(I)Ljava/lang/String;"), - FAST_NATIVE_METHOD(DexCache, setResolvedType, "(ILjava/lang/Class;)V"), - FAST_NATIVE_METHOD(DexCache, setResolvedString, "(ILjava/lang/String;)V"), -}; - -void register_java_lang_DexCache(JNIEnv* env) { - REGISTER_NATIVE_METHODS("java/lang/DexCache"); -} - -} // namespace art diff --git a/runtime/native/java_lang_DexCache.h b/runtime/native/java_lang_DexCache.h deleted file mode 100644 index b1c1f5e72c..0000000000 --- a/runtime/native/java_lang_DexCache.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_NATIVE_JAVA_LANG_DEXCACHE_H_ -#define ART_RUNTIME_NATIVE_JAVA_LANG_DEXCACHE_H_ - -#include <jni.h> - -namespace art { - -void register_java_lang_DexCache(JNIEnv* env); - -} // namespace art - -#endif // ART_RUNTIME_NATIVE_JAVA_LANG_DEXCACHE_H_ diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc index bc23bedc77..8f226ce621 100644 --- a/runtime/native/java_lang_reflect_Executable.cc +++ b/runtime/native/java_lang_reflect_Executable.cc @@ -194,12 +194,146 @@ static jboolean Executable_isAnnotationPresentNative(JNIEnv* env, return annotations::IsMethodAnnotationPresent(method, klass); } +static jint Executable_compareMethodParametersInternal(JNIEnv* env, + jobject thisMethod, + jobject otherMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* this_method = ArtMethod::FromReflectedMethod(soa, thisMethod); + ArtMethod* other_method = ArtMethod::FromReflectedMethod(soa, otherMethod); + + this_method = this_method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + other_method = other_method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + + const DexFile::TypeList* this_list = this_method->GetParameterTypeList(); + const DexFile::TypeList* other_list = other_method->GetParameterTypeList(); + + if (this_list == other_list) { + return 0; + } + + if (this_list == nullptr && other_list != nullptr) { + return -1; + } + + if (other_list == nullptr && this_list != nullptr) { + return 1; + } + + const int32_t this_size = this_list->Size(); + const int32_t other_size = other_list->Size(); + + if (this_size != other_size) { + return (this_size - other_size); + } + + for (int32_t i = 0; i < this_size; ++i) { + const DexFile::TypeId& lhs = this_method->GetDexFile()->GetTypeId( + this_list->GetTypeItem(i).type_idx_); + const DexFile::TypeId& rhs = other_method->GetDexFile()->GetTypeId( + other_list->GetTypeItem(i).type_idx_); + + uint32_t lhs_len, rhs_len; + const char* lhs_data = this_method->GetDexFile()->StringDataAndUtf16LengthByIdx( + lhs.descriptor_idx_, &lhs_len); + const char* rhs_data = other_method->GetDexFile()->StringDataAndUtf16LengthByIdx( + rhs.descriptor_idx_, &rhs_len); + + int cmp = strcmp(lhs_data, rhs_data); + if (cmp != 0) { + return (cmp < 0) ? -1 : 1; + } + } + + return 0; +} + +static jobject Executable_getMethodNameInternal(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + return soa.AddLocalReference<jobject>(method->GetNameAsString(soa.Self())); +} + +static jobject Executable_getMethodReturnTypeInternal(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + ObjPtr<mirror::Class> return_type(method->GetReturnType(true /* resolve */)); + if (return_type.IsNull()) { + CHECK(soa.Self()->IsExceptionPending()); + return nullptr; + } + + return soa.AddLocalReference<jobject>(return_type); +} + +// TODO: Move this to mirror::Class ? Other mirror types that commonly appear +// as arrays have a GetArrayClass() method. This is duplicated in +// java_lang_Class.cc as well. +static ObjPtr<mirror::Class> GetClassArrayClass(Thread* self) + REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); + return Runtime::Current()->GetClassLinker()->FindArrayClass(self, &class_class); +} + +static jobjectArray Executable_getParameterTypesInternal(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + + const DexFile::TypeList* params = method->GetParameterTypeList(); + if (params == nullptr) { + return nullptr; + } + + const uint32_t num_params = params->Size(); + + StackHandleScope<3> hs(soa.Self()); + Handle<mirror::Class> class_array_class = hs.NewHandle(GetClassArrayClass(soa.Self())); + Handle<mirror::ObjectArray<mirror::Class>> ptypes = hs.NewHandle( + mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class.Get(), num_params)); + if (ptypes.IsNull()) { + DCHECK(soa.Self()->IsExceptionPending()); + return nullptr; + } + + MutableHandle<mirror::Class> param(hs.NewHandle<mirror::Class>(nullptr)); + for (uint32_t i = 0; i < num_params; ++i) { + const dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_; + param.Assign(Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method)); + if (param.Get() == nullptr) { + DCHECK(soa.Self()->IsExceptionPending()); + return nullptr; + } + ptypes->SetWithoutChecks<false>(i, param.Get()); + } + + return soa.AddLocalReference<jobjectArray>(ptypes.Get()); +} + +static jint Executable_getParameterCountInternal(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); + + const DexFile::TypeList* params = method->GetParameterTypeList(); + return (params == nullptr) ? 0 : params->Size(); +} + + static JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Executable, compareMethodParametersInternal, + "(Ljava/lang/reflect/Method;)I"), FAST_NATIVE_METHOD(Executable, getAnnotationNative, - "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), - FAST_NATIVE_METHOD(Executable, getDeclaredAnnotationsNative, "()[Ljava/lang/annotation/Annotation;"), + "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), + FAST_NATIVE_METHOD(Executable, getDeclaredAnnotationsNative, + "()[Ljava/lang/annotation/Annotation;"), FAST_NATIVE_METHOD(Executable, getParameterAnnotationsNative, - "()[[Ljava/lang/annotation/Annotation;"), + "()[[Ljava/lang/annotation/Annotation;"), + FAST_NATIVE_METHOD(Executable, getMethodNameInternal, "()Ljava/lang/String;"), + FAST_NATIVE_METHOD(Executable, getMethodReturnTypeInternal, "()Ljava/lang/Class;"), + FAST_NATIVE_METHOD(Executable, getParameterTypesInternal, "()[Ljava/lang/Class;"), + FAST_NATIVE_METHOD(Executable, getParameterCountInternal, "()I"), FAST_NATIVE_METHOD(Executable, getParameters0, "()[Ljava/lang/reflect/Parameter;"), FAST_NATIVE_METHOD(Executable, getSignatureAnnotation, "()[Ljava/lang/String;"), FAST_NATIVE_METHOD(Executable, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"), diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index 9cf80a5bf5..9198964f87 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -456,6 +456,13 @@ static jlong Field_getArtField(JNIEnv* env, jobject javaField) { return reinterpret_cast<jlong>(field); } +static jobject Field_getNameInternal(JNIEnv* env, jobject javaField) { + ScopedFastNativeObjectAccess soa(env); + ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); + return soa.AddLocalReference<jobject>( + field->GetStringName(soa.Self(), true /* resolve */)); +} + static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) { ScopedFastNativeObjectAccess soa(env); ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); @@ -506,6 +513,7 @@ static JNINativeMethod gMethods[] = { FAST_NATIVE_METHOD(Field, getFloat, "(Ljava/lang/Object;)F"), FAST_NATIVE_METHOD(Field, getInt, "(Ljava/lang/Object;)I"), FAST_NATIVE_METHOD(Field, getLong, "(Ljava/lang/Object;)J"), + FAST_NATIVE_METHOD(Field, getNameInternal, "()Ljava/lang/String;"), FAST_NATIVE_METHOD(Field, getShort, "(Ljava/lang/Object;)S"), FAST_NATIVE_METHOD(Field, isAnnotationPresentNative, "(Ljava/lang/Class;)Z"), FAST_NATIVE_METHOD(Field, set, "(Ljava/lang/Object;Ljava/lang/Object;)V"), diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc index 6e5e3d9337..6f0130eb15 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -55,7 +55,8 @@ static jobjectArray Method_getExceptionTypes(JNIEnv* env, jobject javaMethod) { ++i; } CHECK_NE(throws_index, -1); - mirror::ObjectArray<mirror::Class>* declared_exceptions = klass->GetThrows()->Get(throws_index); + mirror::ObjectArray<mirror::Class>* declared_exceptions = + klass->GetProxyThrows()->Get(throws_index); return soa.AddLocalReference<jobjectArray>(declared_exceptions->Clone(soa.Self())); } else { mirror::ObjectArray<mirror::Class>* result_array = diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 9fd2c88c3c..e4d9aa1825 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -106,7 +106,6 @@ #include "native/dalvik_system_VMStack.h" #include "native/dalvik_system_ZygoteHooks.h" #include "native/java_lang_Class.h" -#include "native/java_lang_DexCache.h" #include "native/java_lang_Object.h" #include "native/java_lang_String.h" #include "native/java_lang_StringFactory.h" @@ -1539,7 +1538,6 @@ void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { register_dalvik_system_VMStack(env); register_dalvik_system_ZygoteHooks(env); register_java_lang_Class(env); - register_java_lang_DexCache(env); register_java_lang_Object(env); register_java_lang_invoke_MethodHandleImpl(env); register_java_lang_ref_FinalizerReference(env); diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 2610252aa7..54cce98e8c 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -80,7 +80,6 @@ jclass WellKnownClasses::libcore_util_EmptyArray; jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk; jclass WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer; -jmethodID WellKnownClasses::com_android_dex_Dex_create; jmethodID WellKnownClasses::dalvik_system_VMRuntime_runFinalization; jmethodID WellKnownClasses::java_lang_Boolean_valueOf; jmethodID WellKnownClasses::java_lang_Byte_valueOf; @@ -317,7 +316,6 @@ void WellKnownClasses::Init(JNIEnv* env) { org_apache_harmony_dalvik_ddmc_DdmServer = CacheClass(env, "org/apache/harmony/dalvik/ddmc/DdmServer"); dalvik_system_VMRuntime_runFinalization = CacheMethod(env, dalvik_system_VMRuntime, true, "runFinalization", "(J)V"); - com_android_dex_Dex_create = CacheMethod(env, com_android_dex_Dex, true, "create", "(Ljava/nio/ByteBuffer;)Lcom/android/dex/Dex;"); java_lang_ClassNotFoundException_init = CacheMethod(env, java_lang_ClassNotFoundException, false, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V"); java_lang_ClassLoader_loadClass = CacheMethod(env, java_lang_ClassLoader, false, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index db8a53c44c..af4dbbf076 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -90,7 +90,6 @@ struct WellKnownClasses { static jclass org_apache_harmony_dalvik_ddmc_Chunk; static jclass org_apache_harmony_dalvik_ddmc_DdmServer; - static jmethodID com_android_dex_Dex_create; static jmethodID dalvik_system_VMRuntime_runFinalization; static jmethodID java_lang_Boolean_valueOf; static jmethodID java_lang_Byte_valueOf; |