State of javac support for lworld-values.

Srikanth srikanth.adayapalam at
Mon Mar 26 09:21:17 UTC 2018

On Thursday 15 March 2018 11:53 PM, Karen Kinnear wrote:
> Srikanth,
> I sent a email yesterday, and just sent out a .pdf summarizing a new 
> proposal:
> Summary - proposing that we add a clue (annotation?) for javac that a 
> value-based class
> is migrating to become a value type, and allow javac to be strict with 
> new value types
> and have a choice on handling migrating types. The JVM will continue 
> to be lenient
> to allow migration.
> <>
> If it makes sense to you and the langtools team -
> This would keep the strictness you have implemented for new value types.
> We would like to ask for a way to identify migrating value-based 
> classes to value types,
> both so that we can write tests of JVM functionality, and of course so 
> that we can
> experiment with migration and separate compilation.
> If you could find a way for us to identify in source that we have a 
> value-based class
> migrating to a value type, and to limit the strictness for new value 
> types for now - that would
> enable us to use javac to write tests for the JVM.
> It would also allow us all to start experiments with migration and 
> separation compilation,
> which would be helpful for the JVM, as well as informative for the 
> langtools strictness
> decisions.

Hi Karen,

I think I am hearing 4 goals for this proposal:

     1. A lenient mode in javac that does not issue errors for null 
related violations of value'ness - would enable you to use javac to 
write tests for the JVM.

     2. "It would also allow us all to start experiments with migration 
and separation compilation,which would be helpful for the JVM"

     3. Such a mode could be informative for the langtools strictness 

     4. As a follow up of 3, it may become possible to provide the the 
eventual end programmers a gradual path to fixing value'ness violations 
instead of issuing hard errors.

Are 1 & 2 already supported by invoking valhalla tip javac with -source 
10 option of javac ?
When invoked with -source 10, as long as the source code does not 
contain the tokens __ByValue,
__Flattenable and __MakeDefault, the code should compile and any classes 
tagged __ByValue elsewhere would be treated as value based classes and 
would be compiled with no new/additional strictness.

$ cat
final __ByValue public class X {
     final int x = 10;

$ cat

public class Y {

     void doit(X x, X y) {
         x = null;
         x = (X) null;
         if (x != null) {}
         if (x != y) {}
         if (null instanceof X) {}


// Now seperately compile *without* explicit -source 10:

$ javac -g error: incompatible types: <null> cannot be converted to X
         x = null;
             ^ error: incompatible types: <null> cannot be converted to X
         x = (X) null;
                 ^ error: incomparable types: X and <null>
         if (x != null) {}
               ^ error: value types do not support !=
         if (x != y) {}
               ^ error: incompatible types: <null> cannot be converted to X
         if (null instanceof X) {}
5 errors

// Now seperately compile *with* explicit -source 10:

$ javac -g -source 10
warning: [options] bootstrap class path not set in conjunction with 
-source 10
1 warning

When invoked with -source 10 option, javac does not know anything about 
value types.
Any class file that is referenced in that compilation that has the 
ACC_VALUE bit set or
has a field with ACC_FLATTENABLE bit set will be treated as normal 
classes/fields - these
flags bits will be silently ignored.

Is this not enough for goals 1 & 2 above ?

As for (4), I am not sure it is a great idea ! When eventually this 
functionality gets delivered and used by programmers, deferring errors 
to runtime - those that could be caught at compile time itself sounds 
very un-Java like to me.

I agree because of the way VM handles null assignments now - only 
flattenable fields and array cells may not be null - javac is 
necessarily more picky. But that serves its purpose in minimizing the 
surface where a null pollution may originate.

I will discuss this with the Javac team of course, but if there are 
convincing arguments already, I would like to hear.

If indeed (4) is of dubious value, it also drags (3) into question.

Please confirm if (1) and (2) are sufficiently addressed by javac 
-source 10 invocation.


> So this would explain why we are leaving existing bytecodes such as 
> checkcast and instanceof
> behavior alone. And request that you only put the null checks in for 
> statically known new value types.
> more embedded:
>> On Mar 13, 2018, at 8:53 PM, John Rose <john.r.rose at 
>> <mailto:john.r.rose at>> wrote:
>> On Mar 13, 2018, at 3:04 PM, Karen Kinnear <karen.kinnear at 
>> <mailto:karen.kinnear at>> wrote:
>>> 1. Frederic made a good point - a value type can not have an inner 
>>> class, i.e. a non-static nested class, since it does not have identity.
>> Putting on my Mr. Inner Classes hat, I say, not so fast!
>> Inner-ness is a scoping relation, not an identity relation.
>> There's nothing about value classes that keeps them from
>> being either inner or outer.  Let's not be hasty to find reasons
>> that values don't "code like a class" everywhere it makes sense.
>> (Strong heuristic:  If a value-based class can do X, then a
>> value type can do X, 99% probability.  That applies here.)
>> At the VM level, an inner class has a this$0 reference to the
>> outer instance.  For a value outer class, the this$0 is a flattenable
>> copy of the outer instance.  We could be clever and make it
>> not flat, but I think that's taking a legitimate decision away
>> from the user.
> This was not about flattenable or nullability. This was a question 
> about identity.
> Perhaps I misunderstand and an experiment would help here. If this$0 
> refers
> to an outer instance - not sure what happens if we are now operating 
> on a copy
> of that instance?
>> I grant you that, given an object class and a value class to nest
>> together, the object class should usually be the outer and the
>> value the inner.  But it's a user decision, not a VM or language
>> decision, which goes in which.
>>> 2. Arrays extract from EG minutes: - which I just typed in Friday night
>>> - I don’t think you have had time to make the value array changes yet?
>>> Based on emails this week between Mr Simms, Remi, John 
>>> onvalhalla-dev at 
>>> <mailto:valhalla-dev at><mailto:valhalla-dev at>, 
>>> here is a summary of a new proposal:
>>>   Value type arrays are always flattenable, and therefore not nullable
>> Yes, their elements are flat, thus not nullable.  Just to make sure:
>> The arrays are proper object types and their references are nullable.
> Check.
>>>   If the end user wants non-flattenable/nullable they can use 
>>> Object[] or Interface[] or maybe a future reflective API if needed 
>>> that creates a reference array - but for now let us assume that 
>>> value type arrays are always flattenable, prototype that and then we 
>>> can assess what the cost might be if we need dynamic checking.
>>>    As with fields, implementation determines if the component is 
>>> actually flattened.
>>>   bytecode implications:
>>>      aaload - returns default from default initialized value type 
>>> component
>>>      aastore - throws NPE if attempt to store null. Must store 
>>> default value for component
>>>      anewarray/multianewarray - if the component is a value type, 
>>> create a value type array
> Srikanth - for fields I think you disallow null assignment for value 
> types. I was assuming you would want a similar disallow null 
> assignment to value type array indices.
>> Thanks for writing that down, Karen.
>>> I believe there are two major open issues:
>>> 1. you identified one - which is the discussion around <init>, which 
>>> I think also includes
>>> handling of __MakeDefault
>> Yes, we haven't touched <init> yet.  I think the language folks need to
>> decide what value constructors look like before we can start to talk
>> translation strategy.  My crystal ball tells me that <init> will be 
>> irrelevant
>> to value types, even though at the source level constructors will be
>> important.  ("Codes like a class…")  The JVM rules around <init> are
>> just relentlessly pointer-oriented, so we'll probably break new ground
>> for value factories.  (If we win big, then that ground will serve for
>> factories on object classes and interfaces too, but that's just my
>> hunch for now.)
> Is there an rfe here?
> So how does instance initialization happen for testing right now 
> before this gets resolved?
>>> 2. I think we are still working through nullability of a value type 
>>> issues
>>> I know you and John exchanged a number of emails over the past few 
>>> weeks.
>>> I also believe that last Wednesday at both the Valhalla-vm and 
>>> valhalla EG meetings
>>> we discussed again nullability relative to value type fields.
>> I hope we don't find any important use cases for nullable values, in
>> which case such fields will be relegated to the JVM puzzler list
>> and maybe JLS chapter 13 (binary compatibility).
> This is the value-based class migrates to value type proposal.
>>> Value type fields:
>>>  I would like to have a follow-up discussion about nullability of 
>>> value types based on ACC_FLATTENABLE,
>>> and how to handle migration.
>>> The key points below that I want us to revisit are:
>>>>    - Value instances may not be compared with == or !=. == and != 
>>>> cannot have any value operand(s)
>> This is a conservative choice.  We could assign x.equals(y) as the 
>> meaning
>> of x==y for x, y values.  That's a language team choice, and I don't see
>> a decision on that coming soon.  I recommend filing a tracking issue.
> Conservative for new value types.
> May I suggest that allowing this is conservative for migrating value 
> types.
>>>>    - Null cannot be assigned to value types
> please - just for new value types
>>>>    - Null cannot be casted to or compared with value types.
> please - just for new value types
>>>>    - Fields may be flagged as being__Flattenable. This results in 
>>>> the ACC_FLATTENABLE(0x100) field flag bit being set in the class 
>>>> file. Besides setting this flag bit, the compiler does not use this 
>>>> flag.
>> There are three more places where I'd like to see more work soon-ish:
>> 1. Flip the default on __Flattenable, making another temporary modifier
>> __NotFlattened and having the compiler start to issue ACC_FLATTENABLE
>> by default when it sees that a field is a value type.  This is tricky 
>> and may
>> require additional preloading in javac.  (Not in the VM.)  It's where 
>> we want
>> to get to; eventually removing both pseudo-modifiers (if possible) except
>> maybe for test code (or just use jcod).
> My proposal was in part in response to this request (and your other 
> emails John),
> For new value types - make ACC_FLATTENABLE the default for now.
> Let’s do that experiment before we decide which way we want the flag 
> or the name for it.
>> 2. Flip the default on 'final', in the sense that javac doesn't care 
>> whether
>> a value class's instance field is declared final or not.  We want to 
>> reserve
>> the distinction for potential uses, TBD.
> EG - John challenged folks to make alternative proposals.
>> 3. Allow the __Atomic modifier (or the "volatile" modifier if Brian 
>> OKs it)
>> on value classes, with an ACC_VOLATILE on the class, and appropriate
>> processing in the classfile parser to unflatten, as I outlined elsewhere.
> This is on our todo list once we get basic stuff working.
>> If (as I think) constructors will translate to factory methods not 
>> <init>,
>> then there's nothing for us tools and VM folks to do until the language
>> folks hash out more details about value class constructors.
> thanks for all the reviews and insights,
> Karen
>> Thanks!
>> — John

More information about the valhalla-dev mailing list