From daniel.smith at oracle.com Wed Jan 10 16:05:25 2024 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 10 Jan 2024 16:05:25 +0000 Subject: EG meeting *canceled* 2024-01-10 Message-ID: <575D2C16-A6AD-451F-92F8-62FAF059B340@oracle.com> Not much to talk about today, so let's cancel the meeting. From forax at univ-mlv.fr Mon Jan 22 07:54:00 2024 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 22 Jan 2024 08:54:00 +0100 (CET) Subject: Simplifying 'value' and 'identity' In-Reply-To: References: Message-ID: <975429644.108373598.1705910040982.JavaMail.zimbra@univ-eiffel.fr> [resurecting that thread] ----- Original Message ----- > From: "daniel smith" > To: "valhalla-spec-experts" > Sent: Friday, December 15, 2023 9:22:05 PM > Subject: Simplifying 'value' and 'identity' > When we last checked in on it, our story for superclasses/interfaces of value > classes was as follows: > > In general, classes/interfaces are "unconstrained" and support subclassing by > both value and identity classes. The 'value' and 'identity' keywords act as a > form of "sealing", restricting subclassing to only classes of the given type. > Any class/interface that extends classes/interfaces with both keywords is in > error. > > As a special case, concrete classes and some abstract classes with certain > properties are implicitly 'identity' classes. > > This approach has a three-state categorization scheme expressed with two > keywords ('value', 'identity', and "neither"). This corresponds to two JVM > flags (ACC_IDENTITY and ACC_VALUE). > > I think it holds together fairly well, but it's also somewhat difficult to > communicate, and not as intuitive as we might like. I find myself periodically > reminding people (and sometimes myself): "don't forget that there are both > value abstract classes and unconstrained abstract classes" or "unconstrained > classes can't have mutable fields, those are only for identity classes". > > As we've revised the construction mechanism, we've found ourselves searching for > an explicit keyword for the third, unconstrained state: "value-capable" or > "universal" or something. None of these keywords are very compelling, and I > don't relish the job of trying to get people to adopt these fairly obscure, > infrequently used terms. > > ----- > > If we're willing to give up some fairly marginal fine-grained controls, this > story can be simplified significantly. > > Concrete classes: nothing new?a concrete class is an identity class by default, > but may opt out of identity with the 'value' keyword. Concrete value classes > are implicitly final and subject to a handful of extra constraints. > > Abstract classes: an abstract class is also an identity class by default, but > may use the 'value' modifier to indicate that it doesn't require identity. This > not the same thing as saying its subclasses *must not* make use of identity, > it's just an assertion about the abstract class itself (and its supers). Both > value classes and identity classes may extend an abstract value class. These > abstract classes are subject to the same constraints as concrete value classes. > > Interfaces: all interfaces can be implemented by value classes and identity > classes. Full stop. If you have a particular need to limit the kinds of > implementing classes, you can use a sealed interface and provide the > implementation yourself, or you can make it an informal part of the contract. > But, like access control, synchronization, and other fine-grained, > implementation-oriented features, identity is not something interfaces can > explicitly control. > > This approach has a two-state categorization scheme for classes expressed with > one keyword ('value' and identity). This corresponds to one JVM flag > (ACC_IDENTITY, for {reasons}). Interfaces have only one state. > > What do we lose? > - You can't force an abstract class/interface to be implemented by *only* value > classes > - You can't force an interface to be implemented by *only* identity classes > - You can't declare an abstract class or interface whose type will refuse to > support the 'synchronized' keyword > > I don't think any of these are enough to justify the extra costs of 3 states or > an 'identity' keyword. (For awhile, I was considering keeping around the > 'identity' keyword, just for the purpose of interfaces. But, eh, nobody is > going to use it.) Removing the 'identity' keyword is a good things, but i'm not so sure about not allowing users to declare a value interface, because i think that sealing the interface does not convey the right semantics. The problem is that in the future, a VM may want to flatten a sealed interface (with all its subtypes being value type), currently this is possible on stack but not on heap because '!' can not be used on anything but a value class. I think we should allow an interface to be prefixed by "value" so - the compiler adds the interface in the Preload attribute - '!' is allowed on that interface (in that case all subtypes must be either a value interface or a value class with an implicit constructor) regards, R?mi From dan.heidinga at oracle.com Mon Jan 22 15:48:56 2024 From: dan.heidinga at oracle.com (Dan Heidinga) Date: Mon, 22 Jan 2024 15:48:56 +0000 Subject: Simplifying 'value' and 'identity' In-Reply-To: <975429644.108373598.1705910040982.JavaMail.zimbra@univ-eiffel.fr> References: <975429644.108373598.1705910040982.JavaMail.zimbra@univ-eiffel.fr> Message-ID: Snip > > Interfaces: all interfaces can be implemented by value classes and identity > classes. Full stop. If you have a particular need to limit the kinds of > implementing classes, you can use a sealed interface and provide the > implementation yourself, or you can make it an informal part of the contract. > But, like access control, synchronization, and other fine-grained, > implementation-oriented features, identity is not something interfaces can > explicitly control. > > This approach has a two-state categorization scheme for classes expressed with > one keyword ('value' and identity). This corresponds to one JVM flag > (ACC_IDENTITY, for {reasons}). Interfaces have only one state. > > What do we lose? > - You can't force an abstract class/interface to be implemented by *only* value > classes > - You can't force an interface to be implemented by *only* identity classes > - You can't declare an abstract class or interface whose type will refuse to > support the 'synchronized' keyword > > I don't think any of these are enough to justify the extra costs of 3 states or > an 'identity' keyword. (For awhile, I was considering keeping around the > 'identity' keyword, just for the purpose of interfaces. But, eh, nobody is > going to use it.) Removing the 'identity' keyword is a good things, but i'm not so sure about not allowing users to declare a value interface, because i think that sealing the interface does not convey the right semantics. The problem is that in the future, a VM may want to flatten a sealed interface (with all its subtypes being value type), currently this is possible on stack but not on heap because '!' can not be used on anything but a value class. I?m not clear on how this would work at the VM level. To flatten on heap we need a single known layout that we can embed in the containing object / array. If we added value interfaces back into the language, we?d still be unable to know the field layout to embed in the containing object. An interface that is sealed to a single value class may be a good candidate for layout heroics (and in some distance future, maybe an interface that is sealed to a small set of layouts could be flattened), but in both cases, the key determinate is that the interface is sealed to a set of value classes. Whether the interface is marked as value or not is irrelevant. I think we should allow an interface to be prefixed by "value" so - the compiler adds the interface in the Preload attribute - '!' is allowed on that interface (in that case all subtypes must be either a value interface or a value class with an implicit constructor) Guidance on when to add a class to the preload attribute is something that still needs to be worked out. A good first approximation is anywhere we had put a ?Q? descriptor is a good candidate but there may be others (like the sealed interface case) that are interesting. --Dan regards, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Jan 22 18:34:03 2024 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 22 Jan 2024 19:34:03 +0100 (CET) Subject: Simplifying 'value' and 'identity' In-Reply-To: References: <975429644.108373598.1705910040982.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <1165691929.109121220.1705948443030.JavaMail.zimbra@univ-eiffel.fr> > From: "Dan Heidinga" > To: "Remi Forax" , "daniel smith" > Cc: "valhalla-spec-experts" > Sent: Monday, January 22, 2024 4:48:56 PM > Subject: Re: Simplifying 'value' and 'identity' Hello, > Snip > > Interfaces: all interfaces can be implemented by value classes and identity > > classes. Full stop. If you have a particular need to limit the kinds of > > implementing classes, you can use a sealed interface and provide the > > implementation yourself, or you can make it an informal part of the contract. > > But, like access control, synchronization, and other fine-grained, > > implementation-oriented features, identity is not something interfaces can > > explicitly control. > > This approach has a two-state categorization scheme for classes expressed with > > one keyword ('value' and identity). This corresponds to one JVM flag > > (ACC_IDENTITY, for {reasons}). Interfaces have only one state. > > What do we lose? > > - You can't force an abstract class/interface to be implemented by *only* value > > classes > > - You can't force an interface to be implemented by *only* identity classes > > - You can't declare an abstract class or interface whose type will refuse to > > support the 'synchronized' keyword > > I don't think any of these are enough to justify the extra costs of 3 states or > > an 'identity' keyword. (For awhile, I was considering keeping around the > > 'identity' keyword, just for the purpose of interfaces. But, eh, nobody is > > going to use it.) > Removing the 'identity' keyword is a good things, but i'm not so sure about not > allowing users to declare a value interface, because i think that sealing the > interface does not convey the right semantics. > The problem is that in the future, a VM may want to flatten a sealed interface > (with all its subtypes being value type), currently this is possible on stack > but not on heap because '!' can not be used on anything but a value class. > I?m not clear on how this would work at the VM level. To flatten on heap we need > a single known layout that we can embed in the containing object / array. If we > added value interfaces back into the language, we?d still be unable to know the > field layout to embed in the containing object. If the interface is preloaded, the VM has enough information to compute the tagged union. But storing on heap is IMO harder than reserving registers on stack + discriminator (the real class | null). > An interface that is sealed to a single value class may be a good candidate for > layout heroics (and in some distance future, maybe an interface that is sealed > to a small set of layouts could be flattened), but in both cases, the key > determinate is that the interface is sealed to a set of value classes. Whether > the interface is marked as value or not is irrelevant. Currently, the VM will no try to flatten something which is not explicitly marked by a user as 'value'. I think it should be the same for sealed interfaces, the user should ask by tagging it as 'value' for the VM to consider it as a value interface. It will make the performance more predictable from the user POV. > I think we should allow an interface to be prefixed by "value" so > - the compiler adds the interface in the Preload attribute > - '!' is allowed on that interface (in that case all subtypes must be either a > value interface or a value class with an implicit constructor) > Guidance on when to add a class to the preload attribute is something that still > needs to be worked out. A good first approximation is anywhere we had put a ?Q? > descriptor is a good candidate but there may be others (like the sealed > interface case) that are interesting. Being in the Preload attribute or not is something a user should be able to predict IMO and not something magic that the compiler may or may not do. > --Dan regards, R?mi > regards, > R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Mon Jan 22 18:54:29 2024 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 22 Jan 2024 13:54:29 -0500 Subject: Simplifying 'value' and 'identity' In-Reply-To: <1165691929.109121220.1705948443030.JavaMail.zimbra@univ-eiffel.fr> References: <975429644.108373598.1705910040982.JavaMail.zimbra@univ-eiffel.fr> <1165691929.109121220.1705948443030.JavaMail.zimbra@univ-eiffel.fr> Message-ID: I think we need to separate goals (optimization) from mechanism (syntax). The optimizations you want to support seem to be exposing more flattening possibilities when an interface is sealed to a union of values, and especially one such class.? Which is a fine goal. But if an interface is sealed to a union of values, the compiler already knows that, and can issue a preload request anyway. If it turns out that later a `value` modifier has benefit _to the user_, we can consider adding it later.? But right now, this seems like extrapolating syntax from no implementation examples. On 1/22/2024 1:34 PM, forax at univ-mlv.fr wrote: > > > ------------------------------------------------------------------------ > > *From: *"Dan Heidinga" > *To: *"Remi Forax" , "daniel smith" > > *Cc: *"valhalla-spec-experts" > *Sent: *Monday, January 22, 2024 4:48:56 PM > *Subject: *Re: Simplifying 'value' and 'identity' > > > Hello, > > > Snip > > > > > > Interfaces: all interfaces can be implemented by value classes > and identity > > classes. Full stop. If you have a particular need to limit the > kinds of > > implementing classes, you can use a sealed interface and provide the > > implementation yourself, or you can make it an informal part of > the contract. > > But, like access control, synchronization, and other fine-grained, > > implementation-oriented features, identity is not something > interfaces can > > explicitly control. > > > > This approach has a two-state categorization scheme for classes > expressed with > > one keyword ('value' and identity). This corresponds to one JVM flag > > (ACC_IDENTITY, for {reasons}). Interfaces have only one state. > > > > What do we lose? > > - You can't force an abstract class/interface to be implemented > by *only* value > > classes > > - You can't force an interface to be implemented by *only* > identity classes > > - You can't declare an abstract class or interface whose type > will refuse to > > support the 'synchronized' keyword > > > > I don't think any of these are enough to justify the extra costs > of 3 states or > > an 'identity' keyword. (For awhile, I was considering keeping > around the > > 'identity' keyword, just for the purpose of interfaces. But, eh, > nobody is > > going to use it.) > > Removing the 'identity' keyword is a good things, but i'm not so > sure about not allowing users to declare a value interface, > because i think that sealing the interface does not convey the > right semantics. > > The problem is that in the future, a VM may want to flatten a > sealed interface (with all its subtypes being value type), > currently this is possible on stack but not on heap because '!' > can not be used on anything but a value class. > > I?m not clear on how this would work at the VM level.? To flatten > on heap we need a single known layout that we can embed in the > containing object / array.? If we added value interfaces back into > the language, we?d still be unable to know the field layout to > embed in the containing object. > > > If the interface is preloaded, the VM has enough information to > compute the tagged union. > But storing on heap is IMO harder than reserving registers on stack + > discriminator (the real class | null). > > An interface that is sealed to a single value class may be a good > candidate for layout heroics (and in some distance future, maybe > an interface that is sealed to a small set of layouts could be > flattened), but in both cases, the key determinate is that the > interface is sealed to a set of value classes.? Whether the > interface is marked as value or not is irrelevant. > > > Currently, the VM will no try to flatten something which is not > explicitly marked by a user as 'value'. > I think it should be the same for sealed interfaces, the user should > ask by tagging it as 'value' for the VM to consider it as a value > interface. > It will make the performance more predictable from the user POV. > > > > I think we should allow an interface to be prefixed by "value" so > - the compiler adds the interface in the Preload attribute > - '!' is allowed on that interface (in that case all subtypes must > be either a value interface or a value class with an implicit > constructor) > > Guidance on when to add a class to the preload attribute is > something that still needs to be worked out. A good first > approximation is anywhere we had put a ?Q? descriptor is a good > candidate but there may be others (like the sealed interface case) > that are interesting. > > > Being in the Preload attribute or not is something a user should be > able to predict IMO and not something magic that the compiler may or > may not do. > > --Dan > > > regards, > R?mi > > > > regards, > R?mi > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Wed Jan 24 01:11:18 2024 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 24 Jan 2024 01:11:18 +0000 Subject: JVMS changes for JEP 401 Message-ID: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> I've posted a revised spec change document for JEP 401, Value Classes and Objects, here: https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html Not covered by JVMS is anything to do with our internal-only null restriction annotations, or (naturally) anything about scalarization/flattening. Of course those things represent a large chunk of the code changes that we anticipate delivering with JEP 401. We've already identified a few issues from internal reviews, which I'll address in a followup iteration: - 5.3.5 needs to allow JVM implementations to "speculatively" load classes mentioned by Preload, enabling early field layout computations ("speculative" because the attempt may fail due to circularities, but succeed later) - The categorization of attributes in 4.7 is not a great fit for Preload; maybe we need to redefine the categories a bit - The definition of the Preload attribute could use more (perhaps non-normative) description of how it works, even though this is mostly below the level of the spec; 5.4 could also help clarify this - The reference to the "start of object construction" in the table about ACC_STRICT is vague; maybe we can do better - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow - 2.4 should say more about "sameness" as it relates to "identity" From liangchenblue at gmail.com Wed Jan 24 02:12:30 2024 From: liangchenblue at gmail.com (-) Date: Tue, 23 Jan 2024 20:12:30 -0600 Subject: JVMS changes for JEP 401 In-Reply-To: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> Message-ID: Hi Dan, Thanks for sharing this document! It looks great! There's a typo in section 2.4, where the definition of "element type" for an array type is accidentally removed. The reference to the "start of object construction" can probably be changed to "before the super-call," taken from John's "Constructive Classes" essay. [1] The 4.9.2 rule is correct; perhaps we can be more explicit, that such a putfield can only exist in an that calls a direct superclass's , and the putfield must exist before such a super-call. [1] https://cr.openjdk.org/~jrose/jls/constructive-classes.html Chen On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: > I've posted a revised spec change document for JEP 401, Value Classes and > Objects, here: > > > https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html > > Not covered by JVMS is anything to do with our internal-only null > restriction annotations, or (naturally) anything about > scalarization/flattening. Of course those things represent a large chunk of > the code changes that we anticipate delivering with JEP 401. > > We've already identified a few issues from internal reviews, which I'll > address in a followup iteration: > > - 5.3.5 needs to allow JVM implementations to "speculatively" load classes > mentioned by Preload, enabling early field layout computations > ("speculative" because the attempt may fail due to circularities, but > succeed later) > > - The categorization of attributes in 4.7 is not a great fit for Preload; > maybe we need to redefine the categories a bit > > - The definition of the Preload attribute could use more (perhaps > non-normative) description of how it works, even though this is mostly > below the level of the spec; 5.4 could also help clarify this > > - The reference to the "start of object construction" in the table about > ACC_STRICT is vague; maybe we can do better > > - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased > somehow > > - 2.4 should say more about "sameness" as it relates to "identity" -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Wed Jan 24 02:33:53 2024 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 24 Jan 2024 02:33:53 +0000 Subject: EG meeting, 2024-01-24 Message-ID: <97FE5725-5809-4E3A-990E-23476EE36C81@oracle.com> We'll hold an EG meeting Wednesday, 5pm UTC (9am PST, 12pm EST). Topics: - Revised JVMS changes for JEP 401, which I've shared - Followup discussion in the "Simplifying 'value' and 'identity'" thread, exploring whether there would be a use for 'value' interfaces in the future From ccherlin at gmail.com Mon Jan 29 15:30:01 2024 From: ccherlin at gmail.com (Clement Cherlin) Date: Mon, 29 Jan 2024 09:30:01 -0600 Subject: JVMS changes for JEP 401 In-Reply-To: References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> Message-ID: > On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: >> >> I've posted a revised spec change document for JEP 401, Value Classes and Objects, here: >> >> https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html [snip] >> - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow >> >> - 2.4 should say more about "sameness" as it relates to "identity" On Tue, Jan 23, 2024 at 8:15?PM - wrote: > > Hi Dan, > Thanks for sharing this document! It looks great! > There's a typo in section 2.4, where the definition of "element type" for an array type is accidentally removed. > > The reference to the "start of object construction" can probably be changed to "before the super-call," taken from John's "Constructive Classes" essay. [1] > The 4.9.2 rule is correct; Unless I'm mistaken, the rule in 4.9.2 is not correct. >From the proposal: >> An instance field of this declared in the current class with its ACC_STRICT flag set may be assigned by a putfield instruction occurring in an instance initialization method only if another instance initialization method has not yet been called. As I understand the current design intent, a constructor that calls 'this' is forbidden from assigning to a strict field, because that will lead to a duplicate assignment in a constructor that calls 'super'. This language appears to say the opposite. It seems to state that only the first constructor of the current class can assign the class's strict instance fields. If that is the case, then further constructors (including the one that calls 'super') are forbidden from assigning to strict instance fields. > perhaps we can be more explicit, that such a putfield can only exist in an that calls a direct superclass's , and the putfield must exist before such a super-call. I believe those are the correct requirements. > [1] https://cr.openjdk.org/~jrose/jls/constructive-classes.html Cheers, Clement Cherlin From forax at univ-mlv.fr Mon Jan 29 17:06:14 2024 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 29 Jan 2024 18:06:14 +0100 (CET) Subject: JVMS changes for JEP 401 In-Reply-To: References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> Message-ID: <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "Clement Cherlin" > To: "Valhalla Expert Group Observers" > Cc: "daniel smith" , "valhalla-spec-experts" > Sent: Monday, January 29, 2024 4:30:01 PM > Subject: Re: JVMS changes for JEP 401 >> On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: >>> >>> I've posted a revised spec change document for JEP 401, Value Classes and >>> Objects, here: >>> >>> https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html > > [snip] > >>> - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow >>> >>> - 2.4 should say more about "sameness" as it relates to "identity" > > On Tue, Jan 23, 2024 at 8:15?PM - wrote: >> >> Hi Dan, >> Thanks for sharing this document! It looks great! >> There's a typo in section 2.4, where the definition of "element type" for an >> array type is accidentally removed. >> >> The reference to the "start of object construction" can probably be changed to >> "before the super-call," taken from John's "Constructive Classes" essay. [1] >> The 4.9.2 rule is correct; > > Unless I'm mistaken, the rule in 4.9.2 is not correct. > > From the proposal: >>> An instance field of this declared in the current class with its ACC_STRICT flag >>> set may be assigned by a putfield instruction occurring in an instance >>> initialization method only if another instance initialization method has not >>> yet been called. > > As I understand the current design intent, a constructor that calls > 'this' is forbidden from assigning to a strict field, because that > will lead to a duplicate assignment in a constructor that calls > 'super'. > > This language appears to say the opposite. It seems to state that only > the first constructor of the current class can assign the class's > strict instance fields. If that is the case, then further constructors > (including the one that calls 'super') are forbidden from assigning to > strict instance fields. Hello, the problem is not duplicate assignment, as you said that part of the spec allows that, the problem is assignment of final fields after a call to super() or this() because when the assignment occurs, 'this' may have already leaked to another context. For example, currently you can write class B extends A { final int x; B() { super(); // just after the call to super() (or this()), the parameter this can be used even if it is not fully initialized System.out.println(toString()); // here calls to this.toString() ooopsy ! x = 3; } } With _strict_ final fields, they must be inialized *before* the call to super() / this(), so before a user is allowed to use 'this' as a parameter class B extends A { _strict_ final int x; B() { x = 3; // okay ! super(); System.out.println(toString()); // no problem 'this' is fully initialized at that point x = 3; // not legal anymore } } Note: we need this feature for value types and we think it's also great to have it for identity class because if all final fields are strict, there is no way to have an unsafe initialization. This is a long standing problem when you have multiple threads that access to the same instance. For a thread-safe class, before this change the idea was to not leak 'this' and now the idea is that if you leak 'this' it is innocuous because all strict final fields have already been initialized. > >> perhaps we can be more explicit, that such a putfield can only exist in an >> that calls a direct superclass's , and the putfield must exist >> before such a super-call. > > I believe those are the correct requirements. > >> [1] https://cr.openjdk.org/~jrose/jls/constructive-classes.html > > Cheers, > Clement Cherlin regards, R?mi From forax at univ-mlv.fr Mon Jan 29 17:06:14 2024 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 29 Jan 2024 18:06:14 +0100 (CET) Subject: JVMS changes for JEP 401 In-Reply-To: References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> Message-ID: <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "Clement Cherlin" > To: "Valhalla Expert Group Observers" > Cc: "daniel smith" , "valhalla-spec-experts" > Sent: Monday, January 29, 2024 4:30:01 PM > Subject: Re: JVMS changes for JEP 401 >> On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: >>> >>> I've posted a revised spec change document for JEP 401, Value Classes and >>> Objects, here: >>> >>> https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html > > [snip] > >>> - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow >>> >>> - 2.4 should say more about "sameness" as it relates to "identity" > > On Tue, Jan 23, 2024 at 8:15?PM - wrote: >> >> Hi Dan, >> Thanks for sharing this document! It looks great! >> There's a typo in section 2.4, where the definition of "element type" for an >> array type is accidentally removed. >> >> The reference to the "start of object construction" can probably be changed to >> "before the super-call," taken from John's "Constructive Classes" essay. [1] >> The 4.9.2 rule is correct; > > Unless I'm mistaken, the rule in 4.9.2 is not correct. > > From the proposal: >>> An instance field of this declared in the current class with its ACC_STRICT flag >>> set may be assigned by a putfield instruction occurring in an instance >>> initialization method only if another instance initialization method has not >>> yet been called. > > As I understand the current design intent, a constructor that calls > 'this' is forbidden from assigning to a strict field, because that > will lead to a duplicate assignment in a constructor that calls > 'super'. > > This language appears to say the opposite. It seems to state that only > the first constructor of the current class can assign the class's > strict instance fields. If that is the case, then further constructors > (including the one that calls 'super') are forbidden from assigning to > strict instance fields. Hello, the problem is not duplicate assignment, as you said that part of the spec allows that, the problem is assignment of final fields after a call to super() or this() because when the assignment occurs, 'this' may have already leaked to another context. For example, currently you can write class B extends A { final int x; B() { super(); // just after the call to super() (or this()), the parameter this can be used even if it is not fully initialized System.out.println(toString()); // here calls to this.toString() ooopsy ! x = 3; } } With _strict_ final fields, they must be inialized *before* the call to super() / this(), so before a user is allowed to use 'this' as a parameter class B extends A { _strict_ final int x; B() { x = 3; // okay ! super(); System.out.println(toString()); // no problem 'this' is fully initialized at that point x = 3; // not legal anymore } } Note: we need this feature for value types and we think it's also great to have it for identity class because if all final fields are strict, there is no way to have an unsafe initialization. This is a long standing problem when you have multiple threads that access to the same instance. For a thread-safe class, before this change the idea was to not leak 'this' and now the idea is that if you leak 'this' it is innocuous because all strict final fields have already been initialized. > >> perhaps we can be more explicit, that such a putfield can only exist in an >> that calls a direct superclass's , and the putfield must exist >> before such a super-call. > > I believe those are the correct requirements. > >> [1] https://cr.openjdk.org/~jrose/jls/constructive-classes.html > > Cheers, > Clement Cherlin regards, R?mi From daniel.smith at oracle.com Mon Jan 29 18:22:45 2024 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 29 Jan 2024 18:22:45 +0000 Subject: JVMS changes for JEP 401 In-Reply-To: <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> Message-ID: On Jan 29, 2024, at 9:06?AM, Remi Forax wrote: ----- Original Message ----- From: "Clement Cherlin" To: "Valhalla Expert Group Observers" Cc: "daniel smith" , "valhalla-spec-experts" Sent: Monday, January 29, 2024 4:30:01 PM Subject: Re: JVMS changes for JEP 401 On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: I've posted a revised spec change document for JEP 401, Value Classes and Objects, here: https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html [snip] - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow - 2.4 should say more about "sameness" as it relates to "identity" On Tue, Jan 23, 2024 at 8:15?PM - wrote: Hi Dan, Thanks for sharing this document! It looks great! There's a typo in section 2.4, where the definition of "element type" for an array type is accidentally removed. The reference to the "start of object construction" can probably be changed to "before the super-call," taken from John's "Constructive Classes" essay. [1] The 4.9.2 rule is correct; Unless I'm mistaken, the rule in 4.9.2 is not correct. From the proposal: An instance field of this declared in the current class with its ACC_STRICT flag set may be assigned by a putfield instruction occurring in an instance initialization method only if another instance initialization method has not yet been called. As I understand the current design intent, a constructor that calls 'this' is forbidden from assigning to a strict field, because that will lead to a duplicate assignment in a constructor that calls 'super'. This language appears to say the opposite. It seems to state that only the first constructor of the current class can assign the class's strict instance fields. If that is the case, then further constructors (including the one that calls 'super') are forbidden from assigning to strict instance fields. Hello, the problem is not duplicate assignment, as you said that part of the spec allows that, the problem is assignment of final fields after a call to super() or this() because when the assignment occurs, 'this' may have already leaked to another context. Right. There is a *language* rule that final fields must not be assigned more than once. (Specifically, they must be definitely unassigned before their assignment; we'll add a rule that final fields must be definitely assigned before a 'this()' call.) In the *JVM*, the only new thing we're guarding against is assignments after the constructor call. All assignments before a constructor call, duplicate or not, are allowed. -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Mon Jan 29 18:24:06 2024 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 29 Jan 2024 18:24:06 +0000 Subject: JVMS changes for JEP 401 In-Reply-To: References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> Message-ID: <96F459D5-1F04-47A8-A1DD-3C7E9B743C8D@oracle.com> On Jan 29, 2024, at 10:22?AM, daniel.smith at oracle.com wrote: we'll add a rule that final fields must be definitely assigned before a 'this()' call Oops. I mean *un*assigned before a 'this()' call. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ccherlin at gmail.com Mon Jan 29 20:12:15 2024 From: ccherlin at gmail.com (Clement Cherlin) Date: Mon, 29 Jan 2024 14:12:15 -0600 Subject: JVMS changes for JEP 401 In-Reply-To: References: <147936FE-F316-4C29-BFD4-DAE6B0DA09D5@oracle.com> <1119609899.115393289.1706547974233.JavaMail.zimbra@univ-eiffel.fr> Message-ID: On Mon, Jan 29, 2024 at 12:23?PM Dan Smith wrote: > > On Jan 29, 2024, at 9:06?AM, Remi Forax wrote: > > ----- Original Message ----- > > From: "Clement Cherlin" > To: "Valhalla Expert Group Observers" > Cc: "daniel smith" , "valhalla-spec-experts" > Sent: Monday, January 29, 2024 4:30:01 PM > Subject: Re: JVMS changes for JEP 401 > > > On Tue, Jan 23, 2024 at 7:11?PM Dan Smith wrote: > > > I've posted a revised spec change document for JEP 401, Value Classes and > Objects, here: > > https://cr.openjdk.org/~dlsmith/jep401/jep401-20240116/specs/value-objects-jvms.html > > > [snip] > > - The 4.9.2 rule about ACC_STRICT is hard to parse, will be rephrased somehow > > - 2.4 should say more about "sameness" as it relates to "identity" > > > On Tue, Jan 23, 2024 at 8:15?PM - wrote: > > > Hi Dan, > Thanks for sharing this document! It looks great! > There's a typo in section 2.4, where the definition of "element type" for an > array type is accidentally removed. > > The reference to the "start of object construction" can probably be changed to > "before the super-call," taken from John's "Constructive Classes" essay. [1] > The 4.9.2 rule is correct; > > > Unless I'm mistaken, the rule in 4.9.2 is not correct. > > From the proposal: > > An instance field of this declared in the current class with its ACC_STRICT flag > set may be assigned by a putfield instruction occurring in an instance > initialization method only if another instance initialization method has not > yet been called. > > > As I understand the current design intent, a constructor that calls > 'this' is forbidden from assigning to a strict field, because that > will lead to a duplicate assignment in a constructor that calls > 'super'. > > This language appears to say the opposite. It seems to state that only > the first constructor of the current class can assign the class's > strict instance fields. If that is the case, then further constructors > (including the one that calls 'super') are forbidden from assigning to > strict instance fields. > > > Hello, > the problem is not duplicate assignment, as you said that part of the spec allows that, > the problem is assignment of final fields after a call to super() or this() because when the assignment occurs, 'this' may have already leaked to another context. > > > Right. > > There is a *language* rule that final fields must not be assigned more than once. (Specifically, they must be definitely unassigned before their assignment; we'll add a rule that final fields must be definitely assigned before a 'this()' call.) > > In the *JVM*, the only new thing we're guarding against is assignments after the constructor call. All assignments before a constructor call, duplicate or not, are allowed. In that case, the wording is indeed very confusing. It appeared to me to say that there can be no assignments to strict fields in a constructor of the current class called *from* another constructor of the current class. I see now that interpretation was wrong, but to me it was the most plausible interpretation of the text. The correct interpretation is that strict final fields can be assigned to in a given constructor before a call *from* that constructor to any other constructor (and not afterwards). The intended meaning is (assignment to strict field may occur) only if ((call to (another instance initialization method) from (this instance initialization method)) has not yet occurred), but it read to me as (assignment to strict field may occur) only if ((call to (another instance initialization method) from (any method)) has not yet occurred). I hope I've made it clear where the confusion lay and what could stand to be clarified. Cheers, Clement Cherlin