More performance explorations

Charles Oliver Nutter headius at headius.com
Thu Jun 2 23:39:29 PDT 2011


On Thu, Jun 2, 2011 at 9:37 PM, John Rose <john.r.rose at oracle.com> wrote:
> Thanks; I'll look at your dump later tonight.
> If the problem is friction from interface casts, we can probably remove
> them.  It's hard to figure out how they are getting in, though.  It happens
> when IRubyObject interconverts with Object.  Are you doing it, or is it
> coming from inside the java.lang.invoke classes?  That's the first question.
>  It probably comes from an asType, but some asType calls are implicit within
> the 292 API.  What asType calls (was convertArguments) are in your code?
> Key fact:  asType/convertArguments used to allow interfaces a free unchecked
> pass into and out of Object.  Now only explicitCastArguments does this.  If
> you convert between an interface and Object, you'll get a real checkcast
> (and a potential CCE) from asType.
> Try changing convertArguments globally to explicitCastArguments and see what
> happens.

Ok, I may have gotten confused a bit but the back-and-forth about
where an interface cast would be forced and where it would not.

There are several places where I am using convertArguments/asType, but
since they recently slower than simply doing an inline cache and
non-MH invocation, I ended up disabling them. Specifically, paths that
require pre/post logic had at least one asType in them as part of
routing calls through JRuby's DynamicMethod.call. I can certainly
change them to explicitCastArguments, but perhaps you can explain the
actual difference in observable behavior for me? In this case, I know
all arguments should cast cleanly.

Now as I say, I don't believe those paths are being used in this
benchmark. There are two calls in fib_ruby that are using
invokedynamic.

The logic for the recursive fib_ruby call (Ruby to Ruby) is structured like so:

GWT =>
....test: insertArguments => dropArguments => dropArguments => static
method (DMH)
....target: permuteArguments => insertArguments => insertArguments =>
static method (DMH)

The chain is intentionally simple, which is why the more complex
DynamicMethod path is not being bound (lots more arg fiddling
involved)

For the + call (Ruby to Java), we have the following:

GWT =>
....test: insertArguments => dropArguments => dropArguments => static
method (DMH)
....target: permuteArguments => explicitCastArguments => static or
virtual method (DMH)

And that's it. The exploration I sent earlier today was based on
fib_ruby; I have not compare it to the + call's asm.

> On Jun 2, 2011, at 5:15 PM, Charles Oliver Nutter wrote:
> I'm quite happy to do so! Did SwitchPoint optimization make it in?
>
> Yes, but it's painfully late.  <grumble>You realize that for every power
> user like you who can use it correctly there will be 10 people who find it
> via auto-complete and write bad code.  (If you act as if a 'true' value of
> isValid is trustworthy, you will probably write a race condition into your
> code.)  Some of us on the EG *really* want to avoid having users (not you)
> shoot themselves in the foot.  IBM (Dan) is strongly lobbying to at least
> change the name of the predicate to 'hasBeenInvalidated' so it looks more
> like what it really is, a tricky asymmetric effectively-volatile
> indirectly-mutable-but-monotonic boolean.  (Your comments?  Got an easy fix
> for this issue?)</grumble>

I think I suggested (or almost suggested) the same name in response to
the "isInvalid" discussion. I'm starting to come around to the idea
that we want to emphasize the stable state rather than the unstable
state, after letting it swirl around in my head for a while. Warning:
Brainstorm Ahead!

* hasBeenInvalidated isn't bad, but it's dreadfully long.
isInvalidated conveys the same stable property (that of
invalidatedness) without using a confusing tense (present perfect or
present perfect progressive, I think?)
* it's a SwitchPoint...how about isSwitched or isSwitchedOff? Or
isOff? isDisabled? isDead?
* technically there's nothing "negative" about the SwitchPoint other
than it's being switched to the non-valid state. That could mean some
happily positive event has fired. I almost wonder now if it shouldn't
be SwitchPoint.switchAll and SwitchPoint.isSwitched, but I think that
train has sailed :)

> And just to make sure:  Are you positive you need it?  (<grimace/>I'm
> convinced, but it's one of those safety-vs.power problems.  Your most
> telling point is that the object has the data inside itself, often, and it's
> just rude to users not to share.)  It gets exponentially more painful to
> make changes as each week passes!  We have to get this right soon, as in two
> weeks ago.

Let's put it this way...for the use case I have in mind, I want to
skip generating the switchpoint-based guard logic entirely once it has
been flipped and revert to a slow path version forever. I can do that
myself via a volatile, which I check on every compilation event that
would optionally use the switchpoint logic. It would be cleaner and
less redundant if I could just find out whether the switchpoint might
still be valid (or is definitely invalid) so I can not bother with it
and branch immediately to the slow path logic for all future compiles.

In the absence of the method, I can use Rémi's trick, of course.

> But the answer to your question is, yes; SP.isValid is under review (in the
> hsx/hotspot-comp repo) for proposed inclusion in b145.

Actually my question was whether SwitchPoint optimization (removing
the volatile read, making it the cheapest guard available) made it
into the Hotspot codebase that will eventually become OpenJDK 1.7.0.

- Charlie


More information about the mlvm-dev mailing list