When method is synchronized JIT compiler is responsible for generating
code which acquires lock in prologue and releases it in epilogue and
in unwind block.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/emit-code_32.c           |   39 +++++++++++++++++++++++++++++++++++++
 arch/x86/include/arch/emit-code.h |    4 +++
 include/vm/method.h               |   11 ++++++++++
 jit/emit.c                        |   24 ++++++++++++++++++++++
 4 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/arch/x86/emit-code_32.c b/arch/x86/emit-code_32.c
index d0234ec..fc374e4 100644
--- a/arch/x86/emit-code_32.c
+++ b/arch/x86/emit-code_32.c
@@ -22,6 +22,7 @@
 #include <arch/instruction.h>
 #include <arch/memory.h>
 #include <arch/exception.h>
+#include <arch/stack-frame.h>
 
 #include <assert.h>
 #include <errno.h>
@@ -30,6 +31,8 @@
 #include <stdbool.h>
 #include <string.h>
 
+#include <../jamvm/lock.h>
+
 #define PREFIX_SIZE 1
 #define BRANCH_INSN_SIZE 5
 #define BRANCH_TARGET_OFFSET 1
@@ -831,6 +834,42 @@ static void emit_test_membase_reg(struct buffer *buf, 
struct operand *src,
        emit_membase_reg(buf, 0x85, src, dest);
 }
 
+void emit_lock(struct buffer *buf, struct object *obj)
+{
+       __emit_push_imm(buf, (unsigned long)obj);
+       __emit_call(buf, objectLock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+}
+
+void emit_unlock(struct buffer *buf, struct object *obj)
+{
+       __emit_push_imm(buf, (unsigned long)obj);
+       __emit_call(buf, objectUnlock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+}
+
+void emit_lock_this(struct buffer *buf)
+{
+       unsigned long this_arg_offset;
+
+       this_arg_offset = offsetof(struct jit_stack_frame, args);
+
+       __emit_push_membase(buf, REG_EBP, this_arg_offset);
+       __emit_call(buf, objectLock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+}
+
+void emit_unlock_this(struct buffer *buf)
+{
+       unsigned long this_arg_offset;
+
+       this_arg_offset = offsetof(struct jit_stack_frame, args);
+
+       __emit_push_membase(buf, REG_EBP, this_arg_offset);
+       __emit_call(buf, objectUnlock);
+       __emit_add_imm_reg(buf, 0x04, REG_ESP);
+}
+
 enum emitter_type {
        NO_OPERANDS = 1,
        SINGLE_OPERAND,
diff --git a/arch/x86/include/arch/emit-code.h 
b/arch/x86/include/arch/emit-code.h
index ee12875..13912e8 100644
--- a/arch/x86/include/arch/emit-code.h
+++ b/arch/x86/include/arch/emit-code.h
@@ -11,5 +11,9 @@ void emit_epilog(struct buffer *);
 void emit_body(struct basic_block *, struct buffer *);
 void emit_trampoline(struct compilation_unit *, void *, struct 
jit_trampoline*);
 void emit_unwind(struct buffer *);
+void emit_lock(struct buffer *, struct object *);
+void emit_lock_this(struct buffer *);
+void emit_unlock(struct buffer *, struct object *);
+void emit_unlock_this(struct buffer *);
 
 #endif /* __X86_EMIT_CODE */
diff --git a/include/vm/method.h b/include/vm/method.h
index 142a8c9..5bf94b6 100644
--- a/include/vm/method.h
+++ b/include/vm/method.h
@@ -4,6 +4,7 @@
 #include <vm/vm.h>
 #include <vm/types.h>
 
+#include <stdbool.h>
 #include <string.h>
 
 static inline enum vm_type method_return_type(struct methodblock *method)
@@ -17,4 +18,14 @@ static inline bool method_is_constructor(struct methodblock 
*method)
        return strcmp(method->name,"<init>") == 0;
 }
 
+static inline bool method_is_synchronized(struct methodblock *method)
+{
+       return method->access_flags & ACC_SYNCHRONIZED;
+}
+
+static inline bool method_is_static(struct methodblock *method)
+{
+       return method->access_flags & ACC_STATIC;
+}
+
 #endif
diff --git a/jit/emit.c b/jit/emit.c
index 93d21e9..5ffce24 100644
--- a/jit/emit.c
+++ b/jit/emit.c
@@ -9,6 +9,7 @@
 
 #include <vm/alloc.h>
 #include <vm/buffer.h>
+#include <vm/method.h>
 #include <vm/vm.h>
 
 #include <jit/basic-block.h>
@@ -21,6 +22,22 @@
 #include <stdlib.h>
 #include <string.h>
 
+static void emit_monitor_enter(struct compilation_unit *cu)
+{
+       if (method_is_static(cu->method))
+               emit_lock(cu->objcode, cu->method->class);
+       else
+               emit_lock_this(cu->objcode);
+}
+
+static void emit_monitor_exit(struct compilation_unit *cu)
+{
+       if (method_is_static(cu->method))
+               emit_unlock(cu->objcode, cu->method->class);
+       else
+               emit_unlock_this(cu->objcode);
+}
+
 static struct buffer_operations exec_buf_ops = {
        .expand = expand_buffer_exec,
        .free   = generic_buffer_free,
@@ -38,13 +55,20 @@ int emit_machine_code(struct compilation_unit *cu)
        frame_size = frame_locals_size(cu->stack_frame);
 
        emit_prolog(cu->objcode, frame_size);
+       if (method_is_synchronized(cu->method))
+               emit_monitor_enter(cu);
+
        for_each_basic_block(bb, &cu->bb_list)
                emit_body(bb, cu->objcode);
 
        emit_body(cu->exit_bb, cu->objcode);
+       if (method_is_synchronized(cu->method))
+               emit_monitor_exit(cu);
        emit_epilog(cu->objcode);
 
        emit_body(cu->unwind_bb, cu->objcode);
+       if (method_is_synchronized(cu->method))
+               emit_monitor_exit(cu);
        emit_unwind(cu->objcode);
 
        return 0;
-- 
1.6.0.6


------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT 
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp as they present alongside digital heavyweights like Barbarian 
Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com 
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to