Yet more InitRefs-ing
Fix up some early initialization stuff.
Also, stop pretending that the top of non-main-thread stacks is a
Runnable.
Change-Id: I3e89c6320351c160cfa0bea3cf6bbfd26a5b7c12
diff --git a/vm/Globals.h b/vm/Globals.h
index a197fd7..9d697ce 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -325,6 +325,7 @@
int offJavaLangThread_name;
int offJavaLangThread_priority;
int offJavaLangThread_uncaughtHandler;
+ int offJavaLangThread_contextClassLoader;
/* method offsets - Thread */
int voffJavaLangThread_run;
@@ -347,6 +348,9 @@
/* method offsets - ClassLoader */
int voffJavaLangClassLoader_loadClass;
+ /* direct method pointers - ClassLoader */
+ Method* methJavaLangClassLoader_getSystemClassLoader;
+
/* field offsets - java.lang.reflect.* */
int offJavaLangReflectAccessibleObject_flag;
int offJavaLangReflectConstructor_slot;
@@ -366,7 +370,7 @@
Method* methJavaLangRefReference_enqueueInternal;
/* more method pointers - java.lang.ref.FinalizerReference */
- Method* methJavaLangRefFinalizerReferenceAdd;
+ Method* methJavaLangRefFinalizerReferenceAdd;
/* constructor method pointers; no vtable involved, so use Method* */
Method* methJavaLangStackTraceElement_init;
@@ -388,8 +392,9 @@
/* field offsets - java.io.FileDescriptor */
int offJavaIoFileDescriptor_descriptor;
- /* fake native entry point method */
- Method* methFakeNativeEntry;
+ /* direct method pointers - dalvik.system.NativeStart */
+ Method* methDalvikSystemNativeStart_main;
+ Method* methDalvikSystemNativeStart_run;
/* assorted direct buffer helpers */
Method* methJavaNioReadWriteDirectByteBuffer_init;
diff --git a/vm/InitRefs.c b/vm/InitRefs.c
index a1ca1b1..4855697 100644
--- a/vm/InitRefs.c
+++ b/vm/InitRefs.c
@@ -278,12 +278,13 @@
};
static struct FieldInfo infoThread[] = {
- { &gDvm.offJavaLangThread_vmThread, "vmThread", "Ljava/lang/VMThread;" },
- { &gDvm.offJavaLangThread_group, "group", "Ljava/lang/ThreadGroup;" },
- { &gDvm.offJavaLangThread_daemon, "daemon", "Z" },
- { &gDvm.offJavaLangThread_name, "name", "Ljava/lang/String;" },
- { &gDvm.offJavaLangThread_priority, "priority", "I" },
- { &gDvm.offJavaLangThread_uncaughtHandler, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;" },
+ { &gDvm.offJavaLangThread_vmThread, "vmThread", "Ljava/lang/VMThread;" },
+ { &gDvm.offJavaLangThread_group, "group", "Ljava/lang/ThreadGroup;" },
+ { &gDvm.offJavaLangThread_daemon, "daemon", "Z" },
+ { &gDvm.offJavaLangThread_name, "name", "Ljava/lang/String;" },
+ { &gDvm.offJavaLangThread_priority, "priority", "I" },
+ { &gDvm.offJavaLangThread_uncaughtHandler, "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;" },
+ { &gDvm.offJavaLangThread_contextClassLoader, "contextClassLoader", "Ljava/lang/ClassLoader;" },
{ NULL, NULL, NULL }
};
@@ -440,6 +441,8 @@
const char* name;
const char* descriptor;
} methods[] = {
+ { &gDvm.methJavaLangClassLoader_getSystemClassLoader, "Ljava/lang/ClassLoader;",
+ "getSystemClassLoader", "()Ljava/lang/ClassLoader;" },
{ &gDvm.methJavaLangReflectProxy_constructorPrototype, "Ljava/lang/reflect/Proxy;",
"constructorPrototype", "(Ljava/lang/reflect/InvocationHandler;)V" },
{ &gDvm.methodTraceGcMethod, "Ldalvik/system/VMDebug;", "startGC", "()V" },
@@ -449,6 +452,8 @@
"(Ljava/lang/Class;[Lorg/apache/harmony/lang/annotation/AnnotationMember;)"
"Ljava/lang/annotation/Annotation;" },
{ &gDvm.methodTraceClassPrepMethod, "Ldalvik/system/VMDebug;", "startClassPrep", "()V" },
+ { &gDvm.methDalvikSystemNativeStart_main, "Ldalvik/system/NativeStart;", "main", "([Ljava/lang/String;)V" },
+ { &gDvm.methDalvikSystemNativeStart_run, "Ldalvik/system/NativeStart;", "run", "()V" },
{ &gDvm.methJavaLangRefFinalizerReferenceAdd,
"Ljava/lang/ref/FinalizerReference;", "add", "(Ljava/lang/Object;)V" },
{ NULL, NULL, NULL, NULL }
diff --git a/vm/Jni.c b/vm/Jni.c
index e39a065..58e5459 100644
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -1462,7 +1462,7 @@
/* hack for JNI_OnLoad */
assert(strcmp(thisMethod->name, "nativeLoad") == 0);
loader = _self->classLoaderOverride;
- } else if (thisMethod == gDvm.methFakeNativeEntry) {
+ } else if (thisMethod == gDvm.methDalvikSystemNativeStart_main) {
/* start point of invocation interface */
if (!gDvm.initializing)
loader = trackedLoader = dvmGetSystemClassLoader();
diff --git a/vm/Thread.c b/vm/Thread.c
index a1558ce..cc3d1c4 100644
--- a/vm/Thread.c
+++ b/vm/Thread.c
@@ -774,27 +774,22 @@
thread->threadObj = threadObj;
/*
- * Set the context class loader. This invokes a ClassLoader method,
- * which could conceivably call Thread.currentThread(), so we want the
- * Thread to be fully configured before we do this.
+ * Set the "context class loader" field in the system class loader.
+ *
+ * Retrieving the system class loader will cause invocation of
+ * ClassLoader.getSystemClassLoader(), which could conceivably call
+ * Thread.currentThread(), so we want the Thread to be fully configured
+ * before we do this.
*/
Object* systemLoader = dvmGetSystemClassLoader();
if (systemLoader == NULL) {
LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
- /* keep going */
+ /* keep going? */
+ } else {
+ dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_contextClassLoader,
+ systemLoader);
+ dvmReleaseTrackedAlloc(systemLoader, NULL);
}
- int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
- "contextClassLoader", "Ljava/lang/ClassLoader;");
- if (ctxtClassLoaderOffset < 0) {
- LOGE("Unable to find contextClassLoader field in Thread\n");
- return false;
- }
- dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
- dvmReleaseTrackedAlloc(systemLoader, NULL);
-
- /*
- * Finish our thread prep.
- */
/* include self in non-daemon threads (mainly for AttachCurrentThread) */
gDvm.nonDaemonThreadCount++;
@@ -1136,54 +1131,31 @@
*/
static bool createFakeEntryFrame(Thread* thread)
{
- assert(thread->threadId == kMainThreadId); // main thread only
+ /*
+ * Because we are creating a frame that represents application code, we
+ * want to stuff the application class loader into the method's class
+ * loader field, even though we're using the system class loader to
+ * load it. This makes life easier over in JNI FindClass (though it
+ * could bite us in other ways).
+ *
+ * Unfortunately this is occurring too early in the initialization,
+ * of necessity coming before JNI is initialized, and we're not quite
+ * ready to set up the application class loader. Also, overwriting
+ * the class' defining classloader pointer seems unwise.
+ *
+ * Instead, we save a pointer to the method and explicitly check for
+ * it in FindClass. The method is private so nobody else can call it.
+ */
- /* find the method on first use */
- if (gDvm.methFakeNativeEntry == NULL) {
- ClassObject* nativeStart;
- Method* mainMeth;
+ assert(thread->threadId == kMainThreadId); /* main thread only */
- nativeStart = dvmFindSystemClassNoInit(
- "Ldalvik/system/NativeStart;");
- if (nativeStart == NULL) {
- LOGE("Unable to find dalvik.system.NativeStart class\n");
- return false;
- }
-
- /*
- * Because we are creating a frame that represents application code, we
- * want to stuff the application class loader into the method's class
- * loader field, even though we're using the system class loader to
- * load it. This makes life easier over in JNI FindClass (though it
- * could bite us in other ways).
- *
- * Unfortunately this is occurring too early in the initialization,
- * of necessity coming before JNI is initialized, and we're not quite
- * ready to set up the application class loader.
- *
- * So we save a pointer to the method in gDvm.methFakeNativeEntry
- * and check it in FindClass. The method is private so nobody else
- * can call it.
- */
- //nativeStart->classLoader = dvmGetSystemClassLoader();
-
- mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
- "main", "([Ljava/lang/String;)V");
- if (mainMeth == NULL) {
- LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
- return false;
- }
-
- gDvm.methFakeNativeEntry = mainMeth;
- }
-
- if (!dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry))
+ if (!dvmPushJNIFrame(thread, gDvm.methDalvikSystemNativeStart_main))
return false;
/*
* Null out the "String[] args" argument.
*/
- assert(gDvm.methFakeNativeEntry->registersSize == 1);
+ assert(gDvm.methDalvikSystemNativeStart_main->registersSize == 1);
u4* framePtr = (u4*) thread->curFrame;
framePtr[0] = 0;
@@ -1198,41 +1170,7 @@
*/
static bool createFakeRunFrame(Thread* thread)
{
- ClassObject* nativeStart;
- Method* runMeth;
-
- /*
- * TODO: cache this result so we don't have to dig for it every time
- * somebody attaches a thread to the VM. Also consider changing this
- * to a static method so we don't have a null "this" pointer in the
- * "ins" on the stack. (Does it really need to look like a Runnable?)
- */
- nativeStart = dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
- if (nativeStart == NULL) {
- LOGE("Unable to find dalvik.system.NativeStart class\n");
- return false;
- }
-
- runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
- if (runMeth == NULL) {
- LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
- return false;
- }
-
- if (!dvmPushJNIFrame(thread, runMeth))
- return false;
-
- /*
- * Provide a NULL 'this' argument. The method we've put at the top of
- * the stack looks like a virtual call to run() in a Runnable class.
- * (If we declared the method static, it wouldn't take any arguments
- * and we wouldn't have to do this.)
- */
- assert(runMeth->registersSize == 1);
- u4* framePtr = (u4*) thread->curFrame;
- framePtr[0] = 0;
-
- return true;
+ return dvmPushJNIFrame(thread, gDvm.methDalvikSystemNativeStart_run);
}
/*
@@ -3441,14 +3379,9 @@
groupObj = (Object*) dvmGetFieldObject(threadObj,
gDvm.offJavaLangThread_group);
if (groupObj != NULL) {
- int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
- "name", "Ljava/lang/String;");
- if (offset < 0) {
- LOGW("Unable to find 'name' field in ThreadGroup\n");
- } else {
- nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
- groupName = dvmCreateCstrFromString(nameStr);
- }
+ nameStr = (StringObject*)
+ dvmGetFieldObject(groupObj, gDvm.offJavaLangThreadGroup_name);
+ groupName = dvmCreateCstrFromString(nameStr);
}
if (groupName == NULL)
groupName = strdup("(null; initializing?)");
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index a054bdc..1206383 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -4656,22 +4656,15 @@
Object* dvmGetSystemClassLoader(void)
{
Thread* self = dvmThreadSelf();
- ClassObject* clazz;
- Method* getSysMeth;
- Object* loader;
+ ClassObject* clClass = gDvm.classJavaLangClassLoader;
- clazz = dvmFindSystemClass("Ljava/lang/ClassLoader;");
- if (clazz == NULL)
- return NULL;
-
- getSysMeth = dvmFindDirectMethodByDescriptor(clazz, "getSystemClassLoader",
- "()Ljava/lang/ClassLoader;");
- if (getSysMeth == NULL)
+ if (!dvmIsClassInitialized(clClass) && !dvmInitClass(clClass))
return NULL;
JValue result;
- dvmCallMethod(self, getSysMeth, NULL, &result);
- loader = (Object*)result.l;
+ dvmCallMethod(self, gDvm.methJavaLangClassLoader_getSystemClassLoader,
+ NULL, &result);
+ Object* loader = (Object*)result.l;
dvmAddTrackedAlloc(loader, self);
return loader;
}