As described in the JVM spec in "2.17.5 Detailed Initialization Procedure":
http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#24237

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/class.h |   13 ++++++++++---
 vm/class.c         |   40 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/include/vm/class.h b/include/vm/class.h
index b827afc..d933e84 100644
--- a/include/vm/class.h
+++ b/include/vm/class.h
@@ -7,6 +7,7 @@
 #include "vm/field.h"
 #include "vm/itable.h"
 #include "vm/method.h"
+#include "vm/object.h"
 #include "vm/static.h"
 #include "vm/types.h"
 #include "vm/vm.h"
@@ -14,6 +15,8 @@
 #include "jit/vtable.h"
 
 struct vm_object;
+struct vm_monitor;
+struct vm_thread;
 
 enum vm_class_state {
        VM_CLASS_LOADED,
@@ -35,6 +38,13 @@ struct vm_class {
        enum vm_class_state state;
        char *name;
 
+       /*
+        * This monitor is used during class initialization because the one
+        * in ->object is not yet created.
+        */
+       struct vm_monitor monitor;
+       struct vm_thread *initializing_thread;
+
        struct vm_class *super;
        unsigned int nr_interfaces;
        struct vm_class **interfaces;
@@ -78,9 +88,6 @@ int vm_class_init(struct vm_class *vmc);
 
 static inline int vm_class_ensure_init(struct vm_class *vmc)
 {
-       if (vmc->state == VM_CLASS_INITIALIZED)
-               return 0;
-
        return vm_class_init(vmc);
 }
 
diff --git a/vm/class.c b/vm/class.c
index dd5d0ef..43f6a97 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -45,6 +45,7 @@
 #include "vm/itable.h"
 #include "vm/method.h"
 #include "vm/object.h"
+#include "vm/thread.h"
 #include "lib/string.h"
 #include "vm/vm.h"
 
@@ -132,6 +133,10 @@ static int vm_class_link_common(struct vm_class *vmc)
        if (err)
                return -err;
 
+       err = vm_monitor_init(&vmc->monitor);
+       if (err)
+               return -err;
+
        return 0;
 }
 
@@ -414,16 +419,33 @@ int vm_class_init(struct vm_class *vmc)
 {
        struct vm_object *exception;
 
+       vm_monitor_lock(&vmc->monitor);
+
+       if (vmc->state == VM_CLASS_INITIALIZING) {
+               /* XXX: we need to break recursion. */
+               if (vmc->initializing_thread == vm_thread_self())
+                       goto out_unlock;
+
+               while (vmc->state == VM_CLASS_INITIALIZING)
+                       vm_monitor_wait(&vmc->monitor);
+       }
+
+       if (vmc->state == VM_CLASS_INITIALIZED)
+               goto out_unlock;
+
        if (vmc->state == VM_CLASS_ERRONEOUS) {
                signal_new_exception(vm_java_lang_NoClassDefFoundError,
                                     vmc->name);
-               goto error;
+               vm_monitor_unlock(&vmc->monitor);
+               return -1;
        }
 
        assert(vmc->state == VM_CLASS_LINKED);
 
-       /* XXX: Not entirely true, but we need it to break the recursion. */
-       vmc->state = VM_CLASS_INITIALIZED;
+       vmc->state = VM_CLASS_INITIALIZING;
+       vmc->initializing_thread = vm_thread_self();
+
+       vm_monitor_unlock(&vmc->monitor);
 
        /* Fault injection, for testing purposes */
        if (vm_fault_enabled(VM_FAULT_CLASS_INIT)) {
@@ -475,6 +497,15 @@ int vm_class_init(struct vm_class *vmc)
                }
        }
 
+       vm_monitor_lock(&vmc->monitor);
+       vmc->state = VM_CLASS_INITIALIZED;
+       vm_monitor_notify_all(&vmc->monitor);
+       vm_monitor_unlock(&vmc->monitor);
+
+       return 0;
+
+ out_unlock:
+       vm_monitor_unlock(&vmc->monitor);
        return 0;
 
  error:
@@ -487,7 +518,10 @@ int vm_class_init(struct vm_class *vmc)
                        vmc->name);
        }
 
+       vm_monitor_lock(&vmc->monitor);
        vmc->state = VM_CLASS_ERRONEOUS;
+       vm_monitor_notify_all(&vmc->monitor);
+       vm_monitor_unlock(&vmc->monitor);
 
        return -1;
 }
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to