This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Java: Bryce McKinlay's interface dispatch patch.
- To: egcs-patches at egcs dot cygnus dot com
- Subject: [PATCH] Java: Bryce McKinlay's interface dispatch patch.
- From: Alexandre Petit-Bianco <apbianco at cygnus dot com>
- Date: Tue, 7 Mar 2000 00:59:46 -0800
- Cc: bryce at albatross dot co dot nz
- Reply-to: apbianco at redhat dot com
I checking in this patch which is Bryce McKinlay's implementation of
the interfaces constant-time dispatch and type checking techniques
thought out by Per Bothner:
http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00485.html
This patch must be used in conjunction with a Java run-time patch in
order for it to work. The run-time patch should follow shortly and
will be checked in by Bryce himself.
Kudos are going Per Bothner his design and Bryce for his implementation,
and the rest of the people using Gcc's Java extension for feedback,
testing and support. Thanks!
./A
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
* decl.c (init_decl_processing): Added new class fields `depth',
`ancestors', and `idt' to class_type_node. Use
_Jv_LookupInterfaceMethodIdx for soft_lookupinterfacemthod_node.
* class.c (make_class_data): Push initial values for new fields.
* java-tree.h: Updated prototype for `build_invokeinterface'.
* expr.c (build_invokeinterface): Changed parameters to accept
`method' tree. Calculate index of `method' in its declaring
interface. Build call to _Jv_LookupInterfaceMethodIdx.
(expand_invoke): Call `build_invokeinterface' with new parameters.
* parse.y (patch_invoke): Call `build_invokeinterface' with new
parameters.
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/class.c,v
retrieving revision 1.56
diff -u -p -r1.56 class.c
--- class.c 2000/03/04 22:27:35 1.56
+++ class.c 2000/03/07 07:34:32
@@ -1380,6 +1380,9 @@ make_class_data (type)
PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
+ PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/decl.c,v
retrieving revision 1.51
diff -u -p -r1.51 decl.c
--- decl.c 2000/03/04 18:27:48 1.51
+++ decl.c 2000/03/07 07:34:37
@@ -661,6 +661,9 @@ init_decl_processing ()
PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
PUSH_FIELD (class_type_node, field, "state", byte_type_node);
PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "depth", short_type_node);
+ PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
@@ -815,9 +818,9 @@ init_decl_processing ()
0, NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
- tree_cons (NULL_TREE, ptr_type_node, endlink)));
+ tree_cons (NULL_TREE, int_type_node, endlink)));
soft_lookupinterfacemethod_node
- = builtin_function ("_Jv_LookupInterfaceMethod",
+ = builtin_function ("_Jv_LookupInterfaceMethodIdx",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, double_type_node,
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/expr.c,v
retrieving revision 1.62
diff -u -p -r1.62 expr.c
--- expr.c 2000/02/27 21:39:40 1.62
+++ expr.c 2000/03/07 07:34:43
@@ -1648,11 +1648,15 @@ build_invokevirtual (dtable, method)
}
tree
-build_invokeinterface (dtable, method_name, method_signature)
- tree dtable, method_name, method_signature;
+build_invokeinterface (dtable, method)
+ tree dtable, method;
{
static tree class_ident = NULL_TREE;
tree lookup_arg;
+ tree interface;
+ tree idx;
+ tree meth;
+ int i;
/* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
ensure that the selected method exists, is public and not
@@ -1664,14 +1668,25 @@ build_invokeinterface (dtable, method_na
dtable = build1 (INDIRECT_REF, dtable_type, dtable);
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
lookup_field (&dtable_type, class_ident));
- lookup_arg = build_tree_list (NULL_TREE,
- (build_utf8_ref
- (unmangle_classname
- (IDENTIFIER_POINTER(method_signature),
- IDENTIFIER_LENGTH(method_signature)))));
+
+ interface = DECL_CONTEXT (method);
+
+ i = 1;
+ for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
+ {
+ if (meth == method)
+ {
+ idx = build_int_2 (i, 0);
+ break;
+ }
+ if (meth == NULL_TREE)
+ fatal ("internal error in build_invokeinterface");
+ }
+
lookup_arg = tree_cons (NULL_TREE, dtable,
- tree_cons (NULL_TREE, build_utf8_ref (method_name),
- lookup_arg));
+ tree_cons (NULL_TREE, build_class_ref (interface),
+ build_tree_list (NULL_TREE, idx)));
+
return build (CALL_EXPR, ptr_type_node,
build_address_of (soft_lookupinterfacemethod_node),
lookup_arg, NULL_TREE);
@@ -1770,7 +1785,7 @@ expand_invoke (opcode, method_ref_index,
if (opcode == OPCODE_invokevirtual)
func = build_invokevirtual (dtable, method);
else
- func = build_invokeinterface (dtable, method_name, method_signature);
+ func = build_invokeinterface (dtable, method);
}
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.57
diff -u -p -r1.57 java-tree.h
--- java-tree.h 2000/03/07 06:25:14 1.57
+++ java-tree.h 2000/03/07 07:34:46
@@ -564,7 +564,7 @@ extern tree lookup_name PARAMS ((tree));
extern tree build_known_method_ref PARAMS ((tree, tree, tree, tree, tree));
extern tree build_class_init PARAMS ((tree, tree));
extern tree build_invokevirtual PARAMS ((tree, tree));
-extern tree build_invokeinterface PARAMS ((tree, tree, tree));
+extern tree build_invokeinterface PARAMS ((tree, tree));
extern tree invoke_build_dtable PARAMS ((int, tree));
extern tree build_field_ref PARAMS ((tree, tree, tree));
extern void pushdecl_force_head PARAMS ((tree));
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.137
diff -u -p -r1.137 parse.y
--- parse.y 2000/03/07 06:25:14 1.137
+++ parse.y 2000/03/07 07:35:13
@@ -7524,7 +7524,7 @@ patch_invoke (patch, method, args)
case INVOKE_INTERFACE:
dtable = invoke_build_dtable (1, args);
- func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+ func = build_invokeinterface (dtable, method);
break;
default: