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

[lworld][c1] Optimize withfield bytecode into putfield

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: repo-valhalla
    • Fix Version/s: repo-valhalla
    • Component/s: hotspot
    • Labels:

      Description

      Without optimization, C1 will diligently compile withfield bytecode into a NewValueTypeInstance node, followed by a series of copies of the fields from the original object to the new object. This could generate excessively large amount of code, causing the following test method to fail to compile.

      The proposed fix is -- try to treat a withfield bytecode as a putfield bytecode, as long as the object it operates on does not escape. E.g.,

             5: defaultvalue #1 // class compiler/valhalla/valuetypes/MyValue1
             8: astore_0
             9: iload_0
            10: aload 9
            12: swap
            13: withfield #7 // Field x:I
            16: astore 9

      (This allocates a copy of the object in local#9, modify the "x" field of the copy, and store the copy back into local#9).

      Treat it as

             5: defaultvalue #1 // class compiler/valhalla/valuetypes/MyValue1
             8: astore_0
             9: iload_0
            10: aload 9
            12: swap
            13: putfield #7 // Field x:I

      (This modifies the "x" field of local#9 in place, without allocating a copy -- this is safe because local#9 has not escaped from bytecodes 9 through 16).

      ------

      http://hg.openjdk.java.net/valhalla/valhalla/file/397e474bdb8d/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestOnStackReplacement.java#l112

      $ jtreg -javaoption:-XX:+EnableValhallaC1 -javaoption:-XX:TieredStopAtLevel=1 TestOnStackReplacement.java

          // Test loop peeling and unrolling
          @Test() @Warmup(0) @OSRCompileOnly
          @TempSkipForC1(reason = "C1 inlining overflow")
          public void test3() {
              MyValue1 v1 = MyValue1.createWithFieldsInline(0, 0);
              MyValue1 v2 = MyValue1.createWithFieldsInline(1, 1);
              // Trigger OSR compilation and loop peeling
              for (int i = 0; i < 50_000; ++i) {
                  if (v1.x != 2*i || v2.x != i+1 || v2.y != i+1) {
                      // Uncommon trap
                      throw new RuntimeException("test3 failed");
                  }
                  v1 = MyValue1.createWithFieldsInline(2*(i+1), 0);
                  v2 = MyValue1.createWithFieldsInline(i+2, i+2);
              }
          }

        Attachments

          Activity

            People

            • Assignee:
              iklam Ioi Lam
              Reporter:
              iklam Ioi Lam
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: