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
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to