We used to simply append the subclass' methods to the end of the
vtable of the superclass.

With this patch, we only append those methods which are not defined in
the superclass; the methods which are defined in the superclass are
overridden in the subclass' vtable.

Signed-off-by: Vegard Nossum <vegard.nos...@gmail.com>
---
 include/jit/expression.h |   10 +--------
 include/vm/method.h      |    1 +
 vm/class.c               |   51 ++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/include/jit/expression.h b/include/jit/expression.h
index 0633d6d..beeabbe 100644
--- a/include/jit/expression.h
+++ b/include/jit/expression.h
@@ -326,15 +326,7 @@ static inline int is_invoke_expr(struct expression *expr)
 
 static inline unsigned long expr_method_index(struct expression *expr)
 {
-       struct vm_method *method = expr->target_method;
-       unsigned int base;
-
-       if (method->class->super)
-               base = method->class->super->vtable_size;
-       else
-               base = 0;
-
-       return  base + method->method_index;
+       return expr->target_method->virtual_index;
 }
 
 #endif
diff --git a/include/vm/method.h b/include/vm/method.h
index 031bbe3..ffca1ca 100644
--- a/include/vm/method.h
+++ b/include/vm/method.h
@@ -21,6 +21,7 @@ struct vm_class;
 struct vm_method {
        struct vm_class *class;
        unsigned int method_index;
+       unsigned int virtual_index;
        const struct cafebabe_method_info *method;
 
        char *name;
diff --git a/vm/class.c b/vm/class.c
index 1dd9fb3..dcad2f0 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -50,17 +50,39 @@
 static void
 setup_vtable(struct vm_class *vmc)
 {
+       struct vm_class *super;
        unsigned int super_vtable_size;
        struct vtable *super_vtable;
+       unsigned int vtable_size;
 
-       if (vmc->super) {
-               super_vtable_size = vmc->super->vtable_size;
-               super_vtable = &vmc->super->vtable;
+       super = vmc->super;
+
+       if (super) {
+               super_vtable_size = super->vtable_size;
+               super_vtable = &super->vtable;
        } else {
                super_vtable_size = 0;
        }
 
-       vmc->vtable_size = super_vtable_size + vmc->class->methods_count;
+       vtable_size = 0;
+       for (uint16_t i = 0; i < vmc->class->methods_count; ++i) {
+               struct vm_method *vmm = &vmc->methods[i];
+
+               if (super) {
+                       struct vm_method *vmm2
+                               = vm_class_get_method_recursive(super,
+                                       vmm->name, vmm->type);
+                       if (vmm2) {
+                               vmm->virtual_index = vmm2->virtual_index;
+                               continue;
+                       }
+               }
+
+               vmm->virtual_index = super_vtable_size + vtable_size;
+               ++vtable_size;
+       }
+
+       vmc->vtable_size = super_vtable_size + vtable_size;
 
        vtable_init(&vmc->vtable, vmc->vtable_size);
 
@@ -70,9 +92,26 @@ setup_vtable(struct vm_class *vmc)
                        super_vtable->native_ptr[i]);
 
        /* Our methods */
+       vtable_size = 0;
        for (uint16_t i = 0; i < vmc->class->methods_count; ++i) {
-               vtable_setup_method(&vmc->vtable, super_vtable_size + i,
-                               vm_method_trampoline_ptr(&vmc->methods[i]));
+               struct vm_method *vmm = &vmc->methods[i];
+
+               if (super) {
+                       struct vm_method *vmm2
+                               = vm_class_get_method_recursive(super,
+                                       vmm->name, vmm->type);
+                       if (vmm2) {
+                               vtable_setup_method(&vmc->vtable,
+                                       vmm2->virtual_index,
+                                       vm_method_trampoline_ptr(vmm));
+                               continue;
+                       }
+               }
+
+               vtable_setup_method(&vmc->vtable,
+                       super_vtable_size + vtable_size,
+                       vm_method_trampoline_ptr(vmm));
+               ++vtable_size;
        }
 }
 
-- 
1.6.0.4


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to