JDK-8230501: Class data support for hidden classes

Mandy Chung mandy.chung at oracle.com
Tue Nov 17 20:43:19 UTC 2020

Thanks for the feedback, John and Remi.

Here is the updated specdiff:

I added @apiNote in `defineClassHiddenWithClassData` about mutability.
I keep `classData` that can be used for a single-item class data or of 
type other than List like array, map, or even record. `classDataAt` 
makes it easier for those who use a list as the class data (that can be 
extended for frozen arrays in the future).    The @apiNote suggests the 
good practice to use unmodifiable List. (Stream::asList is not yet 
integrated and no reference from the @apiNote).

I will update https://github.com/openjdk/jdk/pull/1171


On 11/13/20 5:11 PM, John Rose wrote:
> I see your point; it’s the unconditional use of List.{copy,}of
> that is the hard problem (with nulls).  The problem with
> @Stable is a minor internal perf. bug, not a problem with
> the API.
> I agree that the basic single ClassData should not be
> restricted to a List.  (But if it were, it should be copied
> by Stuart’s null-friendly immutable list-maker.)
> I also think it’s reasonable to trust users of condy
> to take adequate care of mutability issues.  I suggest
> adding an @apiNote which says “Think twice before
> passing an array or other mutable structure through
> the ClassData.  If you use a List, make it unmodifiable,
> using List.of or Stream.asList.”
> On Nov 13, 2020, at 3:25 PM, forax at univ-mlv.fr wrote:
>> ----- Mail original -----
>>> De: "John Rose" <john.r.rose at oracle.com>
>>> À: "Remi Forax" <forax at univ-mlv.fr>
>>> Cc: "mandy chung" <mandy.chung at oracle.com>, "valhalla-dev" <valhalla-dev at openjdk.java.net>
>>> Envoyé: Vendredi 13 Novembre 2020 23:46:24
>>> Objet: Re: JDK-8230501: Class data support for hidden classes
>>> On Nov 13, 2020, at 2:02 PM, forax at univ-mlv.fr wrote:
>>>> I want it, null is easy to check in term of bytecode and is aggressively
>>>> propagated by c1 and c2 so you can write the equivalent IFDEF at runtine by
>>>> putting nulls in the right holes.
>>>> It's also pretty useful when you have object that have a double representation,
>>>> i.e. a value that can be a primitive value or a box, again testing if the box
>>>> is null is a common operation.
>>> Null as a static constant can be created easily by other means,
>>> so in most use cases, there’s no need to plumb a null through
>>> a ClassData.  Just use aconst_null or ili.CBs::nullConstant.
>> yes,
>> but i was thinking about using it to define things like a capability, being null meaning the capability doesn't exist,
>> so you still also need to be able to pass a real object if the capability exists.
>> something like
>>   if (ldc condy != null) {
>>     ldc condy
>>     invokevirtual ...
>>   }
>>> Maybe what you are hoping for is statically generated bytecodes
>>> which are invariant across nullable “holes”, where the holes
>>> are filled by a ClassData.
>> yes,
>> it's the same bytecode specialized using holes, so you don't have to generate it at runtime, only to specialize it at runtime.
>>> Fine, in that case use a nullable container, such as Stuart Marks’ Stream::asList.
>> First, you can not using the result of toList() if it's a null friendly List because Mandy propose to use a List.copyOf() in between that will choke is there is a null inside the List.
>> Moreover if Stuart still want to use ListN to both this kind of List and List.of(...) then the result of ListN.get() will not be a constant if the value is null (because of the semantics of @Stable).
>> Which means that classData() will be useless, the only way will be to use classDataAt().
>> To summarize, if the only thing you can inject is a List which will be copy into an immutable list, passing null will not be easy, I can still wrap it and then unwrap it with you own condy BSM, it makes classData() useless as a BSM and makes passing only one object far more complex than the previous proposal.
>>> — John
>> Rémi

More information about the valhalla-dev mailing list