diff options
author | 2017-03-14 13:26:12 +0000 | |
---|---|---|
committer | 2017-03-16 17:56:04 +0000 | |
commit | 6b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bd (patch) | |
tree | a335cae93c0eabae63e39b8bc13ef3e15f4f7e50 | |
parent | f83f3f6ecb1153d96cc8007e8a0d1e35af4d3f38 (diff) |
ART: Get rid of most of java.lang.DexCache.
All remaining functionality is moved over to native. The DexCache
object itself is allocated in the Java heap, even though there's no
longer much of a reason to do so. It can be changed in a future change
if needed.
This also renames mirror::Class:GetInterfaces to GetProxyInterfaces
since it's supposed to be called only for proxies.
Test: test-art-host, cts -m CtsLibcoreTestCases
Change-Id: Ie261f22a9f80c929f01d2b456f170c7a464ba21c
-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; |