Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-12-12 Thread Florian Weimer
* John Rose:

 But, in order to respect the general aim you are mentioning, I have
 unhoisted one of the two words from the Class instance itself.  This
 will cause a minor slowdown in JSR 292 use cases.

What about using ClassValue for the various caches instead?
enumConstants and enumConstantDirectory seem good candidates (callers
cache the value anyway or do additional work while accessing the field).

-- 
Florian Weimerfwei...@bfk.de
BFK edv-consulting GmbH   http://www.bfk.de/
Kriegsstraße 100  tel: +49-721-96201-1
D-76133 Karlsruhe fax: +49-721-96201-99
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-12-08 Thread John Rose
On Dec 8, 2011, at 1:55 AM, Florian Weimer wrote:

 * John Rose:
 
 But, in order to respect the general aim you are mentioning, I have
 unhoisted one of the two words from the Class instance itself.  This
 will cause a minor slowdown in JSR 292 use cases.
 
 What about using ClassValue for the various caches instead?
 enumConstants and enumConstantDirectory seem good candidates (callers
 cache the value anyway or do additional work while accessing the field).

That's a fine idea, Florian, especially when we are counting every word of 
fixed overhead.  (The alternative is keeping one root pointer in Class for the 
whole block of caches.)

Even the reflective caches are candidates for ClassValue treatment, since only 
a minority of classes are subjected to reflective operations.

ClassValue is good for any set of values associated sparsely with classes, as 
long as the query does not happen in a very tight loop.

The trade-off is whether to add another 4-5 cache line touches per use to buy 
the extra compactness.  To compare queries:

  Class cls = ...;
  Object val1 = cls.cache1;
  if (val1 != null) ... // fill cache
  test1(val1);

  load $t1, [$cls + #Class::cache1]
  test $t1
  jump,zero Lfillcache
  call test1($t1)

  ClassValue cval = ...
  Object val2 = cval.get(cls);
  test2(val2);

  load $t1, [$cls + #Class::classValueMap]
  load $t2array, [$t1 + #ClassValueMap::cacheArray]
 implicit { test $t1; jump,zero Lfillcache }  // via trap handler
  load $t3, [$t2array + #Object[]::length]
  sub $t3, 1
  jump,negative Lfatal  // never taken; software invariant
  load $t4a, [$cval + #ClassValue::hashCodeForCache]
  load $t4b, [$cval + #ClassValue::version]
  and $t4a, $t3
  load $t5entry, [$t2array + $t4a*wordSize + #Object[]::base]
  load $t6a, [$t5entry + #Entry::value]
  load $t6b, [$t5entry + #Entry::version]
  cmp $t6b, $t5b
  jump,notEqual Lfillcache
  call test2($t6a)

The pointer dependencies for cache references are:
  ClassValue - t4:{hashCodeForCache,version}
  Class - t1:ClassValueMap - t2:cacheArray - ( t3:length,  t5:Entry - 
t6:{value,version} )

The bracketed items are likely to be on a single cache line, so there are six 
cache references.  For a constant ClassValue, the t4 references can (in 
principle) be hoisted as constants into the code.  And the first indirection 
($t1) could be removed by hoisting the cache array back into Class.

All this reminds me...

Somebody should experiment with re-implementing reflection and proxy creation 
on top of method handles.  It would let us cut out a bunch of old code (both 
C++ and Java), and standardize on a single high-leverage mechanism for runtime 
method composition.  (Look in the current JDK core where bytecode spinning is 
happening...  Those places are all candidates for refactoring with method 
handles.)

We are working on tuning up method handle invocation performance (e.g., 
7023639).  When method handles are robustly performant, we will have the 
attractive option of refactoring older APIs on top of MHs.

It's not too early to start experimenting with a POC for this.  It would be a 
nice big open-source project.  Any takers?

-- John___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-12-04 Thread Rémi Forax
On 12/04/2011 08:38 PM, Joe Darcy wrote:
 Hi John,

 Are there alternatives to adding two new fields to java.lang.Class?  I 
 assume most Class'es won't have ClassValue information associated with 
 them.

 -Joe

If you use Groovy, JRuby or Nashorn in your code, all visible classes 
will use this two fields.

Any alternative will slow down the access to the class value.

BTW, if we had to remove some fields, I vote for moving all fields 
related to the reflection
in a delegate class. Looking up for members is slow so most of the code 
that call reflection
methods use their own cache, so the performance impact will be small in 
my opinion
(I have no data to prove that :)

Rémi

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-12-04 Thread Rémi Forax
On 12/05/2011 01:27 AM, Joe Darcy wrote:
 On 12/4/2011 2:13 PM, Rémi Forax wrote:
 On 12/04/2011 08:38 PM, Joe Darcy wrote:
 Hi John,

 Are there alternatives to adding two new fields to java.lang.Class?  
 I assume most Class'es won't have ClassValue information associated 
 with them.

 -Joe

 If you use Groovy, JRuby or Nashorn in your code, all visible classes 
 will use this two fields.

 Any alternative will slow down the access to the class value.

 In the mean time, all the non-Groovy, non-JRuby, non-Nashorn, etc. 
 uses of class Class and all the classes not visible in those 
 environments when they are being used will be larger.

 Adding the fields may be the right time/space trade-off, but I think 
 the point merits some discussion given how many Class objects get 
 created and the relative proportion of Java executions where 
 ClassValue is currently used.

 The more reasonable time/space trade-off can change over time of course.

 -Joe


I agree but as I said, in that case, I think it's better to take a look 
to the big picture
and see if not only class values fields but also annotations related 
fields or reflection related fields
can be moved.

Also, if we don't provide a fast ClassValue, people will create their 
own concurrent weak hash map
using class as key that will be worst because it seems that only few 
people knows
how to do that right. Personally, I don't.

Rémi

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-12-03 Thread John Rose
The caching ClassValue is still under review.  I took the opportunity to remove 
-Xlint warnings (adding type parameters) and refactor for better readability.

Also, Mike Duigou pointed out that there was still a dependency on 
ClassValue.equals == Object.equals, which could create a side-channel between 
independent CVs.  I removed this by replacing ClassValue with 
ClassValue.Identity as the hash table key.

The cache access is racy, for speed, but all races are (thought to be) benign.  
For cache hits, end-user values are obtained from non-racing accesses.  All 
cache state changes happen either under a per-class lock or during GC (nulling 
of weak references).

Could I have a re-review?

Thanks,
-- John

On Sep 20, 2011, at 4:10 PM, John Rose wrote:

 On Sep 19, 2011, at 2:58 PM, John Rose wrote:
 
 http://cr.openjdk.java.net/~jrose/7030453/webrev.00
 
 After some comments from David Holmes (thanks David!) I added internal 
 comments about race conditions.
 
 I refreshed the webrev with the additional comments.  I also changed one 
 variable to be volatile, with a paragraph of comments explaining why.
 
 (The change to volatile will inhibit CSE of ClassValue.get calls, but I think 
 such CSE was unlikely anyway.  There should be no other performance effects.)
 
 -- John

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-20 Thread Christian Thalinger

On Sep 19, 2011, at 11:58 PM, John Rose wrote:

 http://cr.openjdk.java.net/~jrose/7030453/webrev.00

src/share/classes/java/lang/ClassValue.java:

 233 /** Value stream for for hashCodeForCache.  See similar structure in 
ThreadLocal. */

Two for's.

 578  *  from the ehad of a non-null run, which would allow them

ehad?

Otherwise I think this looks good.

-- Christian

 
 The existing JDK 7 implementation of ClassValue is a place-holder which is 
 defective in several ways:
 - It uses cascaded WeakHashMaps to map from (Class, ClassValue) pairs to 
 values, which is slow.
 - It does not lock the root WeakHashMap, which can cause a race condition the 
 first time a class is encountered.
 - It relies on internal details of WeakHashMap to avoid other race conditions.
 
 The new implementation uses a concurrently readable cache per Class object 
 with entry versioning to manage lookups.  It is more correct and scalable.
 
 The tunable parameters CACHE_LOAD_LIMIT and PROBE_LIMIT were chosen by 
 looking at the behavior of artificial workloads.  Experience with real 
 workloads will probably lead to further modifications (under new Change 
 Requests).  I thought of making them tunable from JVM command line 
 properties, but since no other class in java.lang does this, I held back.
 
 The previous implementation had a store barrier which pushed (via lazySet) 
 pending store values from the user-supplied value before the ClassValue 
 mapping was published.  I removed it because it is a false fix for 
 user-caused race conditions.  (False because it has the desired effect only 
 on some platforms.)  I think it is better to put that issue back onto the 
 user.  We still need a memory fence API to give users the right hook for such 
 problems.
 
 There is a package-private change to java.lang.Class, adding two new fields 
 (to the existing 19 fields declared in Class.java).
 
 Although this class is in java.lang, it is part of JSR 292.  Therefore the 
 review comments will be collected in mlvm-dev.  The review request is CC-ed 
 to hotspot-compiler (where JSR 292 changes are pushed) and core-libs (which 
 is responsible for java.lang).
 
 -- John

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-20 Thread John Rose
On Sep 20, 2011, at 1:02 AM, Christian Thalinger wrote:

 On Sep 19, 2011, at 11:58 PM, John Rose wrote:
 
 http://cr.openjdk.java.net/~jrose/7030453/webrev.00
 
 src/share/classes/java/lang/ClassValue.java:
 
 233 /** Value stream for for hashCodeForCache.  See similar structure in 
 ThreadLocal. */
 
 Two for's.
 
 578  *  from the ehad of a non-null run, which would allow them
 
 ehad?

head

 Otherwise I think this looks good.

Thanks!

-- John
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-20 Thread John Rose
On Sep 19, 2011, at 2:58 PM, John Rose wrote:

 http://cr.openjdk.java.net/~jrose/7030453/webrev.00

After some comments from David Holmes (thanks David!) I added internal comments 
about race conditions.

I refreshed the webrev with the additional comments.  I also changed one 
variable to be volatile, with a paragraph of comments explaining why.

(The change to volatile will inhibit CSE of ClassValue.get calls, but I think 
such CSE was unlikely anyway.  There should be no other performance effects.)

-- John
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-19 Thread John Rose
http://cr.openjdk.java.net/~jrose/7030453/webrev.00

The existing JDK 7 implementation of ClassValue is a place-holder which is 
defective in several ways:
 - It uses cascaded WeakHashMaps to map from (Class, ClassValue) pairs to 
values, which is slow.
 - It does not lock the root WeakHashMap, which can cause a race condition the 
first time a class is encountered.
 - It relies on internal details of WeakHashMap to avoid other race conditions.

The new implementation uses a concurrently readable cache per Class object with 
entry versioning to manage lookups.  It is more correct and scalable.

The tunable parameters CACHE_LOAD_LIMIT and PROBE_LIMIT were chosen by looking 
at the behavior of artificial workloads.  Experience with real workloads will 
probably lead to further modifications (under new Change Requests).  I thought 
of making them tunable from JVM command line properties, but since no other 
class in java.lang does this, I held back.

The previous implementation had a store barrier which pushed (via lazySet) 
pending store values from the user-supplied value before the ClassValue mapping 
was published.  I removed it because it is a false fix for user-caused race 
conditions.  (False because it has the desired effect only on some platforms.)  
I think it is better to put that issue back onto the user.  We still need a 
memory fence API to give users the right hook for such problems.

There is a package-private change to java.lang.Class, adding two new fields (to 
the existing 19 fields declared in Class.java).

Although this class is in java.lang, it is part of JSR 292.  Therefore the 
review comments will be collected in mlvm-dev.  The review request is CC-ed to 
hotspot-compiler (where JSR 292 changes are pushed) and core-libs (which is 
responsible for java.lang).

-- John
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-19 Thread Krystal Mok
Hi John,

On Tue, Sep 20, 2011 at 5:58 AM, John Rose john.r.r...@oracle.com wrote:

 The tunable parameters CACHE_LOAD_LIMIT and PROBE_LIMIT were chosen by
 looking at the behavior of artificial workloads.  Experience with real
 workloads will probably lead to further modifications (under new Change
 Requests).  I thought of making them tunable from JVM command line
 properties, but since no other class in java.lang does this, I held back.


FYI, There's one, java.lang.Integer's cache size is tunable via JVM command
line flag -XX:AutoBoxCacheMax, which in turn sets Java system property
java.lang.Integer.IntegerCache.high, and affects the Integer cache size.
But that's probably a special case anyway.

Regards,
Kris Mok
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Auto Reply: Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-19 Thread kirill . shirokov
On vacation till October 3. Will be reading email occasionally.
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: review request (L): 7030453: JSR 292 ClassValue.get method is too slow

2011-09-19 Thread John Rose
On Sep 19, 2011, at 7:00 PM, Krystal Mok wrote:

 FYI, There's one, java.lang.Integer's cache size is tunable via JVM command 
 line flag -XX:AutoBoxCacheMax, which in turn sets Java system property 
 java.lang.Integer.IntegerCache.high, and affects the Integer cache size. 
 But that's probably a special case anyway.

Thanks for the reminder, Kris.  -- John___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev