You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by dl...@apache.org on 2007/08/13 00:24:07 UTC
svn commit: r565182 -
/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c
Author: dlydick
Date: Sun Aug 12 15:24:05 2007
New Revision: 565182
URL: http://svn.apache.org/viewvc?view=rev&rev=565182
Log:
Process 'clinit' method during system startup on a single
thread. Though not technically required, it is suggested
as a way to keep initialization more understandable.
Modified:
harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c
Modified: harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c?view=diff&rev=565182&r1=565181&r2=565182
==============================================================================
--- harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c (original)
+++ harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/thread.c Sun Aug 12 15:24:05 2007
@@ -317,16 +317,21 @@
*
* As a variation, allocate the system thread
* (@link #JVMCFG_SYSTEM_THREAD JVMCFG_SYSTEM_THREAD@endlink)
- * for an internal task. This method-- thread_new_common()-- is the
+ * for an internal task. The method thread_new_common() is the
* common routine, where thread_new() is the general-purpose function
* and thread_new_system() is for loading a class onto the system
* thread.
*
+ * Use of @b isrunningsystemthread is part of an attempt to keep
+ * JVM startup simpler by only running @c @b \<clinit\> methods
+ * on the system thread. (This is not technically required, but
+ * is only in the interest of this simplification.)
+ *
* @warning Do @e not attempt to call this function
* with @b codeatridx set to @link #jvm_attribute_index_native
jvm_attribute_index_native@endlink because this code
* does not apply to native methods. Call that native
- * method directly from the code instead!
+ * method directly from the opcode processing logic instead!
*
* @param thridx Thread index of unused thread-- passed only to
* @link #thread_new_common()
@@ -348,6 +353,23 @@
* @param isdaemon Daemon thread, @link #rtrue rtrue@endlink or
* @link #rfalse rfalse@endlink
*
+ * @param isrunningsystemthread The requested thread is actually
+ * the system thread, but is @e not a new request.
+ * Instead, it is a request for use of the
+ * system thread while that thread is already
+ * in use. This is typically done when invoking
+ * the @b NEW opcode during initialization, that
+ * is, when no other threads are running, and
+ * an initialization method requests use of
+ * thread resources. Meaningful only when
+ * @b thridx parameter requests the system thread
+ * @link #JVMCFG_SYSTEM_THREAD
+ JVMCFG_SYSTEM_THREAD@endlink. When used,
+ * the @b priority and @b isdaemon parameters
+ * are ignored. If the system thread is not
+ * in use, then this parameter is ignored and
+ * the system thread will be assigned.
+ *
*
* @returns index to thread slot containing this thread.
*
@@ -384,20 +406,11 @@
jvm_attribute_index codeatridx,
jvm_attribute_index excpatridx,
rint priority,
- rboolean isdaemon)
+ rboolean isdaemon,
+ rboolean isrunningsystemthread)
{
ARCH_FUNCTION_NAME(thread_new_common);
- /*
- * Declare slot in use, but not initialized.
- * (Redundant for most situations where
- * thread_allocate_slot() was called, but needed
- * for initializing classes like JVMCFG_NULL_THREAD
- * or JVMCFG_SYSTEM_THREAD with an absolute slot
- * number that was not searched for by the allocator.)
- */
- THREAD(thridx).status = THREAD_STATUS_INUSE | THREAD_STATUS_NULL;
-
/* Check for stack overflow if this frame is loaded */
ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
Code_attribute *pca =
@@ -429,6 +442,41 @@
/*NOTREACHED*/
}
+ /*
+ * Process exceptional case first. This is typically for
+ * processing of a @c @b \<clinit\> method during JVM startup.
+ */
+ if ((JVMCFG_SYSTEM_THREAD == thridx) &&
+ (rtrue == isrunningsystemthread) &&
+ (THREAD(thridx).status & THREAD_STATUS_INUSE) &&
+ (!(THREAD(thridx).status & THREAD_STATUS_NULL)))
+ {
+ /*
+ * Save old stack frame for @b RETURN from @c @b \<clinit\>
+ */
+ PUSH_FRAME(thridx, pca->max_locals);
+
+ /* Load PC of @c @b \<clinit\> method */
+ PUT_PC_IMMEDIATE(thridx,
+ clsidx,
+ mthidx,
+ codeatridx,
+ excpatridx,
+ CODE_CONSTRAINT_START_PC);
+
+ return(thridx);
+ }
+
+ /*
+ * Declare slot in use, but not initialized.
+ * (Redundant for most situations where
+ * thread_allocate_slot() was called, but needed
+ * for initializing classes like JVMCFG_NULL_THREAD
+ * or JVMCFG_SYSTEM_THREAD with an absolute slot
+ * number that was not searched for by the allocator.)
+ */
+ THREAD(thridx).status = THREAD_STATUS_INUSE | THREAD_STATUS_NULL;
+
/*!
* @internal If no stack overflow would occur during execution,
* continue to load up a new thread. Unless this class
@@ -509,7 +557,7 @@
}
/*
- * First two word of stack are reserved
+ * First word of stack is reserved
*/
PUT_SP_IMMEDIATE(thridx, JVMCFG_NULL_SP);
@@ -617,23 +665,45 @@
{
ARCH_FUNCTION_NAME(thread_new_system);
+ jvm_thread_index thridx = JVMCFG_SYSTEM_THREAD;
+ rboolean isrunningsystemthread = rfalse;
+
/* Check if system thread is already in use */
- if (THREAD(JVMCFG_SYSTEM_THREAD).status & THREAD_STATUS_INUSE)
+ if (THREAD(thridx).status & THREAD_STATUS_INUSE)
{
- /* Somebody goofed */
- exit_throw_exception(EXIT_JVM_INTERNAL,
- JVMCLASS_JAVA_LANG_INTERNALERROR);
+ /*
+ * Normally the system thread is a mutually exclusive resource,
+ * but not until the machine is completely initialized.
+ */
+ if ((rtrue == jvm_completely_initialized) ||
+ (THREAD(thridx).status & THREAD_STATUS_NULL))
+ {
+ /* Somebody goofed */
+ exit_throw_exception(EXIT_JVM_INTERNAL,
+ JVMCLASS_JAVA_LANG_INTERNALERROR);
/*NOTREACHED*/
+ }
+
+#if 0
+#warning Is this appropriate? Or should it always throw an error?
+#endif
+ /*
+ * Use system thread that had other activity on its stack,
+ * but running a <clinit>, for example, on top of this
+ * should not affect that activity.
+ */
+ isrunningsystemthread = rtrue;
}
/* If not already in use, reserve it and perform thread setup */
- return(thread_new_common(JVMCFG_SYSTEM_THREAD,
+ return(thread_new_common(thridx,
clsidx,
mthidx,
codeatridx,
excpatridx,
priority,
- isdaemon));
+ isdaemon,
+ isrunningsystemthread));
} /* END of thread_new_system() */
@@ -664,7 +734,8 @@
codeatridx,
excpatridx,
priority,
- isdaemon));
+ isdaemon,
+ rfalse));
} /* END of thread_new() */
@@ -877,6 +948,14 @@
{
exit_throw_exception(EXIT_JVM_ATTRIBUTE,
JVMCLASS_JAVA_LANG_NOSUCHMETHODERROR);
+/* NOTREACHED*/
+ }
+
+ /* Typically will not happen-- if have valid method,also have code*/
+ if (jvm_attribute_index_abstract == codeatridx)
+ {
+ exit_throw_exception(EXIT_JVM_ATTRIBUTE,
+ JVMCLASS_JAVA_LANG_ABSTRACTMETHODERROR);
/* NOTREACHED*/
}