This fixes incorrect lock order reported by helgrind:
==7951== Thread #1: lock order "0x5277F84 before 0x55D7D64" violated
==7951==    at 0x4026125: pthread_mutex_lock (in 
/usr/lib/valgrind/x86-linux/vgpreload_helgrind.so)
==7951==    by 0x80563BE: fixup_direct_calls (emit-code.c:355)
==7951==    by 0x8082A83: jit_magic_trampoline (trampoline.c:161)
==7951==    by 0x88D741C: ???
==7951==    by 0x88D79F9: ???
==7951==   Required order was established by acquisition of lock at 0x5277F84
==7951==    at 0x4026125: pthread_mutex_lock (in 
/usr/lib/valgrind/x86-linux/vgpreload_helgrind.so)
==7951==    by 0x80829E0: jit_magic_trampoline (trampoline.c:125)
==7951==    by 0x88D00CC: ???
==7951==    by 0x88D73CC: ???
==7951==   followed by a later acquisition of lock at 0x55D7D64
==7951==    at 0x4026125: pthread_mutex_lock (in 
/usr/lib/valgrind/x86-linux/vgpreload_helgrind.so)
==7951==    by 0x8076801: trampoline_add_fixup_site (fixup-site.c:53)
==7951==    by 0x805DA8B: invoke (insn-selector.c:754)
==7951==    by 0x8063A08: mono_burg_emit (insn-selector.c:3094)
==7951==    by 0x805E139: emit_code (insn-selector.c:869)
==7951==    by 0x805E37E: insn_select (insn-selector.c:920)
==7951==    by 0x805E4D4: select_instructions (insn-selector.c:970)
==7951==    by 0x8073303: compile (compiler.c:80)
==7951==    by 0x80828A3: jit_java_trampoline (trampoline.c:97)
==7951==    by 0x8082A25: jit_magic_trampoline (trampoline.c:135)
==7951==    by 0x88D00CC: ???
==7951==    by 0x88D73CC: ???

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/emit-code.c           |   12 +++---------
 arch/x86/insn-selector.brg     |    6 +++---
 include/jit/compilation-unit.h |    1 +
 include/jit/compiler.h         |   11 +++++++++--
 jit/compilation-unit.c         |   18 ++++++++++++++++++
 jit/emit.c                     |   12 ++++++++++++
 jit/fixup-site.c               |   27 +++++++++++++++++++++++----
 test/jit/Makefile              |    1 +
 8 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index ea96a03..f7b2e2a 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -338,11 +338,9 @@ void fixup_direct_calls(struct jit_trampoline *t, unsigned 
long target)
 
        pthread_mutex_lock(&t->mutex);
 
-       list_for_each_entry_safe(this, next, &t->fixup_site_list,
-                                fixup_list_node) {
+       list_for_each_entry_safe(this, next, &t->fixup_site_list, 
trampoline_node) {
                unsigned char *site_addr;
                uint32_t new_target;
-               bool is_compiled;
 
                /*
                 * It is possible that we're fixing calls to
@@ -352,18 +350,14 @@ void fixup_direct_calls(struct jit_trampoline *t, 
unsigned long target)
                 * be set yet. We should skip fixing callsites coming
                 * from not yet compiled methods.  .
                 */
-               pthread_mutex_lock(&this->cu->mutex);
-               is_compiled = this->cu->is_compiled;
-               pthread_mutex_unlock(&this->cu->mutex);
-
-               if (!is_compiled)
+               if (!fixup_site_is_ready(this))
                        continue;
 
                site_addr = fixup_site_addr(this);
                new_target = target - ((unsigned long) site_addr + 
CALL_INSN_SIZE);
                cpu_write_u32(site_addr+1, new_target);
 
-               list_del(&this->fixup_list_node);
+               list_del(&this->trampoline_node);
                free_fixup_site(this);
        }
 
diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index 8eead10..5383368 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -3207,9 +3207,9 @@ static void invoke(struct basic_block *s, struct 
tree_node *tree)
        if (!is_compiled) {
                struct fixup_site *fixup;
 
-               fixup = alloc_fixup_site();
-               fixup->cu = s->b_parent;
-               fixup->relcall_insn = call_insn;
+               fixup = alloc_fixup_site(s->b_parent, call_insn);
+               if (!fixup)
+                       error("out of memory");
 
                trampoline_add_fixup_site(method->trampoline, fixup);
        }
diff --git a/include/jit/compilation-unit.h b/include/jit/compilation-unit.h
index c3f55b1..4bfd9d8 100644
--- a/include/jit/compilation-unit.h
+++ b/include/jit/compilation-unit.h
@@ -62,6 +62,7 @@ struct compilation_unit {
        unsigned char *unwind_bb_ptr;
 
        struct list_head static_fixup_site_list;
+       struct list_head call_fixup_site_list;
        struct list_head tableswitch_list;
        struct list_head lookupswitch_list;
 
diff --git a/include/jit/compiler.h b/include/jit/compiler.h
index 6e1196a..7e5796b 100644
--- a/include/jit/compiler.h
+++ b/include/jit/compiler.h
@@ -19,12 +19,17 @@ struct statement;
 struct buffer;
 
 struct fixup_site {
+       pthread_mutex_t mutex;
+       bool ready;
+
+       struct jit_trampoline *target;
        /* Compilation unit to which relcall_insn belongs */
        struct compilation_unit *cu;
        /* We need this, because we don't have native pointer at
           instruction selection */
        struct insn *relcall_insn;
-       struct list_head fixup_list_node;
+       struct list_head trampoline_node;
+       struct list_head cu_node;
 };
 
 struct jit_trampoline {
@@ -65,10 +70,12 @@ void *jit_magic_trampoline(struct compilation_unit *);
 struct jit_trampoline *alloc_jit_trampoline(void);
 struct jit_trampoline *build_jit_trampoline(struct compilation_unit *);
 void free_jit_trampoline(struct jit_trampoline *);
-struct fixup_site *alloc_fixup_site(void);
+struct fixup_site *alloc_fixup_site(struct compilation_unit *, struct insn *);
 void free_fixup_site(struct fixup_site *);
 void trampoline_add_fixup_site(struct jit_trampoline *, struct fixup_site *);
 unsigned char *fixup_site_addr(struct fixup_site *);
+bool fixup_site_is_ready(struct fixup_site *);
+void prepare_call_fixup_sites(struct compilation_unit *);
 
 const char *method_symbol(struct vm_method *method, char *symbol, size_t len);
 
diff --git a/jit/compilation-unit.c b/jit/compilation-unit.c
index 24c5738..e0c4be3 100644
--- a/jit/compilation-unit.c
+++ b/jit/compilation-unit.c
@@ -95,6 +95,7 @@ struct compilation_unit *compilation_unit_alloc(struct 
vm_method *method)
                        goto out_of_memory;
 
                INIT_LIST_HEAD(&cu->static_fixup_site_list);
+               INIT_LIST_HEAD(&cu->call_fixup_site_list);
                INIT_LIST_HEAD(&cu->tableswitch_list);
                INIT_LIST_HEAD(&cu->lookupswitch_list);
 
@@ -162,6 +163,22 @@ static void free_lookupswitch_list(struct compilation_unit 
*cu)
        }
 }
 
+static void free_call_fixup_sites(struct compilation_unit *cu)
+{
+       struct fixup_site *this, *next;
+
+       list_for_each_entry_safe(this, next, &cu->call_fixup_site_list, cu_node)
+       {
+               list_del(&this->cu_node);
+
+               pthread_mutex_lock(&this->target->mutex);
+               list_del(&this->trampoline_node);
+               pthread_mutex_unlock(&this->target->mutex);
+
+               free_fixup_site(this);
+       }
+}
+
 static void free_lir_insn_map(struct compilation_unit *cu)
 {
        free_radix_tree(cu->lir_insn_map);
@@ -178,6 +195,7 @@ void free_compilation_unit(struct compilation_unit *cu)
 {
        struct basic_block *bb, *tmp_bb;
 
+       free_call_fixup_sites(cu);
        shrink_compilation_unit(cu);
 
        list_for_each_entry_safe(bb, tmp_bb, &cu->bb_list, bb_list_node)
diff --git a/jit/emit.c b/jit/emit.c
index ee5c4d9..de0a1ec 100644
--- a/jit/emit.c
+++ b/jit/emit.c
@@ -152,6 +152,17 @@ static void emit_resolution_blocks(struct basic_block *bb, 
struct buffer *buf)
        }
 }
 
+void prepare_call_fixup_sites(struct compilation_unit *cu)
+{
+       struct fixup_site *site;
+
+       list_for_each_entry(site, &cu->call_fixup_site_list, cu_node) {
+               pthread_mutex_lock(&site->mutex);
+               site->ready = true;
+               pthread_mutex_unlock(&site->mutex);
+       }
+}
+
 int emit_machine_code(struct compilation_unit *cu)
 {
        unsigned long frame_size;
@@ -196,6 +207,7 @@ int emit_machine_code(struct compilation_unit *cu)
                emit_resolution_blocks(bb, cu->objcode);
        }
 
+       prepare_call_fixup_sites(cu);
        backpatch_tableswitch_targets(cu);
        backpatch_lookupswitch_targets(cu);
        build_exception_handlers_table(cu);
diff --git a/jit/fixup-site.c b/jit/fixup-site.c
index 0d38d8a..ee48681 100644
--- a/jit/fixup-site.c
+++ b/jit/fixup-site.c
@@ -26,24 +26,32 @@
 
 #include "jit/compiler.h"
 #include "arch/instruction.h"
+#include "vm/stdlib.h"
+
 #include <memory.h>
 #include <malloc.h>
 
-struct fixup_site *alloc_fixup_site(void)
+struct fixup_site *
+alloc_fixup_site(struct compilation_unit *cu, struct insn *call_insn)
 {
        struct fixup_site *site;
 
-       site = malloc(sizeof(*site));
+       site = zalloc(sizeof(*site));
        if (!site)
                return NULL;
 
-       memset(site, 0, sizeof(*site));
+       site->cu = cu;
+       site->relcall_insn = call_insn;
+
+       list_add(&site->cu_node, &cu->call_fixup_site_list);
+       pthread_mutex_init(&site->mutex, NULL);
 
        return site;
 }
 
 void free_fixup_site(struct fixup_site *site)
 {
+       pthread_mutex_destroy(&site->mutex);
        free(site);
 }
 
@@ -51,7 +59,7 @@ void trampoline_add_fixup_site(struct jit_trampoline 
*trampoline,
                               struct fixup_site *site)
 {
        pthread_mutex_lock(&trampoline->mutex);
-       list_add_tail(&site->fixup_list_node, &trampoline->fixup_site_list);
+       list_add_tail(&site->trampoline_node, &trampoline->fixup_site_list);
        pthread_mutex_unlock(&trampoline->mutex);
 }
 
@@ -59,3 +67,14 @@ unsigned char *fixup_site_addr(struct fixup_site *site)
 {
        return buffer_ptr(site->cu->objcode) + site->relcall_insn->mach_offset;
 }
+
+bool fixup_site_is_ready(struct fixup_site *site)
+{
+       bool result;
+
+       pthread_mutex_lock(&site->mutex);
+       result = site->ready;
+       pthread_mutex_unlock(&site->mutex);
+
+       return result;
+}
diff --git a/test/jit/Makefile b/test/jit/Makefile
index 3bb8aa1..17c8a4c 100644
--- a/test/jit/Makefile
+++ b/test/jit/Makefile
@@ -24,6 +24,7 @@ TOPLEVEL_OBJS := \
        jit/exception-bc.o \
        jit/exception.o \
        jit/expression.o \
+       jit/fixup-site.o \
        jit/interval.o \
        jit/invoke-bc.o \
        jit/linear-scan.o \
-- 
1.6.3.3


------------------------------------------------------------------------------
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