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*/
     }