This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Java: Bryce McKinlay's interface dispatch patch.



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:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]