Re: The NoClassDefFoundError bug is back :(

2011-12-08 Thread Charles Oliver Nutter
On Thu, Dec 8, 2011 at 2:16 PM, Rémi Forax  wrote:
> invokeWithArguments uses foldArgument and a generic invoker
> that maybe why you see the same error.
>
> about asType(), the idea is to erase the type before calling
> invokeWithArguments
> instead of
>   mh.invokeWithArgument(args);
> you can use
>   mh.asType(mh.type().erase()).invokeWithArguments(args);
>
> and I have no idea if it works and about the perf cost if there is a cost.

I'll try to give it a shot and see how it looks.

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


Re: Looping construction using only MethodHandles

2011-12-08 Thread MLeo
I do think I remember that (I've been subscribed to the list since
2009-01-21), this was mostly an attempt to see how far it would go (and to
get my brain wired for the MethodHandle API).

However, are the discounted code size budgets the only reason why the
MethodHandle 'loop' can recurse 2x to 6x more than a simpler POJM?
Obviously it doesn't generate stacktraces (at least not that show up), yet
it does consume stack.

One of the other things I'm going to attempt is to create my own While
adapter, with a static field, a bootstrap method and an invoke method that
does an invoke dynamic on the static field. I wonder how small I can get
the class file. I presume that the anonymous classloader in the sun package
will, at some point, be moved/finalized into a java.invoke or java.lang
form?

Thank you for taking a look,

--Maarten Daalder
On 6 December 2011 06:54, Charles Oliver Nutter  wrote:

> This actually came up early this past summer, when I tried to do the
> same thing (after Ola Bini showed me the MutableCallSite invoker
> trick. You can probably find the thread in July some time.
>
> The bottom line was that even if the handles could get folded into
> tail recursion, the call site ends up interfering with the
> MethodHandle optimizer's visibility into the graph.
>
> I was as disappointed as you are (or as you will be, once you've read
> this). I wish I'd been more involved early in the JSR-292 process and
> pushed for a looping construct. Unfortunately that train has sailed,
> and I've found no way to do loops (or any sort of backward branching)
> using the current set of method handle adapters :(
>
> Here's the tease, for future work on invokedynamic: I believe that if
> we had a way to do backward branches, method handles could become a
> turing-complete, user-accessible IR for the JVM's JIT.
>
> - Charlie
>
> On Mon, Dec 5, 2011 at 1:06 PM, MLeo  wrote:
> > Hello all,
> >
> > Over the past few days I've been thinkering with a bit of code that folds
> > over the values of some container using some MethodHandle and a 'zero'
> > value.
> >
> > https://gist.github.com/1425706
> >
> > It's actually an implementation of a strategy to encode higher order
> > functions (HOF) without introducing a plethoramorphic callsite (if I
> > remember the term correctly). If you squint at it right sort of resembles
> > inversion of control. Or it's more like turning a function inside out.
> >
> > And it mostly works, with suprising result.
> > It's not entirely tail call optimized, it still eats stack, but not the
> same
> > amount as an naive unequivalent Java static method that is hand optimized
> > for the task (so no HOF).
> >
> > I'm using the x64 update 2 jdk on Windows Vista with -Xss10m. And the
> naive
> > version bails after a depth of ~11 and after some optimization it
> will
> > get to ~31 (after the first invocation!). The fold, on the other
> hand,
> > only bails out after recursing for ~65 times and gets there nearly
> > immediately, the first run is ~1 lower, but the remainder of
> invocations
> > is consistent (or seems that way, rather, I think it's because not enough
> > optimizations have kicked in yet).
> >
> > Execution time is another story, the POJM (Plain Old Java Method) takes
> > ~5ms, while the fold takes ~30ms. Which, now I think some more about it,
> is
> > more or less in line with the previous initial result, but still seems
> to be
> > a bit slow to me.
> > After some optimizations have kicked in (when the POJM reaches a depth of
> > 31) the execution times stay roughly the same. So it would appear the
> > JVM inlined the POJM 2 or 3 times. Creating the stacktraces doesn't seem
> to
> > impact performance, if I make them recurse 10 times (so it doesn't
> > overflow) then the execution time is roughly the same.
> >
> > Both ways are tested by invoking them through invokeWithArguments (I
> haven't
> > yet managed to get ASM to produce a test class for me), and I let both
> try
> > to sum an array (turned into an Iterator through
> > Arrays.asList(...).iterator()) of a million elements, so both will cause
> a
> > StackOverflowException. The test is to invoke a methods 1000 times (I
> got a
> > bit tired of waiting for a million times) and that I do 6 times (so I
> take 6
> > samples and average across them).
> >
> >
> > Now my question, is there something I can do to make it completely tail
> call
> > optimized? I've tried to 'rotate' the call graph/tree but that obviously
> > wouldn't work (it's still a direct recursion, no matter if you do it
> > directly or in the combiner of a foldArguments). It seems that it is
> almost
> > completely TCO already, but I haven't found where it's leaking stack.
> It's
> > definitely leaking less stack than a simple recursion.
> > Or will we need a special looping combinator here? I initially tried to
> > create a while combinator, however it seems that guardWithTest does not
> > accept MethodHandles returning void (for the targ

Re: The NoClassDefFoundError bug is back :(

2011-12-08 Thread Rémi Forax
On 12/08/2011 06:58 PM, Charles Oliver Nutter wrote:
> I just had a report of the same error in 1.7.0GA, and I saw it on the
> CI server last night after I set up a 1.7.0_01 build. Did it linger
> into GA?
>
> http://ci.jruby.org/job/jruby-test-matrix/jdk=sun-java-7,label=master/406/console
>
> On Tue, Dec 6, 2011 at 3:52 AM, Rémi Forax  wrote:
>> I've forget to say that a workaround is to erase the type used the callsite
>> before calling dynamicInvoker().
> Can you elaborate on this? I'm not using dynamicInvoker...I bind the
> site and use invokeWithArguments. Are you saying I could insert an
> asType() that clears everything to Object?

invokeWithArguments uses foldArgument and a generic invoker
that maybe why you see the same error.

about asType(), the idea is to erase the type before calling 
invokeWithArguments
instead of
   mh.invokeWithArgument(args);
you can use
   mh.asType(mh.type().erase()).invokeWithArguments(args);

and I have no idea if it works and about the perf cost if there is a cost.

>
> If so, would that introduce overhead?
>
> - Charlie

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-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: The NoClassDefFoundError bug is back :(

2011-12-08 Thread Charles Oliver Nutter
I just had a report of the same error in 1.7.0GA, and I saw it on the
CI server last night after I set up a 1.7.0_01 build. Did it linger
into GA?

http://ci.jruby.org/job/jruby-test-matrix/jdk=sun-java-7,label=master/406/console

On Tue, Dec 6, 2011 at 3:52 AM, Rémi Forax  wrote:
> I've forget to say that a workaround is to erase the type used the callsite
> before calling dynamicInvoker().

Can you elaborate on this? I'm not using dynamicInvoker...I bind the
site and use invokeWithArguments. Are you saying I could insert an
asType() that clears everything to Object?

If so, would that introduce overhead?

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


Coro crash running specs

2011-12-08 Thread Charles Oliver Nutter
I'm fixing what looks to be bugs in the coroutine-based Fiber impl,
but I saw this crash today. I think it's a result of an exception
being raised from inside the coroutine.

https://gist.github.com/1447787

To reproduce:

* clone JRuby
* ant jar install-gems fetch-stable-specs
* jruby spec/mspec/bin/mspec ci -T--1.9 -T-X-C
-T-Xfiber.coroutines=true spec/ruby/core/fiber

I saw that OpenJDK is using JIRA now...I wonder if coro could get a
JIRA project for issues?

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