Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8314179

Eliminate useless cyclic object graph

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 22
    • hotspot
    • generic
    • generic

      Currently, C2 can't eliminate the cyclic object graph even though it is useless as a whole. Doubly linked list is the simplest cyclic object graph. In the example, C2 optimizer fails to eliminate both and b even without any gc barrier.

      ```java
          public static void test() {
              var a = new Node();
              var b = new Node();

              a._next = b; b._next = a;
          }
      ```

      here is full output.
      ```
        java.lang.Object::<init> (1 bytes)
      JavaObject(0) GlobalEscape(GlobalEscape) NSR is NSR. Phantom object
      JavaObject(1) NoEscape(NoEscape) is NSR. Null object
      JavaObject(2) GlobalEscape(GlobalEscape) NSR is NSR. Constant pointer
      +++++ Initial worklist for static void DoublyLinkedList.test() (ea_inv=0)
      JavaObject(0) GlobalEscape(GlobalEscape) NSR [ [ ]] 1 Con === 0 [[ ]] Type:top
      JavaObject(2) GlobalEscape(GlobalEscape) NSR [ [ ]] 20 ConP === 0 [[ 24 88 ]] Klass:precise DoublyLinkedList$Node: 0x00007f6bdc371b70:Constant:exact *
      JavaObject(1) NoEscape(NoEscape) NSR [ [ ]] 167 ConP === 0 [[ ]] Type:null
      JavaObject(1) NoEscape(NoEscape) NSR [ [ ]] 167 ConP === 0 [[ ]] Type:null
      JavaObject(3) NoEscape(NoEscape) [ [ 36 ]] 24 Allocate === 5 6 7 8 1 (22 20 21 1 1 1 1 ) [[ 25 26 27 34 35 36 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) DoublyLinkedList::test @ bci:0 (line 8) Type:{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:rawptr:NotNull} !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      JavaObject(4) NoEscape(NoEscape) [ [ 100 ]] 88 Allocate === 38 35 49 8 1 (22 20 21 1 1 41 1 ) [[ 89 90 91 98 99 100 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) DoublyLinkedList::test @ bci:8 (line 9) Type:{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:rawptr:NotNull} !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      Field(5) NoEscape(NoEscape) oop +12 ( )[ [ ]] 155 AddP === _ 41 41 154 [[ 157 ]] Oop:DoublyLinkedList$Node:NotNull:exact+12 * [narrow] !jvms: DoublyLinkedList::test @ bci:18 (line 11)
      Field(6) NoEscape(NoEscape) oop +12 ( )[ [ ]] 158 AddP === _ 105 105 154 [[ 160 ]] Oop:DoublyLinkedList$Node:NotNull:exact+12 * [narrow] !jvms: DoublyLinkedList::test @ bci:23 (line 11)
      LocalVar(7) GlobalEscape(GlobalEscape) [ [ ]] 166 Rethrow === 108 109 31 8 9 exception 115 [[ 0 ]] Type:bottom
      LocalVar(8) NoEscape(NoEscape) [ 24P [ 41 ]] 36 Proj === 24 [[ 37 41 ]] #5 Type:rawptr:NotNull !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      LocalVar(9) NoEscape(NoEscape) [ 88P [ 105 ]] 100 Proj === 88 [[ 101 105 ]] #5 Type:rawptr:NotNull !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(10) NoEscape(NoEscape) [ 36 [ 159 ]] 41 CheckCastPP === 38 36 [[ 155 155 159 88 ]] Oop:DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      LocalVar(11) NoEscape(NoEscape) [ 100 [ 156 ]] 105 CheckCastPP === 102 100 [[ 156 158 158 ]] Oop:DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(12) NoEscape(NoEscape) [ [ ]] 115 Phi === 108 33 97 [[ 166 ]] Oop:java/lang/Throwable (java/io/Serializable):NotNull * !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(13) NoEscape(NoEscape) [ 41 [ ]] 159 EncodeP === _ 41 [[ 160 ]] Type:narrowoop: DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:23 (line 11)
      LocalVar(14) NoEscape(NoEscape) [ 105 [ ]] 156 EncodeP === _ 105 [[ 157 ]] Type:narrowoop: DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:18 (line 11)
      +++++ Calculating escape states and scalar replaceability
      LocalVar(12) NoEscape(NoEscape) -> GlobalEscape(NoEscape) propagated from: LocalVar(7) GlobalEscape(GlobalEscape) [ 115 [ ]] 166 Rethrow === 108 109 31 8 9 exception 115 [[ 0 ]] Type:bottom
      LocalVar(12) GlobalEscape(NoEscape) -> GlobalEscape(GlobalEscape) propagated from: LocalVar(7) GlobalEscape(GlobalEscape) [ 115 [ ]] 166 Rethrow === 108 109 31 8 9 exception 115 [[ 0 ]] Type:bottom
      JavaObject(3) NoEscape(NoEscape) is NSR. is merged with other object: JavaObject(1) NoEscape(NoEscape) NSR
      JavaObject(1) NoEscape(NoEscape) NSR is NSR. is merged with other object: JavaObject(3) NoEscape(NoEscape) NSR
      JavaObject(4) NoEscape(NoEscape) is NSR. is stored into field with NSR base

      ======== Connection graph for DoublyLinkedList::test
      invocation #0: 2 iterations and 0.000009 sec to build connection graph with 169 nodes and worklist size 16

      JavaObject(3) NoEscape(NoEscape) NSR [ 155F [ 36 41 159 158 ]] 24 Allocate === 5 6 7 8 1 (22 20 21 1 1 1 1 ) [[ 25 26 27 34 35 36 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) DoublyLinkedList::test @ bci:0 (line 8) Type:{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:rawptr:NotNull} !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      LocalVar(8) NoEscape(NoEscape) [ 24P [ 41 ]] 36 Proj === 24 [[ 37 41 ]] #5 Type:rawptr:NotNull !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      LocalVar(10) NoEscape(NoEscape) [ 36 24P [ 159 155b ]] 41 CheckCastPP === 38 36 [[ 155 155 159 88 ]] Oop:DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:0 (line 8)
      LocalVar(13) NoEscape(NoEscape) [ 41 24P [ 158 ]] 159 EncodeP === _ 41 [[ 160 ]] Type:narrowoop: DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:23 (line 11)
      Field(6) NoEscape(NoEscape) oop +12 ( 105 88P )[ 159 24P 167P [ ]] 158 AddP === _ 105 105 154 [[ 160 ]] Oop:DoublyLinkedList$Node:NotNull:exact+12 * [narrow] !jvms: DoublyLinkedList::test @ bci:23 (line 11)

      JavaObject(4) NoEscape(NoEscape) NSR [ 158F [ 100 105 156 155 ]] 88 Allocate === 38 35 49 8 1 (22 20 21 1 1 41 1 ) [[ 89 90 91 98 99 100 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) DoublyLinkedList::test @ bci:8 (line 9) Type:{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:rawptr:NotNull} !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(9) NoEscape(NoEscape) [ 88P [ 105 ]] 100 Proj === 88 [[ 101 105 ]] #5 Type:rawptr:NotNull !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(11) NoEscape(NoEscape) [ 100 88P [ 156 158b ]] 105 CheckCastPP === 102 100 [[ 156 158 158 ]] Oop:DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:8 (line 9)
      LocalVar(14) NoEscape(NoEscape) [ 105 88P [ 155 ]] 156 EncodeP === _ 105 [[ 157 ]] Type:narrowoop: DoublyLinkedList$Node:NotNull:exact * !jvms: DoublyLinkedList::test @ bci:18 (line 11)
      Field(5) NoEscape(NoEscape) oop +12 ( 41 24P )[ 156 88P 167P [ ]] 155 AddP === _ 41 41 154 [[ 157 ]] Oop:DoublyLinkedList$Node:NotNull:exact+12 * [narrow] !jvms: DoublyLinkedList::test @ bci:18 (line 11)

      === No allocations eliminated for DoublyLinkedList::test since there are no scalar replaceable candidates ===
      ```
      there are multiple reasons.
      1. EA marks both a NSR because it merges with Null object. same as var b.

      JavaObject(3) NoEscape(NoEscape) is NSR. is merged with other object: JavaObject(1) NoEscape(NoEscape) NSR

      2. Scalar Replacement can't support cyclic object graph. deoptimization need to support rematerialization of cyclic object graph.

      3. with non-trivial gc, we found that gc barrier may interfere with EA.

      Doubly linked list is not uncommon in java even though Java developers may not be aware of it sometimes. eg. Stream framework AbstractPipeline uses Doubly linked list to form a pipeline. In javac, ClassSymbol and ClassType also forms a doubly linked list
       

            Unassigned Unassigned
            xliu Xin Liu
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: