diff options
| author | Dan Bornstein <danfuzz@android.com> | 2011-03-15 14:13:07 -0700 |
|---|---|---|
| committer | Dan Bornstein <danfuzz@android.com> | 2011-03-15 14:13:07 -0700 |
| commit | f1b27b3cfd35dea5ef665c9ba35efc2e34923bca (patch) | |
| tree | 5a59c179143d2218076170b99c751b177f4ff6ed /vm | |
| parent | 65ecc268923edbce15dd772546015157248987d1 (diff) | |
| download | android_dalvik-f1b27b3cfd35dea5ef665c9ba35efc2e34923bca.tar.gz android_dalvik-f1b27b3cfd35dea5ef665c9ba35efc2e34923bca.tar.bz2 android_dalvik-f1b27b3cfd35dea5ef665c9ba35efc2e34923bca.zip | |
Clean up method reference/offset initialization.
Similar to my previous few changes, all of the method lookups got
pulled into one of two new table-driven functions,
initDirectMethodReferences() and initVirtualMethodOffsets().
Change-Id: I382dce9e0b39c9a6f5c90ad49a4a859c5fb2cf42
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/InitRefs.c | 221 | ||||
| -rw-r--r-- | vm/reflect/Proxy.c | 7 |
2 files changed, 88 insertions, 140 deletions
diff --git a/vm/InitRefs.c b/vm/InitRefs.c index e24e45fce..e7894d9fe 100644 --- a/vm/InitRefs.c +++ b/vm/InitRefs.c @@ -262,6 +262,7 @@ static bool initFieldOffsets(void) { if (clazz == NULL) { LOGE("Could not find essential class %s for field lookup\n", className); + continue; } int j; @@ -273,23 +274,20 @@ static bool initFieldOffsets(void) { return ok; } -static bool initConstructorReference(Method** pMethod, const char* name, const char* descriptor) { - ClassObject* clazz = dvmFindSystemClassNoInit(name); +static bool initDirectMethodReference(Method** pMethod, const char* className, + const char* name, const char* descriptor) { + ClassObject* clazz = dvmFindSystemClassNoInit(className); if (clazz == NULL) { - LOGE("Could not find essential class %s for constructor lookup\n", name); + LOGE("Could not find essential class %s for direct method lookup\n", className); + return false; } - /* - * Constructors are direct methods and don't have vtable offsets, which - * is why we resolve constructors to a Method*. - */ - - Method* method = dvmFindDirectMethodByDescriptor(clazz, "<init>", descriptor); + Method* method = dvmFindDirectMethodByDescriptor(clazz, name, descriptor); if (method == NULL) { - LOGE("Could not find essential constructor for class %s with descriptor %s\n", - clazz->descriptor, descriptor); + LOGE("Could not find essential direct method %s.%s with descriptor %s\n", + clazz->descriptor, name, descriptor); return false; } @@ -313,7 +311,6 @@ static bool initConstructorReferences(void) { { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init, "Lorg/apache/harmony/lang/annotation/AnnotationMember;", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V" }, - { NULL, NULL, NULL } }; @@ -321,139 +318,93 @@ static bool initConstructorReferences(void) { int i; for (i = 0; constructors[i].method != NULL; i++) { - ok &= initConstructorReference(constructors[i].method, constructors[i].name, - constructors[i].descriptor); + ok &= initDirectMethodReference(constructors[i].method, constructors[i].name, + "<init>", constructors[i].descriptor); } return ok; } -static bool find2(void) { - ClassObject* clClass = dvmFindSystemClassNoInit("Ljava/lang/ClassLoader;"); - Method* meth = dvmFindVirtualMethodByDescriptor(clClass, "loadClass", - "(Ljava/lang/String;)Ljava/lang/Class;"); - if (meth == NULL) { - LOGE("Unable to find loadClass() in java.lang.ClassLoader\n"); - return false; - } - gDvm.voffJavaLangClassLoader_loadClass = meth->methodIndex; - - return true; -} - -static bool find3(void) { - assert(gDvm.classJavaLangThread != NULL); - assert(gDvm.classJavaLangThreadGroup != NULL); - assert(gDvm.classJavaLangVMThread != NULL); +static bool initDirectMethodReferences(void) { + static struct { + Method** method; + const char* className; + const char* name; + const char* descriptor; + } methods[] = { + { &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;", + "constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" }, + { &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" }, + { &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" }, + { &gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation, + "Lorg/apache/harmony/lang/annotation/AnnotationFactory;", "createAnnotation", + "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)" + "Ljava/lang/annotation/Annotation;" }, + { NULL, NULL, NULL, NULL } + }; - /* - * Cache the vtable offset for "run()". - * - * We don't want to keep the Method* because then we won't find see - * methods defined in subclasses. - */ - Method* meth; - meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V"); - if (meth == NULL) { - LOGE("Unable to find run() in java.lang.Thread\n"); - return false; - } - gDvm.voffJavaLangThread_run = meth->methodIndex; + bool ok = true; + int i; - /* - * Cache vtable offsets for ThreadGroup methods. - */ - meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup, - "removeThread", "(Ljava/lang/Thread;)V"); - if (meth == NULL) { - LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n"); - return false; + for (i = 0; methods[i].method != NULL; i++) { + ok &= initDirectMethodReference(methods[i].method, methods[i].className, + methods[i].name, methods[i].descriptor); } - gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex; - return true; + return ok; } -static bool find6() -{ - /* - * Standard methods we must provide in our proxy. - */ - Method* methE; - Method* methH; - Method* methT; - Method* methF; - methE = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, - "equals", "(Ljava/lang/Object;)Z"); - methH = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, - "hashCode", "()I"); - methT = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, - "toString", "()Ljava/lang/String;"); - methF = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, - "finalize", "()V"); - if (methE == NULL || methH == NULL || methT == NULL || methF == NULL) { - LOGE("Could not find equals/hashCode/toString/finalize in Object\n"); +static bool initVirtualMethodOffset(int* pOffset, const char* className, + const char* name, const char* descriptor) { + ClassObject* clazz = dvmFindSystemClassNoInit(className); + + if (clazz == NULL) { + LOGE("Could not find essential class %s for virtual method lookup\n", className); return false; } - gDvm.voffJavaLangObject_equals = methE->methodIndex; - gDvm.voffJavaLangObject_hashCode = methH->methodIndex; - gDvm.voffJavaLangObject_toString = methT->methodIndex; - gDvm.voffJavaLangObject_finalize = methF->methodIndex; - /* - * The prototype signature needs to be cloned from a method in a - * "real" DEX file. We declared this otherwise unused method just - * for this purpose. - */ - Method* meth; + Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor); - meth = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangReflectProxy, "constructorPrototype", - "(Ljava/lang/reflect/InvocationHandler;)V"); - if (meth == NULL) { - LOGE("Could not find java.lang.Proxy.constructorPrototype()\n"); + if (method == NULL) { + LOGE("Could not find essential virtual method %s.%s with descriptor %s\n", + clazz->descriptor, name, descriptor); return false; } - gDvm.methJavaLangReflectProxy_constructorPrototype = meth; + *pOffset = method->methodIndex; return true; } -/* - * Perform Annotation setup. - */ -static bool find7(void) -{ - Method* meth; - - meth = dvmFindDirectMethodByDescriptor(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory, - "createAnnotation", - "(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)Ljava/lang/annotation/Annotation;"); - if (meth == NULL) { - LOGE("Unable to find createAnnotation() in android AnnotationFactory\n"); - return false; - } - gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation = meth; - +static bool initVirtualMethodOffsets(void) { + static struct { + int* offset; + const char* className; + const char* name; + const char* descriptor; + } methods[] = { + { &gDvm.voffJavaLangClassLoader_loadClass, "Ljava/lang/ClassLoader;", "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;" }, + { &gDvm.voffJavaLangObject_equals, "Ljava/lang/Object;", "equals", + "(Ljava/lang/Object;)Z" }, + { &gDvm.voffJavaLangObject_finalize, "Ljava/lang/Object;", "finalize", "()V" }, + { &gDvm.voffJavaLangObject_hashCode, "Ljava/lang/Object;", "hashCode", "()I" }, + { &gDvm.voffJavaLangObject_toString, "Ljava/lang/Object;", "toString", + "()Ljava/lang/String;" }, + { &gDvm.voffJavaLangThread_run, "Ljava/lang/Thread;", "run", "()V" }, + { &gDvm.voffJavaLangThreadGroup_removeThread, "Ljava/lang/ThreadGroup;", + "removeThread", "(Ljava/lang/Thread;)V" }, + { NULL, NULL, NULL, NULL } + }; - return true; -} + bool ok = true; + int i; -static bool find8(void) { - ClassObject* clazz = - dvmFindClassNoInit("Ldalvik/system/VMDebug;", NULL); - assert(clazz != NULL); - gDvm.methodTraceGcMethod = - dvmFindDirectMethodByDescriptor(clazz, "startGC", "()V"); - gDvm.methodTraceClassPrepMethod = - dvmFindDirectMethodByDescriptor(clazz, "startClassPrep", "()V"); - if (gDvm.methodTraceGcMethod == NULL || - gDvm.methodTraceClassPrepMethod == NULL) - { - LOGE("Unable to find startGC or startClassPrep\n"); - return false; + for (i = 0; methods[i].offset != NULL; i++) { + ok &= initVirtualMethodOffset(methods[i].offset, methods[i].className, + methods[i].name, methods[i].descriptor); } - return true; + return ok; } static bool find9(void) { @@ -497,11 +448,8 @@ bool dvmFindRequiredClassesAndMembers(void) { ok &= initClassReferences(); ok &= initFieldOffsets(); ok &= initConstructorReferences(); - ok &= find2(); - ok &= find3(); - ok &= find6(); - ok &= find7(); - ok &= find8(); + ok &= initDirectMethodReferences(); + ok &= initVirtualMethodOffsets(); ok &= find9(); return ok; @@ -521,21 +469,14 @@ bool dvmFindReferenceMembers(ClassObject* classReference) { bool ok = true; - gDvm.offJavaLangRefReference_referent = - dvmFindFieldOffset(classReference, "referent", "Ljava/lang/Object;"); - ok &= (gDvm.offJavaLangRefReference_referent >= 0); - - gDvm.offJavaLangRefReference_queue = - dvmFindFieldOffset(classReference, "queue", "Ljava/lang/ref/ReferenceQueue;"); - ok &= (gDvm.offJavaLangRefReference_queue >= 0); - - gDvm.offJavaLangRefReference_queueNext = - dvmFindFieldOffset(classReference, "queueNext", "Ljava/lang/ref/Reference;"); - ok &= (gDvm.offJavaLangRefReference_queueNext >= 0); - - gDvm.offJavaLangRefReference_pendingNext = - dvmFindFieldOffset(classReference, "pendingNext", "Ljava/lang/ref/Reference;"); - ok &= (gDvm.offJavaLangRefReference_pendingNext >= 0); + ok &= initFieldOffset(classReference, &gDvm.offJavaLangRefReference_pendingNext, + "pendingNext", "Ljava/lang/ref/Reference;"); + ok &= initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queue, + "queue", "Ljava/lang/ref/ReferenceQueue;"); + ok &= initFieldOffset(classReference, &gDvm.offJavaLangRefReference_queueNext, + "queueNext", "Ljava/lang/ref/Reference;"); + ok &= initFieldOffset(classReference, &gDvm.offJavaLangRefReference_referent, + "referent", "Ljava/lang/Object;"); /* enqueueInternal() is private and thus a direct method. */ Method *meth = dvmFindDirectMethodByDescriptor(classReference, "enqueueInternal", "()Z"); diff --git a/vm/reflect/Proxy.c b/vm/reflect/Proxy.c index 7b413608c..60483de1a 100644 --- a/vm/reflect/Proxy.c +++ b/vm/reflect/Proxy.c @@ -728,6 +728,13 @@ static bool returnTypesAreCompatible(Method* subMethod, Method* baseMethod) */ static void createConstructor(ClassObject* clazz, Method* meth) { + /* + * The constructor signatures (->prototype and ->shorty) need to + * be cloned from a method in a "real" DEX file. We declared the + * otherwise unused method Proxy.constructorPrototype() just for + * this purpose. + */ + meth->clazz = clazz; meth->accessFlags = ACC_PUBLIC | ACC_NATIVE; meth->name = "<init>"; |
