JDK-8249749 : modify a primitive array through a stream and a for cycle causes jre crash
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,11,15,16
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2020-07-17
  • Updated: 2024-11-20
  • Resolved: 2020-08-10
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 11 JDK 16
11.0.10-oracleFixed 16 b11Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Intel i7-8650u 32GB
Windows 10
OpenJDK 14.0.2

A DESCRIPTION OF THE PROBLEM :
I have a very small code:

  public static void main(String[] args) {
    int n = 4096;
    long[] data = new long[n * n];

    for (int k = 0; k < n; k++) {
      IntStream.range(0, n).forEach(j -> {
        for (int i = 0; i < n; i++)
          data[j * n + i]++;
      });
    }
  }

which has the following output:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd01641aee, pid=27584, tid=15100
#
# JRE version: OpenJDK Runtime Environment (14.0.2+12) (build 14.0.2+12-46)
# Java VM: OpenJDK 64-Bit Server VM (14.0.2+12-46, mixed mode, sharing, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# V  [jvm.dll+0x6b1aee]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\elszszo\git\eulerproject\hs_err_pid27584.log
#
# Compiler replay data is saved as:
# C:\Users\elszszo\git\eulerproject\replay_pid27584.log
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#

If I remove either the outer loop (k), or if I use only j*n or i or j as the array index in the increment line instead of the composite j*n + i , it runs without any issue.

REGRESSION : Last worked in version 8u261

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just execute the following method included

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should be executed without jre crash, with no output.
ACTUAL -
jre crash:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd01641aee, pid=27584, tid=15100
#
# JRE version: OpenJDK Runtime Environment (14.0.2+12) (build 14.0.2+12-46)
# Java VM: OpenJDK 64-Bit Server VM (14.0.2+12-46, mixed mode, sharing, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# V  [jvm.dll+0x6b1aee]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\elszszo\git\eulerproject\hs_err_pid27584.log
#
# Compiler replay data is saved as:
# C:\Users\elszszo\git\eulerproject\replay_pid27584.log
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#


---------- BEGIN SOURCE ----------
  @Test
  public void test() {
    int n = 4096;
    long[] data = new long[n * n];

    for (int k = 0; k < n; k++) {
      IntStream.range(0, n).forEach(j -> {
        for (int i = 0; i < n; i++)
          data[j * n + i]++;
      });
    }
  }

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
if I replace the Instream with a conservative for-loop, it works.

FREQUENCY : always



Comments
Fix request (11u) I would like to downport this for parity with 11.0.10-oracle. Applies clean. I'll push it to 11.0.11. This was adressed before, but then dropped because of open follow up issues. JDK-8251925 and JDK-8251994 are fixed now, and both downported by Oracle. I'll bring them to 11.0.11, too and push them together.
22-12-2020

From the submitter: it works like a charm (I also double checked with jdk15 and it fails with that one). So good job guys, thanks for your help.
17-10-2020

Requested the submitter try the latest build of https://jdk.java.net/16/ to verify the fix.
16-10-2020

The fix can't be backported into 15u until JDK-8251994 is resolved.
14-10-2020

Removing 11u backport approval for now. Please flag again when ready to backport.
22-09-2020

Yes, please, wait JDK-8251994. And this change may cause JDK-8251925 too.
27-08-2020

11u backport is delayed until JDK-8251994 is fixed and backported too.
27-08-2020

Problematic code was added in JDK 9 with JDK-8076284.
18-08-2020

Double-checked new test does not fail on current jdk8u/jdk8u-dev (8u272+).
18-08-2020

Fix Request (11u) This resolves a VM crash. While the changeset touches some diagnostic code, the actual fix is small. Patch applies cleanly to 11u, new test fails without the patch, and passes with it. Additionally, tier{1,2} pass with the fix.
18-08-2020

Fix Request for JDK 15u. We should backport the fix to avoid VM crash. The problem affects all releases since JDK 9. Fix is safe and simple - it exits optimization code if value is NULL. Additional changes does not affect the fix. Fix applied cleanly to JDK 15u and passed tier1, hs-tier2-4 testing. Added new test which reproduces the issue. Fix in JDK 16 passed all CI testing tiers.
17-08-2020

Fix applied cleanly to JDK 11u and 15u sources.
17-08-2020

This fix passed all tiers (1-9) testing in CI. I will prepare backports.
17-08-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/216f9d4c7ec9 User: kvn Date: 2020-08-10 22:31:13 +0000
10-08-2020

http://cr.openjdk.java.net/~kvn/8249749/webrev.00/
10-08-2020

Superword does not recognize array indexing pattern used in the test: data[K + i] It recognize memory reference before IV is incremented: LShiftL(ConvI2L(AddI(K, iv)), 3). But not incremented IV: LShiftL(ConvI2L(AddI(K, AddI(iv, 1))), 3). It chocks on additional AddI.
07-08-2020

The simple fix is bailout vectorization if memory node for alignment is not found: src/hotspot/share/opto/superword.cpp Thu Aug 06 19:20:03 2020 -0700 @@ -499,6 +499,10 @@ find_adjacent_refs(); + if (align_to_ref() == NULL) { + return; // Did not find memory reference to align vectors + } + extend_packlist(); if (_do_vector_loop) {
07-08-2020

The difference in failures with Tiered compilation on vs off is due to what is compiled first. In one case (Tiered) it is OSR compilation: C2: 5788 1233 % b 4 java.util.stream.Streams$RangeIntSpliterator::forEachRemaining @ 34 (65 bytes) in an other normal compilation: C2: 3969 274 b java.util.stream.Streams$RangeIntSpliterator::forEachRemaining (65 bytes) OSR can twist loops. But the issue is the same SuperWord optimization can't find correct packs but still trying to do that instead of bailing out early.
21-07-2020

Also fails with JDK 9/10 and is therefore not a recent (backport) regression.
20-07-2020

ILW = Same as JDK-8235762 = P3
20-07-2020

It does not crash with -XX:TieredStopAtLevel=1. This points to a C2 bug. Note, -XX:-TieredCompilation fails differently: # Internal Error (/home/shade/trunks/jdk-jdk/src/hotspot/share/opto/superword.cpp:1716), pid=2002610, tid=2002622 # assert(my_pack(s) == __null) failed: only in one pack Current CompileTask: C2: 218 11 java.util.stream.Streams$RangeIntSpliterator::forEachRemaining (65 bytes) Stack: [0x00007fb5b0164000,0x00007fb5b0265000], sp=0x00007fb5b025f5f0, free space=1005k Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x17ae7a6] SuperWord::construct_my_pack_map()+0x496 V [libjvm.so+0x17b9931] SuperWord::SLP_extract()+0x221 V [libjvm.so+0x17ba059] SuperWord::transform_loop(IdealLoopTree*, bool)+0x209 V [libjvm.so+0x11e6991] PhaseIdealLoop::build_and_optimize(LoopOptsMode)+0x1101 V [libjvm.so+0x93dad6] PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x326 V [libjvm.so+0x93b061] Compile::Optimize()+0xd71 V [libjvm.so+0x93ca50] Compile::Compile(ciEnv*, ciMethod*, int, bool, bool, bool, bool, DirectiveSet*)+0x1500 V [libjvm.so+0x78c3e8] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x188 V [libjvm.so+0x94a1c8] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xc98 V [libjvm.so+0x94ae78] CompileBroker::compiler_thread_loop()+0x6c8 There are related fixed bugs in the same area: JDK-8198680, JDK-8235762.
20-07-2020

Recent jdk/jdk fastdebug build crashes at: # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007fa8b98d503c, pid=2002292, tid=2002304 Current CompileTask: C2: 458 68 % 4 java.util.stream.Streams$RangeIntSpliterator::forEachRemaining @ 34 (65 bytes) Stack: [0x00007fa840064000,0x00007fa840165000], sp=0x00007fa84015f360, free space=1004k Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x179903c] Node::in(unsigned int) const [clone .isra.0] [clone .constprop.2]+0xc V [libjvm.so+0x17a4e89] SWPointer::SWPointer(MemNode*, SuperWord*, Node_Stack*, bool) [clone .constprop.0]+0x79 V [libjvm.so+0x17a5407] SuperWord::align_initial_loop_index(MemNode*)+0x227 V [libjvm.so+0x17b38f0] SuperWord::output()+0x1000 V [libjvm.so+0x17b97e4] SuperWord::SLP_extract()+0xd4 V [libjvm.so+0x17ba059] SuperWord::transform_loop(IdealLoopTree*, bool)+0x209 V [libjvm.so+0x11e6991] PhaseIdealLoop::build_and_optimize(LoopOptsMode)+0x1101 V [libjvm.so+0x93dad6] PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x326 V [libjvm.so+0x93b061] Compile::Optimize()+0xd71 V [libjvm.so+0x93ca50] Compile::Compile(ciEnv*, ciMethod*, int, bool, boo
20-07-2020

The observations on Windows 10: JDK 8: Pass JDK 11: Fail JDK 14: Fail JDK 15: Fail ILW=HLM=P3 Moved to JDK for further investigations.
20-07-2020