A "RecursiveConstants" attribute
daniel.smith at oracle.com
Wed Jan 31 21:13:15 UTC 2018
> On Jan 31, 2018, at 1:39 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> It seems to me that the rational thing to do is, in SE 11, to implicitly assume max-depth is zero, and be done. (IE, pretend to implement this proposal, but don't actually allow classfiles to have the attribute.) Then we won't get any classfiles that have cycles, and the full spectrum of cycle-accepting approaches is still on the table.
> This proposal is essentially about *enabling* recursive constants in the classfile; one would not need a RC attribute if one has no self-reference in the CP. But allowing cycles merely creates a bigger problem down the road -- how should bytecode readers present such a recursive constant using the symbolic reference API? You can't construct such a thing with the API we have, and that's by design; the API has been designed to be value-based (and let compilers intern away the duplication). So allowing controlled cycles in the classfile still doesn't address the question of how to build a symbolic reference for them. The result will probably be classfiles that blow up when you try to parse them -- not good.
> What use cases are we really concerned about here? I may have missed the meeting where these cases were brought up, but it feels a little bit like we're extrapolating from a single example (or maybe a single Future<Example>).
Sorry, I didn't provide enough context for those who weren't part of previous discussions. You're misunderstanding the restriction.
A CONSTANT_Dynamic with recursion depth 0 would not be allowed to have a CONSTANT_Dynamic as its static argument. Its static arguments could only be strings, numbers, classes, etc.
A CONSTANT_Dynamic with recursion depth 1 would be allowed to have a CONSTANT_Dynamic as its static argument, but only if the argument has a recursion depth of 0.
A CONSTANT_Dynamic with recursion depth 2 would be allowed to have a CONSTANT_Dynamic as its static argument, but only if the argument has a recursion depth of 0 or 1.
Under no circumstances would a CONSTANT_Dynamic be allowed to refer to itself—because in order to do so, at some point in the cycle you'd have a CONSTANT_Dynamic with a static argument of an illegal depth.
To restate my point about layering on this restriction after 11: when enforced, this rule gives us the property that there are no structural cycles in a well-formed (per 4.8) constant pool. So if, say, the symbolic reference API is building a structure from a loaded constant pool, it can assume no cycles exist. However, if we don't enforce the rule on version 55.0 class files, we can't retroactively enforce it later, and downstream tools won't get strong guarantees about CONSTANT_Dynamic (however, they will have strong guarantees about future structures like CONSTANT_ArrayType).
More information about the valhalla-spec-observers