This fixes the lighthouse ticket:
http://jato.lighthouseapp.com/projects/29055-jato/tickets/4

Actually, the ticket describes a slightly different scenario. The scenario
from the ticket:

        interface A {
                void foo();
        }

        interface B {
                void foo();
        }

        class C implements A, B {
                void foo() { ... }
        }

Here, the itable for C will contain two entries, one for A.foo() and one
for B.foo(). However, we _must_ do this, since we use the _method address_
as the hidden parameter to the itable resolution stub. If we omitted one
of them, the resolution stub would not be able to find it, e.g.:

        C c = new C();

        ((A) c).foo(); // would succeed
        ((B) c).foo(); // would fail

What the ticket is meant to describe, however, is that we may get the same
method (from the same class) in the itable:

        interface I {
                void foo();
        }

        class A implements I {
                void foo() { ... }
        }

        class B extends A implements I {
                void foo() { ... }
        }

Here, before this patch, we would add I.foo() twice to the itable of B.

Signed-off-by: Vegard Nossum <vegard.nos...@gmail.com>
---
 vm/itable.c |   31 +++++++++++++------------------
 1 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/vm/itable.c b/vm/itable.c
index 83ede3e..b1aaee4 100644
--- a/vm/itable.c
+++ b/vm/itable.c
@@ -29,6 +29,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "lib/array.h"
+
 #include "vm/classloader.h"
 #include "vm/backtrace.h"
 #include "vm/class.h"
@@ -167,34 +169,27 @@ static void *itable_create_conflict_resolver(struct 
vm_class *vmc,
                return vm_method_call_ptr(entry->c_method);
        }
 
-       unsigned int nr_entries = 0;
-       struct itable_entry *entry;
-       list_for_each_entry(entry, methods, node)
-               ++nr_entries;
+       struct array sorted_table;
+       array_init(&sorted_table);
+       array_resize(&sorted_table, 64);
 
-       struct itable_entry **sorted_table
-               = malloc(nr_entries * sizeof(*sorted_table));
-       if (!sorted_table) {
-               NOT_IMPLEMENTED;
-               return &itable_resolver_stub_error;
-       }
-
-       unsigned int i = 0;
+       struct itable_entry *entry;
        list_for_each_entry(entry, methods, node)
-               sorted_table[i++] = entry;
+               array_append(&sorted_table, entry);
 
-       qsort(sorted_table, nr_entries, sizeof(*sorted_table),
-               &itable_entry_compare);
+       array_qsort(&sorted_table, &itable_entry_compare);
+       array_unique(&sorted_table, &itable_entry_compare);
 
-       void *ret = emit_itable_resolver_stub(vmc, sorted_table, nr_entries);
-       free(sorted_table);
+       void *ret = emit_itable_resolver_stub(vmc,
+               (struct itable_entry **) sorted_table.ptr, sorted_table.size);
+       array_destroy(&sorted_table);
 
        return ret;
 }
 
 static void trace_itable(struct vm_class *vmc, struct list_head *itable)
 {
-       trace_printf("trace itable: %s\n", vmc->name);
+       trace_printf("trace itable (duplicates included): %s\n", vmc->name);
 
        for (unsigned int i = 0; i < VM_ITABLE_SIZE; ++i) {
                if (list_is_empty(&itable[i]))
-- 
1.6.0.4


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to