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/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?)");