Re: Draft JVMS changes for Nestmates

2017-04-24 Thread David Holmes

Hi Dan,

On 22/04/2017 2:54 AM, Dan Smith wrote:



On Apr 20, 2017, at 5:36 PM, David Holmes mailto:david.hol...@oracle.com>> wrote:


The rule is:
1) if the referenced method name is not  (cheap), and
2) if the referenced class name is the name of a superclass or direct
superinterface (cheap—superclass chain is already loaded), and
3) if the loaded referenced class actually is a superclass or direct
superinterface (almost always true and cheap, unless there's a name
clash), and
4) if the resolved method is not private (pretty cheap, because
referenced class is already loaded)
*then* check that the stack type is assignable to the current class type.

This is, essentially, the same logic being employed by the old
protected check: if the reference is to a superclass, find the
field/method and decide if it's protected; if the reference is to
some other class, don't worry about it.


So here's the problem, in the spec 5.4 states:

"Linking a class or interface involves verifying and preparing that
class or interface, its direct superclass, its direct superinterfaces,
and its element type (if it is an array type), if necessary.
Resolution of symbolic references in the class or interface is an
optional part of linking."

So resolution is _optional_ at link time! But your updated spec
requires resolution to happen before we can complete verification!

When we do the verification of invokespecial in the VM it is before
resolution and we do not know if the target method is private or not.


In the narrow case of an invokespecial in which (1), (2), and (3) are
true, yes, step (4) requires the verifier to find the declaration that
is being referenced and decide if it is 'private'.

This is the same as what the old 4.10.1.8 check has always required for
every invokevirtual, getfield, and putfield: in narrow circumstances,
track down the declared method and decide if it is  or not.

I've tried to be careful not to claim this process is actually
resolution. It could be, but it could also be a simulation of resolution
that just tells you what method would be found if resolution occurred.
Specific text (tweaked slightly since published version): "Given a
symbolic reference to a field or method in class _ReferencedClass_ named
_MemberName_ with descriptor _MemberDescriptor_, identifies the field or
method _Member_ declared in class _DeclaringClass_ that would be
produced by resolution, as specified in [5.4.3]."

I am curious about the actual implemented details of this in the
protected check. I'm happy to make adjustments to the spec to align with
how we actually do this.


It looks like we do the "pseudo-resolution" of the method 
(InstanceKlass::uncached_lookup_method()) or field 
(InstanceKlass::find_field()).


I'm now curious about whether we essentially do this twice! That would 
be very inefficient. :(


That aside, it seems it is okay for the spec to require this kind of 
"look-ahead".


Thanks,
David


—Dan



Re: Draft JVMS changes for Nestmates

2017-04-21 Thread Dan Smith

> On Apr 20, 2017, at 5:36 PM, David Holmes  wrote:
> 
>> The rule is:
>> 1) if the referenced method name is not  (cheap), and
>> 2) if the referenced class name is the name of a superclass or direct 
>> superinterface (cheap—superclass chain is already loaded), and
>> 3) if the loaded referenced class actually is a superclass or direct 
>> superinterface (almost always true and cheap, unless there's a name clash), 
>> and
>> 4) if the resolved method is not private (pretty cheap, because referenced 
>> class is already loaded)
>> *then* check that the stack type is assignable to the current class type.
>> 
>> This is, essentially, the same logic being employed by the old protected 
>> check: if the reference is to a superclass, find the field/method and decide 
>> if it's protected; if the reference is to some other class, don't worry 
>> about it.
> 
> So here's the problem, in the spec 5.4 states:
> 
> "Linking a class or interface involves verifying and preparing that class or 
> interface, its direct superclass, its direct superinterfaces, and its element 
> type (if it is an array type), if necessary. Resolution of symbolic 
> references in the class or interface is an optional part of linking."
> 
> So resolution is _optional_ at link time! But your updated spec requires 
> resolution to happen before we can complete verification!
> 
> When we do the verification of invokespecial in the VM it is before 
> resolution and we do not know if the target method is private or not.

In the narrow case of an invokespecial in which (1), (2), and (3) are true, 
yes, step (4) requires the verifier to find the declaration that is being 
referenced and decide if it is 'private'.

This is the same as what the old 4.10.1.8 check has always required for every 
invokevirtual, getfield, and putfield: in narrow circumstances, track down the 
declared method and decide if it is  or not.

I've tried to be careful not to claim this process is actually resolution. It 
could be, but it could also be a simulation of resolution that just tells you 
what method would be found if resolution occurred. Specific text (tweaked 
slightly since published version): "Given a symbolic reference to a field or 
method in class _ReferencedClass_ named _MemberName_ with descriptor 
_MemberDescriptor_, identifies the field or method _Member_ declared in class 
_DeclaringClass_ that would be produced by resolution, as specified in [5.4.3]."

I am curious about the actual implemented details of this in the protected 
check. I'm happy to make adjustments to the spec to align with how we actually 
do this.

—Dan



Re: Draft JVMS changes for Nestmates

2017-04-20 Thread David Holmes

Hi Dan,



On 21/04/2017 4:43 AM, Dan Smith wrote:

Security risk

The JEP text should acknowledge that, while this does allow compilers to grant 
finer-grained access to members shared by nestmates, it also pushes compilers 
to grant broader access to members that were previously kept private. It's a 
trade-off, and presumably a good one because nestmates are completely trusted, 
while package-mates might sometimes be suspect.


I'm not following you here. What broader access is being granted to members 
that were previously kept private? This effort allows private-only access to 
members that were previously package-accessible.


Old approach is to widen access to private members to the package level on a 
per-member basis.

New approach is to widen access to private members to the nest level on a 
per-class basis.

Nest is narrower than package (good!), but per-class is more permissive than 
per-member (bad). Some members that are compiled as totally private in JDK 9 will be 
incidentally shared with all nest members in .


I'm not sure how you are coming at this. For a private member in 9 to be incidentally 
shared in  the class of the member has to be added to a nest. With 
no context as to how this may happen I can't really comment further. From the Java 
language perspective if the class is in a nest then such access to private members 
already exists.


Example:

class Outer {
private int x;
private int y;
class Inner { private int z = x; }
}

In JDK 9, this compiles to:

class Outer {
private int x;
private int y;
Outer() {}
static int access$000(Outer arg) { return x; }
}

class Outer$Inner {
private int z;
final Outer this$0;
Outer$Inner(Outer arg) {
this$0 = arg;
z = Outer.access$000(this$0);
}
}

In , this compiles to:

class Outer [NestMembers:{Outer$Inner}] {
private int x;
private int y;
Outer() {}
}

class Outer$Inner [MemberOfNest:Outer] {
private int z;
final Outer this$0;
Outer$Inner(Outer arg) {
this$0 = arg;
z = this$0.x;
}
}

Notice that in JDK 9, Outer shares access to y with nobody, while in 
, Outer shares access to y with its NestMembers.


Only because in JDK9 javac doesn't generate all potential accessors 
(which it could). The current language rules say that y is accessible to 
nestmates. As none try to actually access it javac doesn't bother 
generating the accessor.



In:

"If getfield or putfield is used to access a protected field referenced in a 
superclass ..."

and following, you changed "declared" to read "referenced". Again I do not understand 
what this is supposed to mean. It is the declaration site of the field or method that is needed to determine 
whether that member is in the same or another package. To me "declared in a superclass ..." was 
exactly correct. Your note does not make the change any clearer to me.


Good catch. It's important that the rule be limited to cases that reference a 
superclass*; but it's also important that the declaring class be used for the 
package check.

(*Here's why: if I reference my subclass, and that resolves to a field declared 
in my superclass, the verifier will perform no check, because it may not know 
that the referenced class is a subclass.)

Revised:

"If `getfield` or `putfield` is used to access a `protected` field by reference to a 
superclass, and that field is declared in a different run-time package than the current 
class or interface, then the type of the class instance being accessed must be assignable 
to the current class or interface."


I still think "declared in" is the correct terminology. There's a nuance to how 
you are expressing this that I'm just not getting.


Example:

public class p1.A {
protected int i;
}

public class p2.B extends p1.A {
int test(p2.C arg) {
aload_1
getfield p2.C.i:I
ireturn
}
}

public class p2.C extends p2.B {
}

When the verifier checks the getfield, it will apply the rules in 4.10.1.8. The check 
will trivially pass, because p2.C is not a superclass of the current class (p2.B). There 
will be no test that p2.C is "assignable to the current class or interface". 
Thus, p2.C need not be loaded during verification.

Strictly reading the old rule, "field declared in a superclass" means that the 
verifier would have to load p2.C and resolve (or simulate resolution of) p2.C.i:I in 
order to determine whether the field is declared in a superclass of the current class 
(p2.B).


I'm not 100% sure of what needs loading when, but don't know why this is 
an issue either. The package check is needed to see if the more specific 
protected-access check is needed. As p2.C.i actually refers to the 'i' 
declared in p1.A, then we should be checking if B and A are in the same 
package.



6.5 invokespecial

You note regarding the IllegalAccessError:

"This replaces a VerifyError previously specified by 4.9.2. The check must be 
delayed until after resoluti

Re: Draft JVMS changes for Nestmates

2017-04-20 Thread Dan Smith
> On Apr 19, 2017, at 7:31 PM, David Holmes  wrote:
> 
> Hi Dan,
> 
> On 20/04/2017 2:06 AM, Dan Smith wrote:
>>> On Apr 19, 2017, at 12:45 AM, John Rose >> > wrote:
>>> 
>>> - NMs must be non-empty (degenerate nest is never explicit)
>>> - NMs may not contain duplicates (cf. treatment of ClassFile.interfaces)
>>> - NMs may not contain the current class (i.e., an index to a class
>>> with the same name as this_class)
>>> - NMs may contain only package siblings (ditto)
>>> - NMs and MoN may not refer to array classes (this is probably
>>> implied by the package prefix checks)
>> 
>> These are all do-able, but I'm not sure they're consistent with the
>> spirit of JVMS in its treatment of attributes. We don't usually assert
>> that lists are non-empty, don't contain duplicates, etc. (Granted, most
>> attributes are not relevant to JVM execution.) You mention `interfaces`,
>> but I don't see any such assertion in 4.1.
> 
> The NestMembers duplicate check exists because I copied the spec and code 
> from the InnerClasses attribute. 4.7.6 states the classes[] "must have 
> exactly one corresponding entry ..." - hence a check for duplicates is done. 
> I used the same language when I defined NestMembers. So the precedent does 
> exist.

I think you mean this?

"Every CONSTANT_Class_info entry in the constant_pool table which represents a 
class or interface C that is not a package member must have exactly one 
corresponding entry in the classes array."

Again, this is compiler spec territory. Which I don't mind tolerating in an 
attribute definition that is for Java-specific metadata and that is ignored by 
the JVM. But I'd like to hold critical attributes like NestMembers to a 
different standard.

(That said, if the consensus is to check NestMembers for duplicates, I can live 
with it.)


> On Apr 19, 2017, at 9:56 PM, David Holmes  wrote:
> 
> On 20/04/2017 7:58 AM, Dan Smith wrote:
>> **4.7.25 The `MemberOfNest` Attribute**
>> ---
>> 
>> **The `MemberOfNest` attribute is a fixed-length attribute in the
>> `attributes` table of a `ClassFile` structure ([4.1]).**
>> 
>> **A _nest_ is a set of classes and interfaces that share access to their
>> `private` members ([5.4.4]).**
> 
> Aside: it is this basic definition of "nest" that I expected to appear 
> somewhere earlier in the spec. JVMS doesn't have any upfront "concepts and 
> definitions" section, so not sure where it would go.

Well, there is: Chapter 2. But it doesn't mention accessibility at all, so hard 
to explain nests. 4.7.25, as the first place where the topic comes up, seems 
like the next best place.

>> **A class or interface with a `MemberOfNest` attribute belongs to the
>> nest hosted by a designated _host class_. The host class authorizes
>> membership in the nest with a corresponding entry in its `NestMembers`
>> attribute ([4.7.26], [4.10]).**
> 
> Only nit is I would say "claims membership of" rather than "belongs to". That 
> emphasises that membership must be ratified by the "host class", and matches 
> the following "authorizes membership" text.

Somewhere we need a definitive "class C belongs to the nest N" specification. 
Hence my strong language here.

As you said in the other thread, if I say I belong to a nest, but it turns out 
I'm not authorized, that's a basic well-formedness error and I get a lethal 
injection.

Similarly, I can claim to be my own superclass, and we might say "the 
superclass of C is C", but that class immediately gets killed and anybody who 
depends on the meaning of "superclass" can assume that it has the desired 
properties.

> To me the "authorized" is implicit. By calling it out explicitly it suggests 
> to me there are also UnauthorizedNestMembers. But to me this is an oxymoron - 
> if you are unauthorized you are not an unauthorized-member, you are not any 
> kind of member at all.

An unauthorized nest member is one that gets a lethal injection.


> On Apr 19, 2017, at 10:12 PM, David Holmes  wrote:
> 
>>> 4.10.1.8 Type Checking for Restricted Member References
>>> 
>>> I'm not very good at reading or understanding these rules, but I'm
>>> surprised that the invokespecial rules seem to make no mention of
>>> nestmates at all:
>>> 
>>> "A method reference is allowed by an invokespecial instruction if it
>>> is not a restricted invokespecial reference, ..."
>>> 
>>> This seems to open things up to all private method references??
>> 
>> Well, the whole point of nestmates is to extend, in a regular way,
>> all access rules that pertain to self-access and privacy.
>> If the extension is truly regular, it is not surprising that the spec.
>> changes are subtle like this.  We're not trying to do an ad hoc
>> patch on some set of particular behaviors, but rather extend
>> pre-existing notions so they apply in more conditions, including
>> invokespecial restrictions.
> 
> I was expecting to see the restrictions have a dependency on nestmates 
> actu

Re: Draft JVMS changes for Nestmates

2017-04-20 Thread David Holmes

Hi Dan,

I'll try not to double up on things already discussed elsewhere. And 
avoid bikeshedding :)


On 20/04/2017 5:21 AM, Dan Smith wrote:

Thanks a lot for the feedback! My comments below:


On Apr 19, 2017, at 12:40 AM, David Holmes  wrote:


JEP name

I don't know how permanent JEP names are supposed to be, but I'd prefer a different name at this 
point. Something like: "Expanded JVM Access to Private Members"—shorter, focused on the 
feature itself rather than its relationship to the Java language. Or maybe "Class Nests for 
Access to Private Members".


The intent of the name is to aid in the contextual positioning of this JEP ie 
address why do we even need this. The JEP addresses an inconsistency between 
access controls in the Java programming language and access controls in the 
JVM. The primary goal here is to align the two, while at the same time allowing 
for additional usage of nestmates in the future.


Yeah, but I think explaining the motivation in the title makes for a long title 
and limits the imagination to one particular use case.


The JEP uses "nest top" to describe the class that nest members reference; I prefer "host class", 
which better describes the class's role and isn't tied to the Java "top level class" concept. I know we use 
"host class" internally in Hotspot, perhaps when working with anonymous classes (of the JVM flavor), but I 
think in that context it will ultimately mean the same thing? Are we comfortable repurposing the term in this way?


Given that a nest-top type must be a top-level type, I think nest-top fits 
perfectly.


This is a good example of my point about the title: the JVM has no concept* of "top 
level type", and doesn't need one. We just need a specific class to act as the 
reference point by which a group of classes can talk about a nest.


But we are attempting to justify this by relating to the impedance 
mismatch with the Java language. And we do utilize the notion of 
"top-level class" (as defined by JLS) elsewhere.



For example, I can imagine some language introducing a class 
file—foo.bar.Nest$$001—solely for the purpose of providing a hook for this 
reference point. javac's choice to designate a top-level class as the 
nest-top/nest-host is a compilation strategy.

(*Yes, there's an InnerClasses attribute, and Signature attributes, and lots of 
other stuff to facilitate compilation in the Java language. But those represent 
auxiliary metadata, not core JVM concepts.)


I dislike "host class" because that is already used for the quite different case of 
VMACs. I can live with other names but I think they should incorporate "nest" eg. 
nest-holder, nest-host. But I think nest-top is an ideal match. (And no I didn't invent this 
terminology :) ).


Okay. Probably best to sit on this for awhile and circle back to it, see how 
we're all feeling.


I think nest-host is starting to take the lead :)


I follow Brian's model when it comes to nest membership (5.4.4): every class 
belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted by 
itself. Many nests are singletons without any associated explicit attributes.


I have not yet seen a follow up from John as to whether we require or just 
allow, an empty NestMembers attribute to indicate a singleton nest member.


If in our model *every* class has a nest, then we definitely don't want to 
require every class to have a NestMembers attribute.

In my spec (5.4.4), the presence of a NestMembers attribute is irrelevant. A 
class without a MemberOfNest attribute belongs to its own nest, and there's no 
need to validate anything about NestMembers.


Verification of MemberOfNest

I include a discussion block about different options of validating 
MemberOfNest. I think the consensus, and my preference, is to do it during 
verification of the member class. (NestMembers, on the other hand, is never 
validated, except as a side-effect of checking MemberOfNest.)


Given verification is optional the current approach is to validate during 
linking just prior to the verification step. Whether that can conceptually be 
considered part of verification I am unsure.


I think this is the source of a lot of anomalies—spec treats verification as an 
essential part of linking, while Hotspot treats it as an optional add-on.

You should be okay, for some definition of "just prior". These are the 
constraints, as I read them:
- "A class or interface is completely loaded before it is linked." (5.4)
- Loading includes structural checks (CFE), version checks (UCVE), and 
validation and loading of superclasses and superinterfaces (5.3.5)
- "Errors detected during linkage are thrown at a point in the program where some 
action is taken by the program that might, directly or indirectly, require linkage to the 
class or interface involved in the error." (5.4)

That last one is pretty mysterious to me (what does "some action" mean? what about 
"indirectly"?), but seems to grant pretty wide latitude on the tim

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

One follow up to a new comment John made ...

On 20/04/2017 10:09 AM, John Rose wrote:

On Apr 19, 2017, at 12:56 AM, David Holmes mailto:david.hol...@oracle.com>> wrote:



I don't see how that is a significant concern.  The symbol bodies are
hot in cache
at the point we would check prefixes, since they are already being
scanned for other
purposes, such as initial interning, and also syntax checking.  Existing
processing
is exactly as deep (or shallow) as the checks I want.


I don't follow that. If I'm loading a nest-top class and validating
its NM entries none of those entries need have been loaded yet and so
none will be in the cache.


I see what the problem is:  The only checking I am proposing
is syntax checking on the names.  If by "deep checking" you
mean loading classes from the names, I agree, we don't want
to do that.  The MemberOfNest attribute is passive.  It does
not need to initiate loads; it just needs to validate claims
of nest membership by other classes.

(I even doubt Dan's assertion that in some corner cases,
when the nest-host is trying out a private access, there
must be some loading done to validate the access.  Probably
we can get away with no loading at all, just name checks
against already-loaded classes.)


If the access is legitimate then no loading is needed as the common 
nest-host is already loaded. Currently the implementation will load the 
purported nest-host if needed, so in the case where they are not 
actually nest-mates this would load the "foreign" nest-host class. But 
when the initiator is the nest-host the check can be inverted by 
searching NestMembers for the target class instead. I see one quirky 
aspect of this in that in the unlikely case that the target class is in 
NestMembers but does not itself list the nest-host in its MemberOfNest, 
the access check will succeed, but before the invocation can actually 
happen the target class must be linked and at that point validation 
would fail (assuming we adopt the fail-fast model).


David


— John


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes
Limited response as issues have been covered elsewhere, and Dan has 
revisited suggested spec wording. But for completeness ...


On 20/04/2017 10:32 AM, John Rose wrote:

On Apr 18, 2017, at 11:40 PM, David Holmes mailto:david.hol...@oracle.com>> wrote:


4.7.26 The MemberOfNest Attribute

"the class is implicitly a member of its own nest"

I suggest changing "a" to "the sole". Otherwise "a" implies there may
be other members. As these are static properties being defined I don't
think we need to be accounting for some future dynamic expansion of a
nest.


I think you're missing the point of the spec. logic here.  If there is a
non-empty NestMembers attribute, then in fact there *are* other members.
Therefore "a" is correct, and "the sole" would be incorrect.


Yes another gaseous brain expulsion on my part. I was thinking only of 
the case where neither attributes are present.



Separately, we do need to leave wiggle room for dynamic injection.
Dan, I think that would be done by allowing a dynamic injection
operation to implicitly extend the NestMembers list to make a
"ticket" for the injected class, and implicitly add (if necessary)
a MemberOfNest to the injected class.

...


4.10.1 Verification by Type Checking

Does the order in the rules mandate the order in which the VM must
actually check things? classHasValidNest seems much more complex than
the actual runtime process of validation (though it may just be
exposing distinct steps that are lumped together at runtime).


Agree.  I think this logic can be simplified.  (Will take that to a
separate sub-thread.)


---

4.10.1.8 Type Checking for Restricted Member References

I'm not very good at reading or understanding these rules, but I'm
surprised that the invokespecial rules seem to make no mention of
nestmates at all:

"A method reference is allowed by an invokespecial instruction if it
is not a restricted invokespecial reference, ..."

This seems to open things up to all private method references??


Well, the whole point of nestmates is to extend, in a regular way,
all access rules that pertain to self-access and privacy.
If the extension is truly regular, it is not surprising that the spec.
changes are subtle like this.  We're not trying to do an ad hoc
patch on some set of particular behaviors, but rather extend
pre-existing notions so they apply in more conditions, including
invokespecial restrictions.


I was expecting to see the restrictions have a dependency on nestmates 
actually being involved - which is how I've currently implemented it. I 
can throw away some of the verifier changes if I only need to check for 
private access. But I'm unclear exactly where (in the spec) we enforce 
that only nestmates get this right to use invokespecial on private 
methods? Is it the access check applied during method resolution?


Cheers,
David
-



---

5.4.4 Access Control

I don't think you need to restate:

"A class with a MemberOfNest attribute belongs to the nest hosted by
the referenced host class.

A class without a MemberOfNest attribute implicitly belongs to a nest
hosted by the class itself. (If the class also lacks a NestMembers
attribute, then the nest has only one member.)"

The rule is simply stated as is: "belonging to the same nest as D" -
belonging to the same nest is, or should be, already defined elsewhere.


Actually, there is no "elsewhere"; this is where the condition is defined.
We don't need a special section for "nests"; we don't have a special
section for "packages" either.  So that part reads fine to me.


I'm avoiding commenting on the protected access changes but do want to
raise a concern that there are no changes to Method resolution
(5.4.3.3) yet resolution relies on the definition of access control to
prune/discard inaccessible methods. It appears now that we're allowing
more potential successful resolutions, then using the additional rules
on the invoke* bytecodes to try and discard any undesirable results.

---

6.5 getfield (and others)

You note "These rules are redundant: verification already guarantees
them " but this brings me back to an area I keep raising concerns
about: the split between static verification based checks and dynamic
runtime checks. Yes the verifier precludes certain things but if we
run without verification the rules expressed for the bytecodes are
considered to be still required at runtime. If you delete them because
they overlap with verifier rules we have no way to tell which rules
must be enforced regardless of verification status.

---

6.5 invokespecial

You note regarding the IllegalAccessError:

"This replaces a VerifyError previously specified by 4.9.2. The check
must be delayed until after resolution in order to determine whether
the referenced method is private."

We know the access flags for the referenced method at verification
time - shouldn't that be the sole basis for the verifier check?
Afterall it is verifying the static properties of the classfile and
bytecode. If the ac

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

On 20/04/2017 7:58 AM, Dan Smith wrote:

On Apr 19, 2017, at 1:21 PM, Dan Smith mailto:daniel.sm...@oracle.com>> wrote:



5.4.4 Access Control

I don't think you need to restate:

"A class with a MemberOfNest attribute belongs to the nest hosted by
the referenced host class.

A class without a MemberOfNest attribute implicitly belongs to a nest
hosted by the class itself. (If the class also lacks a NestMembers
attribute, then the nest has only one member.)"

The rule is simply stated as is: "belonging to the same nest as D" -
belonging to the same nest is, or should be, already defined elsewhere.


My intent is that this *is* the definition. But sounds like you're
expecting that definition to be in 4.7.25/4.7.26, which is probably
more intuitive. I'll change that.


Thanks. Yes I was expecting a definition somewhere else, up front.


Okay, here's another attempt at defining the attributes and the "nest"
concept.

I've been uneasy about `NestMembers` being presented as the
"declaration" of the nest, since it's not validated. Instead, I see
`MemberOfNest` as really where nests are defined (as a cumulative result
of many class declarations—like packages), and `NestMembers` as just a
help for validation.


I can't decide whether that understates the importance of the 
bi-directionality of membership, or not - both parties must agree on 
membership for that membership to exist. It may not have any practical 
significance.



With that in mind, `MemberOfNest` ought to come first:



**4.7.25 The `MemberOfNest` Attribute**
---

**The `MemberOfNest` attribute is a fixed-length attribute in the
`attributes` table of a `ClassFile` structure ([4.1]).**

**A _nest_ is a set of classes and interfaces that share access to their
`private` members ([5.4.4]).**


Aside: it is this basic definition of "nest" that I expected to appear 
somewhere earlier in the spec. JVMS doesn't have any upfront "concepts 
and definitions" section, so not sure where it would go.



**A class or interface with a `MemberOfNest` attribute belongs to the
nest hosted by a designated _host class_. The host class authorizes
membership in the nest with a corresponding entry in its `NestMembers`
attribute ([4.7.26], [4.10]).**


Only nit is I would say "claims membership of" rather than "belongs to". 
That emphasises that membership must be ratified by the "host class", 
and matches the following "authorizes membership" text.



**A class or interface without a `MemberOfNest` attribute belongs to the
nest hosted by itself. (Often, this nest is a singleton consisting only
of the class itself.)**

**There may be at most one `MemberOfNest` attribute in the `attributes`
table of a `ClassFile` structure.**

**The `MemberOfNest` attribute has the following format:**

...


**4.7.26 The `NestMembers` Attribute**
--

**The `NestMembers` attribute is a variable-length attribute in the
`attributes` table of a `ClassFile` structure ([4.1]). It authorizes an
enumerated set classes and interfaces to claim membership in a nest
hosted by the current class or interface.**

**There may be at most one `NestMembers` attribute in the `attributes`
table of a `ClassFile` structure.**

**The `attributes` table of a `ClassFile` structure must not contain
both a `MemberOfNest` attribute and a `NestMembers` attribute.**


**This rule prevents a host class from claiming membership in a

different nest. It is implicitly a member of the nest that it hosts.**

**The `NestMembers` attribute has the following format:**

...


5.4.4 Access Control


A class or interface _C_ is _accessible_ to a class or interface _D_ if
and only if either of the following is true:

...

- _R_ is `private` and is declared ~~in _D_~~ **by a class belonging to
the same nest as _D_ ([4.7.25])**.




And now to the bikeshedding game:


:)


`MemberOfNest`, as the key thing, could just be called `Nest` (imagine a
`Package` attribute—we wouldn't call it `MemberOfPackage`). Or, since
it's a reference to a class, `NestHost ` / `NestTop` / `NestMother` /
`NestWhatever`.


I like to distinguish the name of the attribute from the entity the 
attribute represents. Given the names Maurizio chose are not terribly 
wrong, and nothing else is significantly better, I'm quite content with 
them.



`NestMembers` isn't horrible, but we could highlight its validation role
with something like `AuthorizedNestMembers`.


To me the "authorized" is implicit. By calling it out explicitly it 
suggests to me there are also UnauthorizedNestMembers. But to me this is 
an oxymoron - if you are unauthorized you are not an 
unauthorized-member, you are not any kind of member at all.


Cheers,
David


—Dan


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

On 20/04/2017 2:47 AM, Dan Smith wrote:



On Apr 19, 2017, at 8:12 AM, Brian Goetz  wrote:


Yep. Also, multiple classes can claim the same nest member class in their 
NestMembers attributes. Not a problem as long as the MemberOfNest attribute (if 
any) of the member class points to a host class that claims it.



At the risk of bikeshedding, I find the names NestMembers and MemberOfNest 
confusing; I keep having to think about the directionality, since they sound so 
similar.  Would be good to find names that have obviously opposite 
directionality.

A not-very-good suggestion (but which illustrates the directionality thing I'm going for) would be 
"NestDeclaration" and "NestUse".  It's pretty clear which is which without 
thinking about it.

Perhaps: NestHost and NestMember ?


I also don't love that "NestMembers" seems more authoritative than it really 
is. (Doesn't get validated, doesn't suggest that other classes can be dynamically added.)

Something like "AllowedInNest" would better convey the actual meaning of that 
attribute.


I don't see how AllowedInNest is any less authoritative sounding than 
NestMembers. Neither suggests other classes may be added dynamically - 
nor should they in my opinion. These are static attributes of a 
classfile defining a relationship as it was known to exist when the 
classfile was created. Any dynamic means to add to a nest at runtime 
would not be modifying the classfile NestMembers attribute, but the 
runtime representation thereof. I suppose InitialNestMembers may capture 
this more accurately - though it does then beg the question as to how to 
add the to set later.


Aside: when first discussed in the context of generic specialization I 
assumed the NestMembers entry would be a "wildcard" which indicated that 
not only was the named generic type a nestmember, but all 
specializations thereof (which would presumably have a name derived from 
the base generic type). But in the context of Lookup.defineClass I have 
no idea how it is/was expected that nest membership would expand - or 
how the validity of doing so would be established.


David


—Dan



Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

Hi Dan,

On 20/04/2017 2:06 AM, Dan Smith wrote:

On Apr 19, 2017, at 12:45 AM, John Rose mailto:john.r.r...@oracle.com>> wrote:

 - NMs must be non-empty (degenerate nest is never explicit)
 - NMs may not contain duplicates (cf. treatment of ClassFile.interfaces)
 - NMs may not contain the current class (i.e., an index to a class
with the same name as this_class)
 - NMs may contain only package siblings (ditto)
 - NMs and MoN may not refer to array classes (this is probably
implied by the package prefix checks)


These are all do-able, but I'm not sure they're consistent with the
spirit of JVMS in its treatment of attributes. We don't usually assert
that lists are non-empty, don't contain duplicates, etc. (Granted, most
attributes are not relevant to JVM execution.) You mention `interfaces`,
but I don't see any such assertion in 4.1.


The NestMembers duplicate check exists because I copied the spec and 
code from the InnerClasses attribute. 4.7.6 states the classes[] "must 
have exactly one corresponding entry ..." - hence a check for duplicates 
is done. I used the same language when I defined NestMembers. So the 
precedent does exist.



You can identify some package mismatches by looking at names, but not
all (names with the same "package" name may be handled by different
class loaders). I worry that making a partial effort here will give a
false sense of security and lead someone in the future to see that as a
bug and try to fully validate the package restriction.


I concur. We need the actual package check at nest-top validation time 
anyway, so checking this at parsing time seems pure overhead.



I hate array "class names". Ugh. But, again, we're not generally
concerned with that kind of hygiene in attributes.


 - MoN may not contain the current class (ditto)
 - MoN may contain only a package sibling (i.e., a referenced class
name must have the same package prefix as this_class)
 - NMs and MoN may not refer to array classes (this is probably
implied by the package prefix checks)


If MoN names the current class, verification will fail (there's no
matching NM attribute).

If MoN names a class in a different package, verification will fail (the
rule checks "samePackageName").

If MoN names an array type, verification will fail (either due to the
"samePackageName" check or because there's no matching NM attribute).

I don't see the benefit in making these "syntax" checks in addition to
verification checks. (Even a class naming itself as its own superclass
isn't a syntax error—it gets checked later.)


David's prototype has the duplication check, and some of the other
checks happen later.  I think they should all happen during class loading.


Something you might like is if we moved the MoN verification check out
of verification (which is mainly concerned with Code attributes anyway)
and into a late step of the class loading process (5.3.5)? Something like:

1) Get the bits
2) Parse the class
3) Load & validate superclasses
4) Load & validate interfaces
5) Load & validate MemberOfNest


At present I do (5) during "linking" just prior to verification (in case 
verification  is disabled). It happens after the superclass and 
superinterfaces are themselves linked. But note that nest-top validation 
only requires the nest-top to be loaded, not linked.


David
-


—Dan


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

Correction below ...

On 19/04/2017 5:56 PM, David Holmes wrote:

On 19/04/2017 5:51 PM, John Rose wrote:

On Apr 19, 2017, at 12:14 AM, David Holmes mailto:david.hol...@oracle.com>> wrote:


Some of these are a lot more awkward to do during classfile parsing
and will require symbol comparisons. I was wanting to avoid "deep
validation" of NMs as it penalizes all the good code. Having a "bad"
NM entry seems harmless as these entries are only used to validate the
initial claim of nest membership. If an entry is "bad" then by
definition it will not match with any claimee.


I don't see how that is a significant concern.  The symbol bodies are
hot in cache
at the point we would check prefixes, since they are already being
scanned for other
purposes, such as initial interning, and also syntax checking.  Existing
processing
is exactly as deep (or shallow) as the checks I want.


I don't follow that. If I'm loading a nest-top class and validating its
NM entries none of those entries need have been loaded yet and so none
will be in the cache.


Sorry John - brain fart on my part. We're talking about the symbols that 
have just been parsed and loaded into the constant pool, not the classes 
those symbols name.


David
-


David
-


If we turn off the "verify" flag for class loading, then maybe we can
buy something
by dropping those (and all the other) constraint checks.

By syntax checking, I mean that if I mention a CONSTANT_Class in the CP,
and its corresponding CONSTANT_Utf8 has a broken syntax (e.g., "."
instead
of "/", or two "//" in a row) the JVMS mandates an error.  But those
are the
same bytes I want to look at when they are referenced by a MoN or NMs
attribute.  It will all be in cache, and the cycles to do the checks
will be
undetectable.

— John


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 18, 2017, at 11:40 PM, David Holmes  wrote:
> 
> 4.7.26 The MemberOfNest Attribute
> 
> "the class is implicitly a member of its own nest"
> 
> I suggest changing "a" to "the sole". Otherwise "a" implies there may be 
> other members. As these are static properties being defined I don't think we 
> need to be accounting for some future dynamic expansion of a nest.

I think you're missing the point of the spec. logic here.  If there is a
non-empty NestMembers attribute, then in fact there *are* other members.
Therefore "a" is correct, and "the sole" would be incorrect.

Separately, we do need to leave wiggle room for dynamic injection.
Dan, I think that would be done by allowing a dynamic injection
operation to implicitly extend the NestMembers list to make a
"ticket" for the injected class, and implicitly add (if necessary)
a MemberOfNest to the injected class.

...
> 
> 4.10.1 Verification by Type Checking
> 
> Does the order in the rules mandate the order in which the VM must actually 
> check things? classHasValidNest seems much more complex than the actual 
> runtime process of validation (though it may just be exposing distinct steps 
> that are lumped together at runtime).

Agree.  I think this logic can be simplified.  (Will take that to a separate 
sub-thread.)

> ---
> 
> 4.10.1.8 Type Checking for Restricted Member References
> 
> I'm not very good at reading or understanding these rules, but I'm surprised 
> that the invokespecial rules seem to make no mention of nestmates at all:
> 
> "A method reference is allowed by an invokespecial instruction if it is not a 
> restricted invokespecial reference, ..."
> 
> This seems to open things up to all private method references??

Well, the whole point of nestmates is to extend, in a regular way,
all access rules that pertain to self-access and privacy.
If the extension is truly regular, it is not surprising that the spec.
changes are subtle like this.  We're not trying to do an ad hoc
patch on some set of particular behaviors, but rather extend
pre-existing notions so they apply in more conditions, including
invokespecial restrictions.

> 
> ---
> 
> 5.4.4 Access Control
> 
> I don't think you need to restate:
> 
> "A class with a MemberOfNest attribute belongs to the nest hosted by the 
> referenced host class.
> 
> A class without a MemberOfNest attribute implicitly belongs to a nest hosted 
> by the class itself. (If the class also lacks a NestMembers attribute, then 
> the nest has only one member.)"
> 
> The rule is simply stated as is: "belonging to the same nest as D" - 
> belonging to the same nest is, or should be, already defined elsewhere.

Actually, there is no "elsewhere"; this is where the condition is defined.
We don't need a special section for "nests"; we don't have a special
section for "packages" either.  So that part reads fine to me.

> I'm avoiding commenting on the protected access changes but do want to raise 
> a concern that there are no changes to Method resolution (5.4.3.3) yet 
> resolution relies on the definition of access control to prune/discard 
> inaccessible methods. It appears now that we're allowing more potential 
> successful resolutions, then using the additional rules on the invoke* 
> bytecodes to try and discard any undesirable results.
> 
> ---
> 
> 6.5 getfield (and others)
> 
> You note "These rules are redundant: verification already guarantees them " 
> but this brings me back to an area I keep raising concerns about: the split 
> between static verification based checks and dynamic runtime checks. Yes the 
> verifier precludes certain things but if we run without verification the 
> rules expressed for the bytecodes are considered to be still required at 
> runtime. If you delete them because they overlap with verifier rules we have 
> no way to tell which rules must be enforced regardless of verification status.
> 
> ---
> 
> 6.5 invokespecial
> 
> You note regarding the IllegalAccessError:
> 
> "This replaces a VerifyError previously specified by 4.9.2. The check must be 
> delayed until after resolution in order to determine whether the referenced 
> method is private."
> 
> We know the access flags for the referenced method at verification time - 
> shouldn't that be the sole basis for the verifier check? Afterall it is 
> verifying the static properties of the classfile and bytecode. If the actual 
> resolved method has different access to the referenced method then that may 
> lead to ICCE (depending on the exact nature of the change - a private method 
> made public may not be an issue for example).
> 
> ---
> 
> 5.4.3.3 Method resolution
> 
> You did not make any changes here, but as per my comment in the bug report we 
> do require, IMHO, further tightening here to ensure nestmate invokespecial 
> invocations do not resolve to method implementations that they should not. 
> The example here is a hierarchy of nestmates (C extends B extends A) where A 
> and C both declare a private metho

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 18, 2017, at 11:40 PM, David Holmes  wrote:
> 
> I have not yet seen a follow up from John as to whether we require or just 
> allow, an empty NestMembers attribute to indicate a singleton nest member.

I think we should neither require nor allow an empty NestMembers attribute.

Dan may prefer to minimize syntax checking, in which case an empty
NestMembers attribute would be allowed.

Nobody has proposed a reason to require it.  A nest of one member is
(depending on your POV) either the overwhelmingly common trivial case,
or a useless degree of freedom.  Taking the POV (from Brian and me)
hat every class has a nest (just as every class has a package), an
empty NestMembers attribute is just a waste of bits stating the obvious,
about a stand-alone class.

(I'd prefer to disallow the empty NMs attribute, lest it accidentally acquire
some additional meaning.  But as long as we specify that an empty one
conveys the same condition as no attributes at all, we are safe from accident.)

— John

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 19, 2017, at 12:56 AM, David Holmes  wrote:
> 
>> I don't see how that is a significant concern.  The symbol bodies are
>> hot in cache
>> at the point we would check prefixes, since they are already being
>> scanned for other
>> purposes, such as initial interning, and also syntax checking.  Existing
>> processing
>> is exactly as deep (or shallow) as the checks I want.
> 
> I don't follow that. If I'm loading a nest-top class and validating its NM 
> entries none of those entries need have been loaded yet and so none will be 
> in the cache.

I see what the problem is:  The only checking I am proposing
is syntax checking on the names.  If by "deep checking" you
mean loading classes from the names, I agree, we don't want
to do that.  The MemberOfNest attribute is passive.  It does
not need to initiate loads; it just needs to validate claims
of nest membership by other classes.

(I even doubt Dan's assertion that in some corner cases,
when the nest-host is trying out a private access, there
must be some loading done to validate the access.  Probably
we can get away with no loading at all, just name checks
against already-loaded classes.)

— John

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 19, 2017, at 2:10 PM, David Holmes  wrote:
> 
> I find these names very good - granted I've been working with them more than 
> anyone else (but didn't define them). The plurality makes it clear to me.

+1 for plurality; that does it for me too, although it is a one-letter hint.

I'm happy with the names, though I have a little problem (that Dan is trying to 
fix)
with making clear the distinction between a Nest and the Host (or Top or Root) 
of
a Nest.  Things get messy when conflate them, which terminology can help avoid.

— John

P.S. Can't resist, so OK, in the spirit of "crib", how about throwing a private 
"party"?

Background:  The asymmetry of the relation is essential to the design of the 
attributes.

But it does not come from one class being somehow semantically or syntactically
distinguished in any way, other than one:  The special "nest host" (or "nest 
top")
is responsible for inviting any number of classes (including zero) to join its 
nest.

(The nest host is like the admin of a skype conversation, in which all 
conversants
are otherwise equal.  And like skype conversations, the group has only one 
purpose.
For nestmates, the purpose is to broaden the definition of ACC_PRIVATE.)

Under the theory that the nest host invites the other nestmates to the party,
we could emphasize that role in the attribute names:

NestMembers => NestInvitations (=> NestGrants since it is checked reactively)
MemberOfNest => RequestNest (=> Nest, or NestHost—requesting is a given when we 
do access control)

(Hmm…  NMs => PartyInvitations, PartyRoster; MoN => RSVPToParty, JoinParty.)

So, at this point, the best I change I can suggest to strengthen the asymmetry,
but keep the nicest metaphor (nest) is NestGrants / Nest or NestHost.

Why isn't "Nest" ambiguous?  Doesn't it define a nest?  Well, no, if you look
at the way attributes are named in the JVMS, they refer to an "attribute"
(duh) of the containing object.  Thus, if ClassFile has a Nest attribute, it
means that the ClassFile *has* an attribute of type Nest, not that the ClassFile
is defining another entity of type Nest *outside* of the ClassFile.  So I claim
that "Nest" is perfectly unambiguous:  It means that the ClassFile is asserting
the identity of its Nest, using the convention of naming the nest-host.
Choosing the more specific term "NestHost" would make it more clear
that the Nest is being named by mentioning its host.

The word "host" is a good fit (better than top or root) if we are emphasizing
the fact that the host's job is to grant entry into the nest.

Although reusing "host" is a feature rather than a bug, it could also be
NestSecretary, NestDoorman, NestMaitreDeHotel, NestBouncer, etc.

OK, I'm stopping.




Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith
One other topic to add to this thread, which I forgot to mention: compatibility.

Sometimes JVMS changes need to be guarded by rules that preserve old behavior 
for old class file version numbers, in order to prevent changes in behavior 
when an old class is run on a new JVM. My hope is that there's no need for such 
logic here.

Here's my analysis. Let me know if you can think of any other cases, or if you 
feel that any of these changes are concerning.

---

- The MemberOfNest and NestMembers attributes are illegal prior to 54.0. So 
well-formed older classes always belong to singleton nests—they can't claim 
membership in a different nest, and can't act as hosts.

- Access control for private members declared in or called from old class files 
then degenerates to the old rule: the private member must be declared by the 
calling class.

- The verification-time checks on the referenced class of an invokespecial have 
been moved to resolution time. Some cases:

- Referencing a public method in a disallowed class used to be a 
VerifyError*; now it's a IAE at resolution time

- Referencing a private method in a disallowed class used to be a 
VerifyError; now it's an IAE at resolution time

- Referencing a private method in a subclass that resolves to a member of 
the current class used to be a VerifyError; now it's allowed.

- Referencing a nonexistent method in a disallowed class used to be a 
VerifyError; now it's a NSME at resolution time

- Referencing a static method in a disallowed class used to be a 
VerifyError; now it's a ICCE at resolution time

(*Confirmed with some testing, although I found that referencing an 
indirect superinterface caused an ICCE, apparently at resolution time.)

- The verification-time restriction on the target reference stack type of an 
invokespecial is only enforced if the referenced class is a superclass and the 
resolved method is non-private. Only change here (besides those outlined above 
due to a reference to a non-superclass) is that a private method referenced in 
a superclass that used to get a VerifyError (due to a disallowed stack type) 
will now get an IAE at resolution time.

- Verification is more eager to resolve classes and methods referenced by 
`invokespecial`. The change in class loading only affects programs that would 
have had VerifyErrors before (for a reference to a disallowed 
class—superclasses are already loaded). The change in method resolution may be 
visible, depending on how the implementation chooses to handle errors. But 
flexibility for these sorts of changes is granted by 5.4.

- As described in the comment in 5.4.4, tweaking the applicability of the 
`protected` access referenced class restriction causes some IAEs to become 
ICCEs or NSMEs.

- The runtime checks added to `invokespecial` introduce some new ICCEs when the 
current class or referenced class are interfaces.

Summary: almost all of these are simply changes in the error produced, and 
perhaps in the timing of errors being reported, depending on when resolution 
happens. There's one case where the new rules for private invokespecial allow 
something that was an error before (fine). There's also one case where new 
errors are introduced, but that would be a deliberate choice in response to a 
bug report.

—Dan



Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith
> On Apr 19, 2017, at 1:21 PM, Dan Smith  wrote:
> 
>> 
>> 5.4.4 Access Control
>> 
>> I don't think you need to restate:
>> 
>> "A class with a MemberOfNest attribute belongs to the nest hosted by the 
>> referenced host class.
>> 
>> A class without a MemberOfNest attribute implicitly belongs to a nest hosted 
>> by the class itself. (If the class also lacks a NestMembers attribute, then 
>> the nest has only one member.)"
>> 
>> The rule is simply stated as is: "belonging to the same nest as D" - 
>> belonging to the same nest is, or should be, already defined elsewhere.
> 
> My intent is that this *is* the definition. But sounds like you're expecting 
> that definition to be in 4.7.25/4.7.26, which is probably more intuitive. 
> I'll change that.

Okay, here's another attempt at defining the attributes and the "nest" concept.

I've been uneasy about `NestMembers` being presented as the "declaration" of 
the nest, since it's not validated. Instead, I see `MemberOfNest` as really 
where nests are defined (as a cumulative result of many class declarations—like 
packages), and `NestMembers` as just a help for validation.

With that in mind, `MemberOfNest` ought to come first:



**4.7.25 The `MemberOfNest` Attribute**
---

**The `MemberOfNest` attribute is a fixed-length attribute in the `attributes` 
table of a `ClassFile` structure ([4.1]).**

**A _nest_ is a set of classes and interfaces that share access to their 
`private` members ([5.4.4]).**

**A class or interface with a `MemberOfNest` attribute belongs to the nest 
hosted by a designated _host class_. The host class authorizes membership in 
the nest with a corresponding entry in its `NestMembers` attribute ([4.7.26], 
[4.10]).**

**A class or interface without a `MemberOfNest` attribute belongs to the nest 
hosted by itself. (Often, this nest is a singleton consisting only of the class 
itself.)**

**There may be at most one `MemberOfNest` attribute in the `attributes` table 
of a `ClassFile` structure.**

**The `MemberOfNest` attribute has the following format:**

...


**4.7.26 The `NestMembers` Attribute**
--

**The `NestMembers` attribute is a variable-length attribute in the 
`attributes` table of a `ClassFile` structure ([4.1]). It authorizes an 
enumerated set classes and interfaces to claim membership in a nest hosted by 
the current class or interface.**

**There may be at most one `NestMembers` attribute in the `attributes` table of 
a `ClassFile` structure.**

**The `attributes` table of a `ClassFile` structure must not contain both a 
`MemberOfNest` attribute and a `NestMembers` attribute.**

> **This rule prevents a host class from claiming membership in a different 
> nest. It is implicitly a member of the nest that it hosts.**

**The `NestMembers` attribute has the following format:**

...


5.4.4 Access Control


A class or interface _C_ is _accessible_ to a class or interface _D_ if and 
only if either of the following is true:

...

- _R_ is `private` and is declared ~~in _D_~~ **by a class belonging to the 
same nest as _D_ ([4.7.25])**.




And now to the bikeshedding game:

`MemberOfNest`, as the key thing, could just be called `Nest` (imagine a 
`Package` attribute—we wouldn't call it `MemberOfPackage`). Or, since it's a 
reference to a class, `NestHost ` / `NestTop` / `NestMother` / `NestWhatever`.

`NestMembers` isn't horrible, but we could highlight its validation role with 
something like `AuthorizedNestMembers`.

—Dan

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

On 20/04/2017 12:12 AM, Brian Goetz wrote:

Yep. Also, multiple classes can claim the same nest member class in
their NestMembers attributes. Not a problem as long as the
MemberOfNest attribute (if any) of the member class points to a host
class that claims it.



At the risk of bikeshedding, I find the names NestMembers and
MemberOfNest confusing; I keep having to think about the directionality,
since they sound so similar.  Would be good to find names that have
obviously opposite directionality.


I find these names very good - granted I've been working with them more 
than anyone else (but didn't define them). The plurality makes it clear 
to me.


David


A not-very-good suggestion (but which illustrates the directionality
thing I'm going for) would be "NestDeclaration" and "NestUse".  It's
pretty clear which is which without thinking about it.

Perhaps: NestHost and NestMember ?




Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Brian Goetz

Nest host
Nest master
Nest top
Nest owner
Nest dictator-for-life
...


On 4/19/2017 3:21 PM, Dan Smith wrote:

I dislike "host class" because that is already used for the quite different case of 
VMACs. I can live with other names but I think they should incorporate "nest" eg. 
nest-holder, nest-host. But I think nest-top is an ideal match. (And no I didn't invent this 
terminology:)  ).

Okay. Probably best to sit on this for awhile and circle back to it, see how 
we're all feeling.





Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith
Thanks a lot for the feedback! My comments below:

> On Apr 19, 2017, at 12:40 AM, David Holmes  wrote:
> 
>> JEP name
>> 
>> I don't know how permanent JEP names are supposed to be, but I'd prefer a 
>> different name at this point. Something like: "Expanded JVM Access to 
>> Private Members"—shorter, focused on the feature itself rather than its 
>> relationship to the Java language. Or maybe "Class Nests for Access to 
>> Private Members".
> 
> The intent of the name is to aid in the contextual positioning of this JEP ie 
> address why do we even need this. The JEP addresses an inconsistency between 
> access controls in the Java programming language and access controls in the 
> JVM. The primary goal here is to align the two, while at the same time 
> allowing for additional usage of nestmates in the future.

Yeah, but I think explaining the motivation in the title makes for a long title 
and limits the imagination to one particular use case.

>> The JEP uses "nest top" to describe the class that nest members reference; I 
>> prefer "host class", which better describes the class's role and isn't tied 
>> to the Java "top level class" concept. I know we use "host class" internally 
>> in Hotspot, perhaps when working with anonymous classes (of the JVM flavor), 
>> but I think in that context it will ultimately mean the same thing? Are we 
>> comfortable repurposing the term in this way?
> 
> Given that a nest-top type must be a top-level type, I think nest-top fits 
> perfectly.

This is a good example of my point about the title: the JVM has no concept* of 
"top level type", and doesn't need one. We just need a specific class to act as 
the reference point by which a group of classes can talk about a nest.

For example, I can imagine some language introducing a class 
file—foo.bar.Nest$$001—solely for the purpose of providing a hook for this 
reference point. javac's choice to designate a top-level class as the 
nest-top/nest-host is a compilation strategy.

(*Yes, there's an InnerClasses attribute, and Signature attributes, and lots of 
other stuff to facilitate compilation in the Java language. But those represent 
auxiliary metadata, not core JVM concepts.)

> I dislike "host class" because that is already used for the quite different 
> case of VMACs. I can live with other names but I think they should 
> incorporate "nest" eg. nest-holder, nest-host. But I think nest-top is an 
> ideal match. (And no I didn't invent this terminology :) ).

Okay. Probably best to sit on this for awhile and circle back to it, see how 
we're all feeling.

>> I follow Brian's model when it comes to nest membership (5.4.4): every class 
>> belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted 
>> by itself. Many nests are singletons without any associated explicit 
>> attributes.
> 
> I have not yet seen a follow up from John as to whether we require or just 
> allow, an empty NestMembers attribute to indicate a singleton nest member.

If in our model *every* class has a nest, then we definitely don't want to 
require every class to have a NestMembers attribute.

In my spec (5.4.4), the presence of a NestMembers attribute is irrelevant. A 
class without a MemberOfNest attribute belongs to its own nest, and there's no 
need to validate anything about NestMembers.

>> Verification of MemberOfNest
>> 
>> I include a discussion block about different options of validating 
>> MemberOfNest. I think the consensus, and my preference, is to do it during 
>> verification of the member class. (NestMembers, on the other hand, is never 
>> validated, except as a side-effect of checking MemberOfNest.)
> 
> Given verification is optional the current approach is to validate during 
> linking just prior to the verification step. Whether that can conceptually be 
> considered part of verification I am unsure.

I think this is the source of a lot of anomalies—spec treats verification as an 
essential part of linking, while Hotspot treats it as an optional add-on.

You should be okay, for some definition of "just prior". These are the 
constraints, as I read them:
- "A class or interface is completely loaded before it is linked." (5.4)
- Loading includes structural checks (CFE), version checks (UCVE), and 
validation and loading of superclasses and superinterfaces (5.3.5)
- "Errors detected during linkage are thrown at a point in the program where 
some action is taken by the program that might, directly or indirectly, require 
linkage to the class or interface involved in the error." (5.4)

That last one is pretty mysterious to me (what does "some action" mean? what 
about "indirectly"?), but seems to grant pretty wide latitude on the timing.

>> Verification of invokespecial
>> 
>> Allowing invokespecial to refer to classes other than the current class and 
>> its supers is a significant change. I noticed and relied heavily on the 
>> parallel with invokevirtual making protected method calls. So I tried to 
>> mak

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 19, 2017, at 9:47 AM, Dan Smith  wrote:
> 
> Something like "AllowedInNest" would better convey the actual meaning of that 
> attribute.

It's true that this is what the attribute does, which is a plus. But it also is 
less directional than NMs. (Am I claiming I am allowed in some nest or am I 
granting nest privileges to others?  Can't tell from the name.) To me at least 
the plural "s" makes it clear who is in charge of the list of "grantees".


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith

> On Apr 19, 2017, at 8:12 AM, Brian Goetz  wrote:
> 
>> Yep. Also, multiple classes can claim the same nest member class in their 
>> NestMembers attributes. Not a problem as long as the MemberOfNest attribute 
>> (if any) of the member class points to a host class that claims it.
> 
> 
> At the risk of bikeshedding, I find the names NestMembers and MemberOfNest 
> confusing; I keep having to think about the directionality, since they sound 
> so similar.  Would be good to find names that have obviously opposite 
> directionality.  
> 
> A not-very-good suggestion (but which illustrates the directionality thing 
> I'm going for) would be "NestDeclaration" and "NestUse".  It's pretty clear 
> which is which without thinking about it.
> 
> Perhaps: NestHost and NestMember ?

I also don't love that "NestMembers" seems more authoritative than it really 
is. (Doesn't get validated, doesn't suggest that other classes can be 
dynamically added.)

Something like "AllowedInNest" would better convey the actual meaning of that 
attribute.

—Dan

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith
> On Apr 19, 2017, at 1:38 AM, John Rose  wrote:
> 
> "Nest" also connotes a home-like place and therefore privacy.
> (Could also have said "home" or "family"—those are also private spaces.  Or 
> "crib"?)

Sigh. Now I will forever wish we had called this feature "cribs".
https://www.youtube.com/watch?v=cAb54qbMF_k

> Here's a corner case we need to cover:  I have to load my supers before I can 
> load myself.
> If one (or more) of my supers are in the same nest as me, the checking of MoN 
> must succeed
> no matter who is the host class of the nest.
> 
> This could get embarrassing if the host class is the subtype, if the super 
> then needs to
> recursively load the subtype (which is waiting on the supertype to load) 
> before it can
> validate its MoN attribute.  If verification (linking) is started after all 
> of the classes are
> loaded, things are OK, since the MoN checks happen only after everything is 
> loaded.

Yes, I think the earliest we want to be loading MemberOfNest is after 
superclasses and superinterfaces are loaded (5.3.5 step 4). That avoids the 
cycle.

> I was surprised to see invokespecial occasionally mentioned cases where it 
> only works on
> private members.  Is that a current constraint, or a new one?
> 
> I thought a class could invokespecial any of its methods, willy-nilly, and 
> this permission
> would seem to extend naturally to nestmates.  (I think I'm forgetting 
> something here.)

The old constraint is that (non-) invokespecial can only reference the 
current class, a superclass, or a direct superinterface.

The new constraint is that (non-) invokespecial must either reference a 
private method, or must reference the current class, a superclass, or a direct 
superinterface.

The purpose of this check is to force outsiders to use virtual dispatch, rather 
than jumping into the middle of an override chain. But private methods can't be 
overridden, so an "outsider" from the same nest won't be defeating any 
restrictions.

(We could grant all members of a nest the right to call invokespecial on all 
nest members' non-private members and supers, but that's a new feature. Would 
be similar to granting access to inherited protected members.)

>> When invokespecial involves interface types, the verifier can't guarantee 
>> that receiver objects actually implement that interface (JDK-8134358). It's 
>> an open question whether this is really a problem, but I included a 
>> tentative fix in the invokespecial runtime rules.
> 
> I am leaning towards putting this check in.  If we put it in, it should go in 
> everywhere,
> including invokespecial of default methods, both in and out of the caller's 
> nest.
> I think your language might have allowed an untyped loophole for nestmates.
> 
> My goal in this is simplicity of effect:  There are no loopholes, no 
> exceptions
> to typing of the incoming receiver (L0) of a default method.  If we are going 
> to
> check any of these invokespecial receivers, we must check them all.

The verifier attempts to ensure that:
- For non- invokespecial, the type of the objectref is a subtype of the 
referenced class/interface
- For non-, non-private invokespecial, the type of the objectref is a 
subtype of the current class/interface

The proposed rules repeat these two assertions, but with a dynamic check. 
Private methods are treated differently because they aren't subject to the same 
constraints. (It could simplify our lives considerably if we had a dedicated 
`invokeprivate` method, but alas. That's how you should think about it, anyway.)

—Dan

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Dan Smith
> On Apr 19, 2017, at 12:45 AM, John Rose  wrote:
> 
>  - NMs must be non-empty (degenerate nest is never explicit)
>  - NMs may not contain duplicates (cf. treatment of ClassFile.interfaces)
>  - NMs may not contain the current class (i.e., an index to a class with the 
> same name as this_class)
>  - NMs may contain only package siblings (ditto)
>  - NMs and MoN may not refer to array classes (this is probably implied by 
> the package prefix checks)

These are all do-able, but I'm not sure they're consistent with the spirit of 
JVMS in its treatment of attributes. We don't usually assert that lists are 
non-empty, don't contain duplicates, etc. (Granted, most attributes are not 
relevant to JVM execution.) You mention `interfaces`, but I don't see any such 
assertion in 4.1.

You can identify some package mismatches by looking at names, but not all 
(names with the same "package" name may be handled by different class loaders). 
I worry that making a partial effort here will give a false sense of security 
and lead someone in the future to see that as a bug and try to fully validate 
the package restriction.

I hate array "class names". Ugh. But, again, we're not generally concerned with 
that kind of hygiene in attributes.

>  - MoN may not contain the current class (ditto)
>  - MoN may contain only a package sibling (i.e., a referenced class name must 
> have the same package prefix as this_class)
>  - NMs and MoN may not refer to array classes (this is probably implied by 
> the package prefix checks)

If MoN names the current class, verification will fail (there's no matching NM 
attribute).

If MoN names a class in a different package, verification will fail (the rule 
checks "samePackageName").

If MoN names an array type, verification will fail (either due to the 
"samePackageName" check or because there's no matching NM attribute).

I don't see the benefit in making these "syntax" checks in addition to 
verification checks. (Even a class naming itself as its own superclass isn't a 
syntax error—it gets checked later.)

> David's prototype has the duplication check, and some of the other checks 
> happen later.  I think they should all happen during class loading.

Something you might like is if we moved the MoN verification check out of 
verification (which is mainly concerned with Code attributes anyway) and into a 
late step of the class loading process (5.3.5)? Something like:

1) Get the bits
2) Parse the class
3) Load & validate superclasses
4) Load & validate interfaces
5) Load & validate MemberOfNest

—Dan

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

On 19/04/2017 5:51 PM, John Rose wrote:

On Apr 19, 2017, at 12:14 AM, David Holmes mailto:david.hol...@oracle.com>> wrote:


Some of these are a lot more awkward to do during classfile parsing
and will require symbol comparisons. I was wanting to avoid "deep
validation" of NMs as it penalizes all the good code. Having a "bad"
NM entry seems harmless as these entries are only used to validate the
initial claim of nest membership. If an entry is "bad" then by
definition it will not match with any claimee.


I don't see how that is a significant concern.  The symbol bodies are
hot in cache
at the point we would check prefixes, since they are already being
scanned for other
purposes, such as initial interning, and also syntax checking.  Existing
processing
is exactly as deep (or shallow) as the checks I want.


I don't follow that. If I'm loading a nest-top class and validating its 
NM entries none of those entries need have been loaded yet and so none 
will be in the cache.


David
-


If we turn off the "verify" flag for class loading, then maybe we can
buy something
by dropping those (and all the other) constraint checks.

By syntax checking, I mean that if I mention a CONSTANT_Class in the CP,
and its corresponding CONSTANT_Utf8 has a broken syntax (e.g., "." instead
of "/", or two "//" in a row) the JVMS mandates an error.  But those are the
same bytes I want to look at when they are referenced by a MoN or NMs
attribute.  It will all be in cache, and the cycles to do the checks will be
undetectable.

— John


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

Hi Dan,

First, thanks for getting to this so quickly! Much appreciated.

On 19/04/2017 4:42 AM, Dan Smith wrote:

Hi, all.

I've uploaded a draft of JVMS changes for JEP 181 "Align JVM Checks with Java 
Language Rules for Nested Classes" to:
http://cr.openjdk.java.net/~dlsmith/private-access.html

Some comments below on my thinking in drafting the spec text, and on the JEP 
generally.

JEP name

I don't know how permanent JEP names are supposed to be, but I'd prefer a different name at this 
point. Something like: "Expanded JVM Access to Private Members"—shorter, focused on the 
feature itself rather than its relationship to the Java language. Or maybe "Class Nests for 
Access to Private Members".


The intent of the name is to aid in the contextual positioning of this 
JEP ie address why do we even need this. The JEP addresses an 
inconsistency between access controls in the Java programming language 
and access controls in the JVM. The primary goal here is to align the 
two, while at the same time allowing for additional usage of nestmates 
in the future.



Terminology

The term "nest" is nice because it's short and mostly unspoiled by overloading in this 
context (I think?); it's not great because it's informal and doesn't mean anything the first time 
you hear it. I thought about something more clinical like "access control context", but 
I'm not convinced that's an improvement. How do others feel?


I think John has been talking about "nests" for at least 4 years now. :) 
It fits nicely with the existing terminology of "nested types" - it 
seems quite natural that "nested types" form a "nest". I have no problem 
with it being "informal" in some sense, but we are using it to define a 
specific relationship between certain types.



The JEP uses "nest top" to describe the class that nest members reference; I prefer "host class", 
which better describes the class's role and isn't tied to the Java "top level class" concept. I know we use 
"host class" internally in Hotspot, perhaps when working with anonymous classes (of the JVM flavor), but I 
think in that context it will ultimately mean the same thing? Are we comfortable repurposing the term in this way?


Given that a nest-top type must be a top-level type, I think nest-top 
fits perfectly. I dislike "host class" because that is already used for 
the quite different case of VMACs. I can live with other names but I 
think they should incorporate "nest" eg. nest-holder, nest-host. But I 
think nest-top is an ideal match. (And no I didn't invent this 
terminology :) ).



I follow Brian's model when it comes to nest membership (5.4.4): every class 
belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted by 
itself. Many nests are singletons without any associated explicit attributes.


I have not yet seen a follow up from John as to whether we require or 
just allow, an empty NestMembers attribute to indicate a singleton nest 
member.



Verification of MemberOfNest

I include a discussion block about different options of validating 
MemberOfNest. I think the consensus, and my preference, is to do it during 
verification of the member class. (NestMembers, on the other hand, is never 
validated, except as a side-effect of checking MemberOfNest.)


Given verification is optional the current approach is to validate 
during linking just prior to the verification step. Whether that can 
conceptually be considered part of verification I am unsure.



Verification of invokespecial

Allowing invokespecial to refer to classes other than the current class and its 
supers is a significant change. I noticed and relied heavily on the parallel 
with invokevirtual making protected method calls. So I tried to make the two as 
similar as possible. In a few places, the treatment of protected methods 
doesn't seem ideal, and rather than trying to mirror that with non-private 
invokespecial, I modified the protected method treatment.


This concerns me because protected-access is a somewhat complex/messy 
issue so aligning private-access with it seems to go in the wrong 
direction. Cleaning up the protected access rules, while perhaps 
desirable, is technically out-of-scope for this JEP in my opinion.



The "protected check" of verification, in particular, was a mess before, and I 
think I've made it a lot more manageable, and compatible with a parallel rule for 
invokespecial. I could use some feedback on exactly what Hotspot's verifier has been 
doing here, though, since I'm pretty sure it didn't match the old specified rules.


Might be better to take this up separately.


MethodHandle resolution

The spec (5.4.3.5) is vague about what errors can occur during MethodHandle 
resolution. I assume any linkage error specified for the instruction can also 
occur via MethodHandle resolution, and that will include failures due to 
invokespecial improperly referencing a class.


This is an area I have least understanding of, but this seems to cover it:

"

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread David Holmes

Hi John,

Aside: my replies to the experts list are held up for moderation.

On 19/04/2017 4:45 PM, John Rose wrote:

On Apr 18, 2017, at 1:49 PM, Dan Smith mailto:daniel.sm...@oracle.com>> wrote:




On Apr 18, 2017, at 2:12 PM, Remi Forax mailto:fo...@univ-mlv.fr>> wrote:


Verification of MemberOfNest

I include a discussion block about different options of validating
MemberOfNest.
I think the consensus, and my preference, is to do it during
verification of
the member class. (NestMembers, on the other hand, is never
validated, except
as a side-effect of checking MemberOfNest.)


It means that a NestMembers can contains Class that are not yet/never
defined.
It's not a problem for me.


Yep. Also, multiple classes can claim the same nest member class in
their NestMembers attributes. Not a problem as long as the
MemberOfNest attribute (if any) of the member class points to a host
class that claims it.


We need to specify more structural constraints on the new attributes.
If we make them more strongly normalizing, there will be fewer chances
for semantic bugs on unexpected inputs.  Also, making them structural
constraints means we check them early, during class file loading.

These are good, I think:

 - NMs must be non-empty (degenerate nest is never explicit)
 - NMs may not contain duplicates (cf. treatment of ClassFile.interfaces)
 - NMs may not contain the current class (i.e., an index to a class with
the same name as this_class)
 - MoN may not contain the current class (ditto)
 - MoN may contain only a package sibling (i.e., a referenced class name
must have the same package prefix as this_class)
 - NMs may contain only package siblings (ditto)
 - NMs and MoN may not refer to array classes (this is probably implied
by the package prefix checks)

You already covered:
 - a class may have exactly one or zero of NMs or MoN (no double dipping
of any kind)
 - NMs and MoN may only have CONSTANT_Class attributes (implies no
nulls, well-formed names)

David's prototype has the duplication check, and some of the other
checks happen later.  I think they should all happen during class loading.


Some of these are a lot more awkward to do during classfile parsing and 
will require symbol comparisons. I was wanting to avoid "deep 
validation" of NMs as it penalizes all the good code. Having a "bad" NM 
entry seems harmless as these entries are only used to validate the 
initial claim of nest membership. If an entry is "bad" then by 
definition it will not match with any claimee.


David
-


— John


Re: Draft JVMS changes for Nestmates

2017-04-19 Thread Brian Goetz
Yep. Also, multiple classes can claim the same nest member class in 
their NestMembers attributes. Not a problem as long as the 
MemberOfNest attribute (if any) of the member class points to a host 
class that claims it.



At the risk of bikeshedding, I find the names NestMembers and 
MemberOfNest confusing; I keep having to think about the directionality, 
since they sound so similar.  Would be good to find names that have 
obviously opposite directionality.


A not-very-good suggestion (but which illustrates the directionality 
thing I'm going for) would be "NestDeclaration" and "NestUse".  It's 
pretty clear which is which without thinking about it.


Perhaps: NestHost and NestMember ?




Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 19, 2017, at 12:14 AM, David Holmes  wrote:
> 
> Some of these are a lot more awkward to do during classfile parsing and will 
> require symbol comparisons. I was wanting to avoid "deep validation" of NMs 
> as it penalizes all the good code. Having a "bad" NM entry seems harmless as 
> these entries are only used to validate the initial claim of nest membership. 
> If an entry is "bad" then by definition it will not match with any claimee.

I don't see how that is a significant concern.  The symbol bodies are hot in 
cache
at the point we would check prefixes, since they are already being scanned for 
other
purposes, such as initial interning, and also syntax checking.  Existing 
processing
is exactly as deep (or shallow) as the checks I want.

If we turn off the "verify" flag for class loading, then maybe we can buy 
something
by dropping those (and all the other) constraint checks.

By syntax checking, I mean that if I mention a CONSTANT_Class in the CP,
and its corresponding CONSTANT_Utf8 has a broken syntax (e.g., "." instead
of "/", or two "//" in a row) the JVMS mandates an error.  But those are the
same bytes I want to look at when they are referenced by a MoN or NMs
attribute.  It will all be in cache, and the cycles to do the checks will be
undetectable.

— John

Re: Draft JVMS changes for Nestmates

2017-04-19 Thread John Rose
On Apr 18, 2017, at 11:42 AM, Dan Smith  wrote:
> 
> Hi, all.
> 
> I've uploaded a draft of JVMS changes for JEP 181 "Align JVM Checks with Java 
> Language Rules for Nested Classes" to:
> http://cr.openjdk.java.net/~dlsmith/private-access.html

Nice.  More comments on that later.

> Some comments below on my thinking in drafting the spec text, and on the JEP 
> generally.
> 
> JEP name
> 
> I don't know how permanent JEP names are supposed to be, but I'd prefer a 
> different name at this point. Something like: "Expanded JVM Access to Private 
> Members"—shorter, focused on the feature itself rather than its relationship 
> to the Java language. Or maybe "Class Nests for Access to Private Members".

+1 to Brian's suggestion

> Terminology
> 
> The term "nest" is nice because it's short and mostly unspoiled by 
> overloading in this context (I think?); it's not great because it's informal 
> and doesn't mean anything the first time you hear it. I thought about 
> something more clinical like "access control context", but I'm not convinced 
> that's an improvement. How do others feel?

The terms for the JVM's circles of trust are "nest", "package", "module".
"Access control context" does not belong on that list of terms.

"Nest" connotes the motivation to support nested classes.
(Could also have said "block" or "scope"—those are also relevant language 
constructs.)
"Nest" also connotes a home-like place and therefore privacy.
(Could also have said "home" or "family"—those are also private spaces.  Or 
"crib"?)
Only "nest" connotes both AFAIK.

> The JEP uses "nest top" to describe the class that nest members reference; I 
> prefer "host class", which better describes the class's role and isn't tied 
> to the Java "top level class" concept. I know we use "host class" internally 
> in Hotspot, perhaps when working with anonymous classes (of the JVM flavor), 
> but I think in that context it will ultimately mean the same thing? Are we 
> comfortable repurposing the term in this way?

I am comfortable handing over the term "host" for this purpose.

I expect Lookup.defineClass to inject into the nest of the Lookup.lookupClass,
if the lookup has private access.  That's what we call hosting for VMACs,
almost exactly.  (+1 to Brian's comments to Remi.)

I would prefer "nest host" or "nest host class" or "host class of nest" to 
plain "host class",
because it will be better if we mention "nest" when we mention the term for a 
nest's host class.
Downside is pronunciation of "nest-host" sounds like a sneeze.

> I follow Brian's model when it comes to nest membership (5.4.4): every class 
> belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted 
> by itself. Many nests are singletons without any associated explicit 
> attributes.

+1

> Verification of MemberOfNest
> 
> I include a discussion block about different options of validating 
> MemberOfNest. I think the consensus, and my preference, is to do it during 
> verification of the member class. (NestMembers, on the other hand, is never 
> validated, except as a side-effect of checking MemberOfNest.)

See my previous message.  There are more structural constraints I'd like to see.
(But no additional class loading!)

I agree that MemberOfNest needs to be checked early.  I'd prefer to do it along
with the supers but that leads to vicious dependency cycles.  So verification 
time
is best.  IIRC that's also called "link time", which is intuitive to me:  One 
of the first
things you do when you link a class is determine which nest it is in.

I totally agree that NestMembers should only be checked as needed.
It's asymmetric, but the asymmetry lets us escape a bunch of class file loading.

Here's a corner case we need to cover:  I have to load my supers before I can 
load myself.
If one (or more) of my supers are in the same nest as me, the checking of MoN 
must succeed
no matter who is the host class of the nest.

This could get embarrassing if the host class is the subtype, if the super then 
needs to
recursively load the subtype (which is waiting on the supertype to load) before 
it can
validate its MoN attribute.  If verification (linking) is started after all of 
the classes are
loaded, things are OK, since the MoN checks happen only after everything is 
loaded.

N.B. The class file parser code in HotSpot sometimes says "verify" when I think 
it really
means "check constraints".  (The code also mentions constraints.)  It does not 
mean
verification in the sense that we are talking about here.

The extra constraint checking I propose should happen during parsing/loading not
linking/"verification".

> Verification of invokespecial
> 
> Allowing invokespecial to refer to classes other than the current class and 
> its supers is a significant change. I noticed and relied heavily on the 
> parallel with invokevirtual making protected method calls. So I tried to make 
> the two as similar as possible.

Nice work.

> In a few places, the treatment of pr

Re: Draft JVMS changes for Nestmates

2017-04-18 Thread John Rose
On Apr 18, 2017, at 1:49 PM, Dan Smith  wrote:
> 
> 
>> On Apr 18, 2017, at 2:12 PM, Remi Forax > > wrote:
>> 
 Verification of MemberOfNest
 
 I include a discussion block about different options of validating 
 MemberOfNest.
 I think the consensus, and my preference, is to do it during verification 
 of
 the member class. (NestMembers, on the other hand, is never validated, 
 except
 as a side-effect of checking MemberOfNest.)
>> 
>> It means that a NestMembers can contains Class that are not yet/never 
>> defined.
>> It's not a problem for me.
> 
> Yep. Also, multiple classes can claim the same nest member class in their 
> NestMembers attributes. Not a problem as long as the MemberOfNest attribute 
> (if any) of the member class points to a host class that claims it.

We need to specify more structural constraints on the new attributes.
If we make them more strongly normalizing, there will be fewer chances
for semantic bugs on unexpected inputs.  Also, making them structural
constraints means we check them early, during class file loading.

These are good, I think:

 - NMs must be non-empty (degenerate nest is never explicit)
 - NMs may not contain duplicates (cf. treatment of ClassFile.interfaces)
 - NMs may not contain the current class (i.e., an index to a class with the 
same name as this_class)
 - MoN may not contain the current class (ditto)
 - MoN may contain only a package sibling (i.e., a referenced class name must 
have the same package prefix as this_class)
 - NMs may contain only package siblings (ditto)
 - NMs and MoN may not refer to array classes (this is probably implied by the 
package prefix checks)

You already covered:
 - a class may have exactly one or zero of NMs or MoN (no double dipping of any 
kind)
 - NMs and MoN may only have CONSTANT_Class attributes (implies no nulls, 
well-formed names)

David's prototype has the duplication check, and some of the other checks 
happen later.  I think they should all happen during class loading.

— John

Re: Draft JVMS changes for Nestmates

2017-04-18 Thread John Rose
On Apr 18, 2017, at 11:58 AM, Brian Goetz  wrote:
> 
> Minimal candidate:
> 
>class Nest {
>Class hostClass() { ... }
>boolean isMember(Class clazz) {  }
>}
> 
>class Class {
>   Nest getNest() { ... }
>}

Or just:

class Class {
Class getNestHost(); // = this.MemberOfNest_attribute.host_class || this
//and maybe:
//boolean isInSameNest(Class that) { return this.getNestHost() == 
that.getNestHost(); }
}


Re: Draft JVMS changes for Nestmates

2017-04-18 Thread Dan Smith

> On Apr 18, 2017, at 2:12 PM, Remi Forax  wrote:
> 
>>> Verification of MemberOfNest
>>> 
>>> I include a discussion block about different options of validating 
>>> MemberOfNest.
>>> I think the consensus, and my preference, is to do it during verification of
>>> the member class. (NestMembers, on the other hand, is never validated, 
>>> except
>>> as a side-effect of checking MemberOfNest.)
> 
> It means that a NestMembers can contains Class that are not yet/never defined.
> It's not a problem for me.

Yep. Also, multiple classes can claim the same nest member class in their 
NestMembers attributes. Not a problem as long as the MemberOfNest attribute (if 
any) of the member class points to a host class that claims it.

—Dan

Re: Draft JVMS changes for Nestmates

2017-04-18 Thread forax
- Mail original -
> De: "Brian Goetz" 
> À: "Remi Forax" , "Dan Smith" 
> Cc: valhalla-spec-experts@openjdk.java.net
> Envoyé: Mardi 18 Avril 2017 22:19:40
> Objet: Re: Draft JVMS changes for Nestmates

>> The semantics of an anonynmous host class and a nest host class are 
>> different.
>> an anonymous host class is used for every access check while the nest host 
>> class
>> is used
> 
> They are *now*.  But we would like to converge them.  As we bring VMACs
> into the "supported light", we can adjust the semantics.

and retired unsafe.defineAnonymousClass which still have some perf issue ...

Rémi
 


Re: Draft JVMS changes for Nestmates

2017-04-18 Thread Brian Goetz



The semantics of an anonynmous host class and a nest host class are different.
an anonymous host class is used for every access check while the nest host 
class is used


They are *now*.  But we would like to converge them.  As we bring VMACs 
into the "supported light", we can adjust the semantics.





Re: Draft JVMS changes for Nestmates

2017-04-18 Thread Remi Forax
- Mail original -
> De: "Dan Smith" 
> À: valhalla-...@openjdk.java.net
> Envoyé: Mardi 18 Avril 2017 20:44:11
> Objet: Fwd: Draft JVMS changes for Nestmates

> For those not subscribed to (or not paying attention to) 
> valhalla-spec-experts,
> I just posted a link to an updated draft of JVMS changes.
> 
>> Begin forwarded message:
>> 
>> From: Dan Smith 
>> Subject: Draft JVMS changes for Nestmates
>> Date: April 18, 2017 at 12:42:16 PM MDT
>> To: valhalla-spec-experts@openjdk.java.net
>> 
>> Hi, all.
>> 
>> I've uploaded a draft of JVMS changes for JEP 181 "Align JVM Checks with Java
>> Language Rules for Nested Classes" to:
>> http://cr.openjdk.java.net/~dlsmith/private-access.html
>> 
>> Some comments below on my thinking in drafting the spec text, and on the JEP
>> generally.
>> 
>> JEP name
>> 
>> I don't know how permanent JEP names are supposed to be, but I'd prefer a
>> different name at this point. Something like: "Expanded JVM Access to Private
>> Members"—shorter, focused on the feature itself rather than its relationship 
>> to
>> the Java language. Or maybe "Class Nests for Access to Private Members".
>> 
>> Terminology
>> 
>> The term "nest" is nice because it's short and mostly unspoiled by 
>> overloading
>> in this context (I think?); it's not great because it's informal and doesn't
>> mean anything the first time you hear it. I thought about something more
>> clinical like "access control context", but I'm not convinced that's an
>> improvement. How do others feel?
>> 
>> The JEP uses "nest top" to describe the class that nest members reference; I
>> prefer "host class", which better describes the class's role and isn't tied 
>> to
>> the Java "top level class" concept. I know we use "host class" internally in
>> Hotspot, perhaps when working with anonymous classes (of the JVM flavor), 
>> but I
>> think in that context it will ultimately mean the same thing? Are we
>> comfortable repurposing the term in this way?

The semantics of an anonynmous host class and a nest host class are different.
an anonymous host class is used for every access check while the nest host 
class is used 

Anyway, nest host class works for me.

>> 
>> I follow Brian's model when it comes to nest membership (5.4.4): every class
>> belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted 
>> by
>> itself. Many nests are singletons without any associated explicit attributes.
>> 
>> Verification of MemberOfNest
>> 
>> I include a discussion block about different options of validating 
>> MemberOfNest.
>> I think the consensus, and my preference, is to do it during verification of
>> the member class. (NestMembers, on the other hand, is never validated, except
>> as a side-effect of checking MemberOfNest.)

It means that a NestMembers can contains Class that are not yet/never defined.
It's not a problem for me.

>> 
>> Verification of invokespecial
>> 
>> Allowing invokespecial to refer to classes other than the current class and 
>> its
>> supers is a significant change. I noticed and relied heavily on the parallel
>> with invokevirtual making protected method calls. So I tried to make the two 
>> as
>> similar as possible. In a few places, the treatment of protected methods
>> doesn't seem ideal, and rather than trying to mirror that with non-private
>> invokespecial, I modified the protected method treatment.
>> 
>> The "protected check" of verification, in particular, was a mess before, and 
>> I
>> think I've made it a lot more manageable, and compatible with a parallel rule
>> for invokespecial. I could use some feedback on exactly what Hotspot's 
>> verifier
>> has been doing here, though, since I'm pretty sure it didn't match the old
>> specified rules.
>> 
>> MethodHandle resolution
>> 
>> The spec (5.4.3.5) is vague about what errors can occur during MethodHandle
>> resolution. I assume any linkage error specified for the instruction can also
>> occur via MethodHandle resolution, and that will include failures due to
>> invokespecial improperly referencing a class.

method handle behavior is the same as their corresponding bytecodes behavior, 
errors are converted to exceptions.  

>> 
>> Dynamic checking of invokespecial receivers
>> 
>> When invokespecial involves interface types, the verifier can't guarantee 
>> that
>> receiver objects actually implement that interface (JDK-8134358). It's an 
>> open
>> question whether this is really a problem, but I included a tentative fix in
>> the invokespecial runtime rules.

I'm not sure it's related to nestmate ?

>> 
>> Compiler changes
>> 
>> The JEP text can't seem to decide if compiler changes are part of it, or a
>> follow-up exercise. I think we're best off explicitly including the compiler
>> changes, which will provide opportunities for design validation and testing.
>> 
>> API changes
>> 
>> I haven't tried to address changes that need to be made to APIs. Somebody 
>> will
>> need to. For example, Lookup.findSpecial probabl

Re: Draft JVMS changes for Nestmates

2017-04-18 Thread Brian Goetz




JEP name

I don't know how permanent JEP names are supposed to be, but I'd prefer a different name at this 
point. Something like: "Expanded JVM Access to Private Members"—shorter, focused on the 
feature itself rather than its relationship to the Java language. Or maybe "Class Nests for 
Access to Private Members".


I like the latter; it captures the core feature here, which is 
introducing a new concentric sphere of access control in the VM, which 
we call "nests".  That it was inspired by translation challenges in 
Java, or useful to addressing those, is secondary.



Terminology

The term "nest" is nice because it's short and mostly unspoiled by overloading in this 
context (I think?); it's not great because it's informal and doesn't mean anything the first time 
you hear it. I thought about something more clinical like "access control context", but 
I'm not convinced that's an improvement. How do others feel?


Nest connotes "things in other things", like Matryoshka dolls, which I 
think is a positive.




The JEP uses "nest top" to describe the class that nest members reference; I prefer "host class", 
which better describes the class's role and isn't tied to the Java "top level class" concept. I know we use 
"host class" internally in Hotspot, perhaps when working with anonymous classes (of the JVM flavor), but I 
think in that context it will ultimately mean the same thing? Are we comfortable repurposing the term in this way?


Or: "nest host" or "nest host class" or "nest parent" ...

The primary purpose of having a nest top is so that there is a 
well-defined canonical member of each nest, to which we can attach all 
the nest metadata and ensure that computations regarding nest-ness are 
well-defined.  It doesn't have to be the "top" class at the language 
level.  I think the term should connote canonical-ness rather than top-ness.



I follow Brian's model when it comes to nest membership (5.4.4): every class 
belongs to a nest, possibly (in the absence of MemberOfNest) the nest hosted by 
itself. Many nests are singletons without any associated explicit attributes.


More precisely: nests form a /partition/ over classes.  This means every 
class belongs to exactly one nest, so the function Nest(Class) is total.



Compiler changes

The JEP text can't seem to decide if compiler changes are part of it, or a 
follow-up exercise. I think we're best off explicitly including the compiler 
changes, which will provide opportunities for design validation and testing.


That was my bad.  I was trying to capture that we didn't require an 
immediate flag day -- that for any given compiler, dropping access 
bridges out of the compiler implementation could happen any time after 
the VM acquired nestmate support -- but for our own implementation, we'd 
be silly to not get the test and validation benefit of dropping 
unnecessary bridge generation ASAP.



API changes


We need to decide whether we are delivering a reflection component, and 
if so, what that looks like.


Minimal candidate:

class Nest {
Class hostClass() { ... }
boolean isMember(Class clazz) {  }
}

class Class {
   Nest getNest() { ... }
}