Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8205637 JEP 348: Compiler Intrinsics for Java SE APIs
  3. JDK-8219503

13.1: Allow intrinsification where allowed by the Java SE API

XMLWordPrintable

    • Icon: Sub-task Sub-task
    • Resolution: Unresolved
    • Icon: P3 P3
    • None
    • None
    • specification

      This task investigates the boundary between method invocation in the Java language, and the code generated by a Java compiler for method invocation.

      Let's take the `format(String,Object...)` method declared in `String` for discussion. JLS 15.12.3, 13.1, and 15.12.4 cooperate to ensure that an invocation of this static method at compile time results in control being transferred to the body of exactly that static method at run time. 15.12.3 chooses the method declaration at compile time, 13.1 records a reference to it in the class file, and 15.12.4 selects it at run time. (15.12.4.5 does the physical transfer of control.)

      The Amber prototype compiles the invocation in line with 15.12.3 but not 13.1. For example, the compiler emits not an `invokestatic` that references the chosen method, but rather an `invokedynamic` which references a JDK-internal bootstrap method. Consequently, from a JLS point of view, 15.12.4 may end up selecting a method wholly unconnected with 15.12.3's choice. The JLS cannot even predict whether control will be transferred to somewhere "near" the chosen method, such as the overload `format(Locale,String,Object...)` method declared in `String`, or to somewhere exotic, such as a bootstrap method that Java SE provides to [support intrinsification](http://hg.openjdk.java.net/amber/amber/file/057e60b376b9/src/java.base/share/classes/java/lang/invoke/IntrinsicFactory.java), or indeed if control is transferred at all.

      Now suppose the declaration of the `format(String,Object...)` method was annotated by a Java SE annotation that expressed: "If this method is chosen for invocation, then it is legal to select a different method at run time, as long as its results are semantically equivalent to the result observed by selecting this method at run time." The method would be a _compiler intrinsic candidate_. After 15.12.3 has chosen the method, 13.1 could defer to the presence of the annotation, legitimately recording a symbolic reference to a method other than the chosen method, and freeing 15.12.4 from having to select a method connected with 15.12.3's choice. 13.1 would be where intrinsification "happens".

      So, the minimal JLS change to support compiler intrinsics is to make 13.1 understand the Java SE annotation, indicating "OK to invoke something else, or even invoke nothing at all" when recording a method invocation in a class file. The compile-time mechanism in 15.12.3 that chooses a method is unchanged. The run-time mechanism in 15.12.4 is unchanged, but sidelined (and unaware that it's being sidelined).

      ----- Start changes to 13.1

      5. Given a method invocation expression or a method reference expression in a class or interface `C`, referencing a method named `m` declared (or implicitly declared (§9.2)) in a (possibly distinct) class or interface `D`, ... ((Two bullets follow, unchanged.))

      *****Except for intrinsic candidates (see below)*****, a reference to a method must be resolved at compile time to a symbolic reference ... ((Three bullets and one paragraph follow, unchanged)) ... and does not return a value.

      *****If the annotation `@java.lang.compiler.IntrinsicCandidate` applies to the method that is declared in `D` with the name `m` and the signature determined by §15.12.3, then the method is an intrinsic candidate. The Java compiler is permitted to intrinsify the invocation of an intrinsic candidate, that is, compile the method invocation expression in an implementation-specific manner. Whether the reference to the method is resolved to a symbolic reference, and if so, to which type and signature, is determined by the compiler. Whether there is run-time evaluation of the target reference (§15.12.4.1), non-constant arguments (§15.12.4.2), and accessibility of the intrinsic candidate (§15.12.4.3) is unspecified. However, if the intrinsic candidate is `static`, then the compiler must ensure that class `D` is initialized at run time immediately before the program point corresponding to the method invocation expression (§12.4.1), if `D` was not already initialized.*****

      *****If the Java compiler chooses to intrinsify an invocation performed by class `X`, then linkage of `X` by the JVM must throw no more errors, or kinds of errors, than if the compiler had chosen not to intrinsify the invocation. This means that class `X` is indifferent to the compiler's choice to intrinsify the invocation, assuming no binary-incompatible changes are made to the declaration of the chosen method. If a binary-incompatible change is made, then it is permitted for class `X` to continue to link successfully if the invocation was intrinsified, even though class `X` would not link successfully if the invocation had not been intrinsified. (In this regard, intrinsifying an invocation is similar to inlining the value of a static constant variable (§14.21), where changing the variable's value does not affect pre-compiled clients.)*****

      *****((Start informative note))
      The compiler can intrinsify an invocation only when it has innate knowledge of the method chosen by §15.12.3. Intrinsification usually takes one of three forms:

      1. Invoke the chosen method at compile time (if all the actual arguments are constant expressions), or
      2. Invoke a different method at run time (likely with an optimized implementation and different actual arguments), or
      3. Determine an intermediate result at compile time without invoking the chosen method, then invoke a different method at run time that takes the intermediate result and returns a final result.

      The compiler is never required to intrinsify; it can always choose to invoke the chosen method at run time with the given actual arguments, as if the method was not an intrinsic candidate.
      ((End informative note))*****

      ------ End changes to 13.1

            abuckley Alex Buckley
            vromero Vicente Arturo Romero Zaldivar
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: