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

ClassValue.get should be optimized like MutableCallSite.getTarget



    • Type: Enhancement
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 15
    • Fix Version/s: tbd
    • Component/s: hotspot
    • Labels:


      Here’s a scenario where I want constant folding, when types are known statically:

      static final ClassValue<Foo> MYCV = ...;
      static final Class<Bar> C_Bar = Bar.class;
      static final Foo BAR_FOO = MYCV.get(C_Bar);
      Foo getCV0() { return MYCV.get(C_Bar); }
      // == BAR_FOO as a constant
      Foo getCV1(Bar x) { return MYCV.get(x.getClass()); }
      // == BAR_FOO as a constant if Bar is final, or x.getClass == Bar
      Foo getCV2(Object x) { return MYCV.get(x.getClass()); }
      // == BAR_FOO if x.getClass == Bar

      Like MutableCallSite.getTarget, ClassValue.get is likely to be a constant
      value for a long time, and it is profitable for the JIT to speculate that it
      will be constant forever. This requires putting a dependency on n-methods
      that incorporate a speculated constant, so that if MutableCallSite.setTarget
      or ClassValue.remove is called, the code can be recompiled.

      As part of a solution to this, I wonder if maybe we should refactor the existing dependency stuff to work on arbitrary values instead of MHs, so that there is some building block MostlyConstant which holds a speculatively-constant value, so that the JIT will aggressively fold through it with a dependency.

      Or, we can just apply the special logic on CallSite.target to another
      suitable field, of whatever internal ClassValue$Entry structure tracks
      an individual class value binding. To generalize this logic, we could
      mark such fields with an internal annotation. (H/T to Vladimir I.)

      Like @Stable means that a field has an uninitialized past and a
      permanent future, @MostlyConstant (name to be chosen) means that
      the present state is reliable but not necessarily permanent. The two
      annotations would work together, in which case a field would not
      be speculated if it were in its default state.

      For ClassValue::get, the other part of the solution is to be sure that the
      JIT can execute the necessary table lookup performed by ClassValue::get
      at compile time, when (as is often the case) the Class argument can be
      inferred to be a constant.




            Unassigned Unassigned
            jrose John Rose
            0 Vote for this issue
            3 Start watching this issue