<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    <div class="moz-cite-prefix">On 2/12/2016 5:04 PM, Bjorn B Vardal
      wrote:<br>
    </div>
    <blockquote
      cite="mid:201602122201.u1CM1BYo011221@d01av05.pok.ibm.com"
      type="cite">
      <div class="socmaildefaultfont" dir="ltr"
        style="font-family:Arial;font-size:10.5pt">
        <div dir="ltr">
          <div dir="ltr">
            <ol dir="ltr">
              <li>The Top<->Child handshake only needs to happen
                when the Child is loaded (which will load Top as a
                dependency), and access request from Child1 to Child2 is
                reduced to <span style="font-family:courier
                  new,courier,monospace;">Child1->nestTop ==
                  Child2->nestTop</span>. This means that we can fail
                immediately if the handshake fails during class loading,
                i.e. it should not be postponed until a private access
                request fails. Do you agree?<br>
              </li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    I think we have some options here:<br>
     - We could fail fast, rejecting the class.  <br>
     - We could simply load the class into a new nest containing only
    itself; access control (in both directions) that would depend on
    nestmate-ness would fail later.<br>
    <br>
    I think the choice depends on whether we expect to see failures here
    solely because of attacks / broken compilers, or whether we can
    imagine reasonable situations where such a condition could happen
    through separate compilation.  <br>
    <br>
    <blockquote
      cite="mid:201602122201.u1CM1BYo011221@d01av05.pok.ibm.com"
      type="cite">
      <div class="socmaildefaultfont" dir="ltr"
        style="font-family:Arial;font-size:10.5pt">
        <div dir="ltr">
          <div dir="ltr">
            <ol dir="ltr">
              <li>  </li>
              <li>The proposal assumes that nest mates are always
                derived from the same source file. This can be enforced
                by the Java compiler, but is it verifiable by the JVM?
                Both the source file attributes and class name can be
                set to whatever we want, which makes it undesirable for
                verification purposes. The question really has two
                sides:
                <ol>
                  <li>Do nest mates have to be from the same source
                    file?</li>
                  <li>If so, how do we verify it?<br>
                  </li>
                </ol>
              </li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    In Java, this will likely be true, but I can imagine how other
    languages would use this to assemble a nest from multiple separate
    files.  So I don't think we need to claim they must come from the
    same file, nor enforce it-- we only need enforce the integrity of
    the NestXxx attributes.  <br>
    <br>
    <blockquote
      cite="mid:201602122201.u1CM1BYo011221@d01av05.pok.ibm.com"
      type="cite">
      <div class="socmaildefaultfont" dir="ltr"
        style="font-family:Arial;font-size:10.5pt">
        <div dir="ltr">
          <div dir="ltr">
            <ol dir="ltr">
              <li>
                <ol>
                  <li>  </li>
                </ol>
              </li>
              <li>Building on question 2, the solution appears to be
                that nest mates must be loaded by the same class loader.
                If not, someone can load their own class with the same
                name as a class from some nest, using a child class
                loader, which will pass the handshake, effectively
                giving the custom class complete access to that nest.</li>
            </ol>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    Yes.  Same loader, same package, same module, same protection
    domain.  These all seem reasonable constraints here.<br>
    <br>
    <blockquote
      cite="mid:201602122201.u1CM1BYo011221@d01av05.pok.ibm.com"
      type="cite">
      <div class="socmaildefaultfont" dir="ltr"
        style="font-family:Arial;font-size:10.5pt">
        <div dir="ltr">
          <div dir="ltr">
            <div>--<br>
              Bjørn Vårdal</div>
          </div>
        </div>
        <div dir="ltr"> </div>
        <div dir="ltr"> </div>
        <blockquote data-history-content-modified="1" dir="ltr"
          style="border-left:solid #aaaaaa 2px; margin-left:5px;
          padding-left:5px; direction:ltr; margin-right:0px">-----
          Original message -----<br>
          From: Brian Goetz <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com"><brian.goetz@oracle.com></a><br>
          Sent by: "valhalla-spec-experts"
          <a class="moz-txt-link-rfc2396E" href="mailto:valhalla-spec-experts-bounces@openjdk.java.net"><valhalla-spec-experts-bounces@openjdk.java.net></a><br>
          To: <a class="moz-txt-link-abbreviated" href="mailto:valhalla-spec-experts@openjdk.java.net">valhalla-spec-experts@openjdk.java.net</a><br>
          Cc:<br>
          Subject: Nestmates<br>
          Date: Wed, Jan 20, 2016 2:57 PM<br>
           
          <div><font size="2" face="Default Monospace,Courier
              New,Courier,monospace">This topic is at the complete
              opposite end of the spectrum from topics<br>
              we've been discussing so far.  It's mostly an
              implementation story, and<br>
              of particular interest to the compiler and VM implementers
              here.<br>
              <br>
              <br>
              Background<br>
              ----------<br>
              <br>
              Since Java 1.1, the rules for accessibility when inner
              classes are<br>
              involved at the language level are not fully aligned with
              those at the<br>
              VM level.  In particular, private and protected access
              from and to inner<br>
              classes is stricter in the VM than in the language,
              meaning that in<br>
              these cases, the static compiler emits an access bridge
              (access$000)<br>
              which effectively downgrades the accessed member's
              accessibility to<br>
              package.<br>
              <br>
              Access bridges have some disadvantages.  They're ugly, but
              that's not a<br>
              really big deal.  They're imprecise; they allow
              wider-than-necessary<br>
              access to the member.  Again, this is not a huge deal on
              its own.  But<br>
              the real problem is the complexity of the compiler
              implementation when<br>
              we add generic specialization to the story.<br>
              <br>
              Specialization adds a new category of cross-class accesses
              that are<br>
              allowed at the language level but not at the VM level,
              which would<br>
              dramatically increase the need for, and complexity of,
              accessibility<br>
              bridges.  For example:<br>
              <br>
              class Foo<any T> {<br>
                   private T t;<br>
              <br>
                   void m(Foo<int> foo) {<br>
                       int i = foo.t;<br>
                   }<br>
              }<br>
              <br>
              Now we execute:<br>
              <br>
                   Foo<long> fl = ...<br>
                   Foo<int> fi = ...<br>
                   fl.m(fi)<br>
              <br>
              The spirit of the language rules clearly allow the access
              from Foo<long><br>
              to Foo<int>.t -- they are in the "same class".  But
              at the VM level,<br>
              Foo<int> and Foo<long> are different classes,
              so the access from<br>
              Foo<long> to a private member of Foo<int> is
              disallowed.<br>
              <br>
              One reason that this increases the complexity, and not
              just the number,<br>
              of accessibility bridges is that bridges are (currently)
              static methods;<br>
              if they represent instance methods, we pass the receiver
              as the first<br>
              argument.  For access between inner classes, this is fine,
              but when it<br>
              comes to access between specializations, this breeds new
              complexity --<br>
              because the method signature of the accessor needs to be
              specialized<br>
              based on the type parameters of the receiver.  This
              interaction means<br>
              the current static-accessor solution would need its own
              special, ad-hoc<br>
              treatment in specialization, adding to the complexity of
              specialization.<br>
              <br>
              More generally, this situation arises in any case where a
              single logical<br>
              unit of encapsulation at the source level is split into
              multiple runtime<br>
              classes (inner classes, specialization classes, synthetic
              helper<br>
              classes.)  We propose to address this problem more
              generally, by<br>
              providing a mechanism where language compilers can
              indicate that<br>
              multiple runtime classes live in the same unit of
              encapsulation.  We do<br>
              so by (a) adding metadata to classes to indicate which
              classes belong in<br>
              the same encapsulation unit and (b) relaxing some VM
              accessibility rules<br>
              to bring them more in alignment with the language level
              rules.<br>
              <br>
              <br>
              Overview<br>
              --------<br>
              <br>
              Our proposed strategy is to reify the relationship between
              classes that<br>
              are members of the same _nest_.  Nestmate-ness can then be
              considered in<br>
              access control decisions (JVMS 5.4.4).<br>
              <br>
              Classes that derive from a common source class form a
              _nest_, and two<br>
              classes in the same nest are called _nestmates_.
               Nestmate-ness is an<br>
              equivalence relation (reflexive, symmetric, and
              transitive.)  Nestmates<br>
              of a class C include C's inner classes, synthetic classes
              generated as<br>
              part of translating C, and specializations thereof.<br>
              <br>
              Since nestmate-ness is an equivalence relation, it forms a
              partition<br>
              over classes, and we can nominate a canonical member for
              each partition.<br>
                We nominate the "top" (outermost lexically enclosing)
              class in the<br>
              nest as the canonical member; this is the top-level source
              class from<br>
              which all other nestmates derive.<br>
              <br>
              This makes it easy to calculate nestmate-ness for two
              classes C and D; C<br>
              and D are nestmates if their "top" class is the same.<br>
              <br>
              Example<br>
              -------<br>
              <br>
              class Top<any T> {<br>
                   class A<any U> { }<br>
                       class B<V> { }<br>
                   }<br>
              <br>
                   <any T> void genericMethod() { }<br>
              }<br>
              <br>
              When we compile this, we get:<br>
                  Top.class                   // Top<br>
                  Top$A.class                 // Inner class Top.A<br>
                  Top$A$B.class               // Inner class Top.A.B<br>
                  Top$Any.class               // Wildcard interface for
              Top<br>
                  Top$A$Any.class             // Wildcard interface for
              Top.A<br>
                  Top$genericMethod.class     // Holder class for
              generic method<br>
              <br>
              The explicit classes Top, Top.A, and Top.A.B, the
              synthetic $Any<br>
              classes, and the synthetic holder class for genericMethod,
              along with<br>
              all of their specializations, form a nest.  The top member
              of this nest<br>
              is Top.<br>
              <br>
              Since nestmates all derive from a common top-level class,
              they are by<br>
              definition in the same package and module.  A class can be
              in only one<br>
              nest at once.<br>
              <br>
              <br>
              Runtime Representation<br>
              ----------------------<br>
              <br>
              We represent nestmate-ness with two new attributes -- one
              in the top<br>
              member, which describes all the members of the nest, and
              one in each<br>
              member, which requests access to the nest.<br>
              <br>
                   NestTop {<br>
                       u2 name_index;<br>
                       u4 length;<br>
                       u2 child_count;<br>
                       u2 childClazz[child_count];<br>
                   }<br>
              <br>
                   NestChild {<br>
                       u2 name_index;<br>
                       u4 length;<br>
                       u2 topClazz;<br>
                   }<br>
              <br>
              If a class has a NestTop attribute, its nest top is
              itself. If a class<br>
              has a NestChild attribute, its nest top is the class named
              via topClazz.<br>
              If a class is a specialization of another class, its nest
              top is the<br>
              nest top of the class for which it is a specialization.<br>
              <br>
              When loading a class with a NestChild attribute, the VM
              can verify that<br>
              the requested nest permits it as a member, and reject the
              class if the<br>
              child and top do not agree.<br>
              <br>
              The NestTop attribute can enumerate all inner classes and
              synthetic<br>
              classes, but cannot enumerate all specializations thereof.
              When creating<br>
              a specialization of a class, the VM records the
              specialization as being<br>
              a member of whatever nest the template class was a member
              of.<br>
              <br>
              <br>
              Semantics<br>
              ---------<br>
              <br>
              The accessibility rules here are strictly additions;
              nestmate-ness<br>
              creates additional accessibility over and above the
              existing rules.<br>
              <br>
              Informally:<br>
                 - A class can access the private members of its
              nestmates;<br>
                 - A class can access protected members inherited by its
              nestmates.<br>
              <br>
              This is slightly broader than the language semantics (but
              still less<br>
              broad than what we do today with access bridges.)  The
              static compiler<br>
              can continue to enforce the same rules, and the VM will
              allow these<br>
              accesses without bridges.  (We could make the proposal
              match the<br>
              language semantics more closely at the cost of additional
              complexity,<br>
              but its not clear this is worthwhile.)<br>
              <br>
              For private access, we can add the following to 5.4.4:<br>
                 - A class C may access a private member D.R if C and D
              are nestmates.<br>
              <br>
              The rules for protected members are more complicated.
               5.4.3.{2,3} first<br>
              resolve the true owner of the member, and feed that to
              5.4.4; this<br>
              process throws away some needed information.  We would
              augment<br>
              5.4.3.{2,3} as follows:<br>
                - When performing member resolution from class C on
              member D.R, we<br>
              remember both D (the target class) and E (the resolved
              class) and make<br>
              them both available to 5.4.4.<br>
              <br>
              We then adjust 5.4.4 accordingly, by adding:<br>
                - If R is protected, and C and D are nestmates, and E is
              accessible to<br>
              D, then access is allowed.<br>
              <br>
              <br>
              Examples<br>
              --------<br>
              <br>
              For private fields, we generate access bridges whenever an
              inner class<br>
              accesses a private member (field or method) of the
              enclosing class, or<br>
              of another inner class in the same nest.<br>
              <br>
              In the classes below, the accesses shown are all permitted
              by the<br>
              language spec (child to parent, sibling to sibling,
              sibling to child of<br>
              sibling, etc), and the ones requiring access bridges are
              noted.<br>
              <br>
                   class Foo {<br>
                       public static Foo aFoo;<br>
                       public static Inner1 aInner1;<br>
                       public static Inner1.Inner2 aInner2;<br>
                       public static Inner3 aInner3;<br>
              <br>
                       private int foo;<br>
              <br>
                       class Inner1 {<br>
                           private int inner1;<br>
              <br>
                           class Inner2 {<br>
                               private int inner2;<br>
                           }<br>
              <br>
                           void m() {<br>
                               int i = aFoo.foo           // bridge<br>
                                     + aInner1.inner1<br>
                                     + aInner2.inner2     // bridge<br>
                                     + aInner3.inner3;    // bridge<br>
                           }<br>
                       }<br>
              <br>
                       class Inner3 {<br>
                           private int inner3;<br>
              <br>
                           void m() {<br>
                               int i = aFoo.foo           // bridge<br>
                                     + aInner1.inner1     // bridge<br>
                                     + aInner2.inner2     // bridge<br>
                                     + aInner3.inner3;<br>
                           }<br>
                       }<br>
                   }<br>
              <br>
              For protected members, the situation is more subtle.<br>
              <br>
                   /* package p1 */<br>
                   public class Sup {<br>
                       protected int pro;<br>
                   }<br>
              <br>
                   /* package p2 */<br>
                   public class Sub extends p1.Sup {<br>
                       void test() {<br>
                           ... pro ... //no bridge (invokespecial)<br>
                       }<br>
              <br>
                       class Inner {<br>
                           void test() {<br>
                               ... sub.pro ... // bridge generated in
              Sub<br>
                           }<br>
                       }<br>
                   }<br>
              <br>
              Here, the VM rules allow Sub to access protected members
              of Sup, but for<br>
              accesses from Sub.Inner or Sibling to Sub.pro to succeed,
              Sub provides<br>
              an access bridge (which effectively makes Sub.pro
              package-visible<br>
              throughout package p2.)<br>
              <br>
              The rules outlined eliminate access bridges in all of
              these cases.<br>
              <br>
              <br>
              Interaction with defineAnonymousClass<br>
              -------------------------------------<br>
              <br>
              Nestmate-ness also potentially connects nicely with<br>
              Unsafe.defineAnonymousClass.  The intuitive notion of dAC
              is, when you<br>
              load anonymous class C with a host class of H, that C is
              being "injected<br>
              into" H -- access control decisions for C are made using
              H's<br>
              credentials.  With a formal notion of nestmateness, we can
              bring<br>
              additional predictability to dAC by saying that C is
              injected into H's<br>
              nest.</font><br>
            <br>
             </div>
        </blockquote>
        <div dir="ltr"> </div>
      </div>
      <br>
    </blockquote>
    <br>
  </body>
</html>