<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Thanks for the report, this seems related to long loop
      optimizations. CC'ing Roland.</p>
    <p>Maurizio<br>
    </p>
    <div class="moz-cite-prefix">On 18/08/2023 14:43, 刘希晨 wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CABUmArTy1Z0zm-DEgfA=XROogsz=CK-B4co216uOHP2FtaZ0Bg@mail.gmail.com">
      
      <div dir="ltr"><br>
        <div>Hi guys, I came into a jvm crash problem when using native
          memory access when on my macbook with m1 pro, here is the
          minimum reproducible codes:</div>
        <div><br>
        </div>
        <div>
          <div style="background-color:rgb(30,31,34);color:rgb(188,190,196)">
            <pre style="font-family:"JetBrains Mono",monospace;font-size:9.8pt"><span style="color:rgb(207,142,109)">public class </span>CrashExample {
    <span style="color:rgb(207,142,109)">private static final </span>VarHandle <span style="color:rgb(199,125,187);font-style:italic">byteHandle </span>= MethodHandles.<span style="font-style:italic">memorySegmentViewVarHandle</span>(ValueLayout.<span style="color:rgb(199,125,187);font-style:italic">JAVA_BYTE</span>);
    <span style="color:rgb(207,142,109)">private static final long </span><span style="color:rgb(199,125,187);font-style:italic">len </span>= <span style="color:rgb(42,172,184)">100</span>;
    <span style="color:rgb(207,142,109)">private static final byte </span><span style="color:rgb(199,125,187);font-style:italic">CR </span>= (<span style="color:rgb(207,142,109)">byte</span>) <span style="color:rgb(106,171,115)">'</span><span style="color:rgb(207,142,109)">\r</span><span style="color:rgb(106,171,115)">'</span>;
    <span style="color:rgb(207,142,109)">private static final byte </span><span style="color:rgb(199,125,187);font-style:italic">LF </span>= (<span style="color:rgb(207,142,109)">byte</span>) <span style="color:rgb(106,171,115)">'</span><span style="color:rgb(207,142,109)">\n</span><span style="color:rgb(106,171,115)">'</span>;

    <span style="color:rgb(207,142,109)">public static void </span><span style="color:rgb(86,168,245)">main</span>(String[] args) {
        <span style="color:rgb(207,142,109)">for</span>(<span style="color:rgb(207,142,109)">int </span>round = <span style="color:rgb(42,172,184)">0</span>; round < <span style="color:rgb(42,172,184)">1000</span>; round++) {
            <span style="color:rgb(207,142,109)">try</span>(Arena arena = Arena.<span style="font-style:italic">ofConfined</span>()) {
                MemorySegment memorySegment = arena.allocateArray(ValueLayout.<span style="color:rgb(199,125,187);font-style:italic">JAVA_BYTE</span>, <span style="color:rgb(199,125,187);font-style:italic">len</span>);
                <span style="color:rgb(207,142,109)">for</span>(<span style="color:rgb(207,142,109)">int </span>i = <span style="color:rgb(42,172,184)">0</span>; i < <span style="color:rgb(42,172,184)">100000</span>; i++) {
                    <span style="color:rgb(207,142,109)">int </span>index = i % <span style="color:rgb(42,172,184)">99</span>;
                    <span style="color:rgb(199,125,187);font-style:italic">byteHandle</span>.set(memorySegment, index, <span style="color:rgb(199,125,187);font-style:italic">CR</span>);
                    <span style="color:rgb(199,125,187);font-style:italic">byteHandle</span>.set(memorySegment, index + <span style="color:rgb(42,172,184)">1</span>, <span style="color:rgb(199,125,187);font-style:italic">LF</span>);
                    <span style="color:rgb(207,142,109)">byte</span>[] bytes = <span style="font-style:italic">readUntil</span>(memorySegment, <span style="color:rgb(199,125,187);font-style:italic">CR</span>, <span style="color:rgb(199,125,187);font-style:italic">LF</span>);
                }
            }
        }
    }

    <span style="color:rgb(207,142,109)">private static byte</span>[] <span style="color:rgb(86,168,245)">readUntil</span>(MemorySegment segment, <span style="color:rgb(207,142,109)">byte</span>... separators) {
        <span style="color:rgb(207,142,109)">for</span>(<span style="color:rgb(207,142,109)">long </span>cur = <span style="color:rgb(42,172,184)">0</span>; cur <= segment.byteSize() - separators.<span style="color:rgb(199,125,187)">length</span>; cur++) {
            <span style="color:rgb(207,142,109)">if</span>(<span style="font-style:italic">matches</span>(segment, cur, separators)) {
                <span style="color:rgb(207,142,109)">return </span>segment.asSlice(<span style="color:rgb(42,172,184)">0</span>, cur).toArray(ValueLayout.<span style="color:rgb(199,125,187);font-style:italic">JAVA_BYTE</span>);
            }
        }
        <span style="color:rgb(207,142,109)">return null</span>;
    }

    <span style="color:rgb(207,142,109)">public static boolean </span><span style="color:rgb(86,168,245)">matches</span>(MemorySegment m, <span style="color:rgb(207,142,109)">long </span>offset, <span style="color:rgb(207,142,109)">byte</span>[] bytes) {
        <span style="color:rgb(207,142,109)">for</span>(<span style="color:rgb(207,142,109)">int </span>index = <span style="color:rgb(42,172,184)">0</span>; index < bytes.<span style="color:rgb(199,125,187)">length</span>; index++) {
            <span style="color:rgb(207,142,109)">if </span>((<span style="color:rgb(207,142,109)">byte</span>) <span style="color:rgb(199,125,187);font-style:italic">byteHandle</span>.get(m, offset + index) != bytes[index]) {
                <span style="color:rgb(207,142,109)">return false</span>;
            }
        }
        <span style="color:rgb(207,142,109)">return true</span>;
    }
}</pre>
          </div>
        </div>
        <div><br>
        </div>
        <div>the matches() method try to judge if the memorysegment has
          the same content as bytes from offset index, the readUntil()
          method try to traverse the memorysegment until it finds the
          target separators, return the bytes it has traversed.</div>
        <div><br>
        </div>
        <div>in the main() method,  readUntil() method was tested
          multiple times to reach the C2 compiler, then it will cause
          the JVM to crash.</div>
        <div><br>
        </div>
        <div>Here is what I have find out:</div>
        <div>1. Calling readUntil() method with a single byte will not
          cause the JVM to crash ( In our example, CR and LF were used,
          so there are two bytes)</div>
        <div>2. On Windows and Linux, it works well, this example will
          only crash on MacOS, I don't know if x64 or arm CPU makes a
          difference, since I only have a arm-based macbook</div>
        <div>3. It will only crash when entering C2 compiler phase, when
          the methods are not called so much times, they behave normally</div>
        <div>4. crash seems to always happen in the <span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">#
            V [</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">libjvm.dylib</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">+</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">0x139a2c</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">]
            AddNode::IdealIL(PhaseGVN*, bool, BasicType)+</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">0x48</span> or <span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">#
            V [</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">libjvm.dylib</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">+</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">0x958270</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(188,190,196)">]
            SubLNode::Ideal(PhaseGVN*, bool)+</span><span style="font-family:"JetBrains
Mono",monospace;font-size:9.8pt;background-color:rgb(30,31,34);color:rgb(199,125,187);font-style:italic">0xfc</span> </div>
        <div><br>
        </div>
        <div>I have attached the crash report to the mail, I don't know
          if it's a problem about C2 compiler or Panama memaccess,
          cheers</div>
      </div>
    </blockquote>
  </body>
</html>