> On Jul 13, 2020, at 12:19 PM, Dan Smith <[email protected]> wrote:
>
>> On Jul 10, 2020, at 12:23 PM, Dan Smith <[email protected]> wrote:
>>
>> Option G: JVM support for default instance guards
>>
>> Inline class files can indicate that their default instance is invalid. All
>> attempts to operate on that instance (via field/method accesses, other than
>> 'withfield') result in an exception.
>>
>> This tightens up Option F, making it just as impossible to access members of
>> the default instance as it is to access members of 'null'.
>>
>> Same issues as Option E regarding adding a "new NPE" to the platform.
>
> There's a variant of this that deserves spelling out:
>
> ---
>
> Option J: JVM treats default instance as 'null'
>
> Like Option G, an inline class file can indicate that its default instance is
> invalid—in this case, 'null'. All attempts to operate on that instance result
> in an NPE. Conceptually, the null instance and the null reference are the
> same, and should generally be indistinguishable.
>
> (We explored this awhile back as a tool for migration, before going in a
> different direction.)
>
> Some implications:
>
> - The VM probably wants to normalize its encodings (null reference vs. null
> instance), meaning there's a translation layer on field/array reads, just
> like Option I, and also for field/array writes, just like Option D.
>
> - Casts to Q types for certain classes should also translate from null
> reference to null instance, rather than NPE.
>
> - For these classes, the 'withfield' instruction is uniquely able to operate
> on and produce 'null'.
>
> - In the language, the 'null' literal can be assigned to some inline types.
> (In the VM, the verifier could require using 'defaultvalue' instead, if it
> wants to avoid some class loading.)
>
> - We could revisit the question of whether it's possible to migrate an
> identity class to be an inline-default inline class as long as the default
> instance is 'null'. (There are additional issues, like binary compatibility.
> But we could we-open that exploration...)
>
> ---
>
> My sense is that Option I dominates Option J by most measures—it achieves the
> same result (default value is invalid), with less work at flattened storage
> barriers, fewer tweaks to the rest of the system, and a more useful
> programming model (no nulls being passed around).
And here's another option that has been previously discarded, but might be
worth picking back up. This one to address Bucket #2:
---
Option K: JVM initializes fields/arrays to a designated default
The VM allows inline classes to designate a logical default instance, and
during class preparation or array allocation, any fields/components of the
inline type are initialized to the logical default.
Compare to Option D. Rather than adding barriers to reads/writes that interact
with the storage, we simply initialize the storage "properly" in the first
place.
The possibly-fatal downside is that it means every array allocation for that
inline type has to stamp out a bunch of copies of a particular bit pattern,
rather than the simpler all-zeros pattern. But that extra cost may be worth it
in exchange for faster reads/writes to the array. (Same comments for class
instances, although I don't think it's as much of a concern, given the
relatively small sizes of class instances.)
Note that some arrays *already* have to stamp out a nonzero bit pattern, if the
encoding of an inline type uses pointers rather than flattened fields (e.g.,
for an inline class with too many fields).
---
If we're enthusiastic about addressing Bucket #2, this seems like a viable
approach—quite simple, and with comparable performance to most of the other
approaches.