Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Aleksey Shipilev
On 06/16/2013 11:44 PM, Alan Bateman wrote:
 On 13/06/2013 12:47, Aleksey Shipilev wrote:
 Friendly reminder for the reviewers.

 On 06/10/2013 07:53 PM, Aleksey Shipilev wrote:
 This is the follow-up on the issue Doug identified:
   
 http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html


 I had reworked the patch, webrev is here:
http://cr.openjdk.java.net/~shade/8016236/webrev.01/
 The current webrev is here:
http://cr.openjdk.java.net/~shade/8016236/webrev.02/

 I'm just catching up on this thread, webrev.02 looks very good to me. I
 can sponsor it.

Thanks! I'll appreciate this.

 One comment on ClassRepositoryHolder is that it's yet another class
 (we have a proliferation of holder classes since we started using this
 idiom). It makes me wonder if it might be better to move the constant to
 ClassRepository.

Ok, makes sense. I moved it to ClassRepository itself. Given we have the
ClassRepository field in Class, the static initialization will be
performed on the first class load. I have no problems having it public,
since it is protected enough from the external modifications.

The new webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.03/

Testing:
  - Linux/x86_64/release build OK
  - Linux/x86_64/release passes java/lang/reflect jtreg
  - microbenchmark scores are still intact

-Aleksey.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Paul Sandoz

On Jun 17, 2013, at 10:06 AM, Aleksey Shipilev aleksey.shipi...@oracle.com 
wrote:

 On 06/16/2013 11:44 PM, Alan Bateman wrote:
 On 13/06/2013 12:47, Aleksey Shipilev wrote:
 Friendly reminder for the reviewers.
 
 On 06/10/2013 07:53 PM, Aleksey Shipilev wrote:
 This is the follow-up on the issue Doug identified:
 
 http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html
 
 
 I had reworked the patch, webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.01/
 The current webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.02/
 
 I'm just catching up on this thread, webrev.02 looks very good to me. I
 can sponsor it.
 
 Thanks! I'll appreciate this.
 
 One comment on ClassRepositoryHolder is that it's yet another class
 (we have a proliferation of holder classes since we started using this
 idiom). It makes me wonder if it might be better to move the constant to
 ClassRepository.
 
 Ok, makes sense. I moved it to ClassRepository itself. Given we have the
 ClassRepository field in Class, the static initialization will be
 performed on the first class load. I have no problems having it public,
 since it is protected enough from the external modifications.
 
 The new webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.03/
 

Looks good to me.

Paul.

 Testing:
  - Linux/x86_64/release build OK
  - Linux/x86_64/release passes java/lang/reflect jtreg
  - microbenchmark scores are still intact
 
 -Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Peter Levart

On 06/17/2013 10:06 AM, Aleksey Shipilev wrote:

On 06/16/2013 11:44 PM, Alan Bateman wrote:

On 13/06/2013 12:47, Aleksey Shipilev wrote:

Friendly reminder for the reviewers.

On 06/10/2013 07:53 PM, Aleksey Shipilev wrote:

This is the follow-up on the issue Doug identified:
   
http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html



I had reworked the patch, webrev is here:
http://cr.openjdk.java.net/~shade/8016236/webrev.01/

The current webrev is here:
http://cr.openjdk.java.net/~shade/8016236/webrev.02/


I'm just catching up on this thread, webrev.02 looks very good to me. I
can sponsor it.

Thanks! I'll appreciate this.


One comment on ClassRepositoryHolder is that it's yet another class
(we have a proliferation of holder classes since we started using this
idiom). It makes me wonder if it might be better to move the constant to
ClassRepository.

Ok, makes sense. I moved it to ClassRepository itself. Given we have the
ClassRepository field in Class, the static initialization will be
performed on the first class load. I have no problems having it public,
since it is protected enough from the external modifications.


Sorry, Aleksey, just a nit: In getInterfaces(), the method could be 
written using a single volatile read from ReflectionData.interfaces 
field instead of two (by introducing local variable).


Regards, Peter



The new webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.03/

Testing:
   - Linux/x86_64/release build OK
   - Linux/x86_64/release passes java/lang/reflect jtreg
   - microbenchmark scores are still intact

-Aleksey.




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Alan Bateman

On 17/06/2013 09:06, Aleksey Shipilev wrote:

:
Ok, makes sense. I moved it to ClassRepository itself. Given we have the
ClassRepository field in Class, the static initialization will be
performed on the first class load. I have no problems having it public,
since it is protected enough from the external modifications.

The new webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.03/


This looks to good. I agree with Peter's point about the 2 reads in 
getInterfaces() although it's unlikely to make a significant difference.


If you can create the change-set then I can push this for you today.

-Alan




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Aleksey Shipilev
On 06/17/2013 02:20 PM, Peter Levart wrote:
 Sorry, Aleksey, just a nit: In getInterfaces(), the method could be
 written using a single volatile read from ReflectionData.interfaces
 field instead of two (by introducing local variable).

Yes, thanks! Nothing to be sorry of, I'll cover this.

-Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Alan Bateman

On 17/06/2013 13:32, Aleksey Shipilev wrote:

On 06/17/2013 03:44 PM, Alan Bateman wrote:

This looks to good. I agree with Peter's point about the 2 reads in
getInterfaces() although it's unlikely to make a significant
difference.

Oh, it can have the difference on non-x86 hardware and/or in optimized
code. This nit is fixed here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.04/

I did the same testing as before: Linux x86_64/release builds and runs
jdk/test/java/lang/reflect jtreg successfully; the performance is still
there.


If you can create the change-set then I can push this for you today.

Here:
   http://cr.openjdk.java.net/~shade/8016236/8016236.changeset

Although only Alan counts as official reviewer; do we need another one?


The updated webrev looks good for me.

For the jdk repository then only one reviewer with reviewer role is 
required. I see you have Peter and Paul listed in a Reviewed-by line so 
I think we are good. Do you want Doug listed too as this started out as 
a patch from Doug.


-Alan


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Aleksey Shipilev
On 06/17/2013 05:22 PM, Alan Bateman wrote:
 For the jdk repository then only one reviewer with reviewer role is
 required. I see you have Peter and Paul listed in a Reviewed-by line so
 I think we are good. Do you want Doug listed too as this started out as
 a patch from Doug.

Ouch! My bad. Doug had not reviewed the final patch, and the final patch
is significantly different from the original one. Do we still want to
put Doug to Contributed-by, or is there some other tag useful in cases
like these?

-Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Doug Lea

On 06/17/13 09:25, Aleksey Shipilev wrote:


Ouch! My bad. Doug had not reviewed the final patch, and the final patch
is significantly different from the original one. Do we still want to
put Doug to Contributed-by, or is there some other tag useful in cases
like these?



It looks fine to me. Thanks for the thorough care and testing.

I don't think we distinguish idea-cotributed-by vs code-contributed-by :-)

-Doug




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-17 Thread Aleksey Shipilev
On 06/17/2013 05:33 PM, Doug Lea wrote:
 On 06/17/13 09:25, Aleksey Shipilev wrote:
 
 Ouch! My bad. Doug had not reviewed the final patch, and the final patch
 is significantly different from the original one. Do we still want to
 put Doug to Contributed-by, or is there some other tag useful in cases
 like these?

 
 It looks fine to me. Thanks for the thorough care and testing.
 
 I don't think we distinguish idea-cotributed-by vs code-contributed-by :-)

Thanks!

I had updated the changeset capturing both:
  http://cr.openjdk.java.net/~shade/8016236/8016236.changeset

-Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-16 Thread Alan Bateman

On 13/06/2013 12:47, Aleksey Shipilev wrote:

Friendly reminder for the reviewers.

On 06/10/2013 07:53 PM, Aleksey Shipilev wrote:

This is the follow-up on the issue Doug identified:
   http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html

I had reworked the patch, webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.01/

The current webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.02/

I'm just catching up on this thread, webrev.02 looks very good to me. I 
can sponsor it.


One comment on ClassRepositoryHolder is that it's yet another class 
(we have a proliferation of holder classes since we started using this 
idiom). It makes me wonder if it might be better to move the constant to 
ClassRepository.


-Alan.




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-16 Thread Alan Bateman

On 10/06/2013 21:57, Peter Levart wrote:

:

I should note that ReflectionData is invalidated when the class is 
redefined. I don't know if generic signature is one of those things 
that can change with class redefinition, but invalidation is just one 
purpose of ReflectionData and the other is caching (via 
SoftReference), so generic signature can be added to it for that 
purpose. If 'genericSignature' is cached on ReflectionData then it 
would be consistent to also cache the derived 'genericInfo', what do 
you think?


A redefine or retransform is allowed to change attributes so while 
signatures/modifier/hierarchy can't change then the Signature attribute 
might. So I think it's right in the current webrev (but good to think 
about such things).


-Alan.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-13 Thread Aleksey Shipilev
Friendly reminder for the reviewers.

On 06/10/2013 07:53 PM, Aleksey Shipilev wrote:
 This is the follow-up on the issue Doug identified:
   http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html
 
 I had reworked the patch, webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.01/

The current webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.02/

 Notable differences from Doug's version are:
   - handle non-generic cases as well
   - reuse ReflectionData to cache the interfaces
   - code style (chained ternary operators blown up)
   - fixes the race along the way
   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6398355
 
 Testing:
   - Linux x86_64/release: build OK
   - Linux x86_64/release: java/lang/reflect regression tests OK
   - Microbenchmarks show whooping increase in performance, see below

Thanks,
Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Paul Sandoz

On Jun 10, 2013, at 7:20 PM, Aleksey Shipilev aleksey.shipi...@oracle.com 
wrote:

 Thanks for taking a look, Paul!
 Can I count your review as official?

Unfortunately i am not an unofficial reviewer so can only be counted in the 
unofficial category for now :-(


 
 On 06/10/2013 08:44 PM, Paul Sandoz wrote:
 - reuse ReflectionData to cache the interfaces and generic signatures
 
 Any guess on the size impact due to those new fields in ReflectionData?
 
 Seems to be additional 16 bytes (boolean+oop+oop+alignment, see below);
 again, since the ReflectionData is lazily-constructed, this is not the
 issue for most of the classes.
 

In EE-land a lot more reflection tends to happen on application classes.

I see Peter has some ideas to avoid additional fields with a special lazilly 
initialized ClassRepository instance.

Paul.


  Before:
 
 Running 64-bit HotSpot VM.
 Using compressed references with 3-bit shift.
 Objects are 8 bytes aligned.
 
 java.lang.Class.ReflectionData
 offset  size  type description
  012   (assumed to be the object header)
 12 4   int ReflectionData.redefinedCount
 16 4   Field[] ReflectionData.declaredFields
 20 4   Field[] ReflectionData.publicFields
 24 4  Method[] ReflectionData.declaredMethods
 28 4  Method[] ReflectionData.publicMethods
 32 4 Constructor[] ReflectionData.declaredConstructors
 36 4 Constructor[] ReflectionData.publicConstructors
 40 4   Field[] ReflectionData.declaredPublicFields
 44 4  Method[] ReflectionData.declaredPublicMethods
 48 (object boundary, size estimate)
 
  After:
 
 Running 64-bit HotSpot VM.
 Using compressed references with 3-bit shift.
 Objects are 16 bytes aligned.
 
 java.lang.Class.ReflectionData
 offset  size  type description
  012   (assumed to be the object header)
 12 4   int ReflectionData.redefinedCount
 16 1   boolean ReflectionData.genericSignatureResolved
 17 3   (alignment/padding gap)
 20 4   Field[] ReflectionData.declaredFields
 24 4   Field[] ReflectionData.publicFields
 28 4  Method[] ReflectionData.declaredMethods
 32 4  Method[] ReflectionData.publicMethods
 36 4 Constructor[] ReflectionData.declaredConstructors
 40 4 Constructor[] ReflectionData.publicConstructors
 44 4   Field[] ReflectionData.declaredPublicFields
 48 4  Method[] ReflectionData.declaredPublicMethods
 52 4   Class[] ReflectionData.interfaces
 56 4String ReflectionData.genericSignature
 60 4   (loss due to the next object alignment)
 64 (object boundary, size estimate)
 



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Aleksey Shipilev
On 06/11/2013 01:31 AM, Peter Levart wrote:
 While you're at it adding getInterfaces() cache, why not also
 getSuperclass()? Is it maybe already intrinsified?

Yes, the C2 code and benchmarking shows it is already an intrinsic.

-Aleksey.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Aleksey Shipilev
Hi Peter,

On 06/11/2013 12:57 AM, Peter Levart wrote:
 When 'sun.reflect.noCaches=true' system property is defined, 
 reflectionData() returns null. In that case, the code should cope 
 without using ReflectionData (no caching). See other uses of 
 reflectionData() (for example: in privateGetDeclaredFields())...

Good catch. Indeed, I was deluged by newReflectionData returning null.
Fixed.

 If 'genericSignature' is cached on ReflectionData then it would be 
 consistent to also cache the derived 'genericInfo', what do you
 think?

genericSignature is off the ReflectionData now, so it makes a little
sense to move genericInfo there. The interference of genericInfo and
class redefinition is an interesting in itself, and I think it should be
taken care of elsewhere (notably, when JEP-159 lands). I'm somewhat
resistant to do this along with the performance fix.

 If there was a singleton ClassRepository NONE instance, then event
 the boolean flag wouldn't be needed.

Oh, that's a good idea. Implemented.

The new webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.02/

Testing:
  - Linux x86_64/release builds OK
  - Linux x86_64/release jdk/test/java/lang/reflect/ jtreg OK
  - Microbenchmark scores are still showing the major increase
  - Layout dumps show Reflection data is 8 bytes more (1 oop + alignment)

-Aleksey.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Peter Levart

Aleksey,

On 06/11/2013 11:56 AM, Aleksey Shipilev wrote:

Hi Peter,

On 06/11/2013 12:57 AM, Peter Levart wrote:

When 'sun.reflect.noCaches=true' system property is defined,
reflectionData() returns null. In that case, the code should cope
without using ReflectionData (no caching). See other uses of
reflectionData() (for example: in privateGetDeclaredFields())...

Good catch. Indeed, I was deluged by newReflectionData returning null.
Fixed.


If 'genericSignature' is cached on ReflectionData then it would be
consistent to also cache the derived 'genericInfo', what do you
think?

genericSignature is off the ReflectionData now, so it makes a little
sense to move genericInfo there. The interference of genericInfo and
class redefinition is an interesting in itself, and I think it should be
taken care of elsewhere (notably, when JEP-159 lands). I'm somewhat
resistant to do this along with the performance fix.


If there was a singleton ClassRepository NONE instance, then event
the boolean flag wouldn't be needed.

Oh, that's a good idea. Implemented.

The new webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.02/


That's good now. I just wonder if renaming of native getGenericSignature 
- getGenericSignature0 is still needed now that there's no
getGenericSignature non-native method in Class. Every native method 
ending with '0' has a non-native counterpart with same name (just '0' 
stripped).


Regards, Peter



Testing:
   - Linux x86_64/release builds OK
   - Linux x86_64/release jdk/test/java/lang/reflect/ jtreg OK
   - Microbenchmark scores are still showing the major increase
   - Layout dumps show Reflection data is 8 bytes more (1 oop + alignment)

-Aleksey.




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Aleksey Shipilev
On 06/11/2013 03:27 PM, Peter Levart wrote:
 The new webrev is here: 
 http://cr.openjdk.java.net/~shade/8016236/webrev.02/
 
 That's good now.

Thanks!

 I just wonder if renaming of native getGenericSignature -
 getGenericSignature0 is still needed now that there's no 
 getGenericSignature non-native method in Class. Every native method 
 ending with '0' has a non-native counterpart with same name (just
 '0' stripped).

I do think that marking the native methods with the suffixes is a good
thing, easing the future change in the internal APIs (e.g. introducing
non-native getGenericSignature). I can revert this if anybody else
thinks otherwise.

-Aleksey.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread David Chase

On 2013-06-10, at 11:53 AM, Aleksey Shipilev aleksey.shipi...@oracle.com 
wrote:

 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3000.008  nsec/op

Am I reading this correctly?  0.008 nsec/op means 125 times 10-to-the-9th ops 
per second.
That's a high clock rate.

Have most been optimized out, are we using parallelism to our advantage, what 
happened here?

David



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-11 Thread Aleksey Shipilev
On 06/11/2013 07:58 PM, David Chase wrote:
 
 On 2013-06-10, at 11:53 AM, Aleksey Shipilev aleksey.shipi...@oracle.com 
 wrote:
 
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3000.008  nsec/op
 
 Am I reading this correctly?  0.008 nsec/op means 125 times 10-to-the-9th ops 
 per second.

Look up to the table header: that is the error margin.
The result is 5.300 +- 0.008 nsec/op.

 That's a high clock rate.

Yeah, that is why any benchmark rating lower than 1 ns/op is raising the
red flag all over the performance guys. :)

-Aleksey.


RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Aleksey Shipilev
Hi,

This is the follow-up on the issue Doug identified:
  http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html

I had reworked the patch, webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.01/

Notable differences from Doug's version are:
  - handle non-generic cases as well
  - reuse ReflectionData to cache the interfaces and generic signatures
  - code style (chained ternary operators blown up)
  - fixes the race along the way
  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6398355

Testing:
  - Linux x86_64/release: build OK
  - Linux x86_64/release: java/lang/reflect regression tests OK
  - Microbenchmarks show whooping increase in performance, see below

(If there are no stylistic and other comments, I would like to do the
JPRT submit and/or additional testing [which?]).

The benchmark is here (you need JMH to build and run):
  http://cr.openjdk.java.net/~shade/8016236/classbench.zip

Before:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51  
 326.8351.220  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51  
 308.7932.828  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51  
 312.6271.637  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
 216.9838.902  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
 59.9330.183  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 65.4690.284  nsec/op

Doug's version:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
 15.1060.271  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3040.024  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51   
 16.7390.045  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
 213.8251.346  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
 61.6510.394  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 64.3400.522  nsec/op

After:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
 14.9850.104  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3000.008  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51   
 16.8740.175  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51   
 23.9410.177  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51
 8.5830.044  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 12.4000.045  nsec/op

Thanks,
Aleksey.


Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Paul Sandoz

On Jun 10, 2013, at 5:53 PM, Aleksey Shipilev aleksey.shipi...@oracle.com 
wrote:

 Hi,
 
 This is the follow-up on the issue Doug identified:
  http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html
 
 I had reworked the patch, webrev is here:
  http://cr.openjdk.java.net/~shade/8016236/webrev.01/
 
 Notable differences from Doug's version are:
  - handle non-generic cases as well

I was wondering about that case too.


  - reuse ReflectionData to cache the interfaces and generic signatures

Any guess on the size impact due to those new fields in ReflectionData?


  - code style (chained ternary operators blown up)
  - fixes the race along the way
  http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6398355
 
 Testing:
  - Linux x86_64/release: build OK
  - Linux x86_64/release: java/lang/reflect regression tests OK
  - Microbenchmarks show whooping increase in performance, see below
 

Nice improvements.

Paul.


 (If there are no stylistic and other comments, I would like to do the
 JPRT submit and/or additional testing [which?]).
 
 The benchmark is here (you need JMH to build and run):
  http://cr.openjdk.java.net/~shade/8016236/classbench.zip
 
 Before:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51  
 326.8351.220  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51  
 308.7932.828  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51  
 312.6271.637  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
 216.9838.902  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
 59.9330.183  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 65.4690.284  nsec/op
 
 Doug's version:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
 15.1060.271  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3040.024  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51   
 16.7390.045  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
 213.8251.346  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
 61.6510.394  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 64.3400.522  nsec/op
 
 After:
 Benchmark   Mode ThrCnt  Sec 
 Mean   Mean errorUnits
 o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
 14.9850.104  nsec/op
 o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
 5.3000.008  nsec/op
 o.b.ClassBench.generic_getTypeParametersavgt   1  51   
 16.8740.175  nsec/op
 o.b.ClassBench.raw_getGenericInterfaces avgt   1  51   
 23.9410.177  nsec/op
 o.b.ClassBench.raw_getGenericSuperclass avgt   1  51
 8.5830.044  nsec/op
 o.b.ClassBench.raw_getTypeParametersavgt   1  51   
 12.4000.045  nsec/op
 
 Thanks,
 Aleksey.



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Aleksey Shipilev
Thanks for taking a look, Paul!
Can I count your review as official?

On 06/10/2013 08:44 PM, Paul Sandoz wrote:
  - reuse ReflectionData to cache the interfaces and generic signatures
 
 Any guess on the size impact due to those new fields in ReflectionData?

Seems to be additional 16 bytes (boolean+oop+oop+alignment, see below);
again, since the ReflectionData is lazily-constructed, this is not the
issue for most of the classes.

 Before:

Running 64-bit HotSpot VM.
Using compressed references with 3-bit shift.
Objects are 8 bytes aligned.

java.lang.Class.ReflectionData
 offset  size  type description
  012   (assumed to be the object header)
 12 4   int ReflectionData.redefinedCount
 16 4   Field[] ReflectionData.declaredFields
 20 4   Field[] ReflectionData.publicFields
 24 4  Method[] ReflectionData.declaredMethods
 28 4  Method[] ReflectionData.publicMethods
 32 4 Constructor[] ReflectionData.declaredConstructors
 36 4 Constructor[] ReflectionData.publicConstructors
 40 4   Field[] ReflectionData.declaredPublicFields
 44 4  Method[] ReflectionData.declaredPublicMethods
 48 (object boundary, size estimate)

 After:

Running 64-bit HotSpot VM.
Using compressed references with 3-bit shift.
Objects are 16 bytes aligned.

java.lang.Class.ReflectionData
 offset  size  type description
  012   (assumed to be the object header)
 12 4   int ReflectionData.redefinedCount
 16 1   boolean ReflectionData.genericSignatureResolved
 17 3   (alignment/padding gap)
 20 4   Field[] ReflectionData.declaredFields
 24 4   Field[] ReflectionData.publicFields
 28 4  Method[] ReflectionData.declaredMethods
 32 4  Method[] ReflectionData.publicMethods
 36 4 Constructor[] ReflectionData.declaredConstructors
 40 4 Constructor[] ReflectionData.publicConstructors
 44 4   Field[] ReflectionData.declaredPublicFields
 48 4  Method[] ReflectionData.declaredPublicMethods
 52 4   Class[] ReflectionData.interfaces
 56 4String ReflectionData.genericSignature
 60 4   (loss due to the next object alignment)
 64 (object boundary, size estimate)



Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Peter Levart

Hi Aleksey,

When 'sun.reflect.noCaches=true' system property is defined, 
reflectionData() returns null. In that case, the code should cope 
without using ReflectionData (no caching). See other uses of 
reflectionData() (for example: in privateGetDeclaredFields())...


I should note that ReflectionData is invalidated when the class is 
redefined. I don't know if generic signature is one of those things that 
can change with class redefinition, but invalidation is just one purpose 
of ReflectionData and the other is caching (via SoftReference), so 
generic signature can be added to it for that purpose. If 
'genericSignature' is cached on ReflectionData then it would be 
consistent to also cache the derived 'genericInfo', what do you think?


I don't think 3 fields are needed (genericSignatureResolved, 
genericSignature  genericInfo). I think one boolean flag (say : 
genericInfoPresent) and genericInfo is all that is needed. If there was 
a singleton ClassRepository NONE instance, then event the boolean flag 
wouldn't be needed.


Regards, Peter


On 06/10/2013 05:53 PM, Aleksey Shipilev wrote:

Hi,

This is the follow-up on the issue Doug identified:
   http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html

I had reworked the patch, webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.01/

Notable differences from Doug's version are:
   - handle non-generic cases as well
   - reuse ReflectionData to cache the interfaces and generic signatures
   - code style (chained ternary operators blown up)
   - fixes the race along the way
   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6398355

Testing:
   - Linux x86_64/release: build OK
   - Linux x86_64/release: java/lang/reflect regression tests OK
   - Microbenchmarks show whooping increase in performance, see below

(If there are no stylistic and other comments, I would like to do the
JPRT submit and/or additional testing [which?]).

The benchmark is here (you need JMH to build and run):
   http://cr.openjdk.java.net/~shade/8016236/classbench.zip

Before:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51  
326.8351.220  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51  
308.7932.828  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51  
312.6271.637  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
216.9838.902  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
59.9330.183  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
65.4690.284  nsec/op

Doug's version:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
15.1060.271  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
5.3040.024  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51   
16.7390.045  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
213.8251.346  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
61.6510.394  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
64.3400.522  nsec/op

After:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
14.9850.104  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
5.3000.008  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51   
16.8740.175  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51   
23.9410.177  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51
8.5830.044  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
12.4000.045  nsec/op

Thanks,
Aleksey.




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Peter Levart

Hi Aleksey,

While you're at it adding getInterfaces() cache, why not also 
getSuperclass()? Is it maybe already intrinsified?


Regards, Peter

On 06/10/2013 05:53 PM, Aleksey Shipilev wrote:

Hi,

This is the follow-up on the issue Doug identified:
   http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/017798.html

I had reworked the patch, webrev is here:
   http://cr.openjdk.java.net/~shade/8016236/webrev.01/

Notable differences from Doug's version are:
   - handle non-generic cases as well
   - reuse ReflectionData to cache the interfaces and generic signatures
   - code style (chained ternary operators blown up)
   - fixes the race along the way
   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6398355

Testing:
   - Linux x86_64/release: build OK
   - Linux x86_64/release: java/lang/reflect regression tests OK
   - Microbenchmarks show whooping increase in performance, see below

(If there are no stylistic and other comments, I would like to do the
JPRT submit and/or additional testing [which?]).

The benchmark is here (you need JMH to build and run):
   http://cr.openjdk.java.net/~shade/8016236/classbench.zip

Before:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51  
326.8351.220  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51  
308.7932.828  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51  
312.6271.637  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
216.9838.902  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
59.9330.183  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
65.4690.284  nsec/op

Doug's version:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
15.1060.271  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
5.3040.024  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51   
16.7390.045  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51  
213.8251.346  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51   
61.6510.394  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
64.3400.522  nsec/op

After:

Benchmark   Mode ThrCnt  Sec 
Mean   Mean errorUnits
o.b.ClassBench.generic_getGenericInterfaces avgt   1  51   
14.9850.104  nsec/op
o.b.ClassBench.generic_getGenericSuperclass avgt   1  51
5.3000.008  nsec/op
o.b.ClassBench.generic_getTypeParametersavgt   1  51   
16.8740.175  nsec/op
o.b.ClassBench.raw_getGenericInterfaces avgt   1  51   
23.9410.177  nsec/op
o.b.ClassBench.raw_getGenericSuperclass avgt   1  51
8.5830.044  nsec/op
o.b.ClassBench.raw_getTypeParametersavgt   1  51   
12.4000.045  nsec/op

Thanks,
Aleksey.




Re: RFR (S) CR 8016236: Class.getGenericInterfaces performance improvement

2013-06-10 Thread Peter Levart


On 06/10/2013 10:57 PM, Peter Levart wrote:
I don't think 3 fields are needed (genericSignatureResolved, 
genericSignature  genericInfo). I think one boolean flag (say : 
genericInfoPresent) and genericInfo is all that is needed. If there 
was a singleton ClassRepository NONE instance, then even the boolean 
flag wouldn't be needed.


Hi Aleksey,

Here's what I meant by above (no genericSignature caching is needed and 
no additional fields):



private static class LazyHolder {
static final ClassRepository NULL_CLASS_REPOSITORY = 
ClassRepository.make(Ljava/lang/Object;, null);

}

// accessor for generic info repository
private ClassRepository getGenericInfo() {
ClassRepository genericInfo = this.genericInfo;
// lazily initialize repository if necessary
if (genericInfo == null) {
String signature = getGenericSignature();
// create and cache generic info repository
this.genericInfo = genericInfo = (signature == null)
? LazyHolder.NULL_CLASS_REPOSITORY
: ClassRepository.make(signature, getFactory());
}
//return cached repository
return genericInfo == LazyHolder.NULL_CLASS_REPOSITORY
   ? null
   : genericInfo;
}



Regards, Peter