Sample source: public class t { public static final int[] x = { 5, 7, 9, 11 }; } In gcc 3.3 (and 3.4 and earlier than 3.3), this code compiled to something like: .LJv0.0: .long _Jv_intVTable .long 4 .long 5 .long 7 .long 9 .long 11 Now we actually emit code for this. The culprits are a combination of this patch to gcj: 2004-07-08 Richard Henderson <rth@redhat.com> * expr.c (case_identity, get_primitive_array_vtable, java_expand_expr, emit_init_test_initialization): Remove. * java-tree.h (java_expand_expr): Remove. * lang.c (LANG_HOOKS_EXPAND_EXPR): Remove. and this patch to libgcj (which removed the primitive vtables): 2004-07-23 Bryce McKinlay <mckinlay@redhat.com> * prims.cc (_Jv_InitPrimClass): Don't create an array class. (_Jv_CreateJavaVM): Don't pass array vtable parameter to _Jv_InitPrimClass. (DECLARE_PRIM_TYPE): Don't declare array vtables. * include/jvm.h (struct _Jv_ArrayVTable): Removed. * java/lang/Class.h (_Jv_InitPrimClass): Update friend declaration.
Confirmed.
Some of the code from java_expand_expr should be moved into java_gimplify_new_array_init. And maybe fix up libjava code or maybe just storing the array's vtable by using a store. I might look into doing this tomorrow.
Here's my thoughts about this: - This optimization only ever worked for source compilation. Bytecode compilers always emit array initializers as code, so for byte compilation it makes no difference. - I don't see a strong reason not to reference the vtable symbols, but if we decide to remove my patch then we need to be careful that the original bug remains fixed - see: http://gcc.gnu.org/ml/java-patches/2004-q3/msg00343.html - Is this optimization really worth worrying about? I'm pretty sure that performance-wise, the difference is insignificant - binary size is what we should be concerned about here. Is a binary that initializes arrays in code significantly larger?
Created attachment 7473 [details] front-end part Here is the front-end part which is just a port of the expand stuff to the gimplifier (it works in the sense I can see that we get the same assembly code as before the merge of the tree-ssa and now). ChangeLog: * java-gimplify.c: Include parse.h. (get_primitive_array_vtable): New function. (java_gimplify_new_array_init): Add staticly allocated arrays.
Note I attached the front-end part so the only thing left is to fix up libjava to emit the vtables again.
Created attachment 7474 [details] A new patch which completes porting the expand part to the gimplifier This new patch which adds the other part of what the expand code did for NEW_ARRAY_INIT for arrays greater than 10 and constants (with primitive types) to be copied from a static variable: ChangeLog: * java-gimplify.c: Include parse.h. (get_primitive_array_vtable): New function. (java_gimplify_new_array_init): Add staticly allocated primitive arrays and copy arrays which have more than 10 elements and is constant primitives.
I finished up porting the other part of the expand part.
Ada and Java bugs are not release-critical; therefore, I've removed the target milsetone.
Removing target milestone per last comment.
Will not be fixed in 4.1.1; adjust target milestone to 4.1.2.
Closing 4.1 branch.
Tom, this hasn't been reconfirmed in a while. Does this bug still exist in gcj?
It at least still happens with 4.3 and I have no belief that it is fixed with 4.4 if comment #3 applies. Code generated is also absymal (-O2): _ZN1t18__U3c_clinit__U3e_EJvv: .LFB2: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: subl $8, %esp .LCFI2: movl $4, 4(%esp) movl $_Jv_intClass, (%esp) call _Jv_NewPrimArray movl 4(%eax), %edx testl %edx, %edx je .L8 cmpl $1, %edx movl $5, 8(%eax) jbe .L9 cmpl $2, %edx movl $7, 12(%eax) jbe .L10 cmpl $3, %edx movl $9, 16(%eax) jbe .L11 movl $11, 20(%eax) movl %eax, _ZN1t1xE leave ret .L8: movl $0, (%esp) call _Jv_ThrowBadArrayIndex .L9: movl $1, (%esp) call _Jv_ThrowBadArrayIndex .L10: movl $2, (%esp) call _Jv_ThrowBadArrayIndex .L11: movl $3, (%esp) call _Jv_ThrowBadArrayIndex (4.3 again), we do not seem to be able to CSE the load of the array length on the tree level and we have no way (still) of commoning the calls to _Jv_ThrowBadArrayIndex either: <bb 2>: D.241 = _Jv_NewPrimArray (&_Jv_intClass, 4); D.249 = D.241->length; if (D.249 != 0) goto <bb 4>; else goto <bb 3>; <bb 3>: _Jv_ThrowBadArrayIndex (0); <bb 4>: D.241->data[0] = 5; D.263 = D.241->length; if ((unsigned int) D.263 > 1) goto <bb 6>; else goto <bb 5>; <bb 5>: _Jv_ThrowBadArrayIndex (1); <bb 6>: D.241->data[1] = 7; D.277 = D.241->length; if ((unsigned int) D.277 > 2) goto <bb 8>; else goto <bb 7>; <bb 7>: _Jv_ThrowBadArrayIndex (2); <bb 8>: D.241->data[2] = 9; D.291 = D.241->length; if ((unsigned int) D.291 > 3) goto <bb 10>; else goto <bb 9>; <bb 9>: _Jv_ThrowBadArrayIndex (3); <bb 10>: D.241->data[3] = 11; x = D.241; return;
Closing 4.2 branch.
GCC 4.3.4 is being released, adjusting target milestone.
GCC 4.3.5 is being released, adjusting target milestone.
4.3 branch is being closed, moving to 4.4.7 target.
4.4 branch is being closed, moving to 4.5.4 target.
GCC 4.6.4 has been released and the branch has been closed.
The 4.7 branch is being closed, moving target milestone to 4.8.4.
GCC 4.8.4 has been released.
The gcc-4_8-branch is being closed, re-targeting regressions to 4.9.3.
GCC 4.9.3 has been released.
GCC 4.9 branch is being closed
This won't be fixed for 5.x or 6.x so closing as won't fix.