This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
gcj interface dispatch: Handling the "Object case"
- To: java-discuss at sourceware dot cygnus dot com, gcc-patches at egcs dot cygnus dot com
- Subject: gcj interface dispatch: Handling the "Object case"
- From: Bryce McKinlay <bryce at albatross dot co dot nz>
- Date: Wed, 15 Dec 1999 13:56:20 +1300
There is a rare condition where gcj will accidentally generate a
_Jv_LookupInterfaceMethod call with java.lang.Object as the "iface" parameter
from bytecode generated by compilers implementing the "new" JLS spec, such as
recent versions of Jikes. This isn't an issue with the existing interface
dispatch but can be a potential problem with the new constant-time
impementation.
Godmar Back provided the following test case and suggested the fix, which is
simply to rearrange lookup_java_method in typeck.c so that we search for methods
in superinterfaces first.
Test case (compile to bytecode with Jikes 1.06):
interface b {
public boolean equals(Object o);
}
interface c extends b { }
public class i implements c
{
static void f(c _) {
if (_.equals(_)) {
System.out.println("Success.");
}
}
public static void main(String av[]) {
f(new i());
}
}
Fix:
1999-12-13 Bryce McKinlay <bryce@albatross.co.nz>
* typeck.c (lookup_java_method): Search superinterfaces first
when looking up an interface method. From Godmar Back
<gback@cs.utah.edu>
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/typeck.c,v
retrieving revision 1.20
diff -u -r1.20 typeck.c
--- typeck.c 1999/11/18 03:59:48 1.20
+++ typeck.c 1999/12/14 01:19:53
@@ -749,25 +749,11 @@
tree method;
tree currently_searched = searched_class;
- while (currently_searched != NULL_TREE)
- {
- for (method = TYPE_METHODS (currently_searched);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = build_java_signature (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name
- && method_sig == method_signature)
- return method;
- }
- currently_searched = CLASSTYPE_SUPER (currently_searched);
- }
-
- /* If this class is an interface class, search its superinterfaces as
- * well. A superinterface is not an interface's superclass: a
+ /* If this class is an interface class, first search its superinterfaces.
+ * A superinterface is not an interface's superclass: a
* super interface is implemented by the interface.
*/
- currently_searched = searched_class;
if (CLASS_INTERFACE (TYPE_NAME (currently_searched)))
{
int i;
@@ -805,6 +791,22 @@
}
}
}
+
+ currently_searched = searched_class;
+
+ while (currently_searched != NULL_TREE)
+ {
+ for (method = TYPE_METHODS (currently_searched);
+ method != NULL_TREE; method = TREE_CHAIN (method))
+ {
+ tree method_sig = build_java_signature (TREE_TYPE (method));
+ if (DECL_NAME (method) == method_name
+ && method_sig == method_signature)
+ return method;
+ }
+ currently_searched = CLASSTYPE_SUPER (currently_searched);
+ }
+
return NULL_TREE;
}