Note: static field access fixup as well as trampoline backpatching is
steel not MP safe after this patch. This is something yet to be done.
Apart from that there was a race condition on access to fixup site
lists causing the following segfault to occurre:
[thread: main] SIGSEGV at EIP 080550bd while accessing memory address 00000000.
Registers:
eax: 00000000 ebx: 08300908 ecx: 00000000 edx: 08300730
esi: 087c54e8 edi: 087cc3f0 ebp: bfe0e524 esp: bfe0e500
Native and JAVA stack trace:
[<080550bd>] native : <unknown>
[<08062cc5>] native : jit_magic_trampoline+1c5 (jato/jit/trampoline.c:146)
[<a7c0aaec>] trampoline : java/lang/System.<clinit>(System.java:74)
[<0806643f>] native : vm_class_init+13f (jato/jato/vm/class.c:461)
[<08062b2d>] native : <unknown>
[<a7c0abcc>] trampoline : java/lang/System.currentTimeMillis(System.java:222)
[<a7c14f1a>] jit : java/lang/VMThread.sleep(VMThread.java:393)
[<a7c14e12>] jit : java/lang/Thread.sleep(Thread.java:896)
[<a7c14c08>] jit : java/lang/Thread.sleep(Thread.java:861)
[<a7c0d992>] jit : Test.main(Test.java:40)
[<08069d38>] native : main+390 (jato/vm/jato.c:962)
[<b7caa60b>] native : <unknown>
[<08052f70>] native : <unknown>
for the following test case run with -Xtrace:invoke:
public class Test extends Thread {
public static Object syn;
public void run() {
while (true) {
synchronized (Test.syn) {
try {
Test.syn.wait();
} catch (InterruptedException e) {
}
}
}
}
public static void main(String[] args) {
Thread t[] = new Thread[1];
syn = new Object();
for (int i = 0; i < t.length; i++) {
t[i] = new Test();
}
for (int i = 0; i < t.length; i++) {
t[i].start();
}
while (true) {
synchronized (Test.syn) {
Test.syn.notifyAll();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
Signed-off-by: Tomek Grabiec <[email protected]>
---
arch/x86/emit-code.c | 18 ++++++++++++++++--
include/vm/class.h | 3 +++
vm/class.c | 31 ++++++++++++++++++++++++++++++-
vm/static.c | 4 ++++
4 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index f1b7353..1e57d8a 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -420,6 +420,8 @@ void fixup_static(struct vm_class *vmc)
{
struct static_fixup_site *this, *next;
+ pthread_mutex_lock(&vmc->mutex);
+
list_for_each_entry_safe(this, next,
&vmc->static_fixup_site_list, vmc_node)
{
@@ -431,20 +433,28 @@ void fixup_static(struct vm_class *vmc)
cpu_write_u32(site_addr + 2, (unsigned long) new_target);
list_del(&this->vmc_node);
+
+ pthread_mutex_lock(&this->cu->mutex);
list_del(&this->cu_node);
+ pthread_mutex_unlock(&this->cu->mutex);
+
free(this);
}
+
+ pthread_mutex_unlock(&vmc->mutex);
}
int fixup_static_at(unsigned long addr)
{
struct compilation_unit *cu;
- struct static_fixup_site *this;
+ struct static_fixup_site *this, *t;
cu = jit_lookup_cu(addr);
assert(cu);
- list_for_each_entry(this, &cu->static_fixup_site_list, cu_node)
+ pthread_mutex_lock(&cu->mutex);
+
+ list_for_each_entry_safe(this, t, &cu->static_fixup_site_list, cu_node)
{
void *site_addr = buffer_ptr(cu->objcode)
+ this->insn->mach_offset;
@@ -452,6 +462,8 @@ int fixup_static_at(unsigned long addr)
if ((unsigned long) site_addr == addr) {
struct vm_class *vmc = this->vmf->class;
+ pthread_mutex_unlock(&cu->mutex);
+
/* Note: After this call, we can no longer access
* "this" because it may have been deleted already
* (from insite the class initializer of "vmc". */
@@ -464,6 +476,8 @@ int fixup_static_at(unsigned long addr)
}
}
+ pthread_mutex_unlock(&cu->mutex);
+
return 0;
}
diff --git a/include/vm/class.h b/include/vm/class.h
index 2ed5ffe..43d364a 100644
--- a/include/vm/class.h
+++ b/include/vm/class.h
@@ -2,6 +2,7 @@
#define _VM_CLASS_H
#include <assert.h>
+#include <pthread.h>
#include "vm/field.h"
#include "vm/itable.h"
@@ -34,6 +35,8 @@ struct vm_class {
enum vm_class_state state;
char *name;
+ pthread_mutex_t mutex;
+
struct vm_class *super;
unsigned int nr_interfaces;
struct vm_class **interfaces;
diff --git a/vm/class.c b/vm/class.c
index a96f1b6..e357946 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -124,11 +124,28 @@ setup_vtable(struct vm_class *vmc)
}
}
+static int vm_class_link_common(struct vm_class *vmc)
+{
+ int err;
+
+ err = pthread_mutex_init(&vmc->mutex, NULL);
+ if (err)
+ return -err;
+
+ return 0;
+}
+
int vm_class_link(struct vm_class *vmc, const struct cafebabe_class *class)
{
+ int err;
+
vmc->class = class;
vmc->kind = VM_CLASS_KIND_REGULAR;
+ err = vm_class_link_common(vmc);
+ if (err)
+ return -err;
+
const struct cafebabe_constant_info_class *constant_class;
if (cafebabe_class_constant_get_class(class,
class->this_class, &constant_class))
@@ -312,11 +329,17 @@ int vm_class_link(struct vm_class *vmc, const struct
cafebabe_class *class)
INIT_LIST_HEAD(&vmc->static_fixup_site_list);
vmc->state = VM_CLASS_LINKED;
- return 0;
+ return 0;;
}
int vm_class_link_primitive_class(struct vm_class *vmc, const char *class_name)
{
+ int err;
+
+ err = vm_class_link_common(vmc);
+ if (err)
+ return err;
+
vmc->name = strdup(class_name);
if (!vmc->name)
return -ENOMEM;
@@ -343,6 +366,12 @@ 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 err;
+
+ err = vm_class_link_common(vmc);
+ if (err)
+ return err;
+
vmc->name = strdup(class_name);
if (!vmc->name)
return -ENOMEM;
diff --git a/vm/static.c b/vm/static.c
index c910fe3..69551fb 100644
--- a/vm/static.c
+++ b/vm/static.c
@@ -39,7 +39,11 @@ add_static_fixup_site(enum static_fixup_type type, struct
insn *insn,
site->insn = insn;
site->vmf = vmf;
site->cu = cu;
+
+ pthread_mutex_lock(&vmc->mutex);
list_add_tail(&site->vmc_node, &vmc->static_fixup_site_list);
+ pthread_mutex_unlock(&vmc->mutex);
+
list_add_tail(&site->cu_node, &cu->static_fixup_site_list);
return 0;
}
--
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel