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