We should not call class initialization from convert_ldc, and
from compilation in general. That's because class initalization
may trigger compilation of method that caused the initialization
which will result in a dead lock.

We must however return correct class object, so vm_class_ensure_object()
is introduced.

This bug was noticed while running frozenbubble:
[main]  [<0807531f>] native     : jit_magic_trampoline+5d 
(/home/tomek/projects/jato/jato/jit/trampoline.c:123)
[main]  [<a7d592bc>] trampoline : 
gnu/java/security/provider/Gnu$1.run(Gnu.java:64)
[main]  [<a7ccea85>] jit        : 
java/security/AccessController.doPrivileged(AccessController.java:96)
[main]  [<a7d5938e>] jit        : 
gnu/java/security/provider/Gnu.<init>(Gnu.java:55)
[main]  [<a7d6e294>] jit        : 
gnu/java/security/jce/sig/DSSParametersGenerator.<clinit>(DSSParametersGenerator.java:64)
[main]  [<0807c481>] native     : vm_class_init+25e 
(/home/tomek/projects/jato/jato/vm/class.c:561)
[main]  [<0806f91d>] native     : vm_class_ensure_init+19df2 
(/home/tomek/projects/jato/jato/include/vm/class.h:96)
[main]  [<0806f811>] native     : __convert_ldc+281 
(/home/tomek/projects/jato/jato/jit/load-store-bc.c:152)
[main]  [<0806f986>] native     : convert_ldc_w+2b 
(/home/tomek/projects/jato/jato/jit/load-store-bc.c:185)
[main]  [<0806948e>] native     : convert_instruction+a1 
(/home/tomek/projects/jato/jato/jit/bytecode-to-ir.c:165)
[main]  [<08069571>] native     : do_convert_bb_to_ir+da 
(/home/tomek/projects/jato/jato/jit/bytecode-to-ir.c:190)
[main]  [<080695b4>] native     : convert_bb_to_ir+27 
(/home/tomek/projects/jato/jato/jit/bytecode-to-ir.c:206)
[main]  [<08069ab2>] native     : convert_to_ir+13 
(/home/tomek/projects/jato/jato/jit/bytecode-to-ir.c:405)
[main]  [<0806ab12>] native     : compile+75 
(/home/tomek/projects/jato/jato/jit/compiler.c:70)
[main]  [<0807522d>] native     : jit_java_trampoline+10 
(/home/tomek/projects/jato/jato/jit/trampoline.c:96)
[main]  [<08075364>] native     : jit_magic_trampoline+a2 
(/home/tomek/projects/jato/jato/jit/trampoline.c:133)
[main]  [<a7d592bc>] trampoline : 
gnu/java/security/provider/Gnu$1.run(Gnu.java:64)

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/class.h  |    1 +
 jit/load-store-bc.c |    3 +--
 vm/class.c          |   41 +++++++++++++++++++++++++++++------------
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/include/vm/class.h b/include/vm/class.h
index 54e49b2..7c8af6c 100644
--- a/include/vm/class.h
+++ b/include/vm/class.h
@@ -90,6 +90,7 @@ int vm_class_link(struct vm_class *vmc, const struct 
cafebabe_class *class);
 int vm_class_link_primitive_class(struct vm_class *vmc, const char 
*class_name);
 int vm_class_link_array_class(struct vm_class *vmc, const char *class_name);
 int vm_class_init(struct vm_class *vmc);
+int vm_class_ensure_object(struct vm_class *vmc);
 
 static inline int vm_class_ensure_init(struct vm_class *vmc)
 {
diff --git a/jit/load-store-bc.c b/jit/load-store-bc.c
index f636be5..a69a027 100644
--- a/jit/load-store-bc.c
+++ b/jit/load-store-bc.c
@@ -149,8 +149,7 @@ static int __convert_ldc(struct parse_context *ctx, 
unsigned long cp_idx)
                        break;
                }
 
-               vm_class_ensure_init(ret);
-               if (exception_occurred())
+               if (vm_class_ensure_object(ret))
                        return -1;
 
                expr = value_expr(J_REFERENCE, (unsigned long) ret->object);
diff --git a/vm/class.c b/vm/class.c
index b06ea04..12932e8 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -122,6 +122,8 @@ static int vm_class_link_common(struct vm_class *vmc)
        if (err)
                return -err;
 
+       vmc->object = NULL;
+
        return 0;
 }
 
@@ -482,6 +484,32 @@ static bool vm_class_check_class_init_fault(struct 
vm_class *vmc,
        return fault;
 }
 
+int vm_class_ensure_object(struct vm_class *vmc)
+{
+       vm_monitor_lock(&vmc->monitor);
+
+       if (vmc->object)
+               goto out;
+
+       /*
+        * Set the .object member of struct vm_class to point to
+        * the object (of type java.lang.Class) for this class.
+        */
+       vmc->object = vm_object_alloc(vm_java_lang_Class);
+       if (!vmc->object) {
+               NOT_IMPLEMENTED;
+               vm_monitor_unlock(&vmc->monitor);
+               return -1;
+       }
+
+       field_set_object(vmc->object, vm_java_lang_Class_vmdata,
+               (struct vm_object *)vmc);
+
+ out:
+       vm_monitor_unlock(&vmc->monitor);
+       return 0;
+}
+
 int vm_class_init(struct vm_class *vmc)
 {
        struct vm_object *exception;
@@ -536,18 +564,7 @@ int vm_class_init(struct vm_class *vmc)
                        goto error;
        }
 
-       /*
-        * Set the .object member of struct vm_class to point to
-        * the object (of type java.lang.Class) for this class.
-        */
-       vmc->object = vm_object_alloc(vm_java_lang_Class);
-       if (!vmc->object) {
-               NOT_IMPLEMENTED;
-               return -1;
-       }
-
-       field_set_object(vmc->object, vm_java_lang_Class_vmdata,
-               (struct vm_object *)vmc);
+       vm_class_ensure_object(vmc);
 
        if (vmc->class) {
                /* XXX: Make sure there's at most one of these. */
-- 
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