eclipse-omr / omr

Eclipse OMR™ Cross platform components for building reliable, high performance language runtimes
http://www.eclipse.org/omr
Other
948 stars 396 forks source link

Improve l2a IL opcode semantics for collected/non-collected references #6508

Open 0xdaryl opened 2 years ago

0xdaryl commented 2 years ago

Capturing an OpenJ9 Slack channel discussion from here: https://openj9.slack.com/archives/C8312LCV9/p1648614748554659

Hi, does anyone know how I can determine whether the register for l2a node should be a collected reference register or not? 12 replies

Background is, I found a problem with the base register for load instruction of object field. It was not set as collected reference register and caused a GC problem in https://github.com/eclipse-openj9/openj9/issues/14663. For example, the base register (GPR_755) in this IL tree is not a collected reference register because we skip l2a node when populating memory reference.

------------------------------
 n422n    (  0)  ResolveAndNULLCHK on n4147n [#32]                                                    [    0xffff930873a0] bci=[-1,826,660] rc=0 vc=2235 vn=- li=35 udi=- nc=1
 n421n    (  4)    l2a                                                                                [    0xffff93087350] bci=[-1,826,660] rc=4 vc=2235 vn=- li=35 udi=- nc=1
 n4147n   (  1)      lshl (compressionSequence )                                                      [    0xffff934b0000] bci=[-1,826,660] rc=1 vc=2235 vn=- li=- udi=- nc=2 flg=0x800
 n4146n   (  1)        iu2l                                                                           [    0xffff9310ffa0] bci=[-1,826,660] rc=1 vc=2235 vn=- li=- udi=- nc=1
 n4145n   (  1)          iloadi  net/adoptopenjdk/test/nio/NioBuffersTest$Buffers.typeOfBuffer [I[#356  unresolved notAccessed volatile Shadow] [flags 0x2607 0x0 ]  [    0xffff9310ff50] bci=[-1,826,660] rc=1 vc=2235 vn=- li=- udi=- nc=1
 n418n    (  1)            l2a (X>=0 sharedMemory )                                                   [    0xffff93087260] bci=[-1,823,660] rc=1 vc=2235 vn=- li=35 udi=- nc=1 flg=0x100
 n4142n   (  1)              lshl (compressionSequence )                                              [    0xffff9310fe60] bci=[-1,823,660] rc=1 vc=2235 vn=- li=35 udi=- nc=2 flg=0x800
 n4141n   (  1)                ==>iu2l (in GPR_0752)
 n4139n   (  1)                iconst 3                                                               [    0xffff9310fd70] bci=[-1,823,660] rc=1 vc=2235 vn=- li=35 udi=- nc=0
 n4144n   (  1)        iconst 3                                                                       [    0xffff9310ff00] bci=[-1,826,660] rc=1 vc=2235 vn=- li=- udi=- nc=0
------------------------------
------------------------------
 n422n    (  0)  ResolveAndNULLCHK on n4147n [#32]                                                    [    0xffff930873a0] bci=[-1,826,660] rc=0 vc=2235 vn=- li=35 udi=- nc=1
 n421n    (  3)    l2a (in &GPR_0757)                                                                 [    0xffff93087350] bci=[-1,826,660] rc=3 vc=2235 vn=- li=35 udi=41216 nc=1
 n4147n   (  0)      lshl (in &GPR_0757) (compressionSequence )                                       [    0xffff934b0000] bci=[-1,826,660] rc=0 vc=2235 vn=- li=- udi=41216 nc=2 flg=0x800
 n4146n   (  0)        iu2l (in GPR_0754)                                                             [    0xffff9310ffa0] bci=[-1,826,660] rc=0 vc=2235 vn=- li=- udi=40192 nc=1
 n4145n   (  0)          iloadi  net/adoptopenjdk/test/nio/NioBuffersTest$Buffers.typeOfBuffer [I[#356  unresolved notAccessed volatile Shadow] [flags 0x2607 0x0 ] (in GPR_0754)  [    0xffff9310ff50] bci=[-1,826,660] rc=0 vc=2235 vn=- li=- udi=40192 nc=1
 n418n    (  0)            l2a (X!=0 X>=0 sharedMemory )                                              [    0xffff93087260] bci=[-1,823,660] rc=0 vc=2235 vn=- li=35 udi=- nc=1 flg=0x104
 n4142n   (  0)              lshl (in GPR_0755) (X!=0 compressionSequence )                           [    0xffff9310fe60] bci=[-1,823,660] rc=0 vc=2235 vn=- li=35 udi=40576 nc=2 flg=0x804
 n4141n   (  0)                ==>iu2l (in GPR_0752) (X!=0 )
 n4139n   (  0)                iconst 3                                                               [    0xffff9310fd70] bci=[-1,823,660] rc=0 vc=2235 vn=- li=35 udi=- nc=0
 n4144n   (  0)        iconst 3                                                                       [    0xffff9310ff00] bci=[-1,826,660] rc=0 vc=2235 vn=- li=- udi=- nc=0
------------------------------

 [    0xffff93879ef0]   823     lslx    GPR_0755, GPR_0752, 3
 [    0xffff93879ff0]   826     ldrimmw         GPR_0754, [GPR_0755, 0]         ; Backpatched branch to Unresolved Data Snippet Label L0224             # SymRef  net/adoptopenjdk/test/nio/NioBuffersTest$Buffers.typeOfBuffer [I[#356  unresolved notAccessed volatile Shadow] [flags 0x2607 0x0 ]    
 [    0xffff9387a080]   826     dmb     0x00000009
 [    0xffff9387a170]   826     lslx    &GPR_0757, GPR_0754, 3

============================================================

https://github.com/eclipse/omr/blob/72289b92a2a3b678d630ca21d5a3e1a5562968c6/compiler/aarch64/codegen/OMRMemoryReference.cpp#L534-L547

If I change memory reference class not to skip l2a, then I got another GC crash. In this case, the register for l2a (GPR_0018) should not a collected reference register because it contains the entry address of a jitted method.

------------------------------
 n45n     (  0)  treetop                                                                              [    0xffff709c52e
0] bci=[-1,51,92] rc=0 vc=373 vn=- li=4 udi=- nc=1
 n44n     (  0)    calli  java/lang/invoke/ComputedCalls.dispatchDirect_V(JLjava/lang/Object;Ljava/lang/Object;)V[#357  
final native computed-static Method] [flags 0x20500 0x0 ] ()  [    0xffff709c5290] bci=[-1,51,92] rc=0 vc=373 vn=- li=4 
udi=- nc=3 flg=0x20
 n33n     (  0)      ladd (in GPR_0084)                                                               [    0xffff709c4f2
0] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=62304 nc=2
 n32n     (  0)        i2l (in GPR_0084)                                                              [    0xffff709c4ed
0] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=62304 nc=1
 n31n     (  0)          ishr (in GPR_0084) (cannotOverflow )                                         [    0xffff709c4e8
0] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=62304 nc=2 flg=0x1000
 n29n     (  0)            iloadi  <startPCLinkageInfo>[#310  Shadow -4] [flags 0x603 0x0 ] (in GPR_0083) (cannotOverflo
w )  [    0xffff709c4de0] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=61904 nc=1 flg=0x1000
 n28n     (  0)              l2a (in &GPR_0018) (X>=0 sharedMemory )                                  [    0xffff709c4d90] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=35936 nc=1 flg=0x100
 n15n     (  0)                ==>lloadi (in &GPR_0018) (cannotOverflow )
 n30n     (  0)            iconst 16 (X!=0 X>=0 )                                                     [    0xffff709c4e30] bci=[-1,37,92] rc=0 vc=373 vn=- li=4 udi=- nc=0 flg=0x104
 n15n     (  0)        ==>lloadi (in &GPR_0018) (cannotOverflow )
 n39n     (  2)      ==>variableNew (in &GPR_0034) (X!=0 sharedMemory )
 n78n     (  0)      ==>aRegLoad (in &GPR_0016) (SeenRealReference sharedMemory )
———————————————

On all platforms, l2aEvaluator basically does the same thing. It changes the register to a collected reference register if containsCompressionSequence is set on the child node or compressedrefs shift is 0. (and isl2aForCompressedArrayletLeafLoad is not set to the l2a node). https://github.com/eclipse/omr/blob/72289b92a2a3b678d630ca21d5a3e1a5562968c6/compiler/aarch64/codegen/UnaryEvaluator.cpp#L526-L527 https://github.com/eclipse/omr/blob/72289b92a2a3b678d630ca21d5a3e1a5562968c6/compiler/p/codegen/UnaryEvaluator.cpp#L574-L575 https://github.com/eclipse/omr/blob/72289b92a2a3b678d630ca21d5a3e1a5562968c6/compiler/x/codegen/UnaryEvaluator.cpp#L278-L279 https://github.com/eclipse/omr/blob/72289b92a2a3b678d630ca21d5a3e1a5562968c6/compiler/z/codegen/UnaryEvaluator.cpp#L251-L252

0xdaryl commented 2 years ago

After discussion at today's OMR Architecture Meeting (#6451) the consensus was to go ahead and introduce a new IL opcode to handle conversions from long types to collected references (GC objects allocated on a heap). The IL opcode will be treated as a conversion and some work in common code will need to occur to ensure it is handled properly. Also, each backend will need to implement support (should be a relatively minor amount of work).