Closed pshipton closed 1 year ago
@tajila fyi
The crash occurs in a J2I transition frame
@babsingh can you take a quick look, I suspect we will need the JIT team to look at this as well
The invokeBasic
INL is invoked from the JIT. _currentThread->tempSlot
seems invalid. This leads to incorrect values for lambdaForm
, memberName
and ends with a crash while evaluating _sendMethod
.
@nbhuiyan Can you please take a look?
fyi @0xdaryl @jdmpapin
> stackslots summary
[Top frame, J2I Frame] LambdaForm$NFI/0x000000007800f130.invoke_LI_I, !j9method 0x0000FFFE7800F778, Bytecode index = 13:
-- invokevirtual 6 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/Object;I)I
[JIT Frame] LambdaForm$DMH/0x000000008442a680.invokeStatic, !j9method 0x0000FFFF8442AEC8, Bytecode index = 11:
-- invokestatic 9 java/lang/invoke/MethodHandle.linkToStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/invoke/MemberName;)Ljava/lang/Object;
[Bytecode Frame] LambdaForm$NamedFunction.invokeWithArguments, !j9method 0x0000FFFF8438A110, Bytecode index = 21:
-- invokevirtual 59 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
[Bytecode Frame] LambdaForm.interpretName, !j9method 0x0000FFFF8420EF98, Bytecode index = 119:
-- invokevirtual 208 java/lang/invoke/LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object;
> !j9vmthread 0xffff84980d00 | grep -i jitStackFrameFlags // invokeBasic from the JIT
0x38: UDATA jitStackFrameFlags = 0x0000000040000000 (1073741824) // J9_SSF_JIT_NATIVE_TRANSITION_FRAME is set
> !j9vmthread 0xffff84980d00 | grep -i tempslot // (CORRUPT)
0xf0: UDATA tempSlot = 0xFFFFFFFFFFFFFFA8 (-88)
> !j9object 0xf2dfffc2f2bd3882 // lambdaForm from gdb (CORRUPT)
Unable to read object clazz at 0xF2DFFFC2F2BD3882 (clazz = (null))
(gdb) where
...
#11 0x0000ffff89408c34 in mainSynchSignalHandler (signal=11, sigInfo=0xfffee9ab3b50, contextInfo=0xfffee9ab3bd0)
at /home/jenkins/workspace/Build_JDK19_aarch64_linux_Nightly/omr/port/unix/omrsignal.c:1066
#12 <signal handler called>
#13 0x0000ffff89518cb4 in VM_BytecodeInterpreterFull::invokeBasic (_pc=<synthetic pointer>: <optimized out>, _sp=<synthetic pointer>: <optimized out>, this=0xfffee9ab5110)
at /home/jenkins/workspace/Build_JDK19_aarch64_linux_Nightly/openj9/runtime/vm/BytecodeInterpreter.hpp:8956
#14 VM_BytecodeInterpreterFull::run (vmThread=<optimized out>, this=0xfffee9ab5110) at /home/jenkins/workspace/Build_JDK19_aarch64_linux_Nightly/openj9/runtime/vm/BytecodeInterpreter.hpp:10727
#15 bytecodeLoopFull (currentThread=<optimized out>) at /home/jenkins/workspace/Build_JDK19_aarch64_linux_Nightly/openj9/runtime/vm/BytecodeInterpreter.inc:112
#16 0x0000ffff8957a71c in c_cInterpreter () at /home/jenkins/workspace/Build_JDK19_aarch64_linux_Nightly/build/linux-aarch64-server-release/vm/runtime/vm/arm64cinterp.s:110
...
(gdb) p _sendMethod
$1 = (J9Method *) 0xffff841b22f0
(gdb) p memberName
$2 = <optimized out>
(gdb) p lambdaForm
$3 = (j9object_t) 0xf2dfffc2f2bd3882
(gdb) p mhReceiver
$4 = <optimized out>
(gdb) p _literals
$5 = (J9Method *) 0xfffeec5c655c
(gdb) p _pc
$6 = (U_8 *&) <synthetic pointer>: <optimized out>
If the last compiled method in the stack is LambdaForm$DMH/0x000000008442a680.invokeStatic
, then what the JIT-ed code is setting things up for is a linkToStatic
call. Here are the bytecodes for invokeStatic:
> !bytecodes 0x0000FFFF8442AEC8
...
0 aload0
1 invokestatic 6 java/lang/invoke/DirectMethodHandle.internalMemberName(Ljava/lang/Object;)Ljava/lang/Object;
4 astore3
5 aload1
6 aload2
7 aload3
8 checkcast 7 java/lang/invoke/MemberName
11 invokestatic 9 java/lang/invoke/MethodHandle.linkToStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/invoke/MemberName;)Ljava/lang/Object;
14 return1
The compiled code (with some manual annotations) for this method sets both the tempSlot
and the floatTemp1
fields right before the call:
0xfffeec546fcc: mov x0, #0x3 // #3
0xfffeec546fd0: str x0, [x19, #240] // store to VMThread.tempSlot
0xfffeec546fd4: add x1, x19, #0x100 // x1 set to floatTemp1
0xfffeec546fd8: mov x0, #0xffffffffffffffff // #-1
0xfffeec546fdc: str x0, [x1] // store to floatTemp1
0xfffeec546fe0: ldr x0, [x20, #56]
0xfffeec546fe4: ldr x1, [x20, #48]
0xfffeec546fe8: ldr x2, [x20, #40]
0xfffeec546fec: bl 0xfffeec547080 // Call Snippet (java/lang/invoke/MethodHandle.linkToStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/invoke/MemberName;)Ljava/lang/Object;)
The JIT-ed code obtained from the core dump shown above correctly sets tempSlot
to 3, as well as floatTemp1
to -1 since this linkToStatic
call is not for handling an unresolved invokedynamic/invokehandle. Shouldn't that result in getting to the linkToStaticSpecial
INL helper? This could have then resulted in entering the interpreted method LambdaForm$NFI/0x000000007800f130.invoke_LI_I
, which contains the actual invokeBasic
call that results in getting to the crash site in the invokeBasic
INL helper, which is assuming that we reached there from the JIT. Somewhere between the JIT-ed body of invokeStatic
and the invokeBasic
INL helper, both the tempSlot
and floatTemp1
fields are overwritten, which is not surprising given how overused these fields are for various reasons. The tempSlot
field value cannot be relied on after the first use in an INL helper, so not sure how we ended up in this situation.
@gacholio Can you provide your insights on the below solution and let us know if there is a simpler solution?
In the invokeBasic
INL, we rely upon the J9_SSF_JIT_NATIVE_TRANSITION_FRAME
flag in jitStackFrameFlags
to determine if the INL is being directly called from the JIT. During this failure, there is an i2jTransition -> java/lang/Integer.intValue()I [JITed method] -> j2iTransition
. This is followed by a call to the invokeBasic
INL. Before the call to the invokeBasic
INL, the j2iTransition
sets the J9_SSF_JIT_NATIVE_TRANSITION_FRAME
flag in jitStackFrameFlags
since J9AccNative
is set for MethodHandle.invokeBasic
(modifiers
). Even though invokeBasic
is interpreted, the INL falsely believes that it is being directly called by the JIT since the J9_SSF_JIT_NATIVE_TRANSITION_FRAME
flag is set during j2iTransition
.
Add a new flag (J9_SSF_INL_CALL_FROM_JIT = 0x80000000
). JIT will exclusively set this flag in jitStackFrameFlags
whenever it directly calls the linkTo*
and invokeBasic
INLs: J9CodeGenerator.cpp#L772-L840. Prevent this flag to be overridden in j2iTransition
. Update the linkTo*
and invokeBasic
INLs to take the fromJIT
path only if the new flag is set.
> !bytecodes 0x0000FFFE7800F778
Name: invoke_LI_I
Signature: (Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
Access Flags (20080008): default static
Internal Attribute Flags: @FrameIteratorSkip
Max Stack: 4
Argument Count: 2
Temp Count: 0
0 aload0
1 aload1
2 iconst0
3 aaload
4 aload1
5 iconst1
6 aaload
7 checkcast 3 java/lang/Integer
10 invokevirtual 4 java/lang/Integer.intValue()I
13 invokevirtual 6 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/Object;I)I
16 invokestatic 7 java/lang/Integer.valueOf(I)Ljava/lang/Integer;
19 return1
> !j9method 0x0000FFFF841F1A40
J9Method at 0xffff841f1a40 {
Fields for J9Method:
0x0: U8* bytecodes = !j9x 0x0000FFFEC98C19F0 // "״N"
0x8: struct J9ConstantPool* constantPool = !j9constantpool 0x0000FFFF841F1F20 (flags = 0x0)
0x10: void* methodRunAddress = !j9x 0x0000000000000018
0x18: volatile void* extra = !j9x 0x0000FFFEEBFF11F8
}
Signature: java/lang/Integer.intValue()I !bytecodes 0x0000FFFF841F1A40
ROM Method: !j9rommethod 0x0000FFFEC98C19DC
Next Method: !j9method 0x0000FFFF841F1A60
> !j9rommethod 0x0000FFFEC98C19DC | grep modifier
0x8: U32 modifiers = 0x20050201 (537199105)
> !j9method 0x0000FFFF841B22F0
J9Method at 0xffff841b22f0 {
Fields for J9Method:
0x0: U8* bytecodes = !j9x 0x0000FFFEC985B7E4 // " "
0x8: struct J9ConstantPool* constantPool = !j9constantpool 0x0000FFFF841B15C0 (flags = 0x0)
0x10: void* methodRunAddress = !j9x 0x0000000000000086
0x18: volatile void* extra = !j9x 0x0000000000000001
}
Signature: java/lang/invoke/MethodHandle.invokeBasic([Ljava/lang/Object;)Ljava/lang/Object; !bytecodes 0x0000FFFF841B22F0
ROM Method: !j9rommethod 0x0000FFFEC985B7D0
Next Method: !j9method 0x0000FFFF841B2310
> !j9rommethod 0x0000FFFEC985B7D0 | grep modifiers
0x8: U32 modifiers = 0x20030190 (537067920) // J9AccNative is set for MethodHandle.invokeBasic
Doesn't look 19 specific Moving to 0.38
I don't understand the explanation of why this doesn't work like any other INL. jitStackFrameFlags
is managed entirely by the interpreter and I think it should stay that way.
I don't understand the explanation of why this doesn't work like any other INL. jitStackFrameFlags is managed entirely by the interpreter and I think it should stay that way.
This INL has two code paths: one for direct calls from the JIT and other for interpreted mode. The below sequence causes the invokeBasic INL to falsely believe that it is directly invoked by the JIT when it should be interpreted.
Running interpreted code
i2jTransition
java/lang/Integer.intValue()I [JITed method]
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME
invokevirtual MethodHandle.invokeBasic // Falsely assumes a direct call from the JIT even though it is interpreted
OK, I see what I missed in the reviews for the INLs. When the native transition flag is checked, it must also be cleared. I suggest adding a helper to fetch and clear the bit since the pattern is repeated many times. jitStackFrameFlags
can be set to 0 rather than masking out the bit.
We do clear jitStackFrameFlags (set it to 0) at the end of the invokeBasic and linkTo* INLs before calling j2iTransition. ++ @fengxue-IS to review my initial analysis https://github.com/eclipse-openj9/openj9/issues/16741#issuecomment-1447116352 in case the issue was misinterpreted.
I assume you've left out some frames from your stack trace (I suppose they're not missing at the time). The j2i transition runs the INL which invokes a java method which then does the invokebasic?
Yes. In the second frame (JIT'ed), the linkToStatic INL is invoked. The linkToStatic INL calls the method in the top frame and sets the J2I frame. The top frame is interpreted until the JIT'ed Integer.intValue
method is invoked, which requires the I2J and J2I transitions. A J2I transition has happened just before the invokeBasic INL and after the JIT'ed Integer.intValue
.
Below are top 4 frames in the Java stack:
> stackslots summary
[Top frame, J2I Frame] LambdaForm$NFI/0x000000007800f130.invoke_LI_I, !j9method 0x0000FFFE7800F778, Bytecode index = 13:
-- invokevirtual 6 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/Object;I)I
[JIT Frame] LambdaForm$DMH/0x000000008442a680.invokeStatic, !j9method 0x0000FFFF8442AEC8, Bytecode index = 11:
-- invokestatic 9 java/lang/invoke/MethodHandle.linkToStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/invoke/MemberName;)Ljava/lang/Object;
[Bytecode Frame] LambdaForm$NamedFunction.invokeWithArguments, !j9method 0x0000FFFF8438A110, Bytecode index = 21:
-- invokevirtual 59 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
[Bytecode Frame] LambdaForm.interpretName, !j9method 0x0000FFFF8420EF98, Bytecode index = 119:
-- invokevirtual 208 java/lang/invoke/LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object;
In the top J2I frame, bytecodes for LambdaForm$NFI/0x000000007800f130.invoke_LI_I
are
> !bytecodes 0x0000FFFE7800F778
Name: invoke_LI_I
Signature: (Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;
Access Flags (20080008): default static
Internal Attribute Flags: @FrameIteratorSkip
Max Stack: 4
Argument Count: 2
Temp Count: 0
0 aload0
1 aload1
2 iconst0
3 aaload
4 aload1
5 iconst1
6 aaload
7 checkcast 3 java/lang/Integer
10 invokevirtual 4 java/lang/Integer.intValue()I // JIT'ed method
13 invokevirtual 6 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/Object;I)I
16 invokestatic 7 java/lang/Integer.valueOf(I)Ljava/lang/Integer;
19 return1
I think it would be helpful to repost the sequence of events linearly like before.
Simplified linear sequence of key events:
invokestatic MethodHandle.linkToStatic // from the JIT
j2iTransition // from the linkToStatic INL
Enter LambdaForm$NFI/0x000000007800f130.invoke_LI_I and execute bytecodes in interpreted code
i2jTransition
java/lang/Integer.intValue()I [JITed method]
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME because invokeBasic has J9AccNative set
invokevirtual MethodHandle.invokeBasic // Falsely assumes a direct call from the JIT even though it is interpreted
@gacholio Does the above linear sequence highlight the problem mentioned in https://github.com/eclipse-openj9/openj9/issues/16741#issuecomment-1447116352?
Some has been omitted (j2iTransition to get to the INL etc). I'll update tomorrow with what I suspect is the sequence and you can correct me.
Hi... This issue was discussed in the context of the 0.38 release today. My understanding of the next steps here is to agree to some solution based on Babneet's proposal. From a JIT perspective, we'll implement what's necessary based on that design.
It is not clear how frequent this problem occurs given the information above, but the absence of other build failures commented here it sounds like it may be infrequent. Perhaps this issue should move out to 0.40.
I don't see more than one failure reported.
Is this the sequence of events?
invokestatic MethodHandle.linkToStatic // from the JIT
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME because linkToStatic has J9AccNative set
linkToStatic INL // detects and clears J9_SSF_JIT_NATIVE_TRANSITION_FRAME
j2iTransition // from the linkToStatic INL
Enter LambdaForm$NFI/0x000000007800f130.invoke_LI_I and execute bytecodes in interpreted code
i2jTransition
java/lang/Integer.intValue()I [JITed method] // performs invokeBasic
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME because invokeBasic has J9AccNative set
invokeBasic INL // detects and clears J9_SSF_JIT_NATIVE_TRANSITION_FRAME
j2iTransition // from invokeBasic INL
Enter ??? and execute bytecodes in interpreted code
invokevirtual MethodHandle.invokeBasic // The bit should have been cleared by invokeBasic INL
The error case (NPE) leaves the native transition bit set when it builds the resolve frame, which might lead to problems later on.
re https://github.com/eclipse-openj9/openj9/issues/16741#issuecomment-1500451282:
Integer.intValue
(JIT'ed method) does not perform the invokeBasic
INL.Integer.intValue
, we get to j2iTransition
, where the next method is MH.invokebasic
.j2iTransition
, the native transition flag is set, and the INL falsely assumes a call from the JIT.
#### Bytecodes for `LambdaForm$DMH/0x000000008442a680.invokeStatic`
0 aload0 1 invokestatic 6 java/lang/invoke/DirectMethodHandle.internalMemberName(Ljava/lang/Object;)Ljava/lang/Object; 4 astore3 5 aload1 6 aload2 7 aload3 8 checkcast 7 java/lang/invoke/MemberName 11 invokestatic 9 java/lang/invoke/MethodHandle.linkToStatic(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/invoke/MemberName;)Ljava/lang/Object; 14 return1
#### Bytecodes for `LambdaForm$NFI/0x000000007800f130.invoke_LI_I`
0 aload0 1 aload1 2 iconst0 3 aaload 4 aload1 5 iconst1 6 aaload 7 checkcast 3 java/lang/Integer 10 invokevirtual 4 java/lang/Integer.intValue()I 13 invokevirtual 6 java/lang/invoke/MethodHandle.invokeBasic(Ljava/lang/Object;I)I 16 invokestatic 7 java/lang/Integer.valueOf(I)Ljava/lang/Integer; 19 return1
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME because MH.invokeBasic has J9AccNative set --- missing --- invokevirtual MethodHandle.invokeBasic // Falsely assumes a direct call from the JIT even though it is interpreted
The interesting part is still missing here - the j2iTransition to the invokeBasic INL that clears the bit.
The interesting part is still missing here - the j2iTransition to the invokeBasic INL that clears the bit.
I don't believe there will be an j2iTransition for the invokeBasic INL since the parent method (LambdaForm$NFI/0x000000007800f130.invoke_LI_I
) is interpreted. In this method, only Integer.intValue
is JIT'ed.
That makes no sense - there clearly is a j2iTransition for the INL:
j2iTransition // Sets J9_SSF_JIT_NATIVE_TRANSITION_FRAME because MH.invokeBasic has J9AccNative set
and that invokeBasic must invoke some interpreted method before:
invokevirtual MethodHandle.invokeBasic // Falsely assumes a direct call from the JIT even though it is interpreted
@nbhuiyan @0xdaryl I had a discussion with GAC where it was pointed that J9_SSF_JIT_NATIVE_TRANSITION_FRAME
is being correctly set for the invokeBasic
INL in the j2iTransition
. Currently, the JIT correctly sets tempSlot
and floatTemp1
only if the invokeBasic
or linkTo*
INLs are invoked from a JIT'ed method. The JIT will need to cover all cases where these INLs are invoked after the j2iTransition
:
tempSlot
and floatTemp1
if the INLs are invoked after a j2iTransition
but not from a JIT'ed method? ORtempSlot
and floatTemp1
which will tell the INLs to use the interpreted path after a j2iTransition
?J9_SSF_JIT_NATIVE_TRANSITION_FRAME is being correctly set for the invokeBasic INL in the j2iTransition
Yes, but the problem is not with this flag being set, but with the INL functions using this alone to determine whether their caller was JIT-ed code or interpreted. Currently, when INLs use this flag, it only answers whether there was a j2iTransition prior to entering the INL function, which can happen whether INLs are called from the JIT, or we just returned from a JIT-ed method call. This is why we discussed making use of a different available flag that is only ever exclusively set by the JIT-ed code prior to performing a call into the INLs to signal that we arrived there as a result of a call from JIT-ed code.
Can the JIT correctly set the tempSlot and floatTemp1 if the INLs are invoked after a j2iTransition but not from a JIT'ed method?
I don't see how that is possible.
Can the JIT store a special value in the tempSlot and floatTemp1 which will tell the INLs to use the interpreted path after a j2iTransition?
Not possible as well, unless you are suggesting that JIT-ed code must always set tempSlot
and floatTemp1
at every single possible j2i transition points for every method that is ever JIT-ed. Furthermore, tempSlot
and floatTemp1
are used for many other purposes, so we might also see many other issues show up as a result. A JIT compilation should not have to worry about the fact that the caller of the method being compiled would call an INL function right after that.
All calls to INLs from jitted code must go through j2iTransition - the INLs are inlined functions that can not be called directly.
I realize now that my wording suggested that the INLs are callable directly from the JIT, but yes, I meant the JIT-code was calling the INLs via j2iTransition. The problem is around whether the INL's caller (whether or not via j2iTransition) can correctly be determined by the J9_SSF_JIT_NATIVE_TRANSITION_FRAME
flag that is set by j2itransition whether JIT called the INL via j2iTransition or we just returned from calling a JIT-ed method (in this case, Interger.intValue
) from an interpreted method (invoke_LI_I
).
We appear to be using this issue to discuss two completely unrelated things (jitStackFrameFlags usage and the calling convention for the polymorphic signature INLs called from the JIT).
For jitStackFrameFlags, I think there's a fundamental misunderstanding about how it's used. This field should be 0 at all times except when j2iTransition is invoking a native. j2iTransition sets the field, and any stack frame built by the invoked native detects and clears it (the bit is moved into the specialFrameFlags field in the built stack frame).
The field is zeroed before transitioning from the interpreter to compiled code. I see the JIT is zeroing the field when doing a direct JNI callout, which I believe is unnecessary. If the compiled code has to zero the field, the VM has done something wrong.
For the polymorphic INLs, the stack looks like:
arg
...
arg
MH
If the INL is called from the interpreter, we peek back at the bytecode which invoked the INL and get the arg count from the constant pool of the caller.
If the INL is called from compiled code, the VM must somehow be told the argument count. I can see two possible solutions for this:
1) Fill in a field in the thread as suggested. The JIT could match the name of the called method textually to handle the unresolved call case.
2) Again, detecting the INL by name, the JIT could duplicate or move the MH so the stack looked like:
MH
arg
...
arg
or
MH
arg
...
arg
MH
which allows the VM to find the MH to get the arg count. I can imagine this might cause problems with virtual thunks, so setting the slot might be the better solution.
Looks like only invokeBasic has this issue - the other have the MemberName as the last arg.
I suggest changing:
bool fromJIT = J9_ARE_ANY_BITS_SET(_currentThread->jitStackFrameFlags, J9_SSF_JIT_NATIVE_TRANSITION_FRAME);
to:
bool fromJIT = J9_ARE_ANY_BITS_SET(jitStackFrameFlags(REGISTER_ARGS, 0), J9_SSF_JIT_NATIVE_TRANSITION_FRAME);
or:
bool fromJIT = (0 != jitStackFrameFlags(REGISTER_ARGS, 0));
and removing the explicit zeroing from the new INLs.
Created https://github.com/eclipse-openj9/openj9/pull/17244 to address the jitStackFrameFlags
concern, which is mentioned in https://github.com/eclipse-openj9/openj9/issues/16741#issuecomment-1518097463.
For the arg count issue, I don't think solution 2 is much good - it would require some special casing in the stack walker for the unresolved case.
Based on discussions about this problem over a call, it was pointed out to us by @gacholio that we do not go through j2itransition
function upon returning from a compiled method into the interpreted method. Our initial investigations led us to incorrectly assume that it was because of going through j2itransition
that the jitStackFrameFlags
was incorrectly being set to indicate to the INL function that the call was from compiled code.
Therefore, I will be continuing to work with @babsingh to create a reliably reproducible test failure, and also identify where and how the jitStackFrameFlags
get modified.
I believe we can move this issue out of 0.40, given that it is still a work in progress and the problem is rarely seen.
This may be closeable now that #17732 has been merged.
Closing since https://github.com/eclipse-openj9/openj9/pull/17732 is merged. It can be reopened if the failure reoccurs. See https://github.com/eclipse-openj9/openj9/pull/17732#issuecomment-1630037418 for the grinder details that was used to verify the fix.
https://openj9-jenkins.osuosl.org/job/Test_openjdk19_j9_extended.system_aarch64_linux_Nightly_testList_2/111 SC_Softmx_UpDown_0
https://openj9-artifactory.osuosl.org/artifactory/ci-openj9/Test/Test_openjdk19_j9_extended.system_aarch64_linux_Nightly_testList_2/111/system_test_output.tar.gz