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