Reduce meta-data object sizes, introduce meta-data helper classes.
Change-Id: Id14ad218f1c74c659701352fdf1a45bf6444daa3
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index b85969e..92fb6fa 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -18,6 +18,7 @@
#include "class_linker.h"
#include "class_loader.h"
#include "object.h"
+#include "object_utils.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
@@ -63,6 +64,19 @@
return AddLocalReference<jclass>(env, c);
}
+jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
+ Class* c = Decode<Class*>(env, javaClass);
+ if (c->IsPrimitive() || c->IsArrayClass() || c->IsProxyClass()) {
+ return 0; // primitive, array and proxy classes don't have class definitions
+ }
+ const DexFile::ClassDef* class_def = ClassHelper(c).GetClassDef();
+ if (class_def == NULL) {
+ return 0; // not found
+ } else {
+ return class_def->annotations_off_;
+ }
+}
+
template<typename T>
jobjectArray ToArray(JNIEnv* env, const char* array_class_name, const std::vector<T*>& objects) {
jclass array_class = env->FindClass(array_class_name);
@@ -81,14 +95,10 @@
if (m->IsStatic()) {
return false;
}
- if (m->GetName()->CharAt(0) != '<') {
- return false;
- }
- m->InitJavaFields();
- return true;
+ return m->IsConstructor();
}
-jobjectArray Class_getDeclaredConstructors(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
+jobjectArray Class_getDeclaredConstructors(JNIEnv* env, jclass javaClass, jboolean publicOnly) {
Class* c = Decode<Class*>(env, javaClass);
std::vector<Method*> constructors;
@@ -106,11 +116,10 @@
if (public_only && !f->IsPublic()) {
return false;
}
- f->InitJavaFields();
return true;
}
-jobjectArray Class_getDeclaredFields(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
+jobjectArray Class_getDeclaredFields(JNIEnv* env, jclass javaClass, jboolean publicOnly) {
Class* c = Decode<Class*>(env, javaClass);
std::vector<Field*> fields;
@@ -140,14 +149,13 @@
if (public_only && !m->IsPublic()) {
return false;
}
- if (m->GetName()->CharAt(0) == '<') {
+ if (m->IsConstructor()) {
return false;
}
- m->InitJavaFields();
return true;
}
-jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass, jclass javaClass, jboolean publicOnly) {
+jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass javaClass, jboolean publicOnly) {
Class* c = Decode<Class*>(env, javaClass);
std::vector<Method*> methods;
@@ -188,44 +196,52 @@
return Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache).GetDexObject(env);
}
-jint Class_getNonInnerClassModifiers(JNIEnv* env, jclass, jclass javaClass) {
+jint Class_getNonInnerClassModifiers(JNIEnv* env, jclass javaClass) {
Class* c = Decode<Class*>(env, javaClass);
return c->GetAccessFlags() & kAccJavaFlagsMask;
}
-jobject Class_getClassLoader(JNIEnv* env, jclass, jobject javaClass) {
+jobject Class_getClassLoaderNative(JNIEnv* env, jclass javaClass) {
Class* c = Decode<Class*>(env, javaClass);
Object* result = c->GetClassLoader();
return AddLocalReference<jobject>(env, result);
}
-jclass Class_getComponentType(JNIEnv* env, jobject javaThis) {
- return AddLocalReference<jclass>(env, Decode<Class*>(env, javaThis)->GetComponentType());
+jclass Class_getComponentType(JNIEnv* env, jclass javaClass) {
+ return AddLocalReference<jclass>(env, Decode<Class*>(env, javaClass)->GetComponentType());
}
-bool MethodMatches(Method* m, String* name, const std::string& signature) {
- if (!m->GetName()->Equals(name)) {
+bool MethodMatches(MethodHelper* mh, const std::string& name, ObjectArray<Class>* arg_array) {
+ if (name != mh->GetName()) {
return false;
}
- std::string method_signature = m->GetSignature()->ToModifiedUtf8();
- if (!StringPiece(method_signature).starts_with(signature)) {
+ const DexFile::TypeList* m_type_list = mh->GetParameterTypeList();
+ uint32_t m_type_list_size = m_type_list == NULL ? 0 : m_type_list->Size();
+ uint32_t sig_length = arg_array->GetLength();
+
+ if (m_type_list_size != sig_length) {
return false;
}
- if (m->IsMiranda()) {
- return false;
+
+ for (uint32_t i = 0; i < sig_length; i++) {
+ if (mh->GetClassFromTypeIdx(m_type_list->GetTypeItem(i).type_idx_) != arg_array->Get(i)) {
+ return false;
+ }
}
return true;
}
-Method* FindConstructorOrMethodInArray(ObjectArray<Method>* methods, String* name,
- const std::string& signature) {
+Method* FindConstructorOrMethodInArray(ObjectArray<Method>* methods, const std::string& name,
+ ObjectArray<Class>* arg_array) {
if (methods == NULL) {
return NULL;
}
Method* result = NULL;
+ MethodHelper mh;
for (int32_t i = 0; i < methods->GetLength(); ++i) {
Method* method = methods->Get(i);
- if (!MethodMatches(method, name, signature)) {
+ mh.ChangeMethod(method);
+ if (method->IsMiranda() || !MethodMatches(&mh, name, arg_array)) {
continue;
}
@@ -242,49 +258,42 @@
return result;
}
-jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass,
- jclass javaClass, jstring javaName, jobjectArray javaSignature) {
+jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass javaClass, jstring javaName,
+ jobjectArray javaArgs) {
Class* c = Decode<Class*>(env, javaClass);
- String* name = Decode<String*>(env, javaName);
- ObjectArray<Class>* signature_array = Decode<ObjectArray<Class>*>(env, javaSignature);
+ std::string name = Decode<String*>(env, javaName)->ToModifiedUtf8();
+ ObjectArray<Class>* arg_array = Decode<ObjectArray<Class>*>(env, javaArgs);
- std::string signature;
- signature += "(";
- for (int i = 0; i < signature_array->GetLength(); i++) {
- signature += signature_array->Get(i)->GetDescriptor()->ToModifiedUtf8();
- }
- signature += ")";
-
- Method* m = FindConstructorOrMethodInArray(c->GetDirectMethods(), name, signature);
+ Method* m = FindConstructorOrMethodInArray(c->GetDirectMethods(), name, arg_array);
if (m == NULL) {
- m = FindConstructorOrMethodInArray(c->GetVirtualMethods(), name, signature);
+ m = FindConstructorOrMethodInArray(c->GetVirtualMethods(), name, arg_array);
}
if (m != NULL) {
- m->InitJavaFields();
return AddLocalReference<jobject>(env, m);
} else {
return NULL;
}
}
-jobject Class_getDeclaredField(JNIEnv* env, jclass, jclass jklass, jobject jname) {
+jobject Class_getDeclaredFieldNative(JNIEnv* env, jclass jklass, jobject jname) {
Class* klass = Decode<Class*>(env, jklass);
DCHECK(klass->IsClass());
String* name = Decode<String*>(env, jname);
DCHECK(name->GetClass()->IsStringClass());
+ FieldHelper fh;
for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
Field* f = klass->GetInstanceField(i);
- if (f->GetName()->Equals(name)) {
- f->InitJavaFields();
+ fh.ChangeField(f);
+ if (name->Equals(fh.GetName())) {
return AddLocalReference<jclass>(env, f);
}
}
for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
Field* f = klass->GetStaticField(i);
- if (f->GetName()->Equals(name)) {
- f->InitJavaFields();
+ fh.ChangeField(f);
+ if (name->Equals(fh.GetName())) {
return AddLocalReference<jclass>(env, f);
}
}
@@ -302,7 +311,7 @@
*/
jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
Class* c = Decode<Class*>(env, javaThis);
- std::string descriptor(c->GetDescriptor()->ToModifiedUtf8());
+ std::string descriptor(ClassHelper(c).GetDescriptor());
if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
// The descriptor indicates that this is the class for
// a primitive type; special-case the return value.
@@ -370,7 +379,7 @@
}
// Validate method/field access.
-bool CheckMemberAccess(const Class* access_from, const Class* access_to, uint32_t member_flags) {
+bool CheckMemberAccess(const Class* access_from, Class* access_to, uint32_t member_flags) {
// quick accept for public access */
if (member_flags & kAccPublic) {
return true;
@@ -403,7 +412,7 @@
Class* c = Decode<Class*>(env, javaThis);
if (c->IsPrimitive() || c->IsInterface() || c->IsArrayClass() || c->IsAbstract()) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
- "Class %s can not be instantiated", PrettyDescriptor(c->GetDescriptor()).c_str());
+ "Class %s can not be instantiated", PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str());
return NULL;
}
@@ -414,7 +423,7 @@
Method* init = c->FindDirectMethod("<init>", "()V");
if (init == NULL) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
- "Class %s has no default <init>()V constructor", PrettyDescriptor(c->GetDescriptor()).c_str());
+ "Class %s has no default <init>()V constructor", PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str());
return NULL;
}
@@ -433,18 +442,19 @@
Method* caller_caller = frame.GetMethod();
Class* caller_class = caller_caller->GetDeclaringClass();
+ ClassHelper caller_ch(caller_class);
if (!caller_class->CanAccess(c)) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;",
"Class %s is not accessible from class %s",
- PrettyDescriptor(c->GetDescriptor()).c_str(),
- PrettyDescriptor(caller_class->GetDescriptor()).c_str());
+ PrettyDescriptor(ClassHelper(c).GetDescriptor()).c_str(),
+ PrettyDescriptor(caller_ch.GetDescriptor()).c_str());
return NULL;
}
if (!CheckMemberAccess(caller_class, init->GetDeclaringClass(), init->GetAccessFlags())) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalAccessException;",
"%s is not accessible from class %s",
PrettyMethod(init).c_str(),
- PrettyDescriptor(caller_class->GetDescriptor()).c_str());
+ PrettyDescriptor(caller_ch.GetDescriptor()).c_str());
return NULL;
}
@@ -463,15 +473,16 @@
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
NATIVE_METHOD(Class, desiredAssertionStatus, "()Z"),
- NATIVE_METHOD(Class, getClassLoader, "(Ljava/lang/Class;)Ljava/lang/ClassLoader;"),
+ NATIVE_METHOD(Class, getAnnotationDirectoryOffset, "()I"),
+ NATIVE_METHOD(Class, getClassLoaderNative, "()Ljava/lang/ClassLoader;"),
NATIVE_METHOD(Class, getComponentType, "()Ljava/lang/Class;"),
- NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
- NATIVE_METHOD(Class, getDeclaredConstructors, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;"),
- NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
- NATIVE_METHOD(Class, getDeclaredFields, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;"),
- NATIVE_METHOD(Class, getDeclaredMethods, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;"),
+ NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
+ NATIVE_METHOD(Class, getDeclaredConstructors, "(Z)[Ljava/lang/reflect/Constructor;"),
+ NATIVE_METHOD(Class, getDeclaredFieldNative, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"),
+ NATIVE_METHOD(Class, getDeclaredFields, "(Z)[Ljava/lang/reflect/Field;"),
+ NATIVE_METHOD(Class, getDeclaredMethods, "(Z)[Ljava/lang/reflect/Method;"),
NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"),
- NATIVE_METHOD(Class, getNonInnerClassModifiers, "(Ljava/lang/Class;)I"),
+ NATIVE_METHOD(Class, getNonInnerClassModifiers, "()I"),
NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
NATIVE_METHOD(Class, getSuperclass, "()Ljava/lang/Class;"),
NATIVE_METHOD(Class, isAssignableFrom, "(Ljava/lang/Class;)Z"),