5858 */
5959public final class MethodHandleFactory {
6060
61+ private static final DebugLogger log = Context .getContext ().getLogger (StandardMethodHandleFunctionality .class );
62+
6163 private static final MethodHandles .Lookup PUBLIC_LOOKUP = MethodHandles .publicLookup ();
6264 private static final MethodHandles .Lookup LOOKUP = MethodHandles .lookup ();
6365
@@ -100,6 +102,19 @@ public static String stripName(final Object obj) {
100102 return obj .toString ();
101103 }
102104
105+ private static final MethodHandle TRACE ;
106+ private static final MethodHandle TRACE_RETURN ;
107+ private static final MethodHandle TRACE_RETURN_VOID ;
108+ static {
109+ try {
110+ TRACE = LOOKUP .findStatic (MethodHandleFactory .class , "traceArgs" , MethodType .methodType (void .class , DebugLogger .class , String .class , int .class , Object [].class ));
111+ TRACE_RETURN = LOOKUP .findStatic (MethodHandleFactory .class , "traceReturn" , MethodType .methodType (Object .class , DebugLogger .class , Object .class ));
112+ TRACE_RETURN_VOID = LOOKUP .findStatic (MethodHandleFactory .class , "traceReturnVoid" , MethodType .methodType (void .class , DebugLogger .class ));
113+ } catch (NoSuchMethodException | IllegalAccessException e ) {
114+ throw new LookupException (e );
115+ }
116+ }
117+
103118 private static final MethodHandleFunctionality FUNC = new StandardMethodHandleFunctionality ();
104119 private static final boolean PRINT_STACKTRACE = Options .getBooleanProperty ("nashorn.methodhandles.debug.stacktrace" );
105120
@@ -111,16 +126,8 @@ public static MethodHandleFunctionality getFunctionality() {
111126 return FUNC ;
112127 }
113128
114- private static final MethodHandle TRACE = FUNC .findStatic (LOOKUP , MethodHandleFactory .class , "traceArgs" , MethodType .methodType (void .class , DebugLogger .class , String .class , int .class , Object [].class ));
115- private static final MethodHandle TRACE_RETURN = FUNC .findStatic (LOOKUP , MethodHandleFactory .class , "traceReturn" , MethodType .methodType (Object .class , DebugLogger .class , Object .class ));
116- private static final MethodHandle TRACE_RETURN_VOID = FUNC .findStatic (LOOKUP , MethodHandleFactory .class , "traceReturnVoid" , MethodType .methodType (void .class , DebugLogger .class ));
117-
118129 private static final String VOID_TAG = "[VOID]" ;
119130
120- private static void err (final String str ) {
121- Context .getContext ().getErr ().println (str );
122- }
123-
124131 /**
125132 * Tracer that is applied before a value is returned from the traced function. It will output the return
126133 * value and its class
@@ -129,13 +136,11 @@ private static void err(final String str) {
129136 * @return return value unmodified
130137 */
131138 static Object traceReturn (final DebugLogger logger , final Object value ) {
132- final String str = " return" +
139+ if (logger .isLoggable (TRACE_LEVEL )) {
140+ final String str = " return" +
133141 (VOID_TAG .equals (value ) ?
134- ";" :
135- " " + stripName (value ) + "; // [type=" + (value == null ? "null]" : stripName (value .getClass ()) + ']' ));
136- if (logger == null ) {
137- err (str );
138- } else if (logger .isEnabled ()) {
142+ ";" :
143+ " " + stripName (value ) + "; // [type=" + (value == null ? "null]" : stripName (value .getClass ()) + ']' ));
139144 logger .log (TRACE_LEVEL , str );
140145 }
141146
@@ -154,48 +159,44 @@ static void traceReturnVoid(final DebugLogger logger) {
154159 * @param args arguments to the function
155160 */
156161 static void traceArgs (final DebugLogger logger , final String tag , final int paramStart , final Object ... args ) {
157- final StringBuilder sb = new StringBuilder ();
162+ if (logger .isLoggable (TRACE_LEVEL )) {
163+ final StringBuilder sb = new StringBuilder ();
158164
159- sb .append (tag );
165+ sb .append (tag );
160166
161- for (int i = paramStart ; i < args .length ; i ++) {
162- if (i == paramStart ) {
163- sb .append (" => args: " );
164- }
167+ for (int i = paramStart ; i < args .length ; i ++) {
168+ if (i == paramStart ) {
169+ sb .append (" => args: " );
170+ }
171+
172+ sb .append ('\'' ).
173+ append (stripName (argString (args [i ]))).
174+ append ('\'' ).
175+ append (' ' ).
176+ append ('[' ).
177+ append ("type=" ).
178+ append (args [i ] == null ? "null" : stripName (args [i ].getClass ())).
179+ append (']' );
165180
166- sb .append ('\'' ).
167- append (stripName (argString (args [i ]))).
168- append ('\'' ).
169- append (' ' ).
170- append ('[' ).
171- append ("type=" ).
172- append (args [i ] == null ? "null" : stripName (args [i ].getClass ())).
173- append (']' );
174-
175- if (i + 1 < args .length ) {
176- sb .append (", " );
181+ if (i + 1 < args .length ) {
182+ sb .append (", " );
183+ }
177184 }
178- }
179185
180- if (logger == null ) {
181- err (sb .toString ());
182- } else {
183186 logger .log (TRACE_LEVEL , sb );
187+ stacktrace (logger );
184188 }
185- stacktrace (logger );
186189 }
187190
188191 private static void stacktrace (final DebugLogger logger ) {
189192 if (!PRINT_STACKTRACE ) {
190193 return ;
191194 }
192- final ByteArrayOutputStream baos = new ByteArrayOutputStream ();
193- final PrintStream ps = new PrintStream (baos );
194- new Throwable ().printStackTrace (ps );
195- final String st = baos .toString ();
196- if (logger == null ) {
197- err (st );
198- } else {
195+ if (logger .isLoggable (TRACE_LEVEL )) {
196+ final ByteArrayOutputStream baos = new ByteArrayOutputStream ();
197+ final PrintStream ps = new PrintStream (baos );
198+ new Throwable ().printStackTrace (ps );
199+ final String st = baos .toString ();
199200 logger .log (TRACE_LEVEL , st );
200201 }
201202 }
@@ -274,15 +275,13 @@ public static MethodHandle addDebugPrintout(final MethodHandle mh, final int par
274275 * @return traced method handle
275276 */
276277 public static MethodHandle addDebugPrintout (final DebugLogger logger , final Level level , final MethodHandle mh , final int paramStart , final boolean printReturnValue , final Object tag ) {
277- final MethodType type = mh .type ();
278-
279278 //if there is no logger, or if it's set to log only coarser events
280279 //than the trace level, skip and return
281280 if (logger == null || !logger .isLoggable (level )) {
282281 return mh ;
283282 }
284283
285- assert TRACE != null ;
284+ final MethodType type = mh . type () ;
286285
287286 MethodHandle trace = MethodHandles .insertArguments (TRACE , 0 , logger , tag , paramStart );
288287
@@ -318,18 +317,12 @@ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Leve
318317 @ Logger (name ="methodhandles" )
319318 private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality , Loggable {
320319
321- // for bootstrapping reasons, because a lot of static fields use MH for lookups, we
322- // need to set the logger when the Global object is finished. This means that we don't
323- // get instrumentation for public static final MethodHandle SOMETHING = MH... in the builtin
324- // classes, but that doesn't matter, because this is usually not where we want it
325- private DebugLogger log = DebugLogger .DISABLED_LOGGER ;
326-
327320 public StandardMethodHandleFunctionality () {
328321 }
329322
330323 @ Override
331324 public DebugLogger initLogger (final Context context ) {
332- return this . log = context . getLogger ( this . getClass ()) ;
325+ return log ;
333326 }
334327
335328 @ Override
@@ -345,12 +338,12 @@ protected static String describe(final Object... data) {
345338 if (d == null ) {
346339 sb .append ("<null> " );
347340 } else if (isString (d )) {
348- sb .append (d . toString () );
341+ sb .append (d );
349342 sb .append (' ' );
350343 } else if (d .getClass ().isArray ()) {
351344 sb .append ("[ " );
352345 for (final Object da : (Object [])d ) {
353- sb .append (describe (new Object []{ da } )).append (' ' );
346+ sb .append (describe (da )).append (' ' );
354347 }
355348 sb .append ("] " );
356349 } else {
@@ -369,13 +362,8 @@ protected static String describe(final Object... data) {
369362 }
370363
371364 public MethodHandle debug (final MethodHandle master , final String str , final Object ... args ) {
372- if (log .isEnabled ()) {
373- if (PRINT_STACKTRACE ) {
374- stacktrace (log );
375- }
376- return addDebugPrintout (log , Level .INFO , master , Integer .MAX_VALUE , false , str + ' ' + describe (args ));
377- }
378- return master ;
365+ stacktrace (log );
366+ return addDebugPrintout (log , Level .INFO , master , Integer .MAX_VALUE , false , str + ' ' + describe (args ));
379367 }
380368
381369 @ Override
0 commit comments