Initial webrev with changes for JDK 9

Peter Levart peter.levart at gmail.com
Tue Mar 15 13:56:29 UTC 2016


Hi Alan, Paul,

Just a comment on comment: wouldn't the variant with a single compute 
replace a Package with itself on each repeated call? Semantically it is 
the same, but there is a volatile memory store on the cache-hit involved 
where in the original variant, it isn't...

On 03/11/2016 05:50 PM, Paul Sandoz wrote:
> j.l.ClassLoader
>>
> 1777         // define Package object if the named package is not yet defined
> 1778         NamedPackage p = packages.computeIfAbsent(name,
> 1779                                                   k -> NamedPackage.toPackage(name, m));
> 1780         if (p instanceof Package)
> 1781             return (Package)p;
> 1782
> 1783         // otherwise, replace the NamedPackage object with Package object
> 1784         return (Package)packages.compute(name, this::toPackage);
>
> You could merge the computeIfAbsent and compute into a single compute call if you so wish.
>
> return (Package)packages.compute((n, p) -> {
>    // define Package object if the named package is not yet defined
>    if (p == null) return NamedPackage.toPackage(name, m);
>    // otherwise, replace the NamedPackage object with Package object
>    return (p instanceof Package) ? p : toPackage(n, p);
> });

You could pre-screen the .compute with a .get and this would be the more 
optimal (no locking on cache-hits):

NamedPackage p = packages.get(name);
if (p instanceof Package) {
     return (Package) p;
}

return (Package)packages.compute((n, p) -> {
   // define Package object if it is not yet defined or replace it if it 
is a NamedPackage
   return (p instanceof Package) ? p : NamedPackage.toPackage(n, m);
});

See, no private ClassLoader.toPackage(String name, NamedPackage p) needed.


If you also care for constant lambda, this could be optimized even 
further, but for the price of more complex code:


NamedPackage p = packages.get(name);

if (p instanceof Package) {
     return (Package) p;
} else if (p == null) {
     Package pkg = NamedPackage.toPackage(name, m);
     p = packages.putIfAbsent(name, pkg);
     if (p == null) {
         return pkg;
     }
}

return (Package)packages.compute((n, p) -> {
     assert p != null;
     // replace NamedPackage with Package
     return (p instanceof Package) ? p : 
NamedPackage.toPackage(p.name(), p.module());
});


Regards, Peter



More information about the jigsaw-dev mailing list