<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""></div><div class=""><br class=""></div><div class=""><h2 id="vm-bridging" style="font-size: large; margin-top: 3ex; margin-bottom: 0ex; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">VM Bridging</h2><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Historically, bridges have been generated by the static compiler. Bridges are generated today when there is a covariant override (a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">String</code>-returning method overrides an <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Object</code>-returning method), or when there is a generic instantiation (<code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">class Foo implements List<String></code>). (Historically, we also generated access bridges when accessing private fields of classes in the same nest, but nestmates did away with those!)</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Intuitively, a bridge method is generated when a single method implementation wants to respond to two distinct descriptors. At the language level, these two methods really are the same method (the compiler enforces that subclasses cannot override bridges), but at the VM level, they are two completely unrelated methods. This asymmetry is the source of the problems with bridges. One of the main values of making the JVM more aware of bridges is that we no longer need to throw away the useful information that two seemingly different methods are related in this way.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">We took a running leap at this problem back in Java 8, when we were doing default methods; this document constitutes a second run at this problem.</p><h4 id="bridge-anomalies" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Bridge anomalies</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Compiler-generated bridge methods are brittle; separate compilation can easily generate situations where bridges are missing or inconsistent, which in turn can result in AME, invoking a superclass method when an override exists in a subclass, or everyone's favorite anomaly, the bridge loop. Start with:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">class Parent implements Cloneable {
   protected Object clone() { return (Parent)null; }
}

class Child extends Parent {
   protected Parent clone() { return (Parent)super.clone(); }
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Then, change <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent</code> as follows, and recompile only that:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">class Parent implements Cloneable {
   protected Parent clone() { return (Parent)null; }
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">If you call <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">clone()</code> on <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Child</code> you get a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">StackOverflowError</code> (try it!) What's going on is that when we make this change, the place in the hierarchy where the bridge is introduced changes, but we don't recompile the entire hierarchy. As a result, we have a vestigial bridge, and when we invoke <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">clone()</code> with <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">invokevirtual</code> from the new bridge, we hit the old bridge, and loop.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The fundamental problem here is that we are rendering bridges into concrete code "too early", based on a compile-time view of the type hierarchy. We want to make bridge dispatch more dynamic; we can accomplish this by making bridges more declarative than imperative, by recording the notion "A is a bridge for B" in the classfile -- and using that in dispatch -- without having to decide ahead of time exactly what bytecodes to use for bridging.</p><h4 id="generic-specialization" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Generic specialization</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Generics gave us a few situations where we want to be able to access a class member through more than one signature; specialized generics will give us more. For example, in a specialized class:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">class Foo<T> {
    T t;

    T get();
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">In the instantiation <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Foo<int></code>, the type of the field <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">t</code>, and the return type of <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">get()</code>, are <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">int</code>. In the wildcard type <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Foo<?></code>, the type of both of these is <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Object</code>. But because a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Foo<int></code> is a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Foo<?></code>, we want that a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Foo<int></code>responds to invocations of <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">get()Object</code>, and to accesses of the field <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">t</code> as if it were of type <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Object</code>.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">We could handle the method with yet more bridge methods, but bridge methods don't do anything to help us with the field access. (In the M2 prototype we lifted field access on wildcards to method invocations, which was a useful prototyping move, but this does nothing to help existing erased binaries.)</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">So while bridge methods as a mechanism run out of gas here, the <em class="">concept</em> of bridging -- recording that one member is merely an adaptation for another -- is still applicable.</p><h4 id="summary-of-problems" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Summary of problems</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">We can divide the problems with bridges into two groups -- old and new. The old problems are not immediately urgent to fix (brittleness, separate compilation anomalies), but are a persistent source of technical debt, bug tails, and constraints on translation evolution.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The new problems are that specialized generics give us more places we want bridges, making the old problems worse, as well as some places where we want the effects of bridging, but for which traditional bridge methods won't do the trick -- adaptation of fields.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Looking ahead, there are also some other issues on the horizon that we will surely encounter as we migrate the libraries to use specialized generics -- that have related characteristics.</p><h2 id="proposed-solution-forwarded-members" style="font-size: large; margin-top: 3ex; margin-bottom: 0ex; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Proposed solution: <em class="">forwarded members</em></h2><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">I'll lay out one way to express bridges for both fields and methods in the classfile, but there are others. In this model, for a member B that is a bridge for member M, we include a declaration for B in the class file, but we attach a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Forwarding</code> attribute to it, identifying the underlying member <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">M</code> (by descriptor, since its name will be the same) and indicating that attempts to link to B should be forwarded to M:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">Forwarding {
    u2 name;
    u4 length;
    u2 forwardeeType;
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">A method with a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Forwarding</code> attribute has no <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Code</code> attribute. We would then replace existing bridges with forwarding members, and for specializable classes, we would generate a forwarding member for every method and field whose signature contains type variables (and which therefore would change under erasure), whose descriptor is the erasure of the forwardee descriptor.</p><h4 id="adaptation" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Adaptation</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">In all the cases so far, the descriptor of the bridge and of the forwardee differ in relatively narrow ways -- the bridge descriptor can be adapted to the forwardee descriptor with a subset of the adaptations performed by <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">MethodHandle::asType</code>. This is adequate for generic and specialization bridges, but as we'll see below, we may want to extend this set.</p><h4 id="conflicts" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Conflicts</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">If a class contains a bridge whose forwardee descriptor matches the bridge descriptor exactly, the bridge is simply discarded. This decision can be made only looking at the forwarding member, since we'll immediately see that the member descriptor and the forwarding descriptor are identical. (Such situations can arise when a class is specialized with the erasure of its type variables.)</p><h4 id="semantics" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Semantics</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The linkage semantics of forwarding members are different from that of ordinary members. When linking a field or method access, if the resolved target is a forwarding member, we want to make some adjustments <em class="">at the invocation site</em>.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">For a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">getfield</code> that links to a forwarding member, we link the access such that it reads the forwardee field, and then adapts the resulting value to the bridge field type, and leaves the adapted value on the stack. (This is as if the <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">getfield</code> is linked to the result of taking a field getter method handle, and adapting it with <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">asType()</code> to the bridge type.) For a <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">putfield</code>, we do the reverse; we adapt the new field value to the forwardee type, and write to that field.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">If the forwarding member is a method, we re-resolve the method using the forwardee signature, adapt its parameters as we would for <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">putfield</code> and its return value as we would for <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">getfield</code>, and invoke the forwardee <em class="">with the invocation mode present at the call site</em>. Again, the semantics here are as if we took a method handle for the forwardee method, using the invocation mode present at the call site, and adapted it with <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">asType</code> to the bridge descriptor.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The natural interpretation here is that rather than materializing a real field or method body in the class, we manage the forwarding as part of the linkage process, and include any necessary adaptations at the access site. The bridge "body" is never actually invoked; we use the <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Forwarding</code> metadata to adapt and re-link the access sites.</p><h4 id="bridge-loops" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Bridge loops</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The linkage strategy outlined above -- where we truly treat bridges as forwarding to another member -- is the key to breaking the bridge loops. Specifying forwarded members means that the JVM can be aware that two methods are, at some level, the same method; the more complex linkage procedure allows us to invoke the bridgee with the correct invocation mode all the time, even under separate compilation.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">In our <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent</code>/<code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Child</code> example, <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Child::clone</code> will do an <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">invokespecial</code> to invoke <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent::clone()Object</code>, which after recompilation is a bridge to <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent::clone()Parent</code>. We'll see that this is a bridge, and will forward to <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent::clone()Parent</code>, with an <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">invokespecial</code>, and we'll land in the right place.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The elimination of bridge loops here stems from having raised the level of abstraction in which we render the classfile; we record that <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent::clone()Object</code> is merely a bridge for <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Parent::clone()Parent</code>, and so any invocation of the former is redirected -- with the same invocation mode -- to the latter. It is as if the client knew to invoke the right method.</p><h4 id="user-controlled-bridges" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">User-controlled bridges</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The compiler will generate bridges where the language requires it, but we also have the opportunity to enable users to ask for bridges by providing a bridging annotation on the declaration:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">@GenerateBridge(returnType=Object.class)
public static String foo() { ... }</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">This will instruct the compiler to generate an <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Object</code>-returning method that is a bridge for <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">foo()</code>. This could be done for either fields or methods. (People have written frameworks to do this; see for example <a href="http://kohsuke.org/2010/08/07/potd-bridge-method-injector/" class="">http://kohsuke.org/2010/08/07/potd-bridge-method-injector/</a>).</p><h2 id="near-future-problem-type-migration" style="font-size: large; margin-top: 3ex; margin-bottom: 0ex; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Near-future problem: type migration</h2><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">This mechanism may also be able to help us deal with the case when we want to migrate signatures in an otherwise-incompatible manner, such as changing a method that returns <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">int</code> to return <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">long</code>, or an <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">OptionalInt</code> to <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Optional<int></code>, or a old-style <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Date</code> to the newer <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LocalDate</code>. Numerous library modernizations (such as migrating from the old date-time libraries to the JSR-310 versions) are blocked on the ability to make such migrations; specializing the core libraries (especially <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Stream</code>) will also generate such migrations.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Such migrations are a generalization of the sort of bridges we've been discussing here; they involve adding an additional two features:</p><ul style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class=""><li style="margin: 0ex 0em; list-style-type: square;" class="">Additional adaptations, including user-defined adaptations (such as between <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Date</code> and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LocalDate</code>)</li><li style="margin: 0ex 0em; list-style-type: square;" class="">Interaction with overriding, so that subclasses that override the old signature can still work properly.</li></ul><h4 id="projection-embedding-pairs" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Projection-embedding pairs</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Given two types <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">T</code> and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">U</code>, a <em class="">projection-embedding pair</em> is a pair of functions <span class="math inline"><em class="">p</em> : <em class="">T</em> → <em class="">U</em></span> and <span class="math inline"><em class="">e</em> : <em class="">U</em> → <em class="">T</em></span> such that <span class="math inline">∀<em class="">u</em> ∈ <em class="">U</em> <em class="">p</em>(<em class="">e</em>(<em class="">u</em>)) = <em class="">u</em></span>, and, if <span class="math inline"><em class="">t</em></span> is in the range of <span class="math inline"><em class="">p</em></span>, then <span class="math inline"><em class="">e</em>(<em class="">p</em>(<em class="">t</em>)) = <em class="">t</em></span>. Examples of useful projection-embedding pairs are the value sets of <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LV</code> and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">QV</code> for any value class <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">V</code> (we can embed the entirety of <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">QV</code> in <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LV</code>, but <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LV</code> contains one value -- <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">null</code> -- that can't be mapped back), any types <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">T</code>and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">U</code> where <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">T <: U</code>, <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">int</code> and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">long</code> (we can embed <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">int</code> in <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">long</code>), and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Date</code> and <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LocalDate</code>. Intuitively, a p-e pair means we can freely map back and forth for the embeddable subset, and we get some sort of failure (e.g., <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">NPE</code>, or range truncation) otherwise.</p><h4 id="user-provided-adaptations" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">User-provided adaptations</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Many of the adaptations we want to do are handled by <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">MethodHandle::asType</code>: casting, widening, boxing. But sometimes, a migration involves types that require user-provided adaptation behavior, such as converting <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Date</code> to <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">LocalDate</code>. (Bridges need to do these in both directions; we use the embedding for reads and projection for writes.) Here, we can extend the format of the <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Forwarding</code> attribute to capture this additional behavior as pairs of method handles, such as:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">Forwarding {
    u2 name;
    u4 length;
    u2 forwardeeType;
    // adaptation metadata
    u1 pePairs;
    { u2 projection; u2 embedding; }[pePairs];
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">When linking an access site for a forwarding member, when an adaptation is not supported by <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">MethodHandle::asType</code>, we use the user-provided embedding function for adapting return types and field reads, and the projection function for adapting parameter types and field writes.</p><h4 id="overriding" style="font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Overriding</h4><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">A more complicated problem is when we want to migrate the signature of an instance member in a non-final class, because the class may have existing subclasses that override the member, and may not yet have been recompiled. For example, we might start with:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">interface Collection {
    int size();
}

class ArrayList implements Collection {
    int size() { return elements.length; }
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Now, we recompile <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Collection</code> but not <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList</code>:</p><pre style="margin: 1.5ex 2em; width: 60em; padding: 1px 1ex; background-color: rgb(232, 232, 232); font-size: smaller; font-variant-ligatures: normal; orphans: 2; widows: 2; background-position: initial initial; background-repeat: initial initial;" class=""><code style="font-family: 'courier new', monospace; font-size: medium; font-weight: bold;" class="">interface Collection {
    @TypeMigration(returnType=int.class)
    long size();
}</code></pre><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">When we go to load <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList</code>, we'll find that it overrides the bridge (<code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">size()int</code>), and does not override the real method. We'll want to adjust <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList</code> as we load it to make up for this.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Half the problem of this migration is addressed by having a forwarding method from <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">size()int</code> to <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">size()long</code>; any legacy clients that call the old signature will be bridged to the new one. To further indicate that overrides of such a method should be adjusted, suppose we mark this forwarding bridge with <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ACC_MIGRATED</code> (in reality, we can probably use <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ACC_FINAL</code> for this). Now, when we go to load <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList</code>, we'll see that <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">size()int</code> is trying to override a migrated method (this is much like the existing override-a-final check). Instead of rejecting the subtype, instead we use <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ACC_MIGRATED</code> bridges as a signal to fix up overrides.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">We already have all the information in the <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">Forwarding</code> attribute that we need to fix <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList::size</code>; we rewrite the descriptor to the forwardee descriptor, use the projection function for adapting argument types, and the embedding function for adapting the return type, and install the result in <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">ArrayList</code>. It is as if we adapted the subclass method with <code style="white-space: pre; font-family: 'courier new', monospace; font-weight: bold;" class="">asType</code> to the forwardee descriptor, and installed that in the subclass instead.</p><p style="margin: 1ex 0em; font-family: 'Bitstream Vera Sans', Verdana, 'sans serif'; font-size: medium; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">The effect is that in the presence of a migrated bridge, the bridge descriptor is a toxic waste zone; callers are redirected to the new descriptor by bridging, and overriders are redirected to the new descriptor by adaptation.</p></div></body></html>