This is the mail archive of the java-patches@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]

[gij] Fix array accesses


This patch changes code generations fo arrays in libgcj; it generates

  *((elemtype)(&array->data) + index*size_exp)

instead of 

  (array->data)[n]

Now, you might say "That's the same thing."  Well, it is, kinda sorta,
but the array is defined as something like

typedef struct jcharArray
{
  short length;
  jchar data[];
} jcharArray;

where the data field has no declared size; and I think that SSA alias
analysis doesn't see array references into the jarray object as part
of that object.  At least, in my testing I'm discovering that
references to the data field get deleted.  This may be a bug.

Since our IL is not very well-specified, I don't know whether the
thing I used to do is correct.  However, this form is more canonical,
and it's what the C and C++ front ends generate, and it fixes the
problem.

Andrew.


2007-01-09  Andrew Haley  <aph@redhat.com>

	* expr.c (build_java_arrayaccess): Rewrite to generate array
	access in canonical form.
	(expand_java_arraystore): Use build_fold_addr_expr() on address of
	array access.

diff -u /tmp/notnfs/tromey/trunk/gcc/java/expr.c ./expr.c
--- /tmp/notnfs/tromey/trunk/gcc/java/expr.c	2007-01-04 16:43:15.000000000 +0000
+++ ./expr.c	2007-01-08 19:56:33.000000000 +0000
@@ -885,6 +885,7 @@
   tree data_field;
   tree ref;
   tree array_type = TREE_TYPE (TREE_TYPE (array));
+  tree size_exp = fold_convert (sizetype, size_in_bytes (type));
 
   if (!is_array_type_p (TREE_TYPE (array)))
     {
@@ -919,16 +920,34 @@
      to have the bounds check evaluated first. */
   if (throw != NULL_TREE)
     index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
- 
+
   data_field = lookup_field (&array_type, get_identifier ("data"));
 
   ref = build3 (COMPONENT_REF, TREE_TYPE (data_field),    
 		build_java_indirect_ref (array_type, array, 
 					 flag_check_references),
 		data_field, NULL_TREE);
-  
-  node = build4 (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
-  return node;
+
+  /* Take the address of the data field and convert it to a pointer to
+     the element type.  */
+  node = build1 (NOP_EXPR, build_pointer_type (type), build_address_of (ref));
+
+  /* Multiply the index by the size of an element to obtain a byte
+     offset.  Convert the result to a pointer to the element type.  */
+  index = fold_convert (TREE_TYPE (node),
+			build2 (MULT_EXPR, sizetype, 
+				fold_convert (sizetype, index), 
+				size_exp));
+
+  /* Sum the byte offset and the address of the data field.  */
+  node = fold_build2 (PLUS_EXPR, TREE_TYPE (node), node, index);
+
+  /* Finally, return
+
+    *((&array->data) + index*size_exp)
+
+  */
+  return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (node)), node);
 }
 
 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
@@ -1163,7 +1182,7 @@
   java_add_local_var (temp);
   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (temp),
 			 temp, 
-			 build_address_of (access)));
+			 build_fold_addr_expr (access)));
 
   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
     {


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