58
58
*/
59
59
public final class MethodHandleFactory {
60
60
61
+ private static final DebugLogger log = Context .getContext ().getLogger (StandardMethodHandleFunctionality .class );
62
+
61
63
private static final MethodHandles .Lookup PUBLIC_LOOKUP = MethodHandles .publicLookup ();
62
64
private static final MethodHandles .Lookup LOOKUP = MethodHandles .lookup ();
63
65
@@ -100,6 +102,19 @@ public static String stripName(final Object obj) {
100
102
return obj .toString ();
101
103
}
102
104
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
+
103
118
private static final MethodHandleFunctionality FUNC = new StandardMethodHandleFunctionality ();
104
119
private static final boolean PRINT_STACKTRACE = Options .getBooleanProperty ("nashorn.methodhandles.debug.stacktrace" );
105
120
@@ -111,16 +126,8 @@ public static MethodHandleFunctionality getFunctionality() {
111
126
return FUNC ;
112
127
}
113
128
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
-
118
129
private static final String VOID_TAG = "[VOID]" ;
119
130
120
- private static void err (final String str ) {
121
- Context .getContext ().getErr ().println (str );
122
- }
123
-
124
131
/**
125
132
* Tracer that is applied before a value is returned from the traced function. It will output the return
126
133
* value and its class
@@ -129,13 +136,11 @@ private static void err(final String str) {
129
136
* @return return value unmodified
130
137
*/
131
138
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" +
133
141
(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 ()) + ']' ));
139
144
logger .log (TRACE_LEVEL , str );
140
145
}
141
146
@@ -154,48 +159,44 @@ static void traceReturnVoid(final DebugLogger logger) {
154
159
* @param args arguments to the function
155
160
*/
156
161
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 ();
158
164
159
- sb .append (tag );
165
+ sb .append (tag );
160
166
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 (']' );
165
180
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
+ }
177
184
}
178
- }
179
185
180
- if (logger == null ) {
181
- err (sb .toString ());
182
- } else {
183
186
logger .log (TRACE_LEVEL , sb );
187
+ stacktrace (logger );
184
188
}
185
- stacktrace (logger );
186
189
}
187
190
188
191
private static void stacktrace (final DebugLogger logger ) {
189
192
if (!PRINT_STACKTRACE ) {
190
193
return ;
191
194
}
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 ();
199
200
logger .log (TRACE_LEVEL , st );
200
201
}
201
202
}
@@ -274,15 +275,13 @@ public static MethodHandle addDebugPrintout(final MethodHandle mh, final int par
274
275
* @return traced method handle
275
276
*/
276
277
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
-
279
278
//if there is no logger, or if it's set to log only coarser events
280
279
//than the trace level, skip and return
281
280
if (logger == null || !logger .isLoggable (level )) {
282
281
return mh ;
283
282
}
284
283
285
- assert TRACE != null ;
284
+ final MethodType type = mh . type () ;
286
285
287
286
MethodHandle trace = MethodHandles .insertArguments (TRACE , 0 , logger , tag , paramStart );
288
287
@@ -318,18 +317,12 @@ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Leve
318
317
@ Logger (name ="methodhandles" )
319
318
private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality , Loggable {
320
319
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
-
327
320
public StandardMethodHandleFunctionality () {
328
321
}
329
322
330
323
@ Override
331
324
public DebugLogger initLogger (final Context context ) {
332
- return this . log = context . getLogger ( this . getClass ()) ;
325
+ return log ;
333
326
}
334
327
335
328
@ Override
@@ -345,12 +338,12 @@ protected static String describe(final Object... data) {
345
338
if (d == null ) {
346
339
sb .append ("<null> " );
347
340
} else if (isString (d )) {
348
- sb .append (d . toString () );
341
+ sb .append (d );
349
342
sb .append (' ' );
350
343
} else if (d .getClass ().isArray ()) {
351
344
sb .append ("[ " );
352
345
for (final Object da : (Object [])d ) {
353
- sb .append (describe (new Object []{ da } )).append (' ' );
346
+ sb .append (describe (da )).append (' ' );
354
347
}
355
348
sb .append ("] " );
356
349
} else {
@@ -369,13 +362,8 @@ protected static String describe(final Object... data) {
369
362
}
370
363
371
364
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 ));
379
367
}
380
368
381
369
@ Override
0 commit comments