From jbhateja at openjdk.org Tue Jan 3 17:05:34 2023 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Tue, 3 Jan 2023 17:05:34 GMT Subject: [lworld+vector] RFR: Merge lworld [v2] In-Reply-To: <7GRRfillens3_MOVq5Hb2MWfuyTEQuzlyRIuB7KRdFI=.2aa85234-b0c5-4673-9f4b-0fa2ef8df336@github.com> References: <7GRRfillens3_MOVq5Hb2MWfuyTEQuzlyRIuB7KRdFI=.2aa85234-b0c5-4673-9f4b-0fa2ef8df336@github.com> Message-ID: > Merge latest code from lworld into lworld+vector branch. > > Best Regards, > Jatin Jatin Bhateja has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: - post-merge fixes. - Merge branch 'lworld' of http://github.com/openjdk/valhalla into merge_lworld - 8296767: Support multi-field based vector classes. - [lworld+vector] Borrowing MultiFields initial implementation from https://github.com/fparain/valhalla/tree/multifields. Co-authored-by: Frederic Parain ------------- Changes: - all: https://git.openjdk.org/valhalla/pull/815/files - new: https://git.openjdk.org/valhalla/pull/815/files/1f749c90..1f749c90 Webrevs: - full: https://webrevs.openjdk.org/?repo=valhalla&pr=815&range=01 - incr: https://webrevs.openjdk.org/?repo=valhalla&pr=815&range=00-01 Stats: 0 lines in 0 files changed: 0 ins; 0 del; 0 mod Patch: https://git.openjdk.org/valhalla/pull/815.diff Fetch: git fetch https://git.openjdk.org/valhalla pull/815/head:pull/815 PR: https://git.openjdk.org/valhalla/pull/815 From jbhateja at openjdk.org Tue Jan 3 17:05:38 2023 From: jbhateja at openjdk.org (Jatin Bhateja) Date: Tue, 3 Jan 2023 17:05:38 GMT Subject: [lworld+vector] Integrated: Merge lworld In-Reply-To: <7GRRfillens3_MOVq5Hb2MWfuyTEQuzlyRIuB7KRdFI=.2aa85234-b0c5-4673-9f4b-0fa2ef8df336@github.com> References: <7GRRfillens3_MOVq5Hb2MWfuyTEQuzlyRIuB7KRdFI=.2aa85234-b0c5-4673-9f4b-0fa2ef8df336@github.com> Message-ID: On Thu, 29 Dec 2022 08:39:18 GMT, Jatin Bhateja wrote: > Merge latest code from lworld into lworld+vector branch. > > Best Regards, > Jatin This pull request has now been integrated. Changeset: 05e4d0db Author: Jatin Bhateja Committer: Paul Sandoz URL: https://git.openjdk.org/valhalla/commit/05e4d0dbaf4f9093087b78b065314d6dcaa6ed0a Stats: 415200 lines in 5582 files changed: 213641 ins; 137073 del; 64486 mod Merge lworld ------------- PR: https://git.openjdk.org/valhalla/pull/815 From forax at univ-mlv.fr Tue Jan 10 22:38:25 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 10 Jan 2023 23:38:25 +0100 (CET) Subject: Civilizer - let's civilize those primitive types ! Message-ID: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> Hi all, i've developed a small prototype of what the semantics for the next round could be https://github.com/forax/civilizer/ The prototype works with the latest valhalla early access build https://jdk.java.net/valhalla/ Basically, everything is an object, using @Value in front of a class or a record transforms it to a value class, a class with no identity (== compares the fields, synchronized throws an IllegalMonitorStateException, new WeakRef<>(...) throws an IdentityException). Adding @ZeroDefault means that the default value of the value class which is not null is all fields filled with zero. @NonNull allows to declare a non-null type (there is also @Nullable which is the default if there is no null aware annotation). For parameters, like Kotlin, sending null to a parameter of a method annotated with @NonNull throws a NPE. For a field a zero-default annotated with @NonNull ask for flattening, trying to store null also throws a NPE. For a field which is not a zero-default, even if declared @NonNull, the runtime will *not* throw a NPE because the field is null before reaching its initialization assignment in the constructor (and a constructor can call any methods). >From the VM POV, a Q-type never appears inside a method descriptor. It appears inside field descriptor but putfield, getfield and withfield allows a field declared as a Q-type to be accessed as a L-type (this is currently simulated for getfield and putfield with an invokedynamic). This is very similar to the way the VM deals with arrays. And the VM knows if a parameter is a Q-type or not despite the fact that only L-type appears in the method descriptor because the Q-type are declared in the Preload table of the class. It means that if a class/record is not accessed directly by a constructor but by some static factories (like Optional) then moving in between an identity type, a value type (with zero-default or not) are backward compatible changes. regards, R?mi From andvasp at gmail.com Wed Jan 11 11:10:23 2023 From: andvasp at gmail.com (Anderson Vasconcelos Pires) Date: Wed, 11 Jan 2023 08:10:23 -0300 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> Message-ID: Hi Remi! Interesting... What would be the purpose of it? Create code that can have backward compatibility and get benefits when running with jdk-valhalla? Because I do not see differences between: value record Foo(int value) and @Value record Foo(int value); How about the case below: @Value class A { int value;} // not record! before jdk-17 // value is not final too. var a = new A(); a.value = 10; // I expect a compile error if we use value instead of @Value; Would I be obligated to make the value field final? Regards, Anderson. On Tue, Jan 10, 2023 at 7:39 PM Remi Forax wrote: > Hi all, > i've developed a small prototype of what the semantics for the next round > could be > https://github.com/forax/civilizer/ > > The prototype works with the latest valhalla early access build > https://jdk.java.net/valhalla/ > > Basically, everything is an object, using @Value in front of a class or a > record transforms it to a value class, a class with no identity > (== compares the fields, synchronized throws an > IllegalMonitorStateException, new WeakRef<>(...) throws an > IdentityException). > Adding @ZeroDefault means that the default value of the value class which > is not null is all fields filled with zero. > > @NonNull allows to declare a non-null type (there is also @Nullable which > is the default if there is no null aware annotation). > For parameters, like Kotlin, sending null to a parameter of a method > annotated with @NonNull throws a NPE. > For a field a zero-default annotated with @NonNull ask for flattening, > trying to store null also throws a NPE. > For a field which is not a zero-default, even if declared @NonNull, the > runtime will *not* throw a NPE because the field is null before reaching > its initialization assignment in the constructor (and a constructor can > call any methods). > > From the VM POV, a Q-type never appears inside a method descriptor. It > appears inside field descriptor but putfield, getfield and withfield allows > a field declared as a Q-type to be accessed as a L-type (this is currently > simulated for getfield and putfield with an invokedynamic). This is very > similar to the way the VM deals with arrays. And the VM knows if a > parameter is a Q-type or not despite the fact that only L-type appears in > the method descriptor because the Q-type are declared in the Preload table > of the class. > > It means that if a class/record is not accessed directly by a constructor > but by some static factories (like Optional) then moving in between an > identity type, a value type (with zero-default or not) are backward > compatible changes. > > regards, > R?mi > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed Jan 11 14:00:52 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Wed, 11 Jan 2023 15:00:52 +0100 (CET) Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> Message-ID: <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> > From: "Anderson Vasconcelos Pires" > To: "Remi Forax" > Cc: "valhalla-dev" > Sent: Wednesday, January 11, 2023 12:10:23 PM > Subject: Re: Civilizer - let's civilize those primitive types ! > Hi Remi! Hi Anderson, > Interesting... What would be the purpose of it? Create code that can have > backward compatibility and get benefits when running with jdk-valhalla? Mostly prototyping a proposal to remove Q-types (descriptor that starts with Q...;) and replace them by an attribute on methods and fields indicating if the value can be null. see [ https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html | https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html ] > Because I do not see differences between: > value record Foo(int value) and @Value record Foo(int value); yes, there is none (i hope) apart the fact that adding @ZeroDefault or not is a backward compatible change. Currently, there are three kind of class, identity class, value class and primitive class, i propose to have only two, identity class and value class. A zero-default class being a sub-category of value class. A zero-default class Foo does not work like a primitive class as defined in JEP 401. A zero-default class is nullable by default. So you can use it everywhere you want like an identity type or a value type (even in generics). Conceptually, the idea is to de-couple the notion of zero-default from the notion of nullability. By default a value type (zero-default or not) is nullable and you choose if you want the non-null version by adding @NonNull at use site. There is no notion of .val or .ref, if you want a field to be flattened, use a @Zero-Default and declare the field @NonNull. I will add that this is not my idea, this Brian's idea. I'm just proposing a way to achieve that in term of classfile representation / VM semantics. > How about the case below: > @Value class A { int value;} // not record! before jdk-17 // value is not final > too. > var a = new A(); > a.value = 10; // I expect a compile error if we use value instead of @Value; > Would I be obligated to make the value field final? yes, the prototype does not do any verification that the compiler does, i'm too lazy for that but the VM will catch you and throw an Error. About the mutability of fields, fundamentally, value type is about saying, i give up the notion of identity, if you have no identity, you have no location in memory (you can have more than one if you prefer) so the VM is free to pass by reference or pass by value. So you can not mutate a field, because you can only do that if you have one location in memory. > Regards, > Anderson. regards, R?mi > On Tue, Jan 10, 2023 at 7:39 PM Remi Forax < [ mailto:forax at univ-mlv.fr | > forax at univ-mlv.fr ] > wrote: >> Hi all, >> i've developed a small prototype of what the semantics for the next round could >> be >> [ https://github.com/forax/civilizer/ | https://github.com/forax/civilizer/ ] >> The prototype works with the latest valhalla early access build >> [ https://jdk.java.net/valhalla/ | https://jdk.java.net/valhalla/ ] >> Basically, everything is an object, using @Value in front of a class or a record >> transforms it to a value class, a class with no identity >> (== compares the fields, synchronized throws an IllegalMonitorStateException, >> new WeakRef<>(...) throws an IdentityException). >> Adding @ZeroDefault means that the default value of the value class which is not >> null is all fields filled with zero. >> @NonNull allows to declare a non-null type (there is also @Nullable which is the >> default if there is no null aware annotation). >> For parameters, like Kotlin, sending null to a parameter of a method annotated >> with @NonNull throws a NPE. >> For a field a zero-default annotated with @NonNull ask for flattening, trying to >> store null also throws a NPE. >> For a field which is not a zero-default, even if declared @NonNull, the runtime >> will *not* throw a NPE because the field is null before reaching its >> initialization assignment in the constructor (and a constructor can call any >> methods). >> From the VM POV, a Q-type never appears inside a method descriptor. It appears >> inside field descriptor but putfield, getfield and withfield allows a field >> declared as a Q-type to be accessed as a L-type (this is currently simulated >> for getfield and putfield with an invokedynamic). This is very similar to the >> way the VM deals with arrays. And the VM knows if a parameter is a Q-type or >> not despite the fact that only L-type appears in the method descriptor because >> the Q-type are declared in the Preload table of the class. >> It means that if a class/record is not accessed directly by a constructor but by >> some static factories (like Optional) then moving in between an identity type, >> a value type (with zero-default or not) are backward compatible changes. >> regards, >> R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From andvasp at gmail.com Wed Jan 11 17:29:45 2023 From: andvasp at gmail.com (Anderson Vasconcelos Pires) Date: Wed, 11 Jan 2023 14:29:45 -0300 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: Thanks for the prompt response! Mostly prototyping a proposal to remove Q-types (descriptor that starts > with Q...;) and replace them by an attribute on methods and fields > indicating if the value can be null. > > see > https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html > So if you want to remove Q types it means that L type does not need the identity information, right? > > There is no notion of .val or .ref, if you want a field to be flattened, > use a @Zero-Default and declare the field @NonNull. > Pretty good if we do not need to use .val or .ref! Could the @NonNull be replaced by "!" but writing the attribute in the class file? I Like @NonNull but I believe the "!" would be more practical. As @Nullable is the default, maybe it would not be necessary to have it. > yes, the prototype does not do any verification that the compiler does, > i'm too lazy for that but the VM will catch you and throw an Error > > Pretty good for a prototype! > About the mutability of fields, fundamentally, value type is about saying, > i give up the notion of identity, if you have no identity, you have no > location in memory (you can have more than one if you prefer) so the VM is > free to pass by reference or pass by value. So you can not mutate a field, > because you can only do that if you have one location in memory. > > Ok for mutability but now I am a little bit confused about references, identity and memory location. Value class is a reference type that does not have identity. So it means that it can be allocated in the heap, right? So allocating it in the heap will have a memory location, do not? > regards, > > R?mi > > Thanks for the explanation! Regards, Anderson. > > On Tue, Jan 10, 2023 at 7:39 PM Remi Forax wrote: > >> Hi all, >> i've developed a small prototype of what the semantics for the next round >> could be >> https://github.com/forax/civilizer/ >> >> The prototype works with the latest valhalla early access build >> https://jdk.java.net/valhalla/ >> >> Basically, everything is an object, using @Value in front of a class or a >> record transforms it to a value class, a class with no identity >> (== compares the fields, synchronized throws an >> IllegalMonitorStateException, new WeakRef<>(...) throws an >> IdentityException). >> Adding @ZeroDefault means that the default value of the value class which >> is not null is all fields filled with zero. >> >> @NonNull allows to declare a non-null type (there is also @Nullable which >> is the default if there is no null aware annotation). >> For parameters, like Kotlin, sending null to a parameter of a method >> annotated with @NonNull throws a NPE. >> For a field a zero-default annotated with @NonNull ask for flattening, >> trying to store null also throws a NPE. >> For a field which is not a zero-default, even if declared @NonNull, the >> runtime will *not* throw a NPE because the field is null before reaching >> its initialization assignment in the constructor (and a constructor can >> call any methods). >> >> From the VM POV, a Q-type never appears inside a method descriptor. It >> appears inside field descriptor but putfield, getfield and withfield allows >> a field declared as a Q-type to be accessed as a L-type (this is currently >> simulated for getfield and putfield with an invokedynamic). This is very >> similar to the way the VM deals with arrays. And the VM knows if a >> parameter is a Q-type or not despite the fact that only L-type appears in >> the method descriptor because the Q-type are declared in the Preload table >> of the class. >> >> It means that if a class/record is not accessed directly by a constructor >> but by some static factories (like Optional) then moving in between an >> identity type, a value type (with zero-default or not) are backward >> compatible changes. >> >> regards, >> R?mi >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Jan 11 17:35:01 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 11 Jan 2023 17:35:01 +0000 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: I think you may be missing out on the goal here. This is not an exploration of the user model (value vs primitive class, val/ref/bang/etc), this is an exploration of the underlying translation / implementation scheme *that might inform* future evolution of the user model. On Jan 11, 2023, at 12:29 PM, Anderson Vasconcelos Pires > wrote: Thanks for the prompt response! Mostly prototyping a proposal to remove Q-types (descriptor that starts with Q...;) and replace them by an attribute on methods and fields indicating if the value can be null. see https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html So if you want to remove Q types it means that L type does not need the identity information, right? There is no notion of .val or .ref, if you want a field to be flattened, use a @Zero-Default and declare the field @NonNull. Pretty good if we do not need to use .val or .ref! Could the @NonNull be replaced by "!" but writing the attribute in the class file? I Like @NonNull but I believe the "!" would be more practical. As @Nullable is the default, maybe it would not be necessary to have it. yes, the prototype does not do any verification that the compiler does, i'm too lazy for that but the VM will catch you and throw an Error Pretty good for a prototype! About the mutability of fields, fundamentally, value type is about saying, i give up the notion of identity, if you have no identity, you have no location in memory (you can have more than one if you prefer) so the VM is free to pass by reference or pass by value. So you can not mutate a field, because you can only do that if you have one location in memory. Ok for mutability but now I am a little bit confused about references, identity and memory location. Value class is a reference type that does not have identity. So it means that it can be allocated in the heap, right? So allocating it in the heap will have a memory location, do not? regards, R?mi Thanks for the explanation! Regards, Anderson. On Tue, Jan 10, 2023 at 7:39 PM Remi Forax > wrote: Hi all, i've developed a small prototype of what the semantics for the next round could be https://github.com/forax/civilizer/ The prototype works with the latest valhalla early access build https://jdk.java.net/valhalla/ Basically, everything is an object, using @Value in front of a class or a record transforms it to a value class, a class with no identity (== compares the fields, synchronized throws an IllegalMonitorStateException, new WeakRef<>(...) throws an IdentityException). Adding @ZeroDefault means that the default value of the value class which is not null is all fields filled with zero. @NonNull allows to declare a non-null type (there is also @Nullable which is the default if there is no null aware annotation). For parameters, like Kotlin, sending null to a parameter of a method annotated with @NonNull throws a NPE. For a field a zero-default annotated with @NonNull ask for flattening, trying to store null also throws a NPE. For a field which is not a zero-default, even if declared @NonNull, the runtime will *not* throw a NPE because the field is null before reaching its initialization assignment in the constructor (and a constructor can call any methods). From the VM POV, a Q-type never appears inside a method descriptor. It appears inside field descriptor but putfield, getfield and withfield allows a field declared as a Q-type to be accessed as a L-type (this is currently simulated for getfield and putfield with an invokedynamic). This is very similar to the way the VM deals with arrays. And the VM knows if a parameter is a Q-type or not despite the fact that only L-type appears in the method descriptor because the Q-type are declared in the Preload table of the class. It means that if a class/record is not accessed directly by a constructor but by some static factories (like Optional) then moving in between an identity type, a value type (with zero-default or not) are backward compatible changes. regards, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed Jan 11 22:02:45 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Wed, 11 Jan 2023 23:02:45 +0100 (CET) Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> > From: "Brian Goetz" > To: "Anderson Vasconcelos Pires" > Cc: "Remi Forax" , "valhalla-dev" > > Sent: Wednesday, January 11, 2023 6:35:01 PM > Subject: Re: Civilizer - let's civilize those primitive types ! > I think you may be missing out on the goal here. This is not an exploration of > the user model (value vs primitive class, val/ref/bang/etc), this is an > exploration of the underlying translation / implementation scheme *that might > inform* future evolution of the user model. yes, >> On Jan 11, 2023, at 12:29 PM, Anderson Vasconcelos Pires < [ >> mailto:andvasp at gmail.com | andvasp at gmail.com ] > wrote: >> Thanks for the prompt response! >>>> Mostly prototyping a proposal to remove Q-types (descriptor that starts with >>>> Q...;) and replace them by an attribute on methods and fields indicating if the >>>> value can be null. >>> see [ >>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>> | >>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>> ] >> So if you want to remove Q types it means that L type does not need the identity >> information, right? Currently when you have a primitive class, you need to declare the class as a private class *and* you need to use a Q-type each time you mention that class (in a method descriptor, a field descriptor, in a checkcast, see JEP 401). The idea here is when you need to declare the class as a private class but instead of using a Q-type, you use a side attribute that indicates if null is a valid value or not. To answer your question, you do not need the identity information at use site, what you need to know is if it is a zero-default value class and if null is not a valid value. Previous both information where grouped together inside the Q-type, i'm proposing to keep them into two location and let the VM gathers those information together. >>> There is no notion of .val or .ref, if you want a field to be flattened, use a >>> @Zero-Default and declare the field @NonNull. >> Pretty good if we do not need to use .val or .ref! >> Could the @NonNull be replaced by "!" but writing the attribute in the class >> file? >> I Like @NonNull but I believe the "!" would be more practical. See Brian answer, >> As @Nullable is the default, maybe it would not be necessary to have it. We will need a way to say that Map.get() return type is a nullable Foo, even if the V (in Map) is a non-null Foo. >>>> yes, the prototype does not do any verification that the compiler does, i'm too >>>> lazy for that but the VM will catch you and throw an Error >> Pretty good for a prototype! >>> About the mutability of fields, fundamentally, value type is about saying, i >>> give up the notion of identity, if you have no identity, you have no location >>> in memory (you can have more than one if you prefer) so the VM is free to pass >>> by reference or pass by value. So you can not mutate a field, because you can >>> only do that if you have one location in memory. >> Ok for mutability but now I am a little bit confused about references, identity >> and memory location. You are not alone :) In Java, all classes have references / instances / objects. This does not change with the introduction of value class. Identity class have references which have an identity, so == will compare the address in memory. Value class have references which does not have an identity, so == will compare the content on the object. >> Value class is a reference type that does not have identity. So it means that it >> can be allocated in the heap, right? No, it means the opposite. Having an identity is equivalent to saying having an address in memory in the heap. So having no identity means that the VM is free to chose to allocate it in the heap, to not allocate it in the heap, or even to allocate it multiple time in the heap, because from the user POV all these objects can not be distinguished one from another, thus they are one. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 12 09:44:37 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 12 Jan 2023 10:44:37 +0100 (CET) Subject: LW5 issue: InnerClasses attribute access member Message-ID: <916021924.83472961.1673516677519.JavaMail.zimbra@u-pem.fr> Hi all, while writing civilizer [1], i stumble on a behavior of the VM which i think is a bug in the LW5 implementation. The problem is that the VM trusts the "access" member (ACC_IDENTITY, ACC_VALUE, ACC_PRIMITIVE) of the InnerClasses but: - the InnerClass attribute is an attribute for javac not for the VM (see section 4.7.6 of the VM spec) so the VM should not change its behavior depending on the content of that attribute (that's why NestHost/NestMembers are separate attributes from InnerClasses BTW). - those information can be wrong because of separate compilations because javac includes InnerClasses info of inner classes it uses not only the one in the compilation unit. regards, R?mi [1] https://github.com/forax/civilizer From redio.development at gmail.com Thu Jan 12 19:55:25 2023 From: redio.development at gmail.com (Red IO) Date: Thu, 12 Jan 2023 20:55:25 +0100 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> Message-ID: On your last point. Identity != memory location Identity only means that you can identify the object and all references point to the same location in memory (heap or stack). Everything has a memory address period. Rather something lives on the stack or heap every byte of data has a memory address. The runtime is already free to keep a current standard reference type on the stack if it can confirm that it will a) benefit performance and or memory efficiency and b) a situation where a reference to this stack value outside its stackframe exist is impossible. The big benefit of having no identity and therefore being immutable is that the object can be copied without any analysis of multiple references. Since different references to the same object can actually point to different spots in memory. This might sound memory inefficient but remember, stack memory is cheap heap isn't. The idea is that objects without identity can be allocated on the stack most of the time and packed in objects since they don't need to track their references since copies of themselves are interchangeable and indistinguishable. Please correct me if I'm wrong with something I'm still learning. Great regards RedIODev On Wed, Jan 11, 2023, 23:03 wrote: > > > ------------------------------ > > *From: *"Brian Goetz" > *To: *"Anderson Vasconcelos Pires" > *Cc: *"Remi Forax" , "valhalla-dev" < > valhalla-dev at openjdk.java.net> > *Sent: *Wednesday, January 11, 2023 6:35:01 PM > *Subject: *Re: Civilizer - let's civilize those primitive types ! > > I think you may be missing out on the goal here. This is not an > exploration of the user model (value vs primitive class, val/ref/bang/etc), > this is an exploration of the underlying translation / implementation > scheme *that might inform* future evolution of the user model. > > > yes, > > > > On Jan 11, 2023, at 12:29 PM, Anderson Vasconcelos Pires < > andvasp at gmail.com> wrote: > > Thanks for the prompt response! > > Mostly prototyping a proposal to remove Q-types (descriptor that starts >> with Q...;) and replace them by an attribute on methods and fields >> indicating if the value can be null. >> >> see >> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >> > > So if you want to remove Q types it means that L type does not need the > identity information, right? > > > Currently when you have a primitive class, you need to declare the class > as a private class *and* you need to use a Q-type each time you mention > that class (in a method descriptor, a field descriptor, in a checkcast, see > JEP 401). > The idea here is when you need to declare the class as a private class but > instead of using a Q-type, you use a side attribute that indicates if null > is a valid value or not. > > To answer your question, you do not need the identity information at use > site, what you need to know is if it is a zero-default value class and if > null is not a valid value. Previous both information where grouped together > inside the Q-type, i'm proposing to keep them into two location and let the > VM gathers those information together. > > > >> There is no notion of .val or .ref, if you want a field to be flattened, >> use a @Zero-Default and declare the field @NonNull. >> > > Pretty good if we do not need to use .val or .ref! > > Could the @NonNull be replaced by "!" but writing the attribute in the > class file? > > I Like @NonNull but I believe the "!" would be more practical. > > > See Brian answer, > > > As @Nullable is the default, maybe it would not be necessary to have it. > > > We will need a way to say that Map.get() return type > is a nullable Foo, even if the V (in Map) is a non-null Foo. > > > >> yes, the prototype does not do any verification that the compiler does, >> i'm too lazy for that but the VM will catch you and throw an Error >> >> > Pretty good for a prototype! > > >> About the mutability of fields, fundamentally, value type is about >> saying, i give up the notion of identity, if you have no identity, you have >> no location in memory (you can have more than one if you prefer) so the VM >> is free to pass by reference or pass by value. So you can not mutate a >> field, because you can only do that if you have one location in memory. >> >> > Ok for mutability but now I am a little bit confused about references, > identity and memory location. > > > You are not alone :) > > In Java, all classes have references / instances / objects. This does not > change with the introduction of value class. > Identity class have references which have an identity, so == will compare > the address in memory. > Value class have references which does not have an identity, so == will > compare the content on the object. > > Value class is a reference type that does not have identity. So it means > that it can be allocated in the heap, right? > > > No, it means the opposite. Having an identity is equivalent to saying > having an address in memory in the heap. > So having no identity means that the VM is free to chose to allocate it in > the heap, to not allocate it in the heap, or even to allocate it multiple > time in the heap, because from the user POV all these objects can not be > distinguished one from another, thus they are one. > > R?mi > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 12 20:30:07 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 12 Jan 2023 21:30:07 +0100 (CET) Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> Message-ID: <1231498090.83971685.1673555407374.JavaMail.zimbra@u-pem.fr> > From: "Red IO" > To: "Remi Forax" > Cc: "Anderson Vasconcelos Pires" , "valhalla-dev" > , "Brian Goetz" > Sent: Thursday, January 12, 2023 8:55:25 PM > Subject: Re: Civilizer - let's civilize those primitive types ! > On your last point. > Identity != memory location > Identity only means that you can identify the object and all references point to > the same location in memory (heap or stack). Your definition of identity uses "identify" :) > Everything has a memory address period. Rather something lives on the stack or > heap every byte of data has a memory address. The runtime is already free to > keep a current standard reference type on the stack if it can confirm that it > will a) benefit performance and or memory efficiency and b) a situation where a > reference to this stack value outside its stackframe exist is impossible. Not everything has a memory address. By example, Hotspot never allocates objects on stack but uses scalar replacement instead (this may be not true in the future), see [ https://shipilev.net/jvm/anatomy-quarks/18-scalar-replacement/ | https://shipilev.net/jvm/anatomy-quarks/18-scalar-replacement/ ] > The big benefit of having no identity and therefore being immutable is that the > object can be copied without any analysis of multiple references. yes > Since different references to the same object can actually point to different > spots in memory. This might sound memory inefficient but remember, stack memory > is cheap heap isn't. The idea is that objects without identity can be allocated > on the stack most of the time and packed in objects since they don't need to > track their references since copies of themselves are interchangeable and > indistinguishable. > Please correct me if I'm wrong with something I'm still learning. see above. > Great regards > RedIODev regards, R?mi > On Wed, Jan 11, 2023, 23:03 < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] > > wrote: >>> From: "Brian Goetz" < [ mailto:brian.goetz at oracle.com | brian.goetz at oracle.com ] >>> > >>> To: "Anderson Vasconcelos Pires" < [ mailto:andvasp at gmail.com | >>> andvasp at gmail.com ] > >>> Cc: "Remi Forax" < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] >, >>> "valhalla-dev" < [ mailto:valhalla-dev at openjdk.java.net | >>> valhalla-dev at openjdk.java.net ] > >>> Sent: Wednesday, January 11, 2023 6:35:01 PM >>> Subject: Re: Civilizer - let's civilize those primitive types ! >>> I think you may be missing out on the goal here. This is not an exploration of >>> the user model (value vs primitive class, val/ref/bang/etc), this is an >>> exploration of the underlying translation / implementation scheme *that might >>> inform* future evolution of the user model. >> yes, >>>> On Jan 11, 2023, at 12:29 PM, Anderson Vasconcelos Pires < [ >>>> mailto:andvasp at gmail.com | andvasp at gmail.com ] > wrote: >>>> Thanks for the prompt response! >>>>>> Mostly prototyping a proposal to remove Q-types (descriptor that starts with >>>>>> Q...;) and replace them by an attribute on methods and fields indicating if the >>>>>> value can be null. >>>>> see [ >>>>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>>>> | >>>>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>>>> ] >>>> So if you want to remove Q types it means that L type does not need the identity >>>> information, right? >> Currently when you have a primitive class, you need to declare the class as a >> private class *and* you need to use a Q-type each time you mention that class >> (in a method descriptor, a field descriptor, in a checkcast, see JEP 401). >> The idea here is when you need to declare the class as a private class but >> instead of using a Q-type, you use a side attribute that indicates if null is a >> valid value or not. >> To answer your question, you do not need the identity information at use site, >> what you need to know is if it is a zero-default value class and if null is not >> a valid value. Previous both information where grouped together inside the >> Q-type, i'm proposing to keep them into two location and let the VM gathers >> those information together. >>>>> There is no notion of .val or .ref, if you want a field to be flattened, use a >>>>> @Zero-Default and declare the field @NonNull. >>>> Pretty good if we do not need to use .val or .ref! >>>> Could the @NonNull be replaced by "!" but writing the attribute in the class >>>> file? >>>> I Like @NonNull but I believe the "!" would be more practical. >> See Brian answer, >>>> As @Nullable is the default, maybe it would not be necessary to have it. >> We will need a way to say that Map.get() return type is a >> nullable Foo, even if the V (in Map) is a non-null Foo. >>>>>> yes, the prototype does not do any verification that the compiler does, i'm too >>>>>> lazy for that but the VM will catch you and throw an Error >>>> Pretty good for a prototype! >>>>> About the mutability of fields, fundamentally, value type is about saying, i >>>>> give up the notion of identity, if you have no identity, you have no location >>>>> in memory (you can have more than one if you prefer) so the VM is free to pass >>>>> by reference or pass by value. So you can not mutate a field, because you can >>>>> only do that if you have one location in memory. >>>> Ok for mutability but now I am a little bit confused about references, identity >>>> and memory location. >> You are not alone :) >> In Java, all classes have references / instances / objects. This does not change >> with the introduction of value class. >> Identity class have references which have an identity, so == will compare the >> address in memory. >> Value class have references which does not have an identity, so == will compare >> the content on the object. >>>> Value class is a reference type that does not have identity. So it means that it >>>> can be allocated in the heap, right? >> No, it means the opposite. Having an identity is equivalent to saying having an >> address in memory in the heap. >> So having no identity means that the VM is free to chose to allocate it in the >> heap, to not allocate it in the heap, or even to allocate it multiple time in >> the heap, because from the user POV all these objects can not be distinguished >> one from another, thus they are one. >> R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From org.openjdk at io7m.com Thu Jan 12 20:42:41 2023 From: org.openjdk at io7m.com (Mark Raynsford) Date: Thu, 12 Jan 2023 20:42:41 +0000 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <1231498090.83971685.1673555407374.JavaMail.zimbra@u-pem.fr> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> <1231498090.83971685.1673555407374.JavaMail.zimbra@u-pem.fr> Message-ID: <20230112204241.54202675@sunflower.int.arc7.info> On 2023-01-12T21:30:07 +0100 forax at univ-mlv.fr wrote: > > From: "Red IO" > > To: "Remi Forax" > > Since different references to the same object can actually point to different > > spots in memory. This might sound memory inefficient but remember, stack memory > > is cheap heap isn't. The idea is that objects without identity can be allocated For the sake of pedantry, I don't think this is true either. My desktop has 32gb of RAM, of which I'm allowed to allocate all 32gb to the heap if I want. However, on my haven't-touched-the-defaults install: $ ulimit -a stack size (kbytes, -s) 8192 I'm not allowed to grab more than 8192kb of stack. Stack space is an artificially scarce resource. It is "cheaper" in the sense that using it doesn't create more work for the GC, but that's it. -- Mark Raynsford | https://www.io7m.com -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 228 bytes Desc: OpenPGP digital signature URL: From brian.goetz at oracle.com Thu Jan 12 21:17:57 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 12 Jan 2023 21:17:57 +0000 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> Message-ID: <3CFA69DC-B421-4008-9C30-3248A3128470@oracle.com> > Everything has a memory address period. Despite emphasizing it with ?period? as if it were obviously true, this statement is not correct. Value objects can be scalarized into their fields, and those fields can be hoisted into registers, and registers have no memory address. There is no reason why a copy of the object need be placed in memory at all. In fact, this is much of the raison d??tre for Valhalla ? to give the runtime permission to confidently make this optimization, by saying that an object need not live in a single ? or even any ? place in ?memory". From redio.development at gmail.com Fri Jan 13 09:20:19 2023 From: redio.development at gmail.com (Red IO) Date: Fri, 13 Jan 2023 10:20:19 +0100 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <3CFA69DC-B421-4008-9C30-3248A3128470@oracle.com> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> <3CFA69DC-B421-4008-9C30-3248A3128470@oracle.com> Message-ID: Thanks, I didn't think about registers at all while underestimating the depth of optimization the runtime can do. I wasn't expecting the vm to intelligently manage registers at runtime. But I doubt that value objects will be often only stored in registers since their space is (on most platforms) pretty limited. You would need to strip unused fields from the object which often will reduce the object to maybe 1-2 int or something, reducing it to nothing more than the arguments for the next cpu cycle. But storing a larger object > ~200 bytes completely in registers is impossible in the first place. And storing multiple value objects simultaneously in registers is even more unlikely to happen. This level of optimization really makes value objects feel like c structs which shows how great the improvement from objects to value objects really is. It's really only a grouping of local variables in 1 name. Which totally makes sense for pure data carriers especially records. Great regards RedIODev On Thu, Jan 12, 2023, 22:18 Brian Goetz wrote: > > > > Everything has a memory address period. > > Despite emphasizing it with ?period? as if it were obviously true, this > statement is not correct. > > Value objects can be scalarized into their fields, and those fields can be > hoisted into registers, and registers have no memory address. There is no > reason why a copy of the object need be placed in memory at all. In fact, > this is much of the raison d??tre for Valhalla ? to give the runtime > permission to confidently make this optimization, by saying that an object > need not live in a single ? or even any ? place in ?memory". > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Fri Jan 13 15:34:34 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 13 Jan 2023 15:34:34 +0000 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> <3CFA69DC-B421-4008-9C30-3248A3128470@oracle.com> Message-ID: <4AA54914-6A13-40C4-BD74-A69467FC497E@oracle.com> > I didn't think about registers at all while underestimating the depth of optimization the runtime can do. I wasn't expecting the vm to intelligently manage registers at runtime. > > But I doubt that value objects will be often only stored in registers since their space is (on most platforms) pretty limited. You would need to strip unused fields from the object which often will reduce the object to maybe 1-2 int or something, reducing it to nothing more than the arguments for the next cpu cycle. But storing a larger object > ~200 bytes completely in registers is impossible in the first place. And storing multiple value objects simultaneously in registers is even more unlikely to happen. It is easy to think about Valhalla as being about ?blocks and pointers?, and see the main benefit as eliminating some of those pointers by inlining layout into enclosing blocks. And indeed, that is one of the benefits of Valhalla, and the easiest to visualize from a C-centric viewpoint. But, that?s only part of the story. If you have a value type Point, and you return a Point from a method, the calling convention for the method will routinely pass the Point fields in registers. And in many cases, where a value is used only to communicate an aggregate between a caller and a callee, the value need never hit memory at all. This is a significant part of what Valhalla is providing. From jbossons at gmail.com Fri Jan 13 23:15:59 2023 From: jbossons at gmail.com (John Bossons) Date: Fri, 13 Jan 2023 18:15:59 -0500 Subject: Civilizer - let's civilize those primitive types ! Message-ID: Agreed that the use of a .ref or .val tag is an awkward deviation from familiar syntax. Use of a @NotNull annotation is one alternative. A contextual keyword (e.g. *notnull* or *nonulls*) is another. The key thing is that, whether keyword or annotation, it should only need to be specified when a field is defined. Every implication of a *notnull* specification should be capable of being generated by the compiler. Examples: primitive class PhoneNumber { // all fields are non-negative never-null integer values } value class ContactPhoneInfo { private notnull PhoneNumber mobile; // equivalent to PhoneNumber.val private PhoneNumber landLine; // optional, equivalent to PhoneNumber.ref } value class EmailContact { private notnull String emailAddress; // never missing private ContactPhoneInfo phones; // optional, may be missing } The *notnull* modifier can be applied to any value class field type. If the field is a primitive or value object, it signals that the field value may be stored as a flattened value without needing an additional bit or reference to allow for a null value. But it also has other uses, including for identity-type fields like the String field in the above example. For example, if a field is a *notnull*, the compiler could autogenerate code throwing a NullPointerException (or equivalent) if a client attempts to instantiate the value object with a null value for that field. (Or better still, reject client code that attempts to supply an invalid null value). If a value object field is not a *notnull*, the compiler could autogenerate an *Optional* return value for the corresponding accessor. The advantage of the keyword over the annotation is that it can only be used in one place: a field definition, the only place it?s needed. -------------- next part -------------- An HTML attachment was scrubbed... URL: From redio.development at gmail.com Fri Jan 13 23:06:39 2023 From: redio.development at gmail.com (Red IO) Date: Sat, 14 Jan 2023 00:06:39 +0100 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: <4AA54914-6A13-40C4-BD74-A69467FC497E@oracle.com> References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> <220727017.83232325.1673474565165.JavaMail.zimbra@u-pem.fr> <3CFA69DC-B421-4008-9C30-3248A3128470@oracle.com> <4AA54914-6A13-40C4-BD74-A69467FC497E@oracle.com> Message-ID: This sounds really similar to c++ return value optimizations. Of cause it makes sense to not unnecessarily move the return value out of register before returning from the function only to load it back in, in the action directly after the end of the returning function. On Fri, Jan 13, 2023, 16:34 Brian Goetz wrote: > > I didn't think about registers at all while underestimating the depth of > optimization the runtime can do. I wasn't expecting the vm to intelligently > manage registers at runtime. > > > > But I doubt that value objects will be often only stored in registers > since their space is (on most platforms) pretty limited. You would need to > strip unused fields from the object which often will reduce the object to > maybe 1-2 int or something, reducing it to nothing more than the arguments > for the next cpu cycle. But storing a larger object > ~200 bytes completely > in registers is impossible in the first place. And storing multiple value > objects simultaneously in registers is even more unlikely to happen. > > > It is easy to think about Valhalla as being about ?blocks and pointers?, > and see the main benefit as eliminating some of those pointers by inlining > layout into enclosing blocks. And indeed, that is one of the benefits of > Valhalla, and the easiest to visualize from a C-centric viewpoint. But, > that?s only part of the story. If you have a value type Point, and you > return a Point from a method, the calling convention for the method will > routinely pass the Point fields in registers. And in many cases, where a > value is used only to communicate an aggregate between a caller and a > callee, the value need never hit memory at all. This is a significant part > of what Valhalla is providing. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From redio.development at gmail.com Thu Jan 19 20:19:09 2023 From: redio.development at gmail.com (Red IO) Date: Thu, 19 Jan 2023 21:19:09 +0100 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: If we talk about the user model for the explicit nullability of refrences we should think about allowing the developer to turn it around. Meaning that every reference is treated non null when not marked otherwise. But this should definitely strictly be "an option" that you can enable somehow. This can be really beneficial since the compiler can mark every point where an (default) non nullable is assigned (potential) null value or a nullable variable is dereferenced at all. I just got the idea of inverting the nullability default from c# which has this feature. I recently flipped it on one of my projects and the entire code lit up with warnings. Showing countless spots where a null check was missing. It would be logical to use "!" for explicit non-null and "?" for explicit nullable. With 1 being optional in each case rather the default is inversed or not. Great regards RedIODev On Wed, Jan 11, 2023, 18:30 Anderson Vasconcelos Pires wrote: > Thanks for the prompt response! > > Mostly prototyping a proposal to remove Q-types (descriptor that starts >> with Q...;) and replace them by an attribute on methods and fields >> indicating if the value can be null. >> >> see >> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >> > > So if you want to remove Q types it means that L type does not need the > identity information, right? > >> >> There is no notion of .val or .ref, if you want a field to be flattened, >> use a @Zero-Default and declare the field @NonNull. >> > > Pretty good if we do not need to use .val or .ref! > > Could the @NonNull be replaced by "!" but writing the attribute in the > class file? > > I Like @NonNull but I believe the "!" would be more practical. > > As @Nullable is the default, maybe it would not be necessary to have it. > > >> yes, the prototype does not do any verification that the compiler does, >> i'm too lazy for that but the VM will catch you and throw an Error >> >> > Pretty good for a prototype! > > >> About the mutability of fields, fundamentally, value type is about >> saying, i give up the notion of identity, if you have no identity, you have >> no location in memory (you can have more than one if you prefer) so the VM >> is free to pass by reference or pass by value. So you can not mutate a >> field, because you can only do that if you have one location in memory. >> >> > Ok for mutability but now I am a little bit confused about references, > identity and memory location. Value class is a reference type that does not > have identity. So it means that it can be allocated in the heap, right? So > allocating it in the heap will have a memory location, do not? > >> regards, >> >> R?mi >> >> > Thanks for the explanation! > > Regards, > Anderson. > >> >> On Tue, Jan 10, 2023 at 7:39 PM Remi Forax wrote: >> >>> Hi all, >>> i've developed a small prototype of what the semantics for the next >>> round could be >>> https://github.com/forax/civilizer/ >>> >>> The prototype works with the latest valhalla early access build >>> https://jdk.java.net/valhalla/ >>> >>> Basically, everything is an object, using @Value in front of a class or >>> a record transforms it to a value class, a class with no identity >>> (== compares the fields, synchronized throws an >>> IllegalMonitorStateException, new WeakRef<>(...) throws an >>> IdentityException). >>> Adding @ZeroDefault means that the default value of the value class >>> which is not null is all fields filled with zero. >>> >>> @NonNull allows to declare a non-null type (there is also @Nullable >>> which is the default if there is no null aware annotation). >>> For parameters, like Kotlin, sending null to a parameter of a method >>> annotated with @NonNull throws a NPE. >>> For a field a zero-default annotated with @NonNull ask for flattening, >>> trying to store null also throws a NPE. >>> For a field which is not a zero-default, even if declared @NonNull, the >>> runtime will *not* throw a NPE because the field is null before reaching >>> its initialization assignment in the constructor (and a constructor can >>> call any methods). >>> >>> From the VM POV, a Q-type never appears inside a method descriptor. It >>> appears inside field descriptor but putfield, getfield and withfield allows >>> a field declared as a Q-type to be accessed as a L-type (this is currently >>> simulated for getfield and putfield with an invokedynamic). This is very >>> similar to the way the VM deals with arrays. And the VM knows if a >>> parameter is a Q-type or not despite the fact that only L-type appears in >>> the method descriptor because the Q-type are declared in the Preload table >>> of the class. >>> >>> It means that if a class/record is not accessed directly by a >>> constructor but by some static factories (like Optional) then moving in >>> between an identity type, a value type (with zero-default or not) are >>> backward compatible changes. >>> >>> regards, >>> R?mi >>> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 19 20:53:10 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 19 Jan 2023 21:53:10 +0100 (CET) Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: <1879298881.1681645.1674161590558.JavaMail.zimbra@u-pem.fr> > From: "Red IO" > To: "Anderson Vasconcelos Pires" > Cc: "Remi Forax" , "valhalla-dev" > > Sent: Thursday, January 19, 2023 9:19:09 PM > Subject: Re: Civilizer - let's civilize those primitive types ! > If we talk about the user model for the explicit nullability of refrences we > should think about allowing the developer to turn it around. Meaning that every > reference is treated non null when not marked otherwise. But this should > definitely strictly be "an option" that you can enable somehow. > This can be really beneficial since the compiler can mark every point where an > (default) non nullable is assigned (potential) null value or a nullable > variable is dereferenced at all. > I just got the idea of inverting the nullability default from c# which has this > feature. I recently flipped it on one of my projects and the entire code lit up > with warnings. Showing countless spots where a null check was missing. > It would be logical to use "!" for explicit non-null and "?" for explicit > nullable. With 1 being optional in each case rather the default is inversed or > not. This is what the annotation @NullMarked of jspecify does [1], but again, this thread is about getting the VM model right, not getting the Java semantics right. > Great regards > RedIODev [1] https://jspecify.dev/ > On Wed, Jan 11, 2023, 18:30 Anderson Vasconcelos Pires < [ > mailto:andvasp at gmail.com | andvasp at gmail.com ] > wrote: >> Thanks for the prompt response! >>>> Mostly prototyping a proposal to remove Q-types (descriptor that starts with >>>> Q...;) and replace them by an attribute on methods and fields indicating if the >>>> value can be null. >>> see [ >>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>> | >>> https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html >>> ] >> So if you want to remove Q types it means that L type does not need the identity >> information, right? >>> There is no notion of .val or .ref, if you want a field to be flattened, use a >>> @Zero-Default and declare the field @NonNull. >> Pretty good if we do not need to use .val or .ref! >> Could the @NonNull be replaced by "!" but writing the attribute in the class >> file? >> I Like @NonNull but I believe the "!" would be more practical. >> As @Nullable is the default, maybe it would not be necessary to have it. >>>> yes, the prototype does not do any verification that the compiler does, i'm too >>>> lazy for that but the VM will catch you and throw an Error >> Pretty good for a prototype! >>> About the mutability of fields, fundamentally, value type is about saying, i >>> give up the notion of identity, if you have no identity, you have no location >>> in memory (you can have more than one if you prefer) so the VM is free to pass >>> by reference or pass by value. So you can not mutate a field, because you can >>> only do that if you have one location in memory. >> Ok for mutability but now I am a little bit confused about references, identity >> and memory location. Value class is a reference type that does not have >> identity. So it means that it can be allocated in the heap, right? So >> allocating it in the heap will have a memory location, do not? >>>> regards, >>> R?mi >> Thanks for the explanation! >> Regards, >> Anderson. >>>> On Tue, Jan 10, 2023 at 7:39 PM Remi Forax < [ mailto:forax at univ-mlv.fr | >>>> forax at univ-mlv.fr ] > wrote: >>>>> Hi all, >>>>> i've developed a small prototype of what the semantics for the next round could >>>>> be >>>>> [ https://github.com/forax/civilizer/ | https://github.com/forax/civilizer/ ] >>>>> The prototype works with the latest valhalla early access build >>>>> [ https://jdk.java.net/valhalla/ | https://jdk.java.net/valhalla/ ] >>>>> Basically, everything is an object, using @Value in front of a class or a record >>>>> transforms it to a value class, a class with no identity >>>>> (== compares the fields, synchronized throws an IllegalMonitorStateException, >>>>> new WeakRef<>(...) throws an IdentityException). >>>>> Adding @ZeroDefault means that the default value of the value class which is not >>>>> null is all fields filled with zero. >>>>> @NonNull allows to declare a non-null type (there is also @Nullable which is the >>>>> default if there is no null aware annotation). >>>>> For parameters, like Kotlin, sending null to a parameter of a method annotated >>>>> with @NonNull throws a NPE. >>>>> For a field a zero-default annotated with @NonNull ask for flattening, trying to >>>>> store null also throws a NPE. >>>>> For a field which is not a zero-default, even if declared @NonNull, the runtime >>>>> will *not* throw a NPE because the field is null before reaching its >>>>> initialization assignment in the constructor (and a constructor can call any >>>>> methods). >>>>> From the VM POV, a Q-type never appears inside a method descriptor. It appears >>>>> inside field descriptor but putfield, getfield and withfield allows a field >>>>> declared as a Q-type to be accessed as a L-type (this is currently simulated >>>>> for getfield and putfield with an invokedynamic). This is very similar to the >>>>> way the VM deals with arrays. And the VM knows if a parameter is a Q-type or >>>>> not despite the fact that only L-type appears in the method descriptor because >>>>> the Q-type are declared in the Preload table of the class. >>>>> It means that if a class/record is not accessed directly by a constructor but by >>>>> some static factories (like Optional) then moving in between an identity type, >>>>> a value type (with zero-default or not) are backward compatible changes. >>>>> regards, >>>>> R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Tue Jan 24 20:17:55 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 24 Jan 2023 15:17:55 -0500 Subject: Civilizer - let's civilize those primitive types ! In-Reply-To: References: <1770463843.82548771.1673390305709.JavaMail.zimbra@u-pem.fr> <570443953.82990555.1673445652096.JavaMail.zimbra@u-pem.fr> Message-ID: Just a reminder -- this topic is out of scope for valhalla-dev, which is for implementation discussions, not language design. Let's just say that we are more than aware that there is overlap between nullity and value types, and that some developers really^3 like the idea of having nullity control in the language.? We can leave it at that for now. (BTW this has been explored not only by c#, but by several explorations in the Java ecosystem, including the checkers framework and the jspecify effort.? (Which are also out of scope for this list.)) On 1/19/2023 3:19 PM, Red IO wrote: > If we talk about the user model for the explicit nullability of > refrences we should think about allowing the developer to turn it > around. Meaning that every reference is treated non null when not > marked otherwise. But this should definitely strictly be "an option" > that you can enable somehow. > This can be really beneficial since the compiler can mark every point > where an (default) non nullable is assigned (potential) null value or > a nullable variable is dereferenced at all. > I just got the idea of inverting the nullability default from c# which > has this feature. I recently flipped it on one of my projects and the > entire code lit up with warnings. Showing countless spots where a null > check was missing. > It would be logical to use "!" for explicit non-null and "?" for > explicit nullable. With 1 being optional in each case rather the > default is inversed or not. > > Great regards > RedIODev > > On Wed, Jan 11, 2023, 18:30 Anderson Vasconcelos Pires > wrote: > > Thanks for the prompt response! > > Mostly prototyping a proposal to remove Q-types > (descriptor that starts with Q...;) and replace them by an > attribute on methods and fields indicating if the value > can be null. > > see > https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-January/002217.html > > > So if you want to remove Q types it means that L type does not > need the identity information, right? > > > There is no notion of .val or .ref, if you want a field to be > flattened, use a @Zero-Default and declare the field @NonNull. > > > Pretty good if we do not need to use .val or .ref! > > Could the @NonNull be replaced by "!" but writing the attribute in > the class file? > > I Like?@NonNull but I believe the "!" would be more practical. > > As @Nullable is the default, maybe it would not be necessary to > have it. > > yes, the prototype does not do any verification that the > compiler does, i'm too lazy for that but the VM will catch > you and throw an Error > > > Pretty good for a prototype! > > About the mutability of fields, fundamentally, value type is > about saying, i give up the notion of identity, if you have no > identity, you have no location in memory (you can have more > than one if you prefer) so the VM is free to pass by reference > or pass by value. So you can not mutate a field, because you > can only do that if you have one location in memory. > > > Ok for mutability but now I am a little bit confused about > references, identity and memory location. Value class is a > reference type that does not have identity. So it means that it > can be allocated in the heap, right? So allocating it in the heap > will?have a memory location, do not? > > regards, > > R?mi > > > Thanks for the explanation! > > Regards, > Anderson. > > > On Tue, Jan 10, 2023 at 7:39 PM Remi Forax > wrote: > > Hi all, > i've developed a small prototype of what the semantics > for the next round could be > https://github.com/forax/civilizer/ > > The prototype works with the latest valhalla early > access build > https://jdk.java.net/valhalla/ > > Basically, everything is an object, using @Value in > front of a class or a record transforms it to a value > class, a class with no identity > (== compares the fields, synchronized throws an > IllegalMonitorStateException, new WeakRef<>(...) > throws an IdentityException). > Adding @ZeroDefault means that the default value of > the value class which is not null is all fields filled > with zero. > > @NonNull allows to declare a non-null type (there is > also @Nullable which is the default if there is no > null aware annotation). > For parameters, like Kotlin, sending null to a > parameter of a method annotated with @NonNull throws a > NPE. > For a field a zero-default annotated with @NonNull ask > for flattening, trying to store null also throws a NPE. > For a field which is not a zero-default, even if > declared @NonNull, the runtime will *not* throw a NPE > because the field is null before reaching its > initialization assignment in the constructor (and a > constructor can call any methods). > > From the VM POV, a Q-type never appears inside a > method descriptor. It appears inside field descriptor > but putfield, getfield and withfield allows a field > declared as a Q-type to be accessed as a L-type (this > is currently simulated for getfield and putfield with > an invokedynamic). This is very similar to the way the > VM deals with arrays. And the VM knows if a parameter > is a Q-type or not despite the fact that only L-type > appears in the method descriptor because the Q-type > are declared in the Preload table of the class. > > It means that if a class/record is not accessed > directly by a constructor but by some static factories > (like Optional) then moving in between an identity > type, a value type (with zero-default or not) are > backward compatible changes. > > regards, > R?mi > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vromero at openjdk.org Thu Jan 26 04:31:18 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 26 Jan 2023 04:31:18 GMT Subject: RFR: fixing regression test Message-ID: Fixing regression test that was failing after latest merge with lworld ------------- Commit messages: - fixing regression test Changes: https://git.openjdk.org/valhalla/pull/817/files Webrev: https://webrevs.openjdk.org/?repo=valhalla&pr=817&range=00 Stats: 17 lines in 1 file changed: 3 ins; 2 del; 12 mod Patch: https://git.openjdk.org/valhalla/pull/817.diff Fetch: git fetch https://git.openjdk.org/valhalla pull/817/head:pull/817 PR: https://git.openjdk.org/valhalla/pull/817 From vromero at openjdk.org Thu Jan 26 04:51:55 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 26 Jan 2023 04:51:55 GMT Subject: Integrated: fixing regression test In-Reply-To: References: Message-ID: On Thu, 26 Jan 2023 04:25:35 GMT, Vicente Romero wrote: > Fixing regression test that was failing after latest merge with lworld This pull request has now been integrated. Changeset: 1645d96a Author: Vicente Romero URL: https://git.openjdk.org/valhalla/commit/1645d96ac94325065926bc7c6a49dc5c54349960 Stats: 17 lines in 1 file changed: 3 ins; 2 del; 12 mod fixing regression test ------------- PR: https://git.openjdk.org/valhalla/pull/817