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]

Java patch: remove useless array store checks



Assignments to arrays of `final' things don't need the runtime array
store check because the compiler guarantees type compatibility.  For
instance...

      public void demo (Object[] oa, String[] sa)
      {
        // This requires a runtime array store check to make sure
        // we can assign String to the real element type of oa.
	// An exception is thrown by _Jv_CheckArrayStore otherwise.
        oa[0] = "Hello";

        // No runtime check should be required in this case because
	// String is a final class and the compiler guarantees type
	// compatibility.
        sa[0] = "World";
      }

Here's a patch to remove this kind of useless check.  The only gotcha
I found was that I had to force CLASS_FINAL for the small number of
classes we define in decl.c.

Tested on x86 Linux.  Ok?


Sat Oct  6 05:23:20 2001  Anthony Green  <green@redhat.com>

	* parse.y (patch_assignment): Don't emit runtime array store
	checks for stores into arrays of final types.
	* expr.c (expand_java_arraystore): Ditto.
	* decl.c (init_decl_processing): Mark java.lang.String,
	java.lang.Class and gnu.gcj.RawData as final.

Index: gcc/java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.316
diff -u -p -r1.316 parse.y
--- parse.y	2001/10/04 02:58:38	1.316
+++ parse.y	2001/10/06 12:28:21
@@ -12934,7 +12934,8 @@ patch_assignment (node, wfl_op1, wfl_op2
   if (!flag_emit_class_files
       && !flag_emit_xref
       && lvalue_from_array 
-      && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
+      && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type))
+      && ! CLASS_FINAL (TYPE_NAME (TYPE_ARRAY_ELEMENT (lhs_type))))
     {
       tree check;
       tree base = lvalue;
Index: gcc/java/expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.117
diff -u -p -r1.117 expr.c
--- expr.c	2001/09/21 16:58:21	1.117
+++ expr.c	2001/10/06 12:28:22
@@ -960,7 +960,11 @@ expand_java_arraystore (rhs_type_node)
   index = save_expr (index);
   array = save_expr (array);
 
-  if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
+  /* Emit array store check when appropriate.  Runtime array store
+     checks are not needed if we're storing into an array of some
+     `final' class.  */
+  if (TREE_CODE (rhs_type_node) == POINTER_TYPE
+      && ! CLASS_FINAL (TYPE_NAME (TREE_TYPE (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array)))))))
     {
       tree check = build (CALL_EXPR, void_type_node,
 			  build_address_of (soft_checkarraystore_node),
Index: gcc/java/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.109
diff -u -p -r1.109 decl.c
--- decl.c	2001/09/22 18:50:09	1.109
+++ decl.c	2001/10/06 12:28:22
@@ -538,8 +538,11 @@ init_decl_processing ()
   object_type_node = lookup_class (get_identifier ("java.lang.Object"));
   object_ptr_type_node = promote_type (object_type_node);
   string_type_node = lookup_class (get_identifier ("java.lang.String"));
+  /* Mark class as `final' in order to avoid runtime store checks for String[].  */
+  CLASS_FINAL (TYPE_NAME (string_type_node)) = 1;
   string_ptr_type_node = promote_type (string_type_node);
   class_type_node = lookup_class (get_identifier ("java.lang.Class"));
+  CLASS_FINAL (TYPE_NAME (class_type_node)) = 1;
   throwable_type_node = lookup_class (get_identifier ("java.lang.Throwable"));
   exception_type_node = lookup_class (get_identifier ("java.lang.Exception"));
   runtime_exception_type_node = 
@@ -551,8 +554,9 @@ init_decl_processing ()
   no_class_def_found_type_node = 
     lookup_class (get_identifier ("java.lang.NoClassDefFoundError"));
 
-  rawdata_ptr_type_node
-    = promote_type (lookup_class (get_identifier ("gnu.gcj.RawData")));
+  rawdata_ptr_type_node = lookup_class (get_identifier ("gnu.gcj.RawData"));
+  CLASS_FINAL (TYPE_NAME (rawdata_ptr_type_node)) = 1;
+  rawdata_ptr_type_node = promote_type (rawdata_ptr_type_node);
 
   /* If you add to this section, don't forget to increase
      PREDEF_FILENAMES_SIZE.  */


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