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