Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-09 Thread Mandy Chung
On Fri, 3 Sep 2021 12:01:12 GMT, Vladimir Ivanov  wrote:

> > For the change of MethodHandle::asType to a final method, this needs a CSR.
> 
> It is not allowed to extend/subclass `MethodHandle` outside 
> `java.lang.invoke` package.
> So, the aforementioned change doesn't have any compatibility risks. Do I miss 
> something important?
> 
> ```
> /**
>  * Package-private constructor for the method handle implementation 
> hierarchy.
>  * Method handle inheritance will be contained completely within
>  * the {@code java.lang.invoke} package.
>  */
> // @param type type (permanently assigned) of the new method handle
> /*non-public*/
> MethodHandle(MethodType type, LambdaForm form) {
> ```

Sorry for the late reply as I was on vacation and just return today.

Thanks for the clarification.  I missed the fact that `MethodHandle` has no 
public constructor and cannot be extended.  This is fine.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-08 Thread Vladimir Ivanov
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

Thanks for the reviews, Mandy, Paul, Peter, and Stuart.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-07 Thread Stuart Marks
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

I don't have a strong opinion on whether this should use a SoftReference or a 
WeakReference. (In fact, one might say that I have a phantom opinion.) The main 
thing was that the bug report mentioned WeakReference but the commit here uses 
SoftReferences, and I didn't see any discussion about this change. You gave 
some reasons above for why SoftReference is preferable, and that's ok with me.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-03 Thread Vladimir Ivanov
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

Other MethodHandle/LambdaForm caches in `java.lang.invoke` deliberately rely on 
`SoftReference`s. ​(Only `MethodType` table uses `WeakReference`, but it is 
there for interning purposes.) MH adaptations are quite expensive (and may 
involve class loading), so it's beneficial to keep the result around for an 
extended period of time when circumstances allow.

On the other hand, `MH.asType()` case is special because it can hold user 
classes around which makes effective memory footprint of cached value much 
higher. So, `WeakReference` would enable more prompt recycling of heap memory 
at the expense of higher cache miss rate.

Personally, I'm in favor `SoftReference` here since it allows to get most of 
performance benefits out of the cache while preserving the correctness w.r.t. 
heap exhaustion.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-03 Thread Stuart Marks
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

Did we want this to use a soft reference or a weak reference? The original bug 
report mentions weak references, and the typical approach for preventing caches 
from holding onto things unnecessarily is to use weak references. I haven't 
thought through the implications of using soft instead of weak references. 
(Sorry if I missed any discussion on this issue.)

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-03 Thread Peter Levart
On Fri, 3 Sep 2021 14:41:45 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

Marked as reviewed by plevart (Reviewer).

This looks good to me now.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-03 Thread Vladimir Ivanov
On Fri, 3 Sep 2021 12:51:13 GMT, Peter Levart  wrote:

>> Vladimir Ivanov has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Address review comments
>
> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 877:
> 
>> 875: }
>> 876: if (asTypeSoftCache != null) {
>> 877: atc = asTypeSoftCache.get();
> 
> NPE is possible here too! asTypeSoftCache is a non-volatile field which is 
> read twice. First time in the if (...) condition, 2nd time in the line that 
> de-references it to call .get(). This is a data-race since concurrent thread 
> may be setting this field from null to non-null. Those two reads may get 
> reordered. 1st read may return non-null while 2nd may return null. This can 
> be avoided if the field is read just once by introducing a local variable to 
> store its value.

Fixed.

> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 878:
> 
>> 876: if (asTypeSoftCache != null) {
>> 877: atc = asTypeSoftCache.get();
>> 878: if (newType == atc.type) {
> 
> NPE is possible here! act can be null as it is a result of SoftReference::get

Good catch! Fixed.

> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 933:
> 
>> 931: }
>> 932: 
>> 933: /* Returns true when {@code loader} keeps {@code mt} either 
>> directly or indirectly through the loader delegation chain. */
> 
> Well, to be precise, loader can't keep mt alive. It would be better to say 
> "keeps mt components alive" ...

Fixed.

> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 948:
> 
>> 946: if (isBuiltinLoader(defLoader)) {
>> 947: return true; // built-in loaders are always reachable
>> 948: }
> 
> No need for special case here. isAncestorLoaderOf(defLoader, loader) already 
> handles this case.

Though the check is redundant, I find the current version clearer.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v4]

2021-09-03 Thread Vladimir Ivanov
> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Vladimir Ivanov has updated the pull request incrementally with one additional 
commit since the last revision:

  Address review comments

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/5246/files
  - new: https://git.openjdk.java.net/jdk/pull/5246/files/7a87aee3..365dd454

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=03
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=02-03

  Stats: 5 lines in 1 file changed: 1 ins; 0 del; 4 mod
  Patch: https://git.openjdk.java.net/jdk/pull/5246.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/5246/head:pull/5246

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-03 Thread Peter Levart
On Thu, 2 Sep 2021 11:35:52 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 877:

> 875: }
> 876: if (asTypeSoftCache != null) {
> 877: atc = asTypeSoftCache.get();

NPE is possible here too! asTypeSoftCache is a non-volatile field which is read 
twice. First time in the if (...) condition, 2nd time in the line that 
de-references it to call .get(). This is a data-race since concurrent thread 
may be setting this field from null to non-null. Those two reads may get 
reordered. 1st read may return non-null while 2nd may return null. This can be 
avoided if the field is read just once by introducing a local variable to store 
its value.

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 878:

> 876: if (asTypeSoftCache != null) {
> 877: atc = asTypeSoftCache.get();
> 878: if (newType == atc.type) {

NPE is possible here! act can be null as it is a result of SoftReference::get

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 933:

> 931: }
> 932: 
> 933: /* Returns true when {@code loader} keeps {@code mt} either directly 
> or indirectly through the loader delegation chain. */

Well, to be precise, loader can't keep mt alive. It would be better to say 
"keeps mt components alive" ...

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 948:

> 946: if (isBuiltinLoader(defLoader)) {
> 947: return true; // built-in loaders are always reachable
> 948: }

No need for special case here. isAncestorLoaderOf(defLoader, loader) already 
handles this case.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-03 Thread Vladimir Ivanov
On Fri, 3 Sep 2021 00:09:17 GMT, Mandy Chung  wrote:

> For the change of MethodHandle::asType to a final method, this needs a CSR.

It is not allowed to extend/subclass `MethodHandle` outside `java.lang.invoke` 
package. 
So, the aforementioned change doesn't have any compatibility risks. Do I miss 
something important?


/**
 * Package-private constructor for the method handle implementation 
hierarchy.
 * Method handle inheritance will be contained completely within
 * the {@code java.lang.invoke} package.
 */
// @param type type (permanently assigned) of the new method handle
/*non-public*/
MethodHandle(MethodType type, LambdaForm form) {

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-02 Thread Mandy Chung
On Thu, 2 Sep 2021 11:35:52 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

This looks good to me.  

For the change of `MethodHandle::asType` to a final method, this needs a CSR.   
Is this spec change intentional?  I wonder if `MethodHandle` should be a sealed 
class instead.   In any case, maybe you can consider the spec change as a 
separate issue.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v2]

2021-09-02 Thread Vladimir Ivanov
On Wed, 1 Sep 2021 17:28:37 GMT, Mandy Chung  wrote:

>> Vladimir Ivanov has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Address review comments
>
> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 926:
> 
>> 924: /* Returns true when {@code loader} keeps {@code cls} either 
>> directly or indirectly through the loader delegation chain. */
>> 925: private static boolean keepsAlive(Class cls, ClassLoader loader) 
>> {
>> 926: return keepsAlive(cls.getClassLoader(), loader);
> 
> Suggestion:
> 
> ClassLoader defLoader = cls.getClassLoader();
> if (isBuiltinLoader(defLoader)) {
> return true; // built-in loaders are always reachable
> }
> return keepsAlive(defLoader, loader);
> 
> 
> I think it's clearer to check if `cls` is not defined by any builtin loader 
> here and then check if `loader` keeps `cls` alive.
> 
> So `keepsAlive(ClassLoader loader1, ClassLoader loader2)` is not needed and 
> replace line 935 and 940 to `keepsAlive(Class, ClassLoader)` instead.

Sounds good. 

Incorporated your suggestions along with some minor refactorings.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v3]

2021-09-02 Thread Vladimir Ivanov
> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Vladimir Ivanov has updated the pull request incrementally with one additional 
commit since the last revision:

  Address review comments

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/5246/files
  - new: https://git.openjdk.java.net/jdk/pull/5246/files/b2c0..7a87aee3

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=02
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=01-02

  Stats: 41 lines in 1 file changed: 15 ins; 18 del; 8 mod
  Patch: https://git.openjdk.java.net/jdk/pull/5246.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/5246/head:pull/5246

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v2]

2021-09-01 Thread Mandy Chung
On Wed, 1 Sep 2021 16:23:46 GMT, Vladimir Ivanov  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> Vladimir Ivanov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Address review comments

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 926:

> 924: /* Returns true when {@code loader} keeps {@code cls} either 
> directly or indirectly through the loader delegation chain. */
> 925: private static boolean keepsAlive(Class cls, ClassLoader loader) {
> 926: return keepsAlive(cls.getClassLoader(), loader);

Suggestion:

ClassLoader defLoader = cls.getClassLoader();
if (isBuiltinLoader(defLoader)) {
return true; // built-in loaders are always reachable
}
return keepsAlive(defLoader, loader);


I think it's clearer to check if `cls` is not defined by any builtin loader 
here and then check if `loader` keeps `cls` alive.

So `keepsAlive(ClassLoader loader1, ClassLoader loader2)` is not needed and 
replace line 935 and 940 to `keepsAlive(Class, ClassLoader)` instead.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading

2021-09-01 Thread Vladimir Ivanov
On Wed, 25 Aug 2021 09:31:51 GMT, Vladimir Ivanov  wrote:

> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Thanks for the reviews, Paul and Mandy.

What do you think about the latest version?

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading [v2]

2021-09-01 Thread Vladimir Ivanov
> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Vladimir Ivanov has updated the pull request incrementally with one additional 
commit since the last revision:

  Address review comments

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/5246/files
  - new: https://git.openjdk.java.net/jdk/pull/5246/files/87154817..b2c0

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=01
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=00-01

  Stats: 13 lines in 1 file changed: 4 ins; 1 del; 8 mod
  Patch: https://git.openjdk.java.net/jdk/pull/5246.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/5246/head:pull/5246

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading

2021-08-30 Thread Mandy Chung
On Thu, 26 Aug 2021 17:57:26 GMT, Paul Sandoz  wrote:

>> `MethodHandle.asTypeCache` keeps a strong reference to adapted 
>> `MethodHandle` and it can introduce a class loader leak through its 
>> `MethodType`.
>> 
>> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
>> only contain `MethodHandle`s which are guaranteed to not introduce any 
>> dependencies on new class loaders compared to the original `MethodHandle`. 
>> 2nd level is backed by a `SoftReference` and is used as a backup when the 
>> result of `MethodHandle.asType()` conversion can't populate the higher level 
>> cache.  
>> 
>> The fix is based on [the 
>> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>>  made by Peter Levart @plevart back in 2015.
>> 
>> Testing: tier1 - tier6
>
> src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 953:
> 
>> 951: 
>> 952: /* Determine whether {@code descendant} keeps {@code ancestor} 
>> alive through the loader delegation chain. */
>> 953: private static boolean keepsAlive(ClassLoader ancestor, ClassLoader 
>> descendant) {
> 
> Might be clearer to name the method by what it is e.g. isAncestor
> // Returns true if ancestor can be found descendant's delegation chain.

This method is not exactly doing `isAncestor` check.  It returns true if 
`ancestor` is a builtin loader even it's not an ancestor of `descendent`.   I 
agree that it would be helpful if the method is named by what it is.

Maybe naming it `isAncestor` but move the `isSystemLoader(ancestor)` check out 
to  the caller.  Just a thought.

-

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading

2021-08-30 Thread Mandy Chung
On Wed, 25 Aug 2021 09:31:51 GMT, Vladimir Ivanov  wrote:

> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Thanks for fixing this.  JEP 416 depends on this.

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 966:

> 964: }
> 965: 
> 966: private static boolean isSystemLoader(ClassLoader loader) {

These are builtin loaders.  This method may be better to rename to 
`isBuiltinLoader`.

-

Marked as reviewed by mchung (Reviewer).

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


Re: RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading

2021-08-26 Thread Paul Sandoz
On Wed, 25 Aug 2021 09:31:51 GMT, Vladimir Ivanov  wrote:

> `MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
> and it can introduce a class loader leak through its `MethodType`.
> 
> Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
> only contain `MethodHandle`s which are guaranteed to not introduce any 
> dependencies on new class loaders compared to the original `MethodHandle`. 
> 2nd level is backed by a `SoftReference` and is used as a backup when the 
> result of `MethodHandle.asType()` conversion can't populate the higher level 
> cache.  
> 
> The fix is based on [the 
> work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
>  made by Peter Levart @plevart back in 2015.
> 
> Testing: tier1 - tier6

Looks good.

I guess it is not that common for the soft ref to get instantiated i.e. for the 
case of the ~common class loader of `type`, MTC say, and the ~common classoader 
of `newType`, NMTC say, then NMTC is not an ancestor of MTC.

It's possible that `asTypeCache` and `asTypeSoftCache` could both be non-null 
i.e. we don't null out one of them, buy does not seem a problem.

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 869:

> 867: }
> 868: at = asTypeUncached(newType);
> 869: return setAsTypeCache(at);

The following may be a little clearer
Suggestion:

MethodHandle at = asTypeCached(newType);
return at != null
? at
: setAsTypeCache(asTypeUncached(newType));

src/java.base/share/classes/java/lang/invoke/MethodHandle.java line 953:

> 951: 
> 952: /* Determine whether {@code descendant} keeps {@code ancestor} alive 
> through the loader delegation chain. */
> 953: private static boolean keepsAlive(ClassLoader ancestor, ClassLoader 
> descendant) {

Might be clearer to name the method by what it is e.g. isAncestor
// Returns true if ancestor can be found descendant's delegation chain.

-

Marked as reviewed by psandoz (Reviewer).

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


RFR: 8078641: MethodHandle.asTypeCache can retain classes from unloading

2021-08-25 Thread Vladimir Ivanov
`MethodHandle.asTypeCache` keeps a strong reference to adapted `MethodHandle` 
and it can introduce a class loader leak through its `MethodType`.

Proposed fix introduces a 2-level cache (1 element each) where 1st level can 
only contain `MethodHandle`s which are guaranteed to not introduce any 
dependencies on new class loaders compared to the original `MethodHandle`. 2nd 
level is backed by a `SoftReference` and is used as a backup when the result of 
`MethodHandle.asType()` conversion can't populate the higher level cache.  

The fix is based on [the 
work](http://cr.openjdk.java.net/~plevart/jdk9-dev/MethodHandle.asTypeCacheLeak/)
 made by Peter Levart @plevart back in 2015.

Testing: tier1 - tier6

-

Commit messages:
 - Remove the assert
 - Introduce 2nd level MethodHandle.asType cache
 - keepsAlive logic

Changes: https://git.openjdk.java.net/jdk/pull/5246/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=5246&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8078641
  Stats: 108 lines in 2 files changed: 87 ins; 3 del; 18 mod
  Patch: https://git.openjdk.java.net/jdk/pull/5246.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/5246/head:pull/5246

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