On 02/17/2012 06:29 AM, John Rose wrote:
> On Feb 16, 2012, at 8:43 PM, Mark Roos wrote:
>
>> The key code is below and it shows the power of methodHandles is ways one
>> may not expect. And it
>> added almost nothing to the run time ( maybe a few %). It inserts itself
>> into each callsite target and
>> collect entry and exit data.
> Nice!
>
> As a bonus, your profile points are given a chance to modify the arguments
> and return value.
>
> If you don't want to pass the arguments and return value, you can use a
> void-returning combiner with foldArguments (instead of filterArguments). The
> combiner will "see" the arguments and then "return nothing", allowing the
> invoker to continue as before.
Yes, in PHP.reboot I track the hotness of a method by calling a void
returning method that will increment
a counter that is bound to the method.
My first version was using a code very similar to the code of Mark.
I have then switch to use a fold + a void-returning combiner when we
decide to support that idiom.
>
> A different use of foldArguments would also let you pass both the original
> arguments and the return value to the profileExit routine, so it could see
> the whole call. Something like this:
>
> invoker = {spreader which takes standard RtObject[] array};
> profileExit = {method of type (RtCallSite, RtObject, RtObject[]) =>
> RtObject};
> profileExit = insertArguments(profileExit, 0, thisCallSite); //
> (RtObject, RtObject[]) => RtObject
> invoker = foldArguments(profileExit, invoker); // note that invoker
> serves as *combiner*
>
> // add entry profiling last, so that profileExit will see (possibly)
> transformed arguments:
> profileEntry = {method of type (RtCallSite, RtObject[]) => RtObject[]};
> profileEntry = insertArguments(0, thisCallSite); // (RtObject[]) =>
> RtObject[]
> invoker = filterArguments(invoker, profileEntry);
>
> You could also interpose on abnormal termination (exceptions), using
> guardWithCatch.
The try-finallly method handle combiner is one example of the cookbook:
http://code.google.com/p/jsr292-cookbook/source/browse/trunk/interceptors/src/jsr292/cookbook/interceptors/Interceptors.java#68
>
> A relatively simple way to do take full control of traced calls is to
> delegate the actual calling to the profile routine, but this might
> (presently) hurt performance, since it will make all calls go through one hot
> point, profileWrapper:
>
> invoker = {spreader which takes standard RtObject[] array};
> profileWrapper = {method of type (RTCallSite, MethodHandle, RtObject[]) =>
> RtObject};
> // wrapped call will execute this: profileWrapper(thisCallSite,
> unwrappedInvoker, arg...)
> invoker = insertArguments(profileWrapper, 0, thisCallSite, invoker);
>
> I'm glad you are enjoying the toolkit!
>
> -- John
cheers,
Rémi
_______________________________________________
mlvm-dev mailing list
[email protected]
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev