JDK-8058825 : EA: ConnectionGraph::split_unique_types does incorrect scalar replacement
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u40,9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-09-19
  • Updated: 2015-06-03
  • Resolved: 2014-09-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u40Fixed 9 b35Fixed
Related Reports
Relates :  
Description
MH returned for a typed array by compiled MethodHandleImpl::varargsArray throws java.lang.ClassCastException: Cannot cast [Ljava.lang.Object; to [L<your fancy type>.

Issue could be reproduced by following tests starting from 8u40-b06:
java/lang/invoke/JavaDocExamplesTest.java
java/lang/invoke/VarargsArrayTest.java

With 8u40-b05 JavaDocExamplesTest pass, so it seems to be a regression.
This test also passes with 8u20-fcs and with 9-b31.

When MethodHandleImpl::varargsArray compilation disabled via -XX:CompileCommand=exclude,java/lang/invoke/MethodHandleImpl.varargsArray both tests pass.
Comments
[~kvn] I've filed JDK-8059378 to track allocation elimination for non-escaping objects, which don't need rematerialization support.
29-09-2014

noreg-hard: the bug was found w/ an old implementation of Arrays::copyOf intrinsic in 8u40. The intrinsic implementation has been updated in 9. Failed to trigger the same issue from Java code w/o old version of the intrinsic.
29-09-2014

Your fix is correct in this case. Except we will not eliminate such allocations anymore - if it is not referenced in debug info (no deoptimiztion points) we could still eliminate it. But for now lets fix the bug.
25-09-2014

[~kvn], thanks for looking into this. No, there's no more precise CheckCastPP node for this class in the graph. The class is passed as a parameter and the type info is a result of a guard from LibraryCallKit::generate_non_objArray_guard, which narrows the type to "<: Object[]".
25-09-2014

Is there an other CheckCastPP node which cast to String[] exact type? And we can't find it. Your fix is correct if there are no.
24-09-2014

Suggested fix: diff --git a/src/share/vm/opto/escape.cpp b/src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp +++ b/src/share/vm/opto/escape.cpp @@ -2839,6 +2839,13 @@ continue; } } + + const TypeOopPtr *t = igvn->type(n)->isa_oopptr(); + if (t == NULL) + continue; // not a TypeOopPtr + if (!t->klass_is_exact()) + continue; // not an unique type + if (alloc->is_Allocate()) { // Set the scalar_replaceable flag for allocation // so it could be eliminated. @@ -2857,10 +2864,7 @@ // - not determined to be ineligible by escape analysis set_map(alloc, n); set_map(n, alloc); - const TypeOopPtr *t = igvn->type(n)->isa_oopptr(); - if (t == NULL) - continue; // not a TypeOopPtr - const TypeOopPtr* tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni); + const TypeOopPtr* tinst = t->cast_to_instance_id(ni); igvn->hash_delete(n); igvn->set_type(n, tinst); n->raise_bottom_type(tinst); Not sure about performance implications of this change. Need to check whether the new check is too conservative and we can sharped node type.
23-09-2014

ConnectionGraph::split_unique_types doesn't check whether non-escaping object has exact type: src/share/vm/opto/escape.cpp: 2767 void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist) { ... 2853 // in order for an object to be scalar-replaceable, it must be: 2854 // - a direct allocation (not a call returning an object) 2855 // - non-escaping 2856 // - eligible to be a unique type 2857 // - not determined to be ineligible by escape analysis ... 2863 const TypeOopPtr* tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni); Type conversion unconditionally makes the type exact, which doesn't work in all cases.
23-09-2014

EA erroneously narrows array type from "java/lang/Object *[int:0]:NotNull" to "java/lang/Object *[int:0]:NotNull:exact". ======== Connection graph for ArraysCopyOf::test JavaObject NoEscape(NoEscape) [ [ 162 167 ]] 150 AllocateArray === 199 79 67 8 1 ( 66 133 52 52 1 1 1 85 52 105 ) [[ 151 152 153 160 161 162 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) ArraysCopyOf::test @ bci:13 reexecute !jvms: ArraysCopyOf::test @ bci:13 LocalVar [ 150P [ 167 ]] 162 Proj === 150 [[ 163 167 ]] #5 !jvms: ArraysCopyOf::test @ bci:13 LocalVar [ 162 150P [ ]] 167 CheckCastPP === 164 162 [[ 188 ]] #narrowoop: java/lang/Object *[int:0]:NotNull * !jvms: ArraysCopyOf::test @ bci:13 Scalar 167 CheckCastPP === 164 162 [[ 188 ]] #narrowoop: java/lang/Object *[int:0]:NotNull:exact *,iid=150 !jvms: ArraysCopyOf::test @ bci:13 ++++ Eliminated: 150 AllocateArray
23-09-2014

There's a deoptimization taking place and an object of incorrect type is allocated: Uncommon trap occurred in ArraysCopyOf::test (@0x00007fffed1a39c0) thread=140737326892800 reason=unloaded action=reinterpret unloaded_class_index=10 unresolved class: ArraysCopyOf$Inner REALLOC OBJECTS in thread 0x00007ffff000b000 object <0x000000071862b450> of type 'java/lang/Object'[] allocated (16 bytes) DEOPT PACKING thread 0x00007ffff000b000 Compiled frame (sp=0x00007ffff6603670 unextended sp=0x00007ffff6603670, fp=0x00007ffff66036e8, real_fp=0x00007ffff6603690, pc=0x00007fffed1a39c0) nmethod 530224 39 ArraysCopyOf::test (22 bytes) Virtual frames (innermost first): 0 - frame( sp=0x00007ffff6603670, unextended_sp=0x00007ffff6603670, fp=0x00007ffff66036e8, pc=0x00007fffed1a39c0) ArraysCopyOf.test(ArraysCopyOf.java:19) - invokestatic @ bci 18 Created vframeArray 0x00007ffff021c590 DEOPT UNPACKING thread 0x00007ffff000b000 vframeArray 0x00007ffff021c590 mode 2 {method} {0x00007fffe9bc2b50} 'test' '(Ljava/lang/Class;)V' in 'ArraysCopyOf' - invokestatic @ bci 18 sp = 0x00007ffff6603628
22-09-2014

The problem is that Arrays.copyOf() intrinsic returns Object[] array when String[] array is expected.
22-09-2014

It is somehow related to Arrays.copyOf intrinsic. Workaround: -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_copyOf
22-09-2014

ILW=Bad Exception, This test only, none + nightly = HLH=P2
22-09-2014

The failure is specific to 8u40b06. Couldn't reproduce on 9. Missing backport?
19-09-2014