Re: RFR: 8230501: Class data support for hidden classes [v7]

2020-11-30 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
> index)`
> are the bootstrap methods to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the 

Re: RFR: 8230501: Class data support for hidden classes [v6]

2020-11-24 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
> index)`
> are the bootstrap methods to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the 

Re: RFR: 8230501: Class data support for hidden classes [v5]

2020-11-24 Thread Chris Hegarty
On Sat, 21 Nov 2020 00:39:23 GMT, Mandy Chung  wrote:

>> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
>> objects
>> be shared between a hidden class and other classes.  A hidden class can load
>> these live objects as dynamically-computed constants via this API.
>> 
>> Specdiff
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
>> 
>> With this class data support and hidden classes, 
>> `sun.misc.Unsafe::defineAnonymousClass`
>> will be deprecated for removal.  Existing libraries should replace their
>> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
>> `Lookup::defineHiddenClass`
>> or `Lookup::defineHiddenClassWithClassData`.
>> 
>> This patch also updates the implementation of lambda meta factory and
>> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
>> difference
>> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
>> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
>> JDK-8254162 but it helps validating the class data support.
>> 
>> Background
>> --
>> 
>> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
>> "Constant-pool patching" in the "Risks and Assumption" section.
>> 
>> A VM-anonymous class can be defined with its constant-pool entries already
>> resolved to concrete values. This allows critical constants to be shared
>> between a VM-anonymous class and the language runtime that defines it, and
>> between multiple VM-anonymous classes. For example, a language runtime will
>> often have `MethodHandle` objects in its address space that would be useful
>> to newly-defined VM-anonymous classes. Instead of the runtime serializing
>> the objects to constant-pool entries in VM-anonymous classes and then
>> generating bytecode in those classes to laboriously `ldc` the entries,
>> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
>> to its live objects. The relevant constant-pool entries in the newly-defined
>> VM-anonymous class are pre-linked to those objects, improving performance
>> and reducing footprint. In addition, this allows VM-anonymous classes to
>> refer to each other: Constant-pool entries in a class file are based on 
>> names.
>> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
>> can,
>> however, easily track the live Class objects for its VM-anonymous classes and
>> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
>> class's
>> constant pool entries to other VM-anonymous classes.
>> 
>> This extends the hidden classes to allow live objects to be injected
>> in a hidden class and loaded them via condy.
>> 
>> Details
>> ---
>> 
>> A new `Lookup::defineHiddenClassWithClassData` API takes additional
>> `classData` argument compared to `Lookup::defineHiddenClass`.
>> Class data can be method handles, lookup objects, arbitrary user objects
>> or collections of all of the above.
>> 
>> This method behaves as if calling `Lookup::defineHiddenClass` to define
>> a hidden class with a private static unnamed field that is initialized
>> with `classData` at the first instruction of the class initializer.
>> 
>> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
>> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
>> index)`
>> are the bootstrap methods to load the class data of the given lookup's 
>> lookup class.
>> The hidden class will be initialized when `classData` method is called if
>> the hidden class has not been initialized.
>> 
>> For a class data containing more than one single element, libraries can
>> create their convenience method to load a single live object via condy.
>> 
>> Frameworks sometimes want to dynamically create a hidden class (HC) and add 
>> it
>> it the lookup class nest and have HC to carry secrets hidden from that nest.
>> In this case, frameworks should not to use private static finals (in the HCs
>> they spin) to hold secrets because a nestmate of HC may obtain access to
>> such a private static final and observe the framework's secret.  It should 
>> use
>> condy.  In addition, we need to differentiate if a lookup object is created 
>> from
>> the original lookup class or created from teleporting e.g. `Lookup::in`
>> and `MethodHandles::privateLookupIn`.
>> 
>> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
>> object is created by `MethodHandles::lookup` or by bootstrap method 
>> invocation.
>> The operations only apply to a Lookup object with original access are:
>>- create method handles for caller-sensitve methods
>>- obtain class data associated with the lookup class
>> 
>> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
>> ignores the ORIGINAL bit.
>> 
>> 
>> Compatibility Risks
>> ---
>> 
>> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
>> ignore this 

Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-24 Thread Chris Hegarty
On Mon, 23 Nov 2020 17:48:31 GMT, Mandy Chung  wrote:

> > It is my understanding that `Lookup` object returned from 
> > defineHiddenClass[WithClassData] features the ORIGINAL access lookup mode, 
> > right? I cannot find a normative statement to confirm this. If it is the 
> > case, then it would be good to clarify this.
> 
> Yes with ORIGINAL access. I updated `@return` for both `defineHiddenClass` 
> and `defineHiddenClassWithClassData` as follows:
> 
> ```
> - * @return the {@code Lookup} object on the hidden class
> + * @return the {@code Lookup} object on the hidden class with
> + * {@linkplain #ORIGINAL original} and
> + * {@linkplain Lookup#hasFullPrivilegeAccess() full privilege} access
> ```

Thank you. This addresses my concern.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-23 Thread Mandy Chung
On Mon, 23 Nov 2020 10:23:25 GMT, Chris Hegarty  wrote:

> It is my understanding that `Lookup` object returned from 
> defineHiddenClass[WithClassData] features the ORIGINAL access lookup mode, 
> right? I cannot find a normative statement to confirm this. If it is the 
> case, then it would be good to clarify this.

Yes with ORIGINAL access.   I updated `@return` for both `defineHiddenClass` 
and `defineHiddenClassWithClassData` as follows:

- * @return the {@code Lookup} object on the hidden class
+ * @return the {@code Lookup} object on the hidden class with
+ * {@linkplain #ORIGINAL original} and
+ * {@linkplain Lookup#hasFullPrivilegeAccess() full privilege} access

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-23 Thread Chris Hegarty
On Thu, 19 Nov 2020 11:08:26 GMT, Jorn Vernee  wrote:

>> Mandy Chung has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fix the name passed to condy calling classData
>
> Left 2 minor comments on the new additions in line.

It is my understanding that `Lookup` object returned from 
defineHiddenClass[WithClassData] features the ORIGINAL access lookup mode, 
right? I cannot find a normative statement to confirm this. If it is the case, 
then it would be good to clarify this.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v5]

2020-11-20 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
> index)`
> are the bootstrap methods to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the 

Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-20 Thread Jorn Vernee
On Fri, 20 Nov 2020 20:23:27 GMT, Mandy Chung  wrote:

>> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 2148:
>> 
>>> 2146:  * (unlike private static fields that are accessible to 
>>> nestmates).
>>> 2147:  * Care should be taken w.r.t. mutability for example when 
>>> passing
>>> 2148:  * an array or other mutable structure through the class data.
>> 
>> I don't think it's necessarily clear _why_/_how_ care should be taken from 
>> this text. I suggest:
>> Suggestion:
>> 
>>  * Care should be taken w.r.t. mutability for example when passing
>>  * an array or other mutable structure through the class data. Such
>>  * a constant should not be mutated, as downstream consumers of
>>  * this constant, such as other constants, are not guaranteed to see
>>  * the updated value, depending on the timing of their resolution.
>
> What about:
> 
> --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
> +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
> @@ -2156,8 +2156,10 @@ public class MethodHandles {
>   * (unlike private static fields that are accessible to nestmates).
>   * Care should be taken w.r.t. mutability for example when passing
>   * an array or other mutable structure through the class data.
> - * If you use a {@code List}, it is a good practice to make it 
> unmodifiable
> - * for example via {@link List#of List::of}.
> + * Changing any value stored at the class data at runtime may lead to
> + * unpredictable behavior.
> + * If the class data is a {@code List}, it is a good practice to 
> make it
> + * unmodifiable for example via {@link List#of List::of}.
>   *
>   * @param bytes the class bytes
>   * @param classData pre-initialized class data

Looks good!

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-20 Thread Mandy Chung
On Thu, 19 Nov 2020 10:59:30 GMT, Jorn Vernee  wrote:

>> Mandy Chung has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fix the name passed to condy calling classData
>
> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 2148:
> 
>> 2146:  * (unlike private static fields that are accessible to 
>> nestmates).
>> 2147:  * Care should be taken w.r.t. mutability for example when 
>> passing
>> 2148:  * an array or other mutable structure through the class data.
> 
> I don't think it's necessarily clear _why_/_how_ care should be taken from 
> this text. I suggest:
> Suggestion:
> 
>  * Care should be taken w.r.t. mutability for example when passing
>  * an array or other mutable structure through the class data. Such
>  * a constant should not be mutated, as downstream consumers of
>  * this constant, such as other constants, are not guaranteed to see
>  * the updated value, depending on the timing of their resolution.

What about:

--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
@@ -2156,8 +2156,10 @@ public class MethodHandles {
  * (unlike private static fields that are accessible to nestmates).
  * Care should be taken w.r.t. mutability for example when passing
  * an array or other mutable structure through the class data.
- * If you use a {@code List}, it is a good practice to make it 
unmodifiable
- * for example via {@link List#of List::of}.
+ * Changing any value stored at the class data at runtime may lead to
+ * unpredictable behavior.
+ * If the class data is a {@code List}, it is a good practice to make 
it
+ * unmodifiable for example via {@link List#of List::of}.
  *
  * @param bytes the class bytes
  * @param classData pre-initialized class data

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-19 Thread Jorn Vernee
On Wed, 18 Nov 2020 00:50:22 GMT, Mandy Chung  wrote:

>> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
>> objects
>> be shared between a hidden class and other classes.  A hidden class can load
>> these live objects as dynamically-computed constants via this API.
>> 
>> Specdiff
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
>> 
>> With this class data support and hidden classes, 
>> `sun.misc.Unsafe::defineAnonymousClass`
>> will be deprecated for removal.  Existing libraries should replace their
>> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
>> `Lookup::defineHiddenClass`
>> or `Lookup::defineHiddenClassWithClassData`.
>> 
>> This patch also updates the implementation of lambda meta factory and
>> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
>> difference
>> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
>> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
>> JDK-8254162 but it helps validating the class data support.
>> 
>> Background
>> --
>> 
>> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
>> "Constant-pool patching" in the "Risks and Assumption" section.
>> 
>> A VM-anonymous class can be defined with its constant-pool entries already
>> resolved to concrete values. This allows critical constants to be shared
>> between a VM-anonymous class and the language runtime that defines it, and
>> between multiple VM-anonymous classes. For example, a language runtime will
>> often have `MethodHandle` objects in its address space that would be useful
>> to newly-defined VM-anonymous classes. Instead of the runtime serializing
>> the objects to constant-pool entries in VM-anonymous classes and then
>> generating bytecode in those classes to laboriously `ldc` the entries,
>> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
>> to its live objects. The relevant constant-pool entries in the newly-defined
>> VM-anonymous class are pre-linked to those objects, improving performance
>> and reducing footprint. In addition, this allows VM-anonymous classes to
>> refer to each other: Constant-pool entries in a class file are based on 
>> names.
>> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
>> can,
>> however, easily track the live Class objects for its VM-anonymous classes and
>> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
>> class's
>> constant pool entries to other VM-anonymous classes.
>> 
>> This extends the hidden classes to allow live objects to be injected
>> in a hidden class and loaded them via condy.
>> 
>> Details
>> ---
>> 
>> A new `Lookup::defineHiddenClassWithClassData` API takes additional
>> `classData` argument compared to `Lookup::defineHiddenClass`.
>> Class data can be method handles, lookup objects, arbitrary user objects
>> or collections of all of the above.
>> 
>> This method behaves as if calling `Lookup::defineHiddenClass` to define
>> a hidden class with a private static unnamed field that is initialized
>> with `classData` at the first instruction of the class initializer.
>> 
>> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
>> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
>> index)`
>> are the bootstrap methods to load the class data of the given lookup's 
>> lookup class.
>> The hidden class will be initialized when `classData` method is called if
>> the hidden class has not been initialized.
>> 
>> For a class data containing more than one single element, libraries can
>> create their convenience method to load a single live object via condy.
>> 
>> Frameworks sometimes want to dynamically create a hidden class (HC) and add 
>> it
>> it the lookup class nest and have HC to carry secrets hidden from that nest.
>> In this case, frameworks should not to use private static finals (in the HCs
>> they spin) to hold secrets because a nestmate of HC may obtain access to
>> such a private static final and observe the framework's secret.  It should 
>> use
>> condy.  In addition, we need to differentiate if a lookup object is created 
>> from
>> the original lookup class or created from teleporting e.g. `Lookup::in`
>> and `MethodHandles::privateLookupIn`.
>> 
>> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
>> object is created by `MethodHandles::lookup` or by bootstrap method 
>> invocation.
>> The operations only apply to a Lookup object with original access are:
>>- create method handles for caller-sensitve methods
>>- obtain class data associated with the lookup class
>> 
>> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
>> ignores the ORIGINAL bit.
>> 
>> 
>> Compatibility Risks
>> ---
>> 
>> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
>> ignore this 

Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-18 Thread Mandy Chung
On Wed, 18 Nov 2020 17:26:02 GMT, Paul Sandoz  wrote:

>> Mandy Chung has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fix the name passed to condy calling classData
>
> IIUC `classData` can be used for an original lookup that is not produced by 
> the result of `defineHiddenClassWithClassData`, but in such cases the class 
> data will always be null.
> 
> Since `defineHiddenClassWithClassData` rejects null values for class data, we 
> could detect such usage and throw in the bootstrap methods. That would 
> require a special constant assignment for hidden classes with no class data. 
> Probably not worth it.
> 
> Recommend an API note.

@PaulSandoz @JornVernee can you please review CSR:
https://bugs.openjdk.java.net/browse/JDK-8256214

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-18 Thread Mandy Chung
On Wed, 18 Nov 2020 17:26:02 GMT, Paul Sandoz  wrote:

> IIUC classData can be used for an original lookup that is not produced by the 
> result of defineHiddenClassWithClassData, but in such cases the class data 
> will always be null.

Yes that's the case.  I see some clarification would help.I added the 
following in the spec of `classData` and `classDataAt`:

 *  A hidden class created by {@link Lookup#defineHiddenClass(byte[], 
boolean, Lookup.ClassOption...)
 * Lookup::defineHiddenClass} and non-hidden classes have no class data.
 * {@code null} is returned if this method is called on the lookup object
 * on these classes.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-18 Thread Mandy Chung
On Wed, 18 Nov 2020 16:51:47 GMT, Paul Sandoz  wrote:

>> Mandy Chung has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fix the name passed to condy calling classData
>
> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 342:
> 
>> 340:  } catch (ClassCastException e) {
>> 341:  throw e;
>> 342:  } catch (Throwable e) {
> 
> The following might be more appropriate so, in general, errors and runtime 
> exceptions are not explicitly wrapped:
> 
> try {
> return BootstrapMethodInvoker.widenAndCast(classdata, type);
> }
> catch (RuntimeException | Error e) {
> throw e;
> }
> catch (Throwable e) {
> throw new InternalError("Unexpected exception", e);
> }
> 
> same applies to `classDataAt` and `ConstantBootstraps.explicitCast`. 
> Refinement of the runtime exceptions is also possible, but i think the key 
> thing here is to let errors pass through and any possibly expected runtime 
> exceptions will get wrapped in `BootstrapMethodError`.

Yes a good refinement.

diff --git 
a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java 
b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
index 71cae83e160..27d74284dc6 100644
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java
@@ -413,8 +413,8 @@ public final class ConstantBootstraps {
 MethodHandle conv = MethodHandles.explicitCastArguments(id, mt);
 try {
 return conv.invoke(value);
-} catch (ClassCastException e) {
-throw e; // specified, let CCE through
+} catch (RuntimeException|Error e) {
+throw e; // let specified CCE and other runtime exceptions/errors 
through
 } catch (Throwable throwable) {
 throw new InternalError(throwable); // Not specified, throw 
InternalError
 }
diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 
b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
index cd9bdbaf5a3..368948ab5a8 100644
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
@@ -337,8 +342,8 @@ public class MethodHandles {
 
  try {
  return BootstrapMethodInvoker.widenAndCast(classdata, type);
- } catch (ClassCastException e) {
- throw e;
+ } catch (RuntimeException|Error e) {
+ throw e; // let CCE and other runtime exceptions through
  } catch (Throwable e) {
  throw new InternalError(e);
  }
@@ -409,8 +414,8 @@ public class MethodHandles {
 try {
 Object element = classdata.get(index);
 return BootstrapMethodInvoker.widenAndCast(element, type);
-} catch 
(ClassCastException|NullPointerException|IndexOutOfBoundsException e) {
-throw e;
+} catch (RuntimeException|Error e) {
+throw e; // let specified exceptions and other runtime 
exceptions/errors through
 } catch (Throwable e) {
 throw new InternalError(e);
 }

> test/jdk/java/lang/invoke/MethodHandles/classData/ClassDataTest.java line 77:
> 
>> 75:  */
>> 76: @Test
>> 77: public void noClassData() throws Throwable {
> 
> `throws Throwable` needed on this and other method declarations?

`noClassData` only needs `IllegalACcessException`.   `assertClassData` throws 
Throwable because it unwraps from `InvocationTargetException`.  I can take a 
pass to clean this up further.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-18 Thread Paul Sandoz
On Wed, 18 Nov 2020 00:50:22 GMT, Mandy Chung  wrote:

>> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
>> objects
>> be shared between a hidden class and other classes.  A hidden class can load
>> these live objects as dynamically-computed constants via this API.
>> 
>> Specdiff
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
>> 
>> With this class data support and hidden classes, 
>> `sun.misc.Unsafe::defineAnonymousClass`
>> will be deprecated for removal.  Existing libraries should replace their
>> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
>> `Lookup::defineHiddenClass`
>> or `Lookup::defineHiddenClassWithClassData`.
>> 
>> This patch also updates the implementation of lambda meta factory and
>> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
>> difference
>> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
>> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
>> JDK-8254162 but it helps validating the class data support.
>> 
>> Background
>> --
>> 
>> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
>> "Constant-pool patching" in the "Risks and Assumption" section.
>> 
>> A VM-anonymous class can be defined with its constant-pool entries already
>> resolved to concrete values. This allows critical constants to be shared
>> between a VM-anonymous class and the language runtime that defines it, and
>> between multiple VM-anonymous classes. For example, a language runtime will
>> often have `MethodHandle` objects in its address space that would be useful
>> to newly-defined VM-anonymous classes. Instead of the runtime serializing
>> the objects to constant-pool entries in VM-anonymous classes and then
>> generating bytecode in those classes to laboriously `ldc` the entries,
>> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
>> to its live objects. The relevant constant-pool entries in the newly-defined
>> VM-anonymous class are pre-linked to those objects, improving performance
>> and reducing footprint. In addition, this allows VM-anonymous classes to
>> refer to each other: Constant-pool entries in a class file are based on 
>> names.
>> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
>> can,
>> however, easily track the live Class objects for its VM-anonymous classes and
>> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
>> class's
>> constant pool entries to other VM-anonymous classes.
>> 
>> This extends the hidden classes to allow live objects to be injected
>> in a hidden class and loaded them via condy.
>> 
>> Details
>> ---
>> 
>> A new `Lookup::defineHiddenClassWithClassData` API takes additional
>> `classData` argument compared to `Lookup::defineHiddenClass`.
>> Class data can be method handles, lookup objects, arbitrary user objects
>> or collections of all of the above.
>> 
>> This method behaves as if calling `Lookup::defineHiddenClass` to define
>> a hidden class with a private static unnamed field that is initialized
>> with `classData` at the first instruction of the class initializer.
>> 
>> `MethodHandles::classData(Lookup lookup, String name, Class type)` and
>> `MethodHandles::classDataAt(Lookup lookup, String name, Class type, int 
>> index)`
>> are the bootstrap methods to load the class data of the given lookup's 
>> lookup class.
>> The hidden class will be initialized when `classData` method is called if
>> the hidden class has not been initialized.
>> 
>> For a class data containing more than one single element, libraries can
>> create their convenience method to load a single live object via condy.
>> 
>> Frameworks sometimes want to dynamically create a hidden class (HC) and add 
>> it
>> it the lookup class nest and have HC to carry secrets hidden from that nest.
>> In this case, frameworks should not to use private static finals (in the HCs
>> they spin) to hold secrets because a nestmate of HC may obtain access to
>> such a private static final and observe the framework's secret.  It should 
>> use
>> condy.  In addition, we need to differentiate if a lookup object is created 
>> from
>> the original lookup class or created from teleporting e.g. `Lookup::in`
>> and `MethodHandles::privateLookupIn`.
>> 
>> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
>> object is created by `MethodHandles::lookup` or by bootstrap method 
>> invocation.
>> The operations only apply to a Lookup object with original access are:
>>- create method handles for caller-sensitve methods
>>- obtain class data associated with the lookup class
>> 
>> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
>> ignores the ORIGINAL bit.
>> 
>> 
>> Compatibility Risks
>> ---
>> 
>> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
>> ignore this 

Re: RFR: 8230501: Class data support for hidden classes [v4]

2020-11-17 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the return value of 

Re: RFR: 8230501: Class data support for hidden classes [v3]

2020-11-17 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the return value of 

Re: RFR: 8230501: Class data support for hidden classes [v2]

2020-11-13 Thread Jorn Vernee
On Fri, 13 Nov 2020 18:42:53 GMT, Mandy Chung  wrote:

> > Also (as mentioned offline), while it's possible with the current API to 
> > provide an `Object[]` as class data, and then load elements of that array 
> > into CP entries using downstream condys (e.g. by creating an array access 
> > var handle and then using that), I think it would be good to add a 
> > `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this 
> > (seemingly) common case easier (maybe also a `getField` for loading 
> > instance fields). This would help to address the case where multiple live 
> > constants need to be injected.
> 
> I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because 
> an array is modifiable and _not_ true constant. A final instance field can be 
> modified via reflection and therefore it's not trusted as a constant either.

I guess it would be similar to doing something like:

private static final Object[] arr = getArray();
private static final Object o = arr[0];

Setting `arr[0] = new Object();` would not affect `o` after it has been 
initialized. The difference being that a constant for the array element would 
be resolved (more) lazily, so it would be possible to resolve the array, then 
modify it, and then resolve the constant that loads the element, which would 
see the updated value as well.

However, we can already store an array in the constant pool today, and modify 
it if we want, even though, as you say, it is mutable. In that sense 
getArrayElement doesn't introduce anything new.

Mutating the array is probably a bad idea though, so maybe we want to push 
users away from using arrays? To prevent inadvertent modification, maybe an 
immutable `List` should be used in place of a plain array. In that case, would 
you feel differently about added a `getListElement` BSM, that gets an element 
from an (immutable) List instead?

Another idea is to rely on records, since they can not be mutated with 
reflection at all. i.e. we add a getRecordComponent BSM instead, so a class 
data Object can be a record, and then the BSM can be used to extract individual 
components.

WDYT?

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v2]

2020-11-13 Thread Jorn Vernee
On Fri, 13 Nov 2020 19:23:54 GMT, Jorn Vernee  wrote:

>>> Also (as mentioned offline), while it's possible with the current API to 
>>> provide an `Object[]` as class data, and then load elements of that array 
>>> into CP entries using downstream condys (e.g. by creating an array access 
>>> var handle and then using that), I think it would be good to add a 
>>> `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this 
>>> (seemingly) common case easier (maybe also a `getField` for loading 
>>> instance fields). This would help to address the case where multiple live 
>>> constants need to be injected.
>> 
>> I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because 
>> an array is modifiable and _not_ true constant.   A final instance field can 
>> be modified via reflection and therefore it's not trusted as a constant 
>> either.
>
>> > Also (as mentioned offline), while it's possible with the current API to 
>> > provide an `Object[]` as class data, and then load elements of that array 
>> > into CP entries using downstream condys (e.g. by creating an array access 
>> > var handle and then using that), I think it would be good to add a 
>> > `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this 
>> > (seemingly) common case easier (maybe also a `getField` for loading 
>> > instance fields). This would help to address the case where multiple live 
>> > constants need to be injected.
>> 
>> I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because 
>> an array is modifiable and _not_ true constant. A final instance field can 
>> be modified via reflection and therefore it's not trusted as a constant 
>> either.
> 
> I guess it would be similar to doing something like:
> 
> private static final Object[] arr = getArray();
> private static final Object o = arr[0];
> 
> Setting `arr[0] = new Object();` would not affect `o` after it has been 
> initialized. The difference being that a constant for the array element would 
> be resolved (more) lazily, so it would be possible to resolve the array, then 
> modify it, and then resolve the constant that loads the element, which would 
> see the updated value as well.
> 
> However, we can already store an array in the constant pool today, and modify 
> it if we want, even though, as you say, it is mutable. In that sense 
> getArrayElement doesn't introduce anything new.
> 
> Mutating the array is probably a bad idea though, so maybe we want to push 
> users away from using arrays? To prevent inadvertent modification, maybe an 
> immutable `List` should be used in place of a plain array. In that case, 
> would you feel differently about added a `getListElement` BSM, that gets an 
> element from an (immutable) List instead?
> 
> Another idea is to rely on records, since they can not be mutated with 
> reflection at all. i.e. we add a getRecordComponent BSM instead, so a class 
> data Object can be a record, and then the BSM can be used to extract 
> individual components.
> 
> WDYT?

Sorry, this is unrelated to this RFR, I will start a separate discussion thread 
elsewhere.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v2]

2020-11-13 Thread Mandy Chung
On Thu, 12 Nov 2020 15:19:30 GMT, Jorn Vernee  wrote:

> Also (as mentioned offline), while it's possible with the current API to 
> provide an `Object[]` as class data, and then load elements of that array 
> into CP entries using downstream condys (e.g. by creating an array access var 
> handle and then using that), I think it would be good to add a 
> `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this 
> (seemingly) common case easier (maybe also a `getField` for loading instance 
> fields). This would help to address the case where multiple live constants 
> need to be injected.

I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because an 
array is modifiable and _not_ true constant.   A final instance field can be 
modified via reflection and therefore it's not trusted as a constant either.

-

PR: https://git.openjdk.java.net/jdk/pull/1171


Re: RFR: 8230501: Class data support for hidden classes [v2]

2020-11-12 Thread Mandy Chung
> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup class.  Existing code  
> compares
> the return value of 

Re: RFR: 8230501: Class data support for hidden classes

2020-11-12 Thread Mandy Chung
On Thu, 12 Nov 2020 14:18:17 GMT, Jorn Vernee  wrote:

>> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
>> objects
>> be shared between a hidden class and other classes.  A hidden class can load
>> these live objects as dynamically-computed constants via this API.
>> 
>> Specdiff
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
>> 
>> With this class data support and hidden classes, 
>> `sun.misc.Unsafe::defineAnonymousClass`
>> will be deprecated for removal.  Existing libraries should replace their
>> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
>> `Lookup::defineHiddenClass`
>> or `Lookup::defineHiddenClassWithClassData`.
>> 
>> This patch also updates the implementation of lambda meta factory and
>> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
>> difference
>> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
>> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
>> JDK-8254162 but it helps validating the class data support.
>> 
>> Background
>> --
>> 
>> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
>> "Constant-pool patching" in the "Risks and Assumption" section.
>> 
>> A VM-anonymous class can be defined with its constant-pool entries already
>> resolved to concrete values. This allows critical constants to be shared
>> between a VM-anonymous class and the language runtime that defines it, and
>> between multiple VM-anonymous classes. For example, a language runtime will
>> often have `MethodHandle` objects in its address space that would be useful
>> to newly-defined VM-anonymous classes. Instead of the runtime serializing
>> the objects to constant-pool entries in VM-anonymous classes and then
>> generating bytecode in those classes to laboriously `ldc` the entries,
>> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
>> to its live objects. The relevant constant-pool entries in the newly-defined
>> VM-anonymous class are pre-linked to those objects, improving performance
>> and reducing footprint. In addition, this allows VM-anonymous classes to
>> refer to each other: Constant-pool entries in a class file are based on 
>> names.
>> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
>> can,
>> however, easily track the live Class objects for its VM-anonymous classes and
>> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
>> class's
>> constant pool entries to other VM-anonymous classes.
>> 
>> This extends the hidden classes to allow live objects to be injected
>> in a hidden class and loaded them via condy.
>> 
>> Details
>> ---
>> 
>> A new `Lookup::defineHiddenClassWithClassData` API takes additional
>> `classData` argument compared to `Lookup::defineHiddenClass`.
>> Class data can be method handles, lookup objects, arbitrary user objects
>> or collections of all of the above.
>> 
>> This method behaves as if calling `Lookup::defineHiddenClass` to define
>> a hidden class with a private static unnamed field that is initialized
>> with `classData` at the first instruction of the class initializer.
>> 
>> `MethodHandles::classData(Lookup lookup, String name, Class type)`
>> is a bootstrap method to load the class data of the given lookup's lookup 
>> class.
>> The hidden class will be initialized when `classData` method is called if
>> the hidden class has not been initialized.
>> 
>> For a class data containing more than one single element, libraries can
>> create their convenience method to load a single live object via condy.
>> We can reconsider if such a convenience method is needed in the future.
>> 
>> Frameworks sometimes want to dynamically create a hidden class (HC) and add 
>> it
>> it the lookup class nest and have HC to carry secrets hidden from that nest.
>> In this case, frameworks should not to use private static finals (in the HCs
>> they spin) to hold secrets because a nestmate of HC may obtain access to
>> such a private static final and observe the framework's secret.  It should 
>> use
>> condy.  In addition, we need to differentiate if a lookup object is created 
>> from
>> the original lookup class or created from teleporting e.g. `Lookup::in`
>> and `MethodHandles::privateLookupIn`.
>> 
>> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
>> object is created by `MethodHandles::lookup` or by bootstrap method 
>> invocation.
>> The operations only apply to a Lookup object with original access are:
>>- create method handles for caller-sensitve methods
>>- obtain class data associated with the lookup class
>> 
>> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
>> ignores the ORIGINAL bit.
>> 
>> 
>> Compatibility Risks
>> ---
>> 
>> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
>> ignore this original bit except 

Re: RFR: 8230501: Class data support for hidden classes

2020-11-12 Thread Jorn Vernee
On Thu, 12 Nov 2020 15:11:03 GMT, Jorn Vernee  wrote:

>> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
>> objects
>> be shared between a hidden class and other classes.  A hidden class can load
>> these live objects as dynamically-computed constants via this API.
>> 
>> Specdiff
>> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
>> 
>> With this class data support and hidden classes, 
>> `sun.misc.Unsafe::defineAnonymousClass`
>> will be deprecated for removal.  Existing libraries should replace their
>> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
>> `Lookup::defineHiddenClass`
>> or `Lookup::defineHiddenClassWithClassData`.
>> 
>> This patch also updates the implementation of lambda meta factory and
>> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
>> difference
>> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
>> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
>> JDK-8254162 but it helps validating the class data support.
>> 
>> Background
>> --
>> 
>> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
>> "Constant-pool patching" in the "Risks and Assumption" section.
>> 
>> A VM-anonymous class can be defined with its constant-pool entries already
>> resolved to concrete values. This allows critical constants to be shared
>> between a VM-anonymous class and the language runtime that defines it, and
>> between multiple VM-anonymous classes. For example, a language runtime will
>> often have `MethodHandle` objects in its address space that would be useful
>> to newly-defined VM-anonymous classes. Instead of the runtime serializing
>> the objects to constant-pool entries in VM-anonymous classes and then
>> generating bytecode in those classes to laboriously `ldc` the entries,
>> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
>> to its live objects. The relevant constant-pool entries in the newly-defined
>> VM-anonymous class are pre-linked to those objects, improving performance
>> and reducing footprint. In addition, this allows VM-anonymous classes to
>> refer to each other: Constant-pool entries in a class file are based on 
>> names.
>> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
>> can,
>> however, easily track the live Class objects for its VM-anonymous classes and
>> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
>> class's
>> constant pool entries to other VM-anonymous classes.
>> 
>> This extends the hidden classes to allow live objects to be injected
>> in a hidden class and loaded them via condy.
>> 
>> Details
>> ---
>> 
>> A new `Lookup::defineHiddenClassWithClassData` API takes additional
>> `classData` argument compared to `Lookup::defineHiddenClass`.
>> Class data can be method handles, lookup objects, arbitrary user objects
>> or collections of all of the above.
>> 
>> This method behaves as if calling `Lookup::defineHiddenClass` to define
>> a hidden class with a private static unnamed field that is initialized
>> with `classData` at the first instruction of the class initializer.
>> 
>> `MethodHandles::classData(Lookup lookup, String name, Class type)`
>> is a bootstrap method to load the class data of the given lookup's lookup 
>> class.
>> The hidden class will be initialized when `classData` method is called if
>> the hidden class has not been initialized.
>> 
>> For a class data containing more than one single element, libraries can
>> create their convenience method to load a single live object via condy.
>> We can reconsider if such a convenience method is needed in the future.
>> 
>> Frameworks sometimes want to dynamically create a hidden class (HC) and add 
>> it
>> it the lookup class nest and have HC to carry secrets hidden from that nest.
>> In this case, frameworks should not to use private static finals (in the HCs
>> they spin) to hold secrets because a nestmate of HC may obtain access to
>> such a private static final and observe the framework's secret.  It should 
>> use
>> condy.  In addition, we need to differentiate if a lookup object is created 
>> from
>> the original lookup class or created from teleporting e.g. `Lookup::in`
>> and `MethodHandles::privateLookupIn`.
>> 
>> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
>> object is created by `MethodHandles::lookup` or by bootstrap method 
>> invocation.
>> The operations only apply to a Lookup object with original access are:
>>- create method handles for caller-sensitve methods
>>- obtain class data associated with the lookup class
>> 
>> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
>> ignores the ORIGINAL bit.
>> 
>> 
>> Compatibility Risks
>> ---
>> 
>> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
>> ignore this original bit except 

Re: RFR: 8230501: Class data support for hidden classes

2020-11-12 Thread Jorn Vernee
On Wed, 11 Nov 2020 18:52:10 GMT, Mandy Chung  wrote:

> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup 

Re: RFR: 8230501: Class data support for hidden classes

2020-11-11 Thread Mandy Chung
On Wed, 11 Nov 2020 18:52:10 GMT, Mandy Chung  wrote:

> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes, 
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with 
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation.
> The operations only apply to a Lookup object with original access are:
>- create method handles for caller-sensitve methods
>- obtain class data associated with the lookup class
> 
> No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
> ignores the ORIGINAL bit.
> 
> 
> Compatibility Risks
> ---
> 
> `Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
> ignore this original bit except creating method handles for caller-sensitive 
> methods
> that expects the lookup from the original lookup 

Re: RFR: 8230501: Class data support for hidden classes

2020-11-11 Thread Remi Forax
Hi Mandy,
maybe a stupid question but why this mechanism is limited to hidden classes ?

regards,
Rémi

- Mail original -
> De: "Mandy Chung" 
> À: "core-libs-dev" , "hotspot compiler" 
> 
> Envoyé: Mercredi 11 Novembre 2020 19:57:04
> Objet: RFR: 8230501: Class data support for hidden classes

> Provide the `Lookup::defineHiddenClassWithClassData` API that allows live
> objects
> be shared between a hidden class and other classes.  A hidden class can load
> these live objects as dynamically-computed constants via this API.
> 
> Specdiff
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html
> 
> With this class data support and hidden classes,
> `sun.misc.Unsafe::defineAnonymousClass`
> will be deprecated for removal.  Existing libraries should replace their
> calls to `sun.misc.Unsafe::defineAnonymousClass` with
> `Lookup::defineHiddenClass`
> or `Lookup::defineHiddenClassWithClassData`.
> 
> This patch also updates the implementation of lambda meta factory and
> `MemoryAccessVarHandleGenerator` to use class data.   No performance 
> difference
> observed in the jdk.incubator.foreign microbenchmarks.   A side note:
> `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of
> JDK-8254162 but it helps validating the class data support.
> 
> Background
> --
> 
> This is an enhancement following up JEP 371: Hidden Classes w.r.t.
> "Constant-pool patching" in the "Risks and Assumption" section.
> 
> A VM-anonymous class can be defined with its constant-pool entries already
> resolved to concrete values. This allows critical constants to be shared
> between a VM-anonymous class and the language runtime that defines it, and
> between multiple VM-anonymous classes. For example, a language runtime will
> often have `MethodHandle` objects in its address space that would be useful
> to newly-defined VM-anonymous classes. Instead of the runtime serializing
> the objects to constant-pool entries in VM-anonymous classes and then
> generating bytecode in those classes to laboriously `ldc` the entries,
> the runtime can simply supply `Unsafe::defineAnonymousClass` with references
> to its live objects. The relevant constant-pool entries in the newly-defined
> VM-anonymous class are pre-linked to those objects, improving performance
> and reducing footprint. In addition, this allows VM-anonymous classes to
> refer to each other: Constant-pool entries in a class file are based on names.
> They thus cannot refer to nameless VM-anonymous classes. A language runtime 
> can,
> however, easily track the live Class objects for its VM-anonymous classes and
> supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new 
> class's
> constant pool entries to other VM-anonymous classes.
> 
> This extends the hidden classes to allow live objects to be injected
> in a hidden class and loaded them via condy.
> 
> Details
> ---
> 
> A new `Lookup::defineHiddenClassWithClassData` API takes additional
> `classData` argument compared to `Lookup::defineHiddenClass`.
> Class data can be method handles, lookup objects, arbitrary user objects
> or collections of all of the above.
> 
> This method behaves as if calling `Lookup::defineHiddenClass` to define
> a hidden class with a private static unnamed field that is initialized
> with `classData` at the first instruction of the class initializer.
> 
> `MethodHandles::classData(Lookup lookup, String name, Class type)`
> is a bootstrap method to load the class data of the given lookup's lookup 
> class.
> The hidden class will be initialized when `classData` method is called if
> the hidden class has not been initialized.
> 
> For a class data containing more than one single element, libraries can
> create their convenience method to load a single live object via condy.
> We can reconsider if such a convenience method is needed in the future.
> 
> Frameworks sometimes want to dynamically create a hidden class (HC) and add it
> it the lookup class nest and have HC to carry secrets hidden from that nest.
> In this case, frameworks should not to use private static finals (in the HCs
> they spin) to hold secrets because a nestmate of HC may obtain access to
> such a private static final and observe the framework's secret.  It should use
> condy.  In addition, we need to differentiate if a lookup object is created 
> from
> the original lookup class or created from teleporting e.g. `Lookup::in`
> and `MethodHandles::privateLookupIn`.
> 
> This proposes to add a new `ORIGINAL` bit that is only set if the lookup
> object is created by `MethodHandles::lookup` or by bootstrap method 
> invocation

RFR: 8230501: Class data support for hidden classes

2020-11-11 Thread Mandy Chung
Provide the `Lookup::defineHiddenClassWithClassData` API that allows live 
objects
be shared between a hidden class and other classes.  A hidden class can load
these live objects as dynamically-computed constants via this API.

Specdiff
http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html

With this class data support and hidden classes, 
`sun.misc.Unsafe::defineAnonymousClass`
will be deprecated for removal.  Existing libraries should replace their
calls to `sun.misc.Unsafe::defineAnonymousClass` with 
`Lookup::defineHiddenClass`
or `Lookup::defineHiddenClassWithClassData`.

This patch also updates the implementation of lambda meta factory and
`MemoryAccessVarHandleGenerator` to use class data.   No performance difference
observed in the jdk.incubator.foreign microbenchmarks.   A side note: 
`MemoryAccessVarHandleGenerator` is removed in the upcoming integration of 
JDK-8254162 but it helps validating the class data support.

Background
--

This is an enhancement following up JEP 371: Hidden Classes w.r.t.
"Constant-pool patching" in the "Risks and Assumption" section.

A VM-anonymous class can be defined with its constant-pool entries already
resolved to concrete values. This allows critical constants to be shared
between a VM-anonymous class and the language runtime that defines it, and
between multiple VM-anonymous classes. For example, a language runtime will
often have `MethodHandle` objects in its address space that would be useful
to newly-defined VM-anonymous classes. Instead of the runtime serializing
the objects to constant-pool entries in VM-anonymous classes and then
generating bytecode in those classes to laboriously `ldc` the entries,
the runtime can simply supply `Unsafe::defineAnonymousClass` with references
to its live objects. The relevant constant-pool entries in the newly-defined
VM-anonymous class are pre-linked to those objects, improving performance
and reducing footprint. In addition, this allows VM-anonymous classes to
refer to each other: Constant-pool entries in a class file are based on names.
They thus cannot refer to nameless VM-anonymous classes. A language runtime can,
however, easily track the live Class objects for its VM-anonymous classes and
supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new class's
constant pool entries to other VM-anonymous classes.

This extends the hidden classes to allow live objects to be injected
in a hidden class and loaded them via condy.

Details
---

A new `Lookup::defineHiddenClassWithClassData` API takes additional
`classData` argument compared to `Lookup::defineHiddenClass`.
Class data can be method handles, lookup objects, arbitrary user objects
or collections of all of the above.

This method behaves as if calling `Lookup::defineHiddenClass` to define
a hidden class with a private static unnamed field that is initialized
with `classData` at the first instruction of the class initializer.

`MethodHandles::classData(Lookup lookup, String name, Class type)`
is a bootstrap method to load the class data of the given lookup's lookup class.
The hidden class will be initialized when `classData` method is called if
the hidden class has not been initialized.

For a class data containing more than one single element, libraries can
create their convenience method to load a single live object via condy.
We can reconsider if such a convenience method is needed in the future.

Frameworks sometimes want to dynamically create a hidden class (HC) and add it
it the lookup class nest and have HC to carry secrets hidden from that nest.
In this case, frameworks should not to use private static finals (in the HCs
they spin) to hold secrets because a nestmate of HC may obtain access to
such a private static final and observe the framework's secret.  It should use
condy.  In addition, we need to differentiate if a lookup object is created from
the original lookup class or created from teleporting e.g. `Lookup::in`
and `MethodHandles::privateLookupIn`.

This proposes to add a new `ORIGINAL` bit that is only set if the lookup
object is created by `MethodHandles::lookup` or by bootstrap method invocation.
The operations only apply to a Lookup object with original access are:
   - create method handles for caller-sensitve methods
   - obtain class data associated with the lookup class

No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which
ignores the ORIGINAL bit.


Compatibility Risks
---

`Lookup::lookupModes` includes a new `ORIGINAL` bit.  Most lookup operations
ignore this original bit except creating method handles for caller-sensitive 
methods
that expects the lookup from the original lookup class.  Existing code  compares
the return value of `lookupModes` to be a fixed value may be impacted.   However
existing client has no need to expect a fixed value of lookup modes.
The incompatibility risk of this spec change is low.

-

Commit messages: