Hi Tomek,
Tomek Grabiec wrote:
> 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 <[email protected]>
Looks good to me. Lets cc Siam who authored the original monitor support
patches if he wants to comment on them and Vegard for heads up on cafebabe.
> ---
> 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;
------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel