From daniel.smith at oracle.com Wed Oct 18 15:01:36 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 18 Oct 2023 15:01:36 +0000 Subject: EG meeting 2023-10-18 Message-ID: <2579B60B-7228-4BA8-A3FA-E1A767AF73AB@oracle.com> An EG meeting will be held today, October 18, at 4pm UTC (9am PDT, 12pm EDT). To discuss: revised JEPs. JEP 401: Value Classes and Objects https://openjdk.org/jeps/401 Language details: https://bugs.openjdk.org/browse/JDK-8317277 JVM details: https://bugs.openjdk.org/browse/JDK-8317278 Library details: https://bugs.openjdk.org/browse/JDK-8317279 Null-Restricted Value Class Types https://openjdk.org/jeps/8316779 Language details: https://bugs.openjdk.org/browse/JDK-8317765 JVM details: https://bugs.openjdk.org/browse/JDK-8317766 Library details: https://bugs.openjdk.org/browse/JDK-8317767 From forax at univ-mlv.fr Sat Oct 21 07:27:37 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 21 Oct 2023 09:27:37 +0200 (CEST) Subject: Implicit constructor of the super class of a null restricted value class Message-ID: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> Hello, I had a little more time to re-read the different specs :) In https://bugs.openjdk.org/browse/JDK-8317765, an implicit constructor must be public and the super class is either Object or a super class with an implicit constructor. This means that we can NOT create a null restricted value record because the constructor of Record is protected. I think the constraints on the implicit constructor of the super class should be relaxed. The implicit constructor of the super class does not have to be public. The implicit constructor of a super class just has to be visible from the implicit constructor of the value class like if there was a super() call inside the implicit constructor of the value class. regards, R?mi From forax at univ-mlv.fr Sat Oct 21 08:04:39 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 21 Oct 2023 10:04:39 +0200 (CEST) Subject: Not yet again ! Message-ID: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> Hello, in https://bugs.openjdk.org/browse/JDK-8317766, the atomicity of a null restricted value class is set using a marker interface named LooselyConsistentValue. Last year, we stop to use interfaces IdentityObject and ValueObject to specify value/identity-ness. LooselyConsistentValue exhibits exactly the same bad behaviors as those interfaces. A marker interface can not only be used to specify a property by implementing it, it can also be used as a type, worst it will appear as a type because of type inference. As examples: Long and Double now have LooselyConsistentValue as a common super type and one can creates arrays of LooselyConsistentValue just to mess with the poor brain of everybody else trying to figure out exactly what it means. I understand the relunctance to introduce a new keyword to avoid people to use that keyword because it may be faster at the expanse of the safety of the code. But in reality, it's not a problem. A lot of people never heard about strictfp before it was retired. Being a keyword does not make it automatically popular. A contrario, using a keyword extensively inside the JDK will make it popular. In my opinion, it's more important to ONLY use the keyword non-atomic (or whatever its name) on Long and Double inside the JDK than to use a marker interface instead a keyword. Note: that an annotation is always a better as a "marker interface" than an interface, but I think we should stick to our mantra that an annotation should not change the behavior. regards, R?mi From daniel.smith at oracle.com Sat Oct 21 13:48:31 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Sat, 21 Oct 2023 13:48:31 +0000 Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> Message-ID: On Oct 21, 2023, at 12:27 AM, Remi Forax wrote: In https://bugs.openjdk.org/browse/JDK-8317765, an implicit constructor must be public and the super class is either Object or a super class with an implicit constructor. This means that we can NOT create a null restricted value record because the constructor of Record is protected. I think the constraints on the implicit constructor of the super class should be relaxed. The implicit constructor of the super class does not have to be public. Sure, we could relax the rule. But why? Specifically, when it comes to Record, is there any reason the constructor can't be made public? (My interpretation of the code is that somebody wanted to emphasize that Record is an abstract class by making the constructor protected. But 'abstract' and 'protected' have the same effect here, you don't need them both.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Sat Oct 21 14:03:55 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sat, 21 Oct 2023 16:03:55 +0200 (CEST) Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> > From: "daniel smith" > To: "Remi Forax" > Cc: "valhalla-spec-experts" > Sent: Saturday, October 21, 2023 3:48:31 PM > Subject: Re: Implicit constructor of the super class of a null restricted value > class >> On Oct 21, 2023, at 12:27 AM, Remi Forax wrote: >> In [ https://bugs.openjdk.org/browse/JDK-8317765 | >> https://bugs.openjdk.org/browse/JDK-8317765 ] , >> an implicit constructor must be public and the super class is either Object or a >> super class with an implicit constructor. >> This means that we can NOT create a null restricted value record because the >> constructor of Record is protected. >> I think the constraints on the implicit constructor of the super class should be >> relaxed. The implicit constructor of the super class does not have to be >> public. > Sure, we could relax the rule. But why? > Specifically, when it comes to Record, is there any reason the constructor can't > be made public? > (My interpretation of the code is that somebody wanted to emphasize that Record > is an abstract class by making the constructor protected. But 'abstract' and > 'protected' have the same effect here, you don't need them both.) Record is an example, even if we change the constructor of Record to public, an implicit constructor of a super class does not have to be public, being visible to the value class seems enough. One reason we want to support super classes for value class is to be able to retrofit existing classes, in that case, why not allowing classes that have a superclass with an empty constructor non public to be retrofitted. regards, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Sat Oct 21 15:28:13 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Sat, 21 Oct 2023 11:28:13 -0400 Subject: Not yet again ! In-Reply-To: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> References: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <70a7d643-1a21-ce64-b97c-f7e2a23f9ebc@oracle.com> > Last year, we stop to use interfaces IdentityObject and ValueObject to specify value/identity-ness. > LooselyConsistentValue exhibits exactly the same bad behaviors as those interfaces. I think if you work through the details, you'll find that it is not the *exact* same set of behaviors. Which is the problem with arguments like this: "X is like Y, and Y didn't work -> X won't work" are only superficially satisfying. Could you work through your argument with more details, and with less "we did that before and it failed"?? Because the reasons I recall for pulling back on {Identity,Value}Object don't seem to apply here.? There may be new, different arguments that do apply, but you'll have to make them more directly... From forax at univ-mlv.fr Sat Oct 21 15:46:53 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sat, 21 Oct 2023 17:46:53 +0200 (CEST) Subject: Not yet again ! In-Reply-To: <70a7d643-1a21-ce64-b97c-f7e2a23f9ebc@oracle.com> References: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> <70a7d643-1a21-ce64-b97c-f7e2a23f9ebc@oracle.com> Message-ID: <389515296.31232610.1697903213265.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "Brian Goetz" > To: "Remi Forax" , "valhalla-spec-experts" > Sent: Saturday, October 21, 2023 5:28:13 PM > Subject: Re: Not yet again ! >> Last year, we stop to use interfaces IdentityObject and ValueObject to specify >> value/identity-ness. >> LooselyConsistentValue exhibits exactly the same bad behaviors as those >> interfaces. > > I think if you work through the details, you'll find that it is not the > *exact* same set of behaviors. > > Which is the problem with arguments like this: "X is like Y, and Y > didn't work -> X won't work" are only superficially satisfying. Could > you work through your argument with more details, and with less "we did > that before and it failed"?? Because the reasons I recall for pulling > back on {Identity,Value}Object don't seem to apply here.? There may be > new, different arguments that do apply, but you'll have to make them > more directly... You may find easier to answer to a direct question: Why do you want the tearability of a nullable value type, which is an implementation detail, to be part of the type system ? regards, R?mi From daniel.smith at oracle.com Sat Oct 21 18:58:58 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Sat, 21 Oct 2023 18:58:58 +0000 Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> > On Oct 21, 2023, at 7:03 AM, forax at univ-mlv.fr wrote: > > Record is an example, even if we change the constructor of Record to public, an implicit constructor of a super class does not have to be public, being visible to the value class seems enough. Okay, so four cases: - Existing constructor is public. Replace it with an implicit constructor. - Existing constructor is protected. Replace it with a (public) implicit constructor. No meaningful change in accessibility. - Existing constructor is package-access. Declaring an implicit constructor will allow more subclasses to extend it. Only other mechanism for controlling who can extend the class is 'sealed'; that may be a reasonable workaround, given that all subclasses are in the same package. - Existing constructor is private. Same as package-access, except 'sealed' is even easier, since the 'permits' clause can be inferred. So, yes, there's a meaningful change in the package-access/private case. The trade-off for supporting limited constructor access is that the VM would have to work harder to validate it: as described currently, ImplicitCreation is a boolean flag. If access could be restricted, the access level would have to appear in the ImplicitCreation attribute and be enforced at class loading. Otherwise: abstract class Sup { private implicit Sup(); } value class Sub extends Sup { public implicit Sub(); } Sup s = (new Sub![1])[0]; // oops (Compile Sup with a public constructor first, then recompile with private access.) I don't think these use cases are worth the extra validation cost. 'sealed' seems like a reasonable workaround. From john.r.rose at oracle.com Sat Oct 21 19:22:56 2023 From: john.r.rose at oracle.com (John Rose) Date: Sat, 21 Oct 2023 12:22:56 -0700 Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> Message-ID: If the super were concrete (non-abstract) then changing the implicit constructor to public breaks abstraction, so that would not be something to encourage. I guess that?s one reason we are focusing on abstract supers. For an abstract super, having an implicit constructor allows a lesser abstraction leak. First build a subclass with an implicit constructor and no fields. Then instantiate it implicitly. Perhaps you use reflection on the Class mirror to make an array and then load the first element, uninitialized. There is your super-state, exposed by a hostile party, assuming the subclass was able to initialize enough to instantiate its implicit instance. I just remembered that since the implicit constructor of the sub never actually runs, it never dynamically resolves its reference to the super. That means that if the super marked its implicit constructor as private, there?s no detection of this fact, in the normal course of object construction. Did we think about plugging that hole? I guess so, since it would need the kind of VM load-time check that Dan says below that he wants to avoid. So mark the super-ctor public, and forget about the accessibility check to the super-ctor; it would never fail, so it doesn?t matter that you don?t check it. (Alternative model: Should we actually run that trivial little implicit ctor, once around loading? The silly thing surely shouldn?t fail, but if it does, perhaps because of a super-ctor access problem, then we don?t want the class itself to initialize further.) On 21 Oct 2023, at 11:58, Dan Smith wrote: >> On Oct 21, 2023, at 7:03 AM, forax at univ-mlv.fr wrote: >> >> Record is an example, even if we change the constructor of Record to public, an implicit constructor of a super class does not have to be public, being visible to the value class seems enough. Yes, I?m curious about this too, not just for Record but for third-party classes we don?t control. Dan?s answer is that those third parties would have to edit their supers a little anyway. So why not ask them to mark the implicit constructor public, along the way? Marking it public avows clearly that there are will be ways to obtain the initial super-state, so let?s mark it public. If you can?t mark it public, maybe you should not allow implicit constructors in subs. Here?s the access check that would be required, because the implicit constructor is not actually ever run. > ? > The trade-off for supporting limited constructor access is that the VM would have to work harder to validate it: as described currently, ImplicitCreation is a boolean flag. If access could be restricted, the access level would have to appear in the ImplicitCreation attribute and be enforced at class loading. (If we ever go to a design where supers DO NOT need to be edited to align them with value subs, then we have a different set of things to worry about. I guess that?s unlikely, although it is possible in principle. The things that can go wrong with an unmarked super of a value can be set right, in principle, by a dynamic check on putfield that refuses to store into a value sub. That?s what I mean by ?in principle?.) From brian.goetz at oracle.com Sat Oct 21 23:33:01 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Sat, 21 Oct 2023 19:33:01 -0400 Subject: Not yet again ! In-Reply-To: <389515296.31232610.1697903213265.JavaMail.zimbra@univ-eiffel.fr> References: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> <70a7d643-1a21-ce64-b97c-f7e2a23f9ebc@oracle.com> <389515296.31232610.1697903213265.JavaMail.zimbra@univ-eiffel.fr> Message-ID: > You may find easier to answer to a direct question: Since you're the one complaining, the burden is really on you to explain why it is _not_ a good idea.? But I have an answer anyway: > Why do you want the tearability of a nullable value type, which is an implementation detail, to be part of the type system ? > Because it is not an implementation detail.? It is a semantic property of the class that describes how instances may react under race.?? Whether or not a marker interface is the best way to do this or not, this is 100% fair game for representing in the type system. Got any other arguments? From forax at univ-mlv.fr Sun Oct 22 00:50:30 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sun, 22 Oct 2023 02:50:30 +0200 (CEST) Subject: Not yet again ! In-Reply-To: References: <536960013.31030747.1697875479862.JavaMail.zimbra@univ-eiffel.fr> <70a7d643-1a21-ce64-b97c-f7e2a23f9ebc@oracle.com> <389515296.31232610.1697903213265.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <1452992792.31321512.1697935830218.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "Brian Goetz" > To: "Remi Forax" > Cc: "valhalla-spec-experts" > Sent: Sunday, October 22, 2023 1:33:01 AM > Subject: Re: Not yet again ! >> You may find easier to answer to a direct question: > > Since you're the one complaining, the burden is really on you to explain > why it is _not_ a good idea.? But I have an answer anyway: > >> Why do you want the tearability of a nullable value type, which is an >> implementation detail, to be part of the type system ? >> > > Because it is not an implementation detail.? It is a semantic property > of the class that describes how instances may react under race. > Whether or not a marker interface is the best way to do this or not, > this is 100% fair game for representing in the type system. > > Got any other arguments? No, same argument, the interface by being part of the type system should make the property "being tearable" transitive but this is not the case. The marker interface make the instance typed by the interface not-tearable but the instance of a class that implements the interface tearable. A class that contains a field typed by the interface is not tearable. An array of the interface has its element not tearable. A field/array element typed by an interface Foo that extends that interface is not tearable, too. So a field/array element typed by the interface and all its sub-interfaces/sub-abstract-classes are not tearable but all the sub-concrete-value-classes are tearable. For me, this is an abuse of the notion of interface/subtyping and I really hope I will not have to explain that to my students ... regards, R?mi From forax at univ-mlv.fr Mon Oct 23 16:33:48 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 23 Oct 2023 18:33:48 +0200 (CEST) Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> Message-ID: <628427960.32907452.1698078828278.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "daniel smith" > To: "Remi Forax" > Cc: "valhalla-spec-experts" > Sent: Saturday, October 21, 2023 8:58:58 PM > Subject: Re: Implicit constructor of the super class of a null restricted value class Hello Daniel, I was agreeing with you until this morning shower ... >> On Oct 21, 2023, at 7:03 AM, forax at univ-mlv.fr wrote: >> >> Record is an example, even if we change the constructor of Record to public, an >> implicit constructor of a super class does not have to be public, being visible >> to the value class seems enough. > > Okay, so four cases: > > - Existing constructor is public. Replace it with an implicit constructor. > > - Existing constructor is protected. Replace it with a (public) implicit > constructor. No meaningful change in accessibility. It depends if the class is abstract or not. Do we allow a value class to extends a non-abstract class, like Timestamp inherits from Date ? > > - Existing constructor is package-access. Declaring an implicit constructor will > allow more subclasses to extend it. Only other mechanism for controlling who > can extend the class is 'sealed'; that may be a reasonable workaround, given > that all subclasses are in the same package. > > - Existing constructor is private. Same as package-access, except 'sealed' is > even easier, since the 'permits' clause can be inferred. > > So, yes, there's a meaningful change in the package-access/private case. You have forgotten that "sealed" requires that the permittted subclasses have a stable name, for example, you can not use sealed if one of the permitted subclass is local to a method. Sealed is not a replacement for the constructor accessibility. > > The trade-off for supporting limited constructor access is that the VM would > have to work harder to validate it: as described currently, ImplicitCreation is > a boolean flag. If access could be restricted, the access level would have to > appear in the ImplicitCreation attribute and be enforced at class loading. yes, the attribute ImplicitCreation should to be extended to ImplicitCreation_attribute { u2 attribute_name_index; u4 attribute_length; u2 access_flags; // <-- add an access flag here } > Otherwise: > > abstract class Sup { > private implicit Sup(); > } > > value class Sub extends Sup { > public implicit Sub(); > } > > Sup s = (new Sub![1])[0]; // oops > > (Compile Sup with a public constructor first, then recompile with private > access.) > regards, R?mi From daniel.smith at oracle.com Mon Oct 23 18:15:41 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 23 Oct 2023 18:15:41 +0000 Subject: Implicit constructor of the super class of a null restricted value class In-Reply-To: <628427960.32907452.1698078828278.JavaMail.zimbra@univ-eiffel.fr> References: <1997401020.31002320.1697873257667.JavaMail.zimbra@univ-eiffel.fr> <1054978332.31213229.1697897035664.JavaMail.zimbra@univ-eiffel.fr> <7076E6D9-C8EF-4AF6-A38D-786822FAD297@oracle.com> <628427960.32907452.1698078828278.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <6656FD27-A984-43E7-B5E2-82C398888A1E@oracle.com> On Oct 23, 2023, at 9:33 AM, forax at univ-mlv.fr wrote: - Existing constructor is protected. Replace it with a (public) implicit constructor. No meaningful change in accessibility. It depends if the class is abstract or not. Do we allow a value class to extends a non-abstract class, like Timestamp inherits from Date ? No, superclasses of value classes must be abstract classes (or Object). This is because concrete classes are always either 'identity' or 'value' (or Object), and concrete 'value' classes must be final. We can revisit some of these assumptions, but I don't think there's a strong motivation for the added complexity. (In effect, we'd be talking about taking the weirdness of Object, a non-identity class with (direct) identity instances, and promoting it to a full-scale language feature.) - Existing constructor is package-access. Declaring an implicit constructor will allow more subclasses to extend it. Only other mechanism for controlling who can extend the class is 'sealed'; that may be a reasonable workaround, given that all subclasses are in the same package. - Existing constructor is private. Same as package-access, except 'sealed' is even easier, since the 'permits' clause can be inferred. So, yes, there's a meaningful change in the package-access/private case. You have forgotten that "sealed" requires that the permittted subclasses have a stable name, for example, you can not use sealed if one of the permitted subclass is local to a method. Sealed is not a replacement for the constructor accessibility. I mean, sure. Now we're in extreme corner case territory. But yes, you can construct examples in which 'sealed' is a somewhat inconvenient workaround. The trade-off for supporting limited constructor access is that the VM would have to work harder to validate it: as described currently, ImplicitCreation is a boolean flag. If access could be restricted, the access level would have to appear in the ImplicitCreation attribute and be enforced at class loading. yes, the attribute ImplicitCreation should to be extended to ImplicitCreation_attribute { u2 attribute_name_index; u4 attribute_length; u2 access_flags; // <-- add an access flag here } "Is capable of being extended to": sure, absolutely, we could do that. "Should be extended to": as I said, I don't think these use cases are worth it. -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Oct 30 09:25:18 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 30 Oct 2023 10:25:18 +0100 (CET) Subject: JVM implementation of null-restricted value class types for cast and array Message-ID: <212190472.38983672.1698657918944.JavaMail.zimbra@univ-eiffel.fr> Hello, in https://bugs.openjdk.org/browse/JDK-8317766, cast and array creation are specified using the usual opcodes checkcast and anewarray but with the constant pool constant is a condy. While I like the fact that those opcodes directly use a condy unlike in the parametrized VM proposal where there are intermediary constant pool constants, I think this is too early to introduce suck non backward compatible design. Just to be clear, the design is fine because obviously class file are versioned but I do not see the point of introducing such radical change now given that we will need something like that for the parametrized VM anyway. So I would prefer to introduce this kind of constant pool description all at once instead of saying, it currently only work with CheckedType and we will extend this design later. With my ASM hat, given that we can use invokedynamic to represent checkcast and anewarray in a fully backward compatible way (in term of produced bytecode), I would prefer null-restricted value types opcodes to use indy until we are sure of how to represent specialized opcodes as part of the design of the parametrized VM. For bytecode libraries, I would mean only one API change instead of two. regards, R?mi From daniel.smith at oracle.com Mon Oct 30 17:29:42 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 30 Oct 2023 17:29:42 +0000 Subject: JVM implementation of null-restricted value class types for cast and array In-Reply-To: <212190472.38983672.1698657918944.JavaMail.zimbra@univ-eiffel.fr> References: <212190472.38983672.1698657918944.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <7A929A29-663A-4EDD-B927-B6AF51463251@oracle.com> > On Oct 30, 2023, at 2:25 AM, Remi Forax wrote: > > Hello, > in https://bugs.openjdk.org/browse/JDK-8317766, > cast and array creation are specified using the usual opcodes checkcast and anewarray but with the constant pool constant is a condy. > > While I like the fact that those opcodes directly use a condy unlike in the parametrized VM proposal where there are intermediary constant pool constants, > I think this is too early to introduce suck non backward compatible design. Possibly you're misunderstanding here: the idea would be for checkcast and anewarray to support *both* a CONSTANT_Class and a CONSTANT_Dynamic (of the appropriate shape). Fully backward compatible. > given that we will need something like that for the parametrized VM anyway. So I would prefer to introduce this kind of constant pool description all at once instead of saying, it currently only work with CheckedType and we will extend this design later. CheckedType is the mechanism that we envision for expressing, e.g., a cast to a species type. Agree we should not introduce one thing now, something different later?avoiding that is one of our goals. From daniel.smith at oracle.com Mon Oct 30 17:53:57 2023 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 30 Oct 2023 17:53:57 +0000 Subject: JVM implementation of null-restricted value class types for cast and array In-Reply-To: <7A929A29-663A-4EDD-B927-B6AF51463251@oracle.com> References: <212190472.38983672.1698657918944.JavaMail.zimbra@univ-eiffel.fr> <7A929A29-663A-4EDD-B927-B6AF51463251@oracle.com> Message-ID: > On Oct 30, 2023, at 10:29 AM, Dan Smith wrote: > >> On Oct 30, 2023, at 2:25 AM, Remi Forax wrote: >> >> Hello, >> in https://bugs.openjdk.org/browse/JDK-8317766, >> cast and array creation are specified using the usual opcodes checkcast and anewarray but with the constant pool constant is a condy. >> >> While I like the fact that those opcodes directly use a condy unlike in the parametrized VM proposal where there are intermediary constant pool constants, >> I think this is too early to introduce suck non backward compatible design. > > Possibly you're misunderstanding here: the idea would be for checkcast and anewarray to support *both* a CONSTANT_Class and a CONSTANT_Dynamic (of the appropriate shape). Fully backward compatible. (I've updated the text to make this a little clearer.) From forax at univ-mlv.fr Mon Oct 30 18:37:57 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 30 Oct 2023 19:37:57 +0100 (CET) Subject: JVM implementation of null-restricted value class types for cast and array In-Reply-To: <7A929A29-663A-4EDD-B927-B6AF51463251@oracle.com> References: <212190472.38983672.1698657918944.JavaMail.zimbra@univ-eiffel.fr> <7A929A29-663A-4EDD-B927-B6AF51463251@oracle.com> Message-ID: <972303798.39446876.1698691077121.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "daniel smith" > To: "Remi Forax" > Cc: "valhalla-spec-experts" > Sent: Monday, October 30, 2023 6:29:42 PM > Subject: Re: JVM implementation of null-restricted value class types for cast and array >> On Oct 30, 2023, at 2:25 AM, Remi Forax wrote: >> >> Hello, >> in https://bugs.openjdk.org/browse/JDK-8317766, >> cast and array creation are specified using the usual opcodes checkcast and >> anewarray but with the constant pool constant is a condy. >> >> While I like the fact that those opcodes directly use a condy unlike in the >> parametrized VM proposal where there are intermediary constant pool constants, >> I think this is too early to introduce suck non backward compatible design. > > Possibly you're misunderstanding here: the idea would be for checkcast and > anewarray to support *both* a CONSTANT_Class and a CONSTANT_Dynamic (of the > appropriate shape). Fully backward compatible. It's backward compatible in term of data structure not in term of semantics. All libraries that are reading/writing bycodes strongly type the method that read/write opcodes. Enhancing an opcode to allow another constant pool constant is something that was already done in 8 when invokestatic/invokespecial were enhanced to support calling method of interfaces. This required all bytecode libraries that read/write bytecode to have their API updated. Here the change is worst because CheckedType is a full dynamic type so its value is fully opaque from the POV of a bytecode libraries. For example, libraries like ASM usually provide ways to repackage/shade classes, for that the class name need to be available at bytecode level, here, because CheckedType is opaque, we can not provide such feature anymore. In term fo impact, it means that all tools that are manipulating the bytecode without running the condy bootstrap methods are now second class citizens. > >> given that we will need something like that for the parametrized VM anyway. So I >> would prefer to introduce this kind of constant pool description all at once >> instead of saying, it currently only work with CheckedType and we will extend >> this design later. > > CheckedType is the mechanism that we envision for expressing, e.g., a cast to a > species type. Agree we should not introduce one thing now, something different > later?avoiding that is one of our goals. My gut feeling is that for all languages that are using erasure Java, Kotlin or Scala, allowing a cast to a species means that now casts have teeth, you are forcing everybody that want to compile to the new java version to re-audit all the code because there will be new CCE at runtime. I do no think you can do that. It's a migration which is equivalent to the migration from Python 2 to Python 3. I've no proof of that but we now at least in the JDK that there is a lot of code that will not work if species are fully reified. You can take a look to the methods called by List.copyOf() to have an idea of the issues. R?mi