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

C2: Escape Analysis misses opportunity for stack allocation

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      A DESCRIPTION OF THE REQUEST :
      Please refer to the source code to understand what's going on.

      Points of interest:

      This will be stack allocated:
          float[] m = new float[16];
          Mat mat = new Mat(m)

      This will not:
          Mat mat = new Mat(new float[16])

      Run the JVM with -verbose:gc flag and see the output.

      JUSTIFICATION :
      I don't see any good reason why this behaviour would be justified, since the workaround is really simple.

      This suggests the compiler is being silly nad not recognizing a situation where a very simple optimization could be used.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Escape analysis should be able to optimize all of the examples below.
      ACTUAL -
      It only optimizes the first one.

      GC activity suggests that objects in example 2 and 3 are being allocated on heap. (run with -verbose:gc flag)

      ---------- BEGIN SOURCE ----------
      public class StackAllocationTest {

      public static void main(String[] args) {
      System.out.println("TEST1, new Mat(m)");
      test1();
      System.out.println("TEST2, new Mat(new float[16])");
      test2();
      System.out.println("TEST2, new Mat()");
      test3();
      }

      static void test1() {
      float result = 0;

      for(int i=0; i<100000000; i++) {
      float[] m = new float[16];
      Mat mat = new Mat(m);
      mat.set(i, i, i);
      mat.mul(0.5f);

      result += mat.getX() + mat.getY() - mat.getZ();
      }

      System.out.println("Result: " + result);
      }

      static void test2() {
      float result = 0;

      for(int i=0; i<100000000; i++) {
      Mat mat = new Mat(new float[16]);
      mat.set(i, i, i);
      mat.mul(0.5f);

      result += mat.getX() + mat.getY() - mat.getZ();
      }

      System.out.println("Result: " + result);
      }

      static void test3() {
      float result = 0;

      for(int i=0; i<100000000; i++) {
      Mat mat = new Mat();
      mat.set(i, i, i);
      mat.mul(0.5f);

      result += mat.getX() + mat.getY() - mat.getZ();
      }

      System.out.println("Result: " + result);
      }

      static class Mat {
      final float[] matrix;

      public Mat(float[] mat) {
      this.matrix = mat;
      }

      public Mat() {
      this.matrix = new float[16];
      }

      public void set(float x, float y, float z) {
      matrix[12] = x;
      matrix[13] = y;
      matrix[14] = z;
      }

      public void mul(float scale) {
      matrix[12] *= scale;
      matrix[13] *= scale;
      matrix[14] *= scale;
      }

      public float getX() {
      return matrix[12];
      }

      public float getY() {
      return matrix[13];
      }

      public float getZ() {
      return matrix[14];
      }
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Allocate float[] first, then pass it to the constructor of a wrapper object

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: