This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH handling of Java builtins; fixes super bytecode calls


I tracked down a bug to the fact that super.f() when emitted as
bytecode used a invokevirtual instead of an invokespecial opcode.
This turned out to be due to the CALL_WITH_SUPER flag being dropped.
This is turn was because Tom's recent patches for optimizing builtin
functions would create a new CALL_EXPR, even when not optimizing,
and the CALL_WITH_SUPER flag was not being copied.  I figured rather
than the obvious fix of copying the CALL_WITH_SUPER flag it would be
better just retain the old CALL_EXPR node instead of creating a new
one.  So I dropped Tom's build_call_or_builtin and replaced it with a
check_for_builtin function.

Tom, could you check that builtins are still being optimized with
this patch?
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/per/
2002-02-18  Per Bothner  <per@bothner.com>

	* builtins.c (check_for_builtin):  New function.
	(build_call_or_builtin):  Remove.
	* java-tree.h:  Update accordingly.
	* expr.c (expand_invoke):  Use build + check_for_builtin instead
	of build_call_or_builtin.
	* parse.y (patch_invoke):  Likewise.  This avoids needlessly creating
	a new CALL_EXPR node, which means we don't lose the CALL_USING_SUPER
	flag (which had caused jcf-write to incorrectly emit invokevirtual).

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/builtins.c,v
retrieving revision 1.2
diff -u -p -r1.2 builtins.c
--- builtins.c	2002/01/27 22:28:42	1.2
+++ builtins.c	2002/02/18 07:09:04
@@ -324,42 +324,30 @@ initialize_builtins ()
 #include "builtins.def"
 }
 
-/* Generate a method call.  If the call matches a builtin, return the
+/* If the call matches a builtin, return the
    appropriate builtin expression instead.  */
 tree
-build_call_or_builtin (method, func, method_arguments)
-     tree method, func, method_arguments;
+check_for_builtin (method, call)
+     tree method;
+     tree call;
 {
-  tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
-  tree method_name = DECL_NAME (method);
-  tree method_return_type = TREE_TYPE (TREE_TYPE (method));
-  tree call = NULL_TREE;
-
-  /* Only look if we're generating object code and optimizing.  */
-  if (! flag_emit_class_files && optimize)
+  if (! flag_emit_class_files && optimize && TREE_CODE (call) == CALL_EXPR)
     {
       int i;
+      tree method_arguments = TREE_OPERAND (call, 1);
+      tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
+      tree method_name = DECL_NAME (method);
+      tree method_return_type = TREE_TYPE (TREE_TYPE (method));
 
       for (i = 0; java_builtins[i].creator != NULL; ++i)
 	{
 	  if (method_class == java_builtins[i].class_name.t
 	      && method_name == java_builtins[i].method_name.t)
 	    {
-	      call = (*java_builtins[i].creator) (method_return_type,
+	      return (*java_builtins[i].creator) (method_return_type,
 						  method_arguments);
-	      break;
 	    }
 	}
     }
-
-  if (call == NULL_TREE)
-    {
-      /* Either nothing matched, or the creator function decided not
-	 to inline.  In either case, emit a call.  */
-      call = build (CALL_EXPR, method_return_type, func, method_arguments,
-		    NULL_TREE);
-      TREE_SIDE_EFFECTS (call) = 1;
-    }
-
   return call;
 }
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.131
diff -u -p -r1.131 expr.c
--- expr.c	2002/01/28 16:52:27	1.131
+++ expr.c	2002/02/18 07:09:07
@@ -2112,7 +2112,9 @@ expand_invoke (opcode, method_ref_index,
     }
   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
 
-  call = build_call_or_builtin (method, func, arg_list);
+  call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
+  TREE_SIDE_EFFECTS (call) = 1;
+  call = check_for_builtin (method, call);
 
   if (check != NULL_TREE)
     {
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.134
diff -u -p -r1.134 java-tree.h
--- java-tree.h	2002/01/22 20:23:45	1.134
+++ java-tree.h	2002/02/18 07:09:08
@@ -1087,7 +1087,7 @@ extern HOST_WIDE_INT java_array_type_len
 extern int read_class PARAMS ((tree));
 extern void load_class PARAMS ((tree, int));
 
-extern tree build_call_or_builtin PARAMS ((tree, tree, tree));
+extern tree check_for_builtin PARAMS ((tree, tree));
 extern void initialize_builtins PARAMS ((void));
 
 extern tree lookup_name PARAMS ((tree));
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.350
diff -u -p -r1.350 parse.y
--- parse.y	2002/02/04 02:38:16	1.350
+++ parse.y	2002/02/18 07:09:17
@@ -10690,14 +10690,10 @@ patch_invoke (patch, method, args)
       func = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (method)), func);
     }
 
-  if (TREE_CODE (patch) == CALL_EXPR)
-    patch = build_call_or_builtin (method, func, args);
-  else
-    {
-      TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
-      TREE_OPERAND (patch, 0) = func;
-      TREE_OPERAND (patch, 1) = args;
-    }
+  TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
+  TREE_OPERAND (patch, 0) = func;
+  TREE_OPERAND (patch, 1) = args;
+  patch = check_for_builtin (method, patch);
   original_call = patch;
 
   /* We're processing a `new TYPE ()' form. New is called and its

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