On May 12, 2018, at 7:32 AM, Brian Goetz <brian.go...@oracle.com> wrote: > > I want to drill into this point a bit. I know that you would prefer not to > make heroic efforts to deal with cases where a random subset of a hierarchy > was compiled with one polarity and the rest with the other, but I think > there’s reasons to keep drilling on it. (Also, because I don’t think you’ll > get away with it.)
When you say "polarity" it sounds like the two states are equally likely. In fact, one state is clearly preferable, and one is locally incorrect and tolerated—to some extent—by the rest of the system. This is true in both Q-world and L-world. In Q-world, eventually the adapter spinners will say, "you can't do that". In L-world, there are no adapter spinners, but the same "laws of value physics" apply. At some point legacy code can do something so bad that we must forbid it, lest we inflict a performance hit on the entire system. What is the point at which that occurs? I think the easiest way to find this point is make a fairly restrictive JVM (plus lint modes in javac) and learn what bad code looks like, and (more subtly) what not-quite-bad code looks like, that we want to keep running. An obvious example of bad code is something that calls monitorenter. In the setting of null hygiene, bad code can use null as an out-of-band value of a VBC, and expect the rest of the system to faithfully store it in arbitrary containers, eventually returning it undamanged to the bad actor. This can't work. Finding ways to sieve out the really bad legacy code from workable stuff is an experimental process. > I’ll note that this reminds me further of a related migration discussion in > Burlington (DanH was there too) when we were exploring how to crowbar L/D > primitives into one slot. Teaching the interpreter to do so in a consistent > world was easy; the hard part was dealing with calling sequences / overrides > across separately compiled files that had differentially gotten the memo > about the new encoding. We talked about various adapters/fixups needed at > the junction of a slot arity mismatch. The thing that's different here is there are no explicit adapters across different descriptors. The L-world JVM can spin them internally as needed, as it already does, under the matched descriptors. What's also different is everything runs under one slot; the J and D descriptors are just hard to work with because of low-level stack wrangling problems. > While we didn’t solve it then either, I claim we want to solve it anyway, > because this is how we get to primitives as values. Based on our conversations about the matter, I'll be surprised if we get to primitives as values and preserve the two-slot nature of J and D, unless we introduce one-slot versions of those types. The two-slot problem is hard all the way around, not just in L-world. In any case, I think we don't need to solve primitives-as-values in L-world, as long as we think L-world doesn't deprives us of important moves. > Just as the ValueTypes attribute lists the types known as of compile time to > be values, we can similarly reify, on a per-class basis, whether the class > is able to treat primitives as values. When class A calls / overrides a > method in B with the same encoding, everything is great; when A and B differ > on the value-ness of primitives, an adaptation, similar to the > scalarize/bufferize adaptation, is needed at the junction. Over time, fewer > classes will be out of date and the adapters will eventually be purged from > the ecosystem. That sounds plausible. We might be able to pull the trick of normalizing old descriptors to new one, rewriting "I" to "Lint;" etc. Or we might choose to let new and old descriptors co-exist. It does feel like the flattened calling sequence problem we are talking about with L-world, but it is riskier, since the classfiles must embody a tentative solution to a problem that might change between compile time and run time, rather than having the JVM come up with a solution on the fly, from final information. I don't think we ever want to change J and D to single slot entities. I think we will want to make new L-type descriptors like Llong; and Ldouble; (or Q-type, in Q-world). — John