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

[lworld][c1] Optimize withfield bytecode into putfield

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • repo-valhalla
    • repo-valhalla
    • hotspot

      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);
              }
          }

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

              Created:
              Updated:
              Resolved: