Signed-off-by: Saeed Siam <[EMAIL PROTECTED]>
---
Makefile | 3 +-
arch/x86/insn-selector.brg | 13 +-----
include/vm/vm.h | 3 +
jamvm/class.c | 10 +++++
.../jamvm/MethodInvocationAndReturnTest.java | 40 ++++++++++++++++++++
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/Makefile b/Makefile
index 2c180c6..c9e2cb7 100644
--- a/Makefile
+++ b/Makefile
@@ -64,7 +64,8 @@ JIT_OBJS = \
jit/trace-jit.o \
jit/trampoline.o \
jit/tree-printer.o \
- jit/typeconv-bc.o
+ jit/typeconv-bc.o \
+ jit/vtable.o
VM_OBJS = \
vm/bitset.o \
diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index 9df7b8d..98925ea 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -372,7 +372,6 @@ reg: EXPR_INVOKE(arg) 1
reg: EXPR_INVOKEVIRTUAL(arg) 1
{
- unsigned long method_table_offset;
struct var_info *return_value;
struct var_info *call_target;
unsigned long method_offset;
@@ -381,7 +380,6 @@ reg: EXPR_INVOKEVIRTUAL(arg) 1
struct expression *expr;
expr = to_expr(tree);
- method_table_offset = offsetof(struct classblock, method_table);
method_offset = expr_method_index(expr) * sizeof(void *);
return_value = get_fixed_var(s->b_parent, REG_EAX);
@@ -390,16 +388,11 @@ reg: EXPR_INVOKEVIRTUAL(arg) 1
call_target = get_var(s->b_parent);
stack_ptr = get_fixed_var(s->b_parent, REG_ESP);
- /*
- * FIXME: This is horrible due to lack of per-method vtables.
- */
bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, stack_ptr, 0,
call_target));
bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
offsetof(struct object, class), call_target));
- bb_add_insn(s, imm_reg_insn(INSN_ADD_IMM_REG, sizeof(struct object),
call_target));
- bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
method_table_offset, call_target));
- bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
method_offset, call_target));
- bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
offsetof(struct methodblock, trampoline), call_target));
- bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
offsetof(struct buffer, buf), call_target));
+ bb_add_insn(s, membase_reg_insn(INSN_MOV_MEMBASE_REG, call_target,
sizeof(struct object), call_target));
+ bb_add_insn(s, imm_reg_insn(INSN_ADD_IMM_REG, method_offset,
call_target));
+
bb_add_insn(s, reg_insn(INSN_CALL_REG, call_target));
args_count = nr_args(to_expr(expr->args_list));
diff --git a/include/vm/vm.h b/include/vm/vm.h
index 0884a2a..be9a0c7 100644
--- a/include/vm/vm.h
+++ b/include/vm/vm.h
@@ -33,6 +33,8 @@
/* Configure options */
#include <vm/config.h>
+#include <jit/vtable.h>
+
#ifndef TRUE
#define TRUE 1
#define FALSE 0
@@ -491,6 +493,7 @@ typedef struct refs_offsets_entry {
#define CLASS_PAD_SIZE 4
typedef struct classblock {
+ struct vtable vtable;
uintptr_t pad[CLASS_PAD_SIZE];
char *name;
char *signature;
diff --git a/jamvm/class.c b/jamvm/class.c
index db3a6ab..1e09908 100644
--- a/jamvm/class.c
+++ b/jamvm/class.c
@@ -980,6 +980,14 @@ void linkClass(Class *class) {
cb->method_table = method_table;
cb->method_table_size = method_table_size;
+ if (!(cb->access_flags & ACC_INTERFACE)) {
+ vtable_init(&cb->vtable, method_table_size);
+ for (i = 0; i < method_table_size; i++) {
+ mb = method_table[i];
+ vtable_setup_method(&cb->vtable, mb->method_table_index,
trampoline_ptr(mb));
+ }
+ }
+
/* Handle finalizer */
/* If this is Object find the finalize method. All subclasses will
@@ -1515,6 +1523,8 @@ void freeClassData(Class *class) {
free(cb->methods);
free(cb->inner_classes);
+ vtable_release(&cb->vtable);
+
if(cb->annotations != NULL) {
free(cb->annotations->data);
free(cb->annotations);
diff --git a/regression/jamvm/MethodInvocationAndReturnTest.java
b/regression/jamvm/MethodInvocationAndReturnTest.java
index 8fd5dcb..4131514 100644
--- a/regression/jamvm/MethodInvocationAndReturnTest.java
+++ b/regression/jamvm/MethodInvocationAndReturnTest.java
@@ -25,6 +25,19 @@ public class MethodInvocationAndReturnTest extends TestCase {
public static void main(String[] args) {
testReturnFromInvokeVirtualReinstatesTheFrameOfTheInvoker();
+
+ Super superClass = new Super();
+ Inherited inherited = new Inherited();
+ AbstractInherited abstractInherited = new AbstractInherited();
+
+ assertEquals(0, superClass.retInt());
+ assertEquals(1, inherited.retInt());
+
+ superClass = inherited;
+ assertEquals(1, superClass.retInt());
+
+ assertEquals(1, abstractInherited.retInt());
+
Runtime.getRuntime().halt(retval);
}
@@ -51,3 +64,30 @@ public class MethodInvocationAndReturnTest extends TestCase {
}
}
}
+
+class Super {
+
+ int retInt() {
+ return 0;
+ }
+}
+
+class Inherited extends Super{
+
+ //@Override
+ int retInt() {
+ return 1;
+ }
+}
+
+abstract class AbstractSuper {
+ abstract int retInt();
+}
+
+class AbstractInherited extends AbstractSuper {
+
+ //@Override
+ int retInt() {
+ return 1;
+ }
+}
--
1.5.4.4
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jatovm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel