58
58
*/
59
59
public final class MethodHandleFactory {
60
60
61
- private static final DebugLogger log = Context .getContext ().getLogger (StandardMethodHandleFunctionality .class );
62
-
63
61
private static final MethodHandles .Lookup PUBLIC_LOOKUP = MethodHandles .publicLookup ();
64
62
private static final MethodHandles .Lookup LOOKUP = MethodHandles .lookup ();
65
63
@@ -128,6 +126,10 @@ public static MethodHandleFunctionality getFunctionality() {
128
126
129
127
private static final String VOID_TAG = "[VOID]" ;
130
128
129
+ private static void err (final String str ) {
130
+ Context .getContext ().getErr ().println (str );
131
+ }
132
+
131
133
/**
132
134
* Tracer that is applied before a value is returned from the traced function. It will output the return
133
135
* value and its class
@@ -136,11 +138,16 @@ public static MethodHandleFunctionality getFunctionality() {
136
138
* @return return value unmodified
137
139
*/
138
140
static Object traceReturn (final DebugLogger logger , final Object value ) {
139
- if (logger .isLoggable (TRACE_LEVEL )) {
140
- final String str = " return" +
141
+ if (logger != null && !logger .isLoggable (TRACE_LEVEL )) {
142
+ return value ;
143
+ }
144
+ final String str = " return" +
141
145
(VOID_TAG .equals (value ) ?
142
146
";" :
143
147
" " + stripName (value ) + "; // [type=" + (value == null ? "null]" : stripName (value .getClass ()) + ']' ));
148
+ if (logger == null ) {
149
+ err (str );
150
+ } else {
144
151
logger .log (TRACE_LEVEL , str );
145
152
}
146
153
@@ -159,44 +166,51 @@ static void traceReturnVoid(final DebugLogger logger) {
159
166
* @param args arguments to the function
160
167
*/
161
168
static void traceArgs (final DebugLogger logger , final String tag , final int paramStart , final Object ... args ) {
162
- if (logger .isLoggable (TRACE_LEVEL )) {
163
- final StringBuilder sb = new StringBuilder ();
169
+ if (logger != null && !logger .isLoggable (TRACE_LEVEL )) {
170
+ return ;
171
+ }
172
+ final StringBuilder sb = new StringBuilder ();
164
173
165
- sb .append (tag );
174
+ sb .append (tag );
166
175
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 (']' );
176
+ for (int i = paramStart ; i < args .length ; i ++) {
177
+ if (i == paramStart ) {
178
+ sb .append (" => args: " );
179
+ }
180
180
181
- if (i + 1 < args .length ) {
182
- sb .append (", " );
183
- }
181
+ sb .append ('\'' ).
182
+ append (stripName (argString (args [i ]))).
183
+ append ('\'' ).
184
+ append (' ' ).
185
+ append ('[' ).
186
+ append ("type=" ).
187
+ append (args [i ] == null ? "null" : stripName (args [i ].getClass ())).
188
+ append (']' );
189
+
190
+ if (i + 1 < args .length ) {
191
+ sb .append (", " );
184
192
}
193
+ }
185
194
195
+ if (logger == null ) {
196
+ err (sb .toString ());
197
+ } else {
186
198
logger .log (TRACE_LEVEL , sb );
187
- stacktrace (logger );
188
199
}
200
+ stacktrace (logger );
189
201
}
190
202
191
203
private static void stacktrace (final DebugLogger logger ) {
192
- if (!PRINT_STACKTRACE ) {
204
+ if (!PRINT_STACKTRACE || ( logger != null && ! logger . isLoggable ( TRACE_LEVEL )) ) {
193
205
return ;
194
206
}
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 ();
207
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream ();
208
+ final PrintStream ps = new PrintStream (baos );
209
+ new Throwable ().printStackTrace (ps );
210
+ final String st = baos .toString ();
211
+ if (logger == null ) {
212
+ err (st );
213
+ } else {
200
214
logger .log (TRACE_LEVEL , st );
201
215
}
202
216
}
@@ -216,26 +230,14 @@ private static String argString(final Object arg) {
216
230
}
217
231
218
232
if (arg instanceof ScriptObject ) {
219
- return arg . toString () +
233
+ return arg +
220
234
" (map=" + Debug .id (((ScriptObject )arg ).getMap ()) +
221
235
')' ;
222
236
}
223
237
224
238
return arg .toString ();
225
239
}
226
240
227
- /**
228
- * Add a debug printout to a method handle, tracing parameters and return values
229
- * Output will be unconditional to stderr
230
- *
231
- * @param mh method handle to trace
232
- * @param tag start of trace message
233
- * @return traced method handle
234
- */
235
- public static MethodHandle addDebugPrintout (final MethodHandle mh , final Object tag ) {
236
- return addDebugPrintout (null , Level .OFF , mh , 0 , true , tag );
237
- }
238
-
239
241
/**
240
242
* Add a debug printout to a method handle, tracing parameters and return values
241
243
*
@@ -249,20 +251,6 @@ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Leve
249
251
return addDebugPrintout (logger , level , mh , 0 , true , tag );
250
252
}
251
253
252
- /**
253
- * Add a debug printout to a method handle, tracing parameters and return values
254
- * Output will be unconditional to stderr
255
- *
256
- * @param mh method handle to trace
257
- * @param paramStart first param to print/trace
258
- * @param printReturnValue should we print/trace return value if available?
259
- * @param tag start of trace message
260
- * @return traced method handle
261
- */
262
- public static MethodHandle addDebugPrintout (final MethodHandle mh , final int paramStart , final boolean printReturnValue , final Object tag ) {
263
- return addDebugPrintout (null , Level .OFF , mh , paramStart , printReturnValue , tag );
264
- }
265
-
266
254
/**
267
255
* Add a debug printout to a method handle, tracing parameters and return values
268
256
*
@@ -317,12 +305,18 @@ public static MethodHandle addDebugPrintout(final DebugLogger logger, final Leve
317
305
@ Logger (name ="methodhandles" )
318
306
private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality , Loggable {
319
307
308
+ // For bootstrapping reasons, because a lot of static fields use MH for lookups, we
309
+ // need to set the logger when the Global object is finished. This means that we don't
310
+ // get instrumentation for public static final MethodHandle SOMETHING = MH... in the builtin
311
+ // classes, but that doesn't matter, because this is usually not where we want it
312
+ private DebugLogger log = DebugLogger .DISABLED_LOGGER ;
313
+
320
314
public StandardMethodHandleFunctionality () {
321
315
}
322
316
323
317
@ Override
324
318
public DebugLogger initLogger (final Context context ) {
325
- return log ;
319
+ return this . log = context . getLogger ( this . getClass ()) ;
326
320
}
327
321
328
322
@ Override
@@ -362,8 +356,13 @@ protected static String describe(final Object... data) {
362
356
}
363
357
364
358
public MethodHandle debug (final MethodHandle master , final String str , final Object ... args ) {
365
- stacktrace (log );
366
- return addDebugPrintout (log , Level .INFO , master , Integer .MAX_VALUE , false , str + ' ' + describe (args ));
359
+ if (log .isEnabled ()) {
360
+ if (PRINT_STACKTRACE ) {
361
+ stacktrace (log );
362
+ }
363
+ return addDebugPrintout (log , Level .INFO , master , Integer .MAX_VALUE , false , str + ' ' + describe (args ));
364
+ }
365
+ return master ;
367
366
}
368
367
369
368
@ Override
0 commit comments