On 04/20/2013 09:31 AM, Peter Levart wrote:
Hi Mandy,

I have another idea. Before jumping to implement it, I will first ask what do you think of it. For example:

- have an optimal interface names key calculated from interfaces.
- visibility of interfaces and other validations are pushed to slow-path (inside ProxyClassFactory.apply) - the proxy Class object returned from WeakCache.get() is post-validated with a check like:

for (Class<?> intf : interfaces) {
    if (!intf.isAssignableFrom(proxyClass)) {
        throw new IllegalArgumentException();
    }
}
// return post-validated proxyClass from getProxyClass0()...

I just did it:

http://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc/webrev.03/index.html

I also incorporated the expunging optimization that I talked about in one of previous mails.

And the keys, composed of interface names, are now more space-friendly too:
- a key for 0 interface proxy is a singleton Object
- a key for 1 interface proxy is the name of the interface itself (an already interned String) - a key for 2 interface proxy is a special class with 2 references to interned Strings - a key for 3+ interface proxy is a special class wrapping an array of interned Strings

The performance is screaming again (WeakCache+post-validation):


                                        ns/op   WeakCache+ WeakCache+
Test                     Threads     Original   pre-valid. post-valid.
=======================  =======  ===========  =========== ===========
Proxy_getProxyClass            1     2,420.99 2,258.00       211.04
                               4     3,075.39 2,644.26       282.93
                               8     5,374.45 5,159.71       432.14

Proxy_isProxyClassTrue         1        97.75 45.37        42.67
                               4     2,505.92 42.59        42.77
                               8     5,042.61 75.44        73.20

Proxy_isProxyClassFalse        1        89.20 1.40         1.40
                               4     2,548.61 1.40         1.40
                               8     4,901.56 2.82         2.80

Annotation_equals              1       224.39 201.82       202.97
                               4     2,046.21 200.61       204.89
                               8     3,564.78 347.27       344.57


And the space savings are now even greater. Patched code is always better space-wise. The savings are:

32 bit addressing:

- 56 bytes per proxy class implementing 1 interface
- 32 bytes per proxy class implementing 2 interfaces
- 16 bytes per proxy class implementing 3 or more interfaces

64 bit addressing:

- 80 bytes per proxy class implementing 1 interface
- 56 bytes per proxy class implementing 2 interfaces
- 24 bytes per proxy class implementing 3 or more interfaces


Regards, Peter


P.S. Details:

32 bit addressing:


   ** Original j.l.r.Proxy
   ** 0 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       760       360
       2         9      1072       312
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 1 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       768       368
       1         2       920       152
       1         3      1072       152
       1         4      1224       152
       1         5      1376       152
       1         6      1528       152
       1         7      1680       152
       1         8      1832       152
       2         9      2152       320
       2        10      2304       152
       2        11      2456       152
       2        12      2672       216
       2        13      2824       152
       2        14      2976       152
       2        15      3128       152
       2        16      3280       152
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 2 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       768       368
       1         2       920       152
       1         3      1072       152
       1         4      1224       152
       1         5      1376       152
       1         6      1528       152
       1         7      1680       152
       1         8      1832       152
       2         9      2152       320
       2        10      2304       152
       2        11      2456       152
       2        12      2672       216
       2        13      2824       152
       2        14      2976       152
       2        15      3128       152
       2        16      3280       152
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 3 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       776       376
       1         2       936       160
       1         3      1096       160
       1         4      1256       160
       1         5      1416       160
       1         6      1576       160
       1         7      1736       160
       1         8      1896       160
       2         9      2224       328
       2        10      2384       160
       2        11      2544       160
       2        12      2768       224
       2        13      2928       160
       2        14      3088       160
       2        15      3248       160
       2        16      3408       160
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 4 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       776       376
       1         2       936       160
       1         3      1096       160
       1         4      1256       160
       1         5      1416       160
       1         6      1576       160
       1         7      1736       160
       1         8      1896       160
       2         9      2224       328
       2        10      2384       160
       2        11      2544       160
       2        12      2768       224
       2        13      2928       160
       2        14      3088       160
       2        15      3248       160
       2        16      3408       160
--------  --------  --------  --------


   ** Patched j.l.r.Proxy
   ** 0 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       768       528
       2         9      1072       304
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 1 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       752       512
       1         2       848        96
       1         3       944        96
       1         4      1040        96
       1         5      1136        96
       1         6      1232        96
       1         7      1328        96
       1         8      1424        96
       2         9      1728       304
       2        10      1824        96
       2        11      1920        96
       2        12      2080       160
       2        13      2176        96
       2        14      2272        96
       2        15      2368        96
       2        16      2464        96
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 2 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       776       536
       1         2       896       120
       1         3      1016       120
       1         4      1136       120
       1         5      1256       120
       1         6      1376       120
       1         7      1496       120
       1         8      1616       120
       2         9      1944       328
       2        10      2064       120
       2        11      2184       120
       2        12      2368       184
       2        13      2488       120
       2        14      2608       120
       2        15      2728       120
       2        16      2848       120
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 3 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       800       560
       1         2       944       144
       1         3      1088       144
       1         4      1232       144
       1         5      1376       144
       1         6      1520       144
       1         7      1664       144
       1         8      1808       144
       2         9      2160       352
       2        10      2304       144
       2        11      2448       144
       2        12      2656       208
       2        13      2800       144
       2        14      2944       144
       2        15      3088       144
       2        16      3232       144
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 4 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       800       560
       1         2       944       144
       1         3      1088       144
       1         4      1232       144
       1         5      1376       144
       1         6      1520       144
       1         7      1664       144
       1         8      1808       144
       2         9      2160       352
       2        10      2304       144
       2        11      2448       144
       2        12      2656       208
       2        13      2800       144
       2        14      2944       144
       2        15      3088       144
       2        16      3232       144
--------  --------  --------  --------


64 bit addressing:


   ** Original j.l.r.Proxy
   ** 0 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       632       632
       1         1      1208       576
       2         9      1728       520
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 1 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       632       632
       1         1      1216       584
       1         2      1448       232
       1         3      1680       232
       1         4      1912       232
       1         5      2144       232
       1         6      2376       232
       1         7      2608       232
       1         8      2840       232
       2         9      3368       528
       2        10      3600       232
       2        11      3832       232
       2        12      4192       360
       2        13      4424       232
       2        14      4656       232
       2        15      4888       232
       2        16      5120       232
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 2 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       632       632
       1         1      1224       592
       1         2      1464       240
       1         3      1704       240
       1         4      1944       240
       1         5      2184       240
       1         6      2424       240
       1         7      2664       240
       1         8      2904       240
       2         9      3440       536
       2        10      3680       240
       2        11      3920       240
       2        12      4288       368
       2        13      4528       240
       2        14      4768       240
       2        15      5008       240
       2        16      5248       240
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 3 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       632       632
       1         1      1232       600
       1         2      1480       248
       1         3      1728       248
       1         4      1976       248
       1         5      2224       248
       1         6      2472       248
       1         7      2720       248
       1         8      2968       248
       2         9      3512       544
       2        10      3760       248
       2        11      4008       248
       2        12      4384       376
       2        13      4632       248
       2        14      4880       248
       2        15      5128       248
       2        16      5376       248
--------  --------  --------  --------

   ** Original j.l.r.Proxy
   ** 4 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       632       632
       1         1      1240       608
       1         2      1496       256
       1         3      1752       256
       1         4      2008       256
       1         5      2264       256
       1         6      2520       256
       1         7      2776       256
       1         8      3032       256
       2         9      3584       552
       2        10      3840       256
       2        11      4096       256
       2        12      4480       384
       2        13      4736       256
       2        14      4992       256
       2        15      5248       256
       2        16      5504       256
--------  --------  --------  --------


   ** Patched j.l.r.Proxy
   ** 0 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       336       336
       1         1      1216       880
       2         9      1720       504
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 1 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       336       336
       1         1      1200       864
       1         2      1352       152
       1         3      1504       152
       1         4      1656       152
       1         5      1808       152
       1         6      1960       152
       1         7      2112       152
       1         8      2264       152
       2         9      2768       504
       2        10      2920       152
       2        11      3072       152
       2        12      3352       280
       2        13      3504       152
       2        14      3656       152
       2        15      3808       152
       2        16      3960       152
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 2 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       336       336
       1         1      1232       896
       1         2      1416       184
       1         3      1600       184
       1         4      1784       184
       1         5      1968       184
       1         6      2152       184
       1         7      2336       184
       1         8      2520       184
       2         9      3056       536
       2        10      3240       184
       2        11      3424       184
       2        12      3736       312
       2        13      3920       184
       2        14      4104       184
       2        15      4288       184
       2        16      4472       184
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 3 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       336       336
       1         1      1272       936
       1         2      1496       224
       1         3      1720       224
       1         4      1944       224
       1         5      2168       224
       1         6      2392       224
       1         7      2616       224
       1         8      2840       224
       2         9      3416       576
       2        10      3640       224
       2        11      3864       224
       2        12      4216       352
       2        13      4440       224
       2        14      4664       224
       2        15      4888       224
       2        16      5112       224
--------  --------  --------  --------

   ** Patched j.l.r.Proxy
   ** 4 interfaces / proxy class

   class     proxy   size of  delta to
 loaders   classes    caches  prev.ln.
--------  --------  --------  --------
       0         0       336       336
       1         1      1280       944
       1         2      1512       232
       1         3      1744       232
       1         4      1976       232
       1         5      2208       232
       1         6      2440       232
       1         7      2672       232
       1         8      2904       232
       2         9      3488       584
       2        10      3720       232
       2        11      3952       232
       2        12      4312       360
       2        13      4544       232
       2        14      4776       232
       2        15      5008       232
       2        16      5240       232
--------  --------  --------  --------


On 04/20/2013 09:31 AM, Peter Levart wrote:
Hi Mandy,

I have another idea. Before jumping to implement it, I will first ask what do you think of it. For example:

- have an optimal interface names key calculated from interfaces.
- visibility of interfaces and other validations are pushed to slow-path (inside ProxyClassFactory.apply) - the proxy Class object returned from WeakCache.get() is post-validated with a check like:

for (Class<?> intf : interfaces) {
    if (!intf.isAssignableFrom(proxyClass)) {
        throw new IllegalArgumentException();
    }
}
// return post-validated proxyClass from getProxyClass0()...

I feel that Class.isAssignableFrom(Class) check could be much faster and that the only reason the check can fail is if some interface is not visible from the class loader.

Am I correct?

Regards, Peter



On 04/19/2013 04:36 PM, Peter Levart wrote:
Hi Mandy,

On 04/19/2013 07:33 AM, Mandy Chung wrote:

https://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc/webrev.02/index.html What about package-private in java.lang.reflect? It makes Proxy itself much easier to read. When we decide which way to go, I can remove the interface and only leave a single package-private class...


thanks. Moving it to a single package-private classin java.lang.reflectand remove the interface sounds good.

Right.


I have merged your patch with the recent TL repo and did some clean up while reviewing it. Some comments: 1. getProxyClass0 should validate the input interfaces and throw IAE if any illegal argument (e.g. interfaces are not visible to the given loader) before calling proxyClassCache.get(loader, interfaces). I moved back the validation code from ProxyClassFactory.apply to getProxyClass0.

Ops, you're right. There could be a request with interface(s) with same name(s) but loaded by different loader(s) and such code could return wrong pre-cached proxy class instead of throwing exception. Unfortunately, moving validation to slow-path was the cause of major performance and scalability improvement observed. With validation moved back to getProxyClass0 (in spite of using two-level WeakCache), we have the following performance (WeakCache#1):


Summary (4 Cores x 2 Threads i7 CPU):

Test                     Threads  ns/op Original WeakCache#1
=======================  =======  ============== ===========
Proxy_getProxyClass            1        2,403.27 2,174.51
                               4        3,039.01 2,555.00
                               8        5,193.58 4,273.42

Proxy_isProxyClassTrue         1           95.02 43.14
                               4        2,266.29 43.23
                               8        4,782.29 72.06

Proxy_isProxyClassFalse        1           95.02 1.36
                               4        2,186.59 1.36
                               8        4,891.15 2.72

Annotation_equals              1          240.10 195.68
                               4        1,864.06 201.41
                               8        8,639.20 337.46

It's a little better than original getProxyClass(), but not much. The isProxyClass() and consequently Annotation.equals() are far better though. But as you might have guessed, I kind of solved that too...

My first attempt was to optimize the interface validation. Only the "visibility" part is necessary to be performed on fast-path. Uniqueness and other things can be performed on slow-path. With split-validation and hacks like:

private static final MethodHandle findLoadedClass0MH, findBootstrapClassMH;
    private static final ClassLoader dummyCL = new ClassLoader() {};

    static {
        try {
Method method = ClassLoader.class.getDeclaredMethod("findLoadedClass0", String.class);
            method.setAccessible(true);
findLoadedClass0MH = MethodHandles.lookup().unreflect(method);

method = ClassLoader.class.getDeclaredMethod("findBootstrapClass", String.class);
            method.setAccessible(true);
findBootstrapClassMH = MethodHandles.lookup().unreflect(method);
        } catch (NoSuchMethodException e) {
throw (Error) new NoSuchMethodError(e.getMessage()).initCause(e);
        } catch (IllegalAccessException e) {
throw (Error) new IllegalAccessError(e.getMessage()).initCause(e);
        }
    }

    static Class<?> findLoadedClass(ClassLoader loader, String name) {
        try {
            if (VM.isSystemDomainLoader(loader)) {
return (Class<?>) findBootstrapClassMH.invokeExact(dummyCL, name);
            } else {
return (Class<?>) findLoadedClass0MH.invokeExact(loader, name);
            }
        } catch (RuntimeException | Error e) {
            throw e;
        } catch (Throwable t) {
            throw new UndeclaredThrowableException(t);
        }
    }


... using findLoadedClass(loader, intf.getName()) and only doing Class.forName(intf.getName(), false, loader) if the former returned null ... I managed to reclaim some performance (WeakCache#1+):


Test Threads ns/op Original WeakCache#1 WeakCache#1+ ======================= ======= ============== =========== ============
Proxy_getProxyClass            1        2,403.27 2,174.51 1,589.36
                               4        3,039.01 2,555.00 1,929.11
                               8        5,193.58 4,273.42 3,409.77


...but that was still not very satisfactory.

I modified the KeyFactory to create keys that weakly-reference interface Class objects and implement hashCode/equals in terms of comparing those Class objects. With such keys, no false aliasing can occur and the whole validation can be pushed back to slow-path. I tried hard to create keys with as little space overhead as possible:

http://dl.dropboxusercontent.com/u/101777488/jdk8-tl/proxy-wc-wi/webrev.01/index.html

...but there can be no miracles. The good news is that the performance is back (WeakCache#2):


Summary (4 Cores x 2 Threads i7 CPU):

Test                     Threads  ns/op Original WeakCache#1 WeakCache#2
=======================  =======  ============== =========== ===========
Proxy_getProxyClass            1        2,403.27 2,174.51 163.57
                               4        3,039.01 2,555.00 211.70
                               8        5,193.58 4,273.42 322.14

Proxy_isProxyClassTrue         1           95.02 43.14 41.23
                               4        2,266.29 43.23 42.20
                               8        4,782.29 72.06 72.21

Proxy_isProxyClassFalse        1           95.02 1.36 1.36
                               4        2,186.59 1.36 1.36
                               8        4,891.15 2.72 2.72

Annotation_equals              1          240.10 195.68 194.61
                               4        1,864.06 201.41 198.81
                               8        8,639.20 337.46 342.90


... and the most common usage (proxy class implementing exactly one interface) uses even less space than with interface-names-key - 16 bytes saved per proxy class vs. 8 bytes saved (32 bit addressing mode):

--------------------------------------
      Original j.l.r.Proxy
      1 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       768       368
       1         2       920       152
       1         3      1072       152
       1         4      1224       152
       1         5      1376       152
       1         6      1528       152
       1         7      1680       152
       1         8      1832       152
       2         9      2152       320
       2        10      2304       152
       2        11      2456       152
       2        12      2672       216
       2        13      2824       152
       2        14      2976       152
       2        15      3128       152
       2        16      3280       152

--------------------------------------
      Patched j.l.r.Proxy
      1 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       792       552
       1         2       928       136
       1         3      1064       136
       1         4      1200       136
       1         5      1336       136
       1         6      1472       136
       1         7      1608       136
       1         8      1744       136
       2         9      2088       344
       2        10      2224       136
       2        11      2360       136
       2        12      2560       200
       2        13      2696       136
       2        14      2832       136
       2        15      2968       136
       2        16      3104       136


Did you know, that Proxy.getProxyClass() can generate proxy classes implementing 0 interfaces? It can. There's exactly one such class generated per class loader:


--------------------------------------
      Original j.l.r.Proxy
      0 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       760       360
       2         2      1072       312

--------------------------------------
      Patched j.l.r.Proxy
      0 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       728       488
       2         2      1040       312


With 2 or more interfaces implemented by proxy class the space overhead increases faster than with original Proxy:


--------------------------------------
      Original j.l.r.Proxy
      2 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       768       368
       1         2       920       152
       1         3      1072       152
       1         4      1224       152
       1         5      1376       152
       1         6      1528       152
       1         7      1680       152
       1         8      1832       152
       2         9      2152       320
       2        10      2304       152
       2        11      2456       152
       2        12      2672       216
       2        13      2824       152
       2        14      2976       152
       2        15      3128       152
       2        16      3280       152

--------------------------------------
      Patched j.l.r.Proxy
      2 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       832       592
       1         2      1008       176
       1         3      1184       176
       1         4      1360       176
       1         5      1536       176
       1         6      1712       176
       1         7      1888       176
       1         8      2064       176
       2         9      2448       384
       2        10      2624       176
       2        11      2800       176
       2        12      3040       240
       2        13      3216       176
       2        14      3392       176
       2        15      3568       176
       2        16      3744       176

--------------------------------------
      Original j.l.r.Proxy
      3 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       776       376
       1         2       936       160
       1         3      1096       160
       1         4      1256       160
       1         5      1416       160
       1         6      1576       160
       1         7      1736       160
       1         8      1896       160
       2         9      2224       328
       2        10      2384       160
       2        11      2544       160
       2        12      2768       224
       2        13      2928       160
       2        14      3088       160
       2        15      3248       160
       2        16      3408       160

--------------------------------------
      Patched j.l.r.Proxy
      3 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       864       624
       1         2      1072       208
       1         3      1280       208
       1         4      1488       208
       1         5      1696       208
       1         6      1904       208
       1         7      2112       208
       1         8      2320       208
       2         9      2736       416
       2        10      2944       208
       2        11      3152       208
       2        12      3424       272
       2        13      3632       208
       2        14      3840       208
       2        15      4048       208
       2        16      4256       208

--------------------------------------
      Original j.l.r.Proxy
      4 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       400       400
       1         1       776       376
       1         2       936       160
       1         3      1096       160
       1         4      1256       160
       1         5      1416       160
       1         6      1576       160
       1         7      1736       160
       1         8      1896       160
       2         9      2224       328
       2        10      2384       160
       2        11      2544       160
       2        12      2768       224
       2        13      2928       160
       2        14      3088       160
       2        15      3248       160
       2        16      3408       160

--------------------------------------
      Patched j.l.r.Proxy
      4 interfaces / proxy class

class     proxy     size of   delta to
loaders   classes   caches    prev.ln.
--------  --------  --------  --------
       0         0       240       240
       1         1       896       656
       1         2      1136       240
       1         3      1376       240
       1         4      1616       240
       1         5      1856       240
       1         6      2096       240
       1         7      2336       240
       1         8      2576       240
       2         9      3024       448
       2        10      3264       240
       2        11      3504       240
       2        12      3808       304
       2        13      4048       240
       2        14      4288       240
       2        15      4528       240
       2        16      4768       240


There's an increase of 8 bytes per proxy class key for each 2 interfaces added to proxy class in original Proxy code, but there's an increase of 32 bytes per proxy class key for each single interface added in patched Proxy code.

I think the most common usage is to implement a single interface and there is 16 bytes gained for each such usage compared to original Proxy code.

2. I did some cleanup to restore some original comments to make the diffs clearer where the change is. 3. I removed the newInstance method which is dead code after my previous code. Since we are in this code, I took the chance to clean that up and also change a couple for-loop to use for-each.

I have put the merged and slightly modified Proxy.java and webrev at:
http://cr.openjdk.java.net/~mchung/jdk8/webrevs/7123493/webrev.00/

We will use this bug for your contribution:
   7123493 : (proxy) Proxy.getProxyClass doesn't scale under high load

I took j.l.r.Proxy file from your webrev and just changed the KeyFactory implementation. WeakCache is generic and can be used unchanged with either implementation of KeyFactory.


For the weak cache class, since it's for proxy implementation use, I suggest to take out the supportContainsValueOperation flagas it always keeps the reverse map for isProxyClass lookup.

You can simply call Objects.requireNonNull(param) instead of requireNonNull(param, "param-name") since the proxy implementation should have made sure the argument is non-null.

Formatting nits:

  68         Object cacheKey = CacheKey.valueOf(
  69             key,
  70             refQueue
  71         );

should be: all in one line or line break on a long-line.  Same for
method signature.

 237         void expungeFrom(
 238             ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
 239             ConcurrentMap<?, Boolean> reverseMap
 240         );

should be:

void expungeFrom(ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> map,
                 ConcurrentMap<?, Boolean> reverseMap);

so that it'll be more consistent with the existing code.  I'll do a
detailed review on the weak cache class as you will finalize the code
per the decision to go with the two-level weak cache.

I hope I have addressed all that in above webrev.

Regards, Peter


Thanks again for the good work.

Mandy
[1] http://openjdk.java.net/jeps/161



Reply via email to