This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Java patch: remove useless array store checks
- To: gcc-patches at gcc dot gnu dot org
- Subject: Java patch: remove useless array store checks
- From: Anthony Green <green at redhat dot com>
- Date: Sat, 6 Oct 2001 06:34:01 -0700
- Reply-to: green at cygnus dot com
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. */