src/jdk/nashorn/internal/lookup/MethodHandleFactory.java

Wed, 11 Sep 2013 20:49:28 +0530

author
sundar
date
Wed, 11 Sep 2013 20:49:28 +0530
changeset 546
2d4c8fa8a5f4
parent 211
3a209cbd1d8f
child 952
6d5471a497fb
child 963
e2497b11a021
permissions
-rw-r--r--

8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
Reviewed-by: jlaskey, hannesw

jlaskey@3 1 /*
jlaskey@7 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
jlaskey@3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jlaskey@3 4 *
jlaskey@3 5 * This code is free software; you can redistribute it and/or modify it
jlaskey@3 6 * under the terms of the GNU General Public License version 2 only, as
jlaskey@3 7 * published by the Free Software Foundation. Oracle designates this
jlaskey@3 8 * particular file as subject to the "Classpath" exception as provided
jlaskey@3 9 * by Oracle in the LICENSE file that accompanied this code.
jlaskey@3 10 *
jlaskey@3 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jlaskey@3 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jlaskey@3 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jlaskey@3 14 * version 2 for more details (a copy is included in the LICENSE file that
jlaskey@3 15 * accompanied this code).
jlaskey@3 16 *
jlaskey@3 17 * You should have received a copy of the GNU General Public License version
jlaskey@3 18 * 2 along with this work; if not, write to the Free Software Foundation,
jlaskey@3 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jlaskey@3 20 *
jlaskey@3 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jlaskey@3 22 * or visit www.oracle.com if you need additional information or have any
jlaskey@3 23 * questions.
jlaskey@3 24 */
jlaskey@3 25
sundar@133 26 package jdk.nashorn.internal.lookup;
jlaskey@3 27
lagergren@11 28 import java.io.ByteArrayOutputStream;
jlaskey@3 29 import java.io.PrintStream;
jlaskey@3 30 import java.lang.invoke.MethodHandle;
jlaskey@3 31 import java.lang.invoke.MethodHandles;
jlaskey@3 32 import java.lang.invoke.MethodType;
jlaskey@3 33 import java.lang.invoke.SwitchPoint;
jlaskey@3 34 import java.lang.reflect.Method;
jlaskey@3 35 import java.util.ArrayList;
jlaskey@3 36 import java.util.Arrays;
jlaskey@3 37 import java.util.List;
jlaskey@3 38 import java.util.logging.Level;
attila@29 39 import jdk.nashorn.internal.runtime.ConsString;
attila@29 40 import jdk.nashorn.internal.runtime.Debug;
attila@29 41 import jdk.nashorn.internal.runtime.DebugLogger;
attila@29 42 import jdk.nashorn.internal.runtime.ScriptObject;
attila@29 43 import jdk.nashorn.internal.runtime.options.Options;
jlaskey@3 44
jlaskey@3 45 /**
jlaskey@3 46 * This class is abstraction for all method handle, switchpoint and method type
jlaskey@3 47 * operations. This enables the functionality interface to be subclassed and
lagergren@11 48 * intrumensted, as it has been proven vital to keep the number of method
jlaskey@3 49 * handles in the system down.
lagergren@11 50 *
jlaskey@3 51 * All operations of the above type should go through this class, and not
jlaskey@3 52 * directly into java.lang.invoke
lagergren@11 53 *
jlaskey@3 54 */
jlaskey@3 55 public final class MethodHandleFactory {
jlaskey@3 56
jlaskey@3 57 private static final MethodHandles.Lookup PUBLIC_LOOKUP = MethodHandles.publicLookup();
jlaskey@3 58 private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
jlaskey@3 59
lagergren@11 60 private static final Level TRACE_LEVEL = Level.INFO;
jlaskey@3 61
jlaskey@3 62 private MethodHandleFactory() {
jlaskey@3 63 }
jlaskey@3 64
jlaskey@3 65 /**
jlaskey@3 66 * Runtime exception that collects every reason that a method handle lookup operation can go wrong
jlaskey@3 67 */
jlaskey@3 68 @SuppressWarnings("serial")
jlaskey@3 69 public static class LookupException extends RuntimeException {
jlaskey@3 70 /**
jlaskey@3 71 * Constructor
jlaskey@3 72 * @param e causing exception
jlaskey@3 73 */
jlaskey@3 74 public LookupException(final Exception e) {
jlaskey@3 75 super(e);
jlaskey@3 76 }
jlaskey@3 77 }
jlaskey@3 78
jlaskey@3 79 /**
jlaskey@3 80 * Helper function that takes a class or an object with a toString override
jlaskey@3 81 * and shortens it to notation after last dot. This is used to facilitiate
jlaskey@3 82 * pretty printouts in various debug loggers - internal only
jlaskey@3 83 *
jlaskey@3 84 * @param obj class or object
jlaskey@3 85 *
jlaskey@3 86 * @return pretty version of object as string
jlaskey@3 87 */
jlaskey@3 88 public static String stripName(final Object obj) {
jlaskey@3 89 if (obj == null) {
jlaskey@3 90 return "null";
jlaskey@3 91 }
jlaskey@3 92
jlaskey@3 93 if (obj instanceof Class) {
jlaskey@3 94 return ((Class<?>)obj).getSimpleName();
jlaskey@3 95 }
jlaskey@3 96 return obj.toString();
jlaskey@3 97 }
jlaskey@3 98
jlaskey@3 99 private static final MethodHandleFunctionality STANDARD = new StandardMethodHandleFunctionality();
lagergren@11 100 private static final MethodHandleFunctionality FUNC;
lagergren@11 101
lagergren@11 102 private static final String DEBUG_PROPERTY = "nashorn.methodhandles.debug";
lagergren@11 103 private static final DebugLogger LOG = new DebugLogger("methodhandles", DEBUG_PROPERTY);
lagergren@11 104
lagergren@11 105 static {
lagergren@11 106 if (LOG.isEnabled() || Options.getBooleanProperty(DEBUG_PROPERTY)) {
lagergren@11 107 if (Options.getStringProperty(DEBUG_PROPERTY, "").equals("create")) {
lagergren@11 108 FUNC = new TraceCreateMethodHandleFunctionality();
lagergren@11 109 } else {
lagergren@11 110 FUNC = new TraceMethodHandleFunctionality();
lagergren@11 111 }
lagergren@11 112 } else {
lagergren@11 113 FUNC = STANDARD;
lagergren@11 114 }
lagergren@11 115 }
jlaskey@3 116
jlaskey@3 117 private static final boolean PRINT_STACKTRACE = Options.getBooleanProperty("nashorn.methodhandles.debug.stacktrace");
jlaskey@3 118
lagergren@11 119
jlaskey@3 120 /**
jlaskey@3 121 * Return the method handle functionality used for all method handle operations
jlaskey@3 122 * @return a method handle functionality implementation
jlaskey@3 123 */
jlaskey@3 124 public static MethodHandleFunctionality getFunctionality() {
jlaskey@3 125 return FUNC;
jlaskey@3 126 }
jlaskey@3 127
jlaskey@3 128 private static final MethodHandle TRACE = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceArgs", MethodType.methodType(void.class, DebugLogger.class, String.class, int.class, Object[].class));
jlaskey@3 129 private static final MethodHandle TRACE_RETURN = STANDARD.findStatic(LOOKUP, MethodHandleFactory.class, "traceReturn", MethodType.methodType(Object.class, DebugLogger.class, Object.class));
jlaskey@3 130
jlaskey@3 131 /**
jlaskey@3 132 * Tracer that is applied before a value is returned from the traced function. It will output the return
jlaskey@3 133 * value and its class
jlaskey@3 134 *
jlaskey@3 135 * @param value return value for filter
jlaskey@3 136 * @return return value unmodified
jlaskey@3 137 */
jlaskey@3 138 static Object traceReturn(final DebugLogger logger, final Object value) {
jlaskey@3 139 final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']');
lagergren@211 140 logger.log(TRACE_LEVEL, str);
jlaskey@3 141 return value;
jlaskey@3 142 }
jlaskey@3 143
jlaskey@3 144 /**
jlaskey@3 145 * Tracer that is applied before a function is called, printing the arguments
jlaskey@3 146 *
jlaskey@3 147 * @param tag tag to start the debug printout string
jlaskey@3 148 * @param paramStart param index to start outputting from
jlaskey@3 149 * @param args arguments to the function
jlaskey@3 150 */
jlaskey@3 151 static void traceArgs(final DebugLogger logger, final String tag, final int paramStart, final Object... args) {
jlaskey@3 152 final StringBuilder sb = new StringBuilder();
jlaskey@3 153
jlaskey@3 154 sb.append(tag);
jlaskey@3 155
jlaskey@3 156 for (int i = paramStart; i < args.length; i++) {
jlaskey@3 157 if (i == paramStart) {
jlaskey@3 158 sb.append(" => args: ");
jlaskey@3 159 }
jlaskey@3 160
jlaskey@3 161 sb.append('\'').
jlaskey@3 162 append(stripName(argString(args[i]))).
jlaskey@3 163 append('\'').
jlaskey@3 164 append(' ').
jlaskey@3 165 append('[').
jlaskey@3 166 append("type=").
jlaskey@3 167 append(args[i] == null ? "null" : stripName(args[i].getClass())).
jlaskey@3 168 append(']');
jlaskey@3 169
jlaskey@3 170 if (i + 1 < args.length) {
jlaskey@3 171 sb.append(", ");
jlaskey@3 172 }
jlaskey@3 173 }
jlaskey@3 174
lagergren@11 175 assert logger != null;
lagergren@211 176 logger.log(TRACE_LEVEL, sb);
lagergren@11 177 stacktrace(logger);
lagergren@11 178 }
lagergren@11 179
lagergren@11 180 private static void stacktrace(final DebugLogger logger) {
lagergren@11 181 if (!PRINT_STACKTRACE) {
lagergren@11 182 return;
jlaskey@3 183 }
lagergren@11 184 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
lagergren@11 185 final PrintStream ps = new PrintStream(baos);
lagergren@11 186 new Throwable().printStackTrace(ps);
lagergren@211 187 logger.log(TRACE_LEVEL, baos.toString());
jlaskey@3 188 }
jlaskey@3 189
jlaskey@3 190 private static String argString(final Object arg) {
jlaskey@3 191 if (arg == null) {
jlaskey@3 192 return "null";
jlaskey@3 193 }
jlaskey@3 194
jlaskey@3 195 if (arg.getClass().isArray()) {
jlaskey@3 196 final List<Object> list = new ArrayList<>();
jlaskey@3 197 for (final Object elem : (Object[])arg) {
jlaskey@3 198 list.add('\'' + argString(elem) + '\'');
jlaskey@3 199 }
jlaskey@3 200
jlaskey@3 201 return list.toString();
jlaskey@3 202 }
jlaskey@3 203
jlaskey@3 204 if (arg instanceof ScriptObject) {
jlaskey@3 205 return arg.toString() +
jlaskey@3 206 " (map=" + Debug.id((((ScriptObject)arg).getMap())) +
jlaskey@3 207 ")";
jlaskey@3 208 }
jlaskey@3 209
jlaskey@3 210 return arg.toString();
jlaskey@3 211 }
jlaskey@3 212
jlaskey@3 213 /**
jlaskey@3 214 * Add a debug printout to a method handle, tracing parameters and return values
jlaskey@3 215 *
jlaskey@3 216 * @param logger a specific logger to which to write the output
jlaskey@3 217 * @param mh method handle to trace
jlaskey@3 218 * @param tag start of trace message
jlaskey@3 219 * @return traced method handle
jlaskey@3 220 */
jlaskey@3 221 public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) {
jlaskey@3 222 return addDebugPrintout(logger, mh, 0, true, tag);
jlaskey@3 223 }
jlaskey@3 224
jlaskey@3 225
jlaskey@3 226 /**
jlaskey@3 227 * Add a debug printout to a method handle, tracing parameters and return values
jlaskey@3 228 *
jlaskey@3 229 * @param logger a specific logger to which to write the output
jlaskey@3 230 * @param mh method handle to trace
jlaskey@3 231 * @param paramStart first param to print/trace
jlaskey@3 232 * @param printReturnValue should we print/trace return value if available?
jlaskey@3 233 * @param tag start of trace message
jlaskey@3 234 * @return traced method handle
jlaskey@3 235 */
jlaskey@3 236 public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
jlaskey@3 237 final MethodType type = mh.type();
jlaskey@3 238
jlaskey@3 239 if (logger != null && logger.levelAbove(TRACE_LEVEL)) {
jlaskey@3 240 return mh;
jlaskey@3 241 }
jlaskey@3 242
lagergren@11 243 assert logger != null;
jlaskey@3 244 assert TRACE != null;
jlaskey@3 245
jlaskey@3 246 MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart);
jlaskey@3 247
jlaskey@3 248 trace = MethodHandles.foldArguments(
jlaskey@3 249 mh,
jlaskey@3 250 trace.asCollector(
jlaskey@3 251 Object[].class,
jlaskey@3 252 type.parameterCount()).
jlaskey@3 253 asType(type.changeReturnType(void.class)));
jlaskey@3 254
jlaskey@3 255 final Class<?> retType = type.returnType();
jlaskey@3 256 if (retType != void.class && printReturnValue) {
jlaskey@3 257 final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger);
jlaskey@3 258 trace = MethodHandles.filterReturnValue(trace,
jlaskey@3 259 traceReturn.asType(
jlaskey@3 260 traceReturn.type().changeParameterType(0, retType).changeReturnType(retType)));
jlaskey@3 261 }
jlaskey@3 262
jlaskey@3 263 return trace;
jlaskey@3 264 }
jlaskey@3 265
jlaskey@3 266 /**
lagergren@11 267 * The standard class that marshalls all method handle operations to the java.lang.invoke
jlaskey@3 268 * package. This exists only so that it can be subclassed and method handles created from
jlaskey@3 269 * Nashorn made possible to instrument.
jlaskey@3 270 *
jlaskey@3 271 * All Nashorn classes should use the MethodHandleFactory for their method handle operations
jlaskey@3 272 */
jlaskey@3 273 private static class StandardMethodHandleFunctionality implements MethodHandleFunctionality {
jlaskey@3 274
jlaskey@3 275 @Override
jlaskey@3 276 public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
jlaskey@3 277 return MethodHandles.filterArguments(target, pos, filters);
jlaskey@3 278 }
jlaskey@3 279
jlaskey@3 280 @Override
jlaskey@3 281 public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
jlaskey@3 282 return MethodHandles.filterReturnValue(target, filter);
jlaskey@3 283 }
jlaskey@3 284
jlaskey@3 285 @Override
jlaskey@3 286 public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
jlaskey@3 287 return MethodHandles.guardWithTest(test, target, fallback);
jlaskey@3 288 }
jlaskey@3 289
jlaskey@3 290 @Override
jlaskey@3 291 public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
jlaskey@3 292 return MethodHandles.insertArguments(target, pos, values);
jlaskey@3 293 }
jlaskey@3 294
jlaskey@3 295 @Override
jlaskey@3 296 public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
jlaskey@3 297 return MethodHandles.dropArguments(target, pos, valueTypes);
jlaskey@3 298 }
jlaskey@3 299
jlaskey@3 300 @Override
attila@29 301 public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> valueTypes) {
attila@29 302 return MethodHandles.dropArguments(target, pos, valueTypes);
attila@29 303 }
attila@29 304
attila@29 305 @Override
jlaskey@3 306 public MethodHandle asType(final MethodHandle handle, final MethodType type) {
jlaskey@3 307 return handle.asType(type);
jlaskey@3 308 }
jlaskey@3 309
jlaskey@3 310 @Override
jlaskey@3 311 public MethodHandle bindTo(final MethodHandle handle, final Object x) {
jlaskey@3 312 return handle.bindTo(x);
jlaskey@3 313 }
jlaskey@3 314
jlaskey@3 315 @Override
jlaskey@3 316 public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
jlaskey@3 317 return MethodHandles.foldArguments(target, combiner);
jlaskey@3 318 }
jlaskey@3 319
jlaskey@3 320 @Override
jlaskey@3 321 public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
jlaskey@3 322 return MethodHandles.explicitCastArguments(target, type);
jlaskey@3 323 }
jlaskey@3 324
jlaskey@3 325 @Override
jlaskey@3 326 public MethodHandle arrayElementGetter(final Class<?> type) {
jlaskey@3 327 return MethodHandles.arrayElementGetter(type);
jlaskey@3 328 }
jlaskey@3 329
jlaskey@3 330 @Override
jlaskey@3 331 public MethodHandle arrayElementSetter(final Class<?> type) {
jlaskey@3 332 return MethodHandles.arrayElementSetter(type);
jlaskey@3 333 }
jlaskey@3 334
jlaskey@3 335 @Override
jlaskey@3 336 public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
jlaskey@3 337 return MethodHandles.throwException(returnType, exType);
jlaskey@3 338 }
jlaskey@3 339
jlaskey@3 340 @Override
jlaskey@3 341 public MethodHandle constant(final Class<?> type, final Object value) {
jlaskey@3 342 return MethodHandles.constant(type, value);
jlaskey@3 343 }
jlaskey@3 344
jlaskey@3 345 @Override
jlaskey@3 346 public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
jlaskey@3 347 return handle.asCollector(arrayType, arrayLength);
jlaskey@3 348 }
jlaskey@3 349
jlaskey@3 350 @Override
jlaskey@3 351 public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
jlaskey@3 352 return handle.asSpreader(arrayType, arrayLength);
jlaskey@3 353 }
jlaskey@3 354
jlaskey@3 355 @Override
jlaskey@3 356 public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 357 try {
jlaskey@3 358 return explicitLookup.findGetter(clazz, name, type);
jlaskey@3 359 } catch (final NoSuchFieldException | IllegalAccessException e) {
jlaskey@3 360 throw new LookupException(e);
jlaskey@3 361 }
jlaskey@3 362 }
jlaskey@3 363
jlaskey@3 364 @Override
jlaskey@3 365 public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 366 try {
jlaskey@3 367 return explicitLookup.findStaticGetter(clazz, name, type);
jlaskey@3 368 } catch (final NoSuchFieldException | IllegalAccessException e) {
jlaskey@3 369 throw new LookupException(e);
jlaskey@3 370 }
jlaskey@3 371 }
jlaskey@3 372
jlaskey@3 373
jlaskey@3 374 @Override
jlaskey@3 375 public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 376 try {
jlaskey@3 377 return explicitLookup.findSetter(clazz, name, type);
jlaskey@3 378 } catch (final NoSuchFieldException | IllegalAccessException e) {
jlaskey@3 379 throw new LookupException(e);
jlaskey@3 380 }
jlaskey@3 381 }
jlaskey@3 382
jlaskey@3 383 @Override
jlaskey@3 384 public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 385 try {
jlaskey@3 386 return explicitLookup.findStaticSetter(clazz, name, type);
jlaskey@3 387 } catch (final NoSuchFieldException | IllegalAccessException e) {
jlaskey@3 388 throw new LookupException(e);
jlaskey@3 389 }
jlaskey@3 390 }
jlaskey@3 391
jlaskey@3 392 @Override
jlaskey@3 393 public MethodHandle find(final Method method) {
jlaskey@3 394 try {
jlaskey@3 395 return PUBLIC_LOOKUP.unreflect(method);
jlaskey@3 396 } catch (final IllegalAccessException e) {
jlaskey@3 397 throw new LookupException(e);
jlaskey@3 398 }
jlaskey@3 399 }
jlaskey@3 400
jlaskey@3 401 @Override
jlaskey@3 402 public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
jlaskey@3 403 try {
jlaskey@3 404 return explicitLookup.findStatic(clazz, name, type);
jlaskey@3 405 } catch (final NoSuchMethodException | IllegalAccessException e) {
jlaskey@3 406 throw new LookupException(e);
jlaskey@3 407 }
jlaskey@3 408 }
jlaskey@3 409
jlaskey@3 410 @Override
jlaskey@3 411 public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
jlaskey@3 412 try {
jlaskey@3 413 return explicitLookup.findVirtual(clazz, name, type);
jlaskey@3 414 } catch (final NoSuchMethodException | IllegalAccessException e) {
jlaskey@3 415 throw new LookupException(e);
jlaskey@3 416 }
jlaskey@3 417 }
jlaskey@3 418
jlaskey@3 419 @Override
jlaskey@3 420 public SwitchPoint createSwitchPoint() {
jlaskey@3 421 return new SwitchPoint();
jlaskey@3 422 }
jlaskey@3 423
jlaskey@3 424 @Override
jlaskey@3 425 public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
jlaskey@3 426 return sp.guardWithTest(before, after);
jlaskey@3 427 }
jlaskey@3 428
jlaskey@3 429 @Override
jlaskey@3 430 public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
jlaskey@3 431 return MethodType.methodType(returnType, paramTypes);
jlaskey@3 432 }
jlaskey@3 433
jlaskey@3 434 }
jlaskey@3 435
jlaskey@3 436 /**
jlaskey@3 437 * Class used for instrumenting and debugging Nashorn generated method handles
jlaskey@3 438 */
jlaskey@3 439 private static class TraceMethodHandleFunctionality extends StandardMethodHandleFunctionality {
jlaskey@3 440
jlaskey@3 441 protected static String describe(final Object... data) {
jlaskey@3 442 final StringBuilder sb = new StringBuilder();
jlaskey@3 443
jlaskey@3 444 for (int i = 0; i < data.length; i++) {
jlaskey@3 445 final Object d = data[i];
jlaskey@3 446 if (d == null) {
jlaskey@3 447 sb.append("<null> ");
jlaskey@3 448 } else if (d instanceof String || d instanceof ConsString) {
jlaskey@3 449 sb.append(d.toString());
jlaskey@3 450 sb.append(' ');
jlaskey@3 451 } else if (d.getClass().isArray()) {
jlaskey@3 452 sb.append("[ ");
jlaskey@3 453 for (final Object da : (Object[])d) {
jlaskey@3 454 sb.append(describe(new Object[]{ da })).append(' ');
jlaskey@3 455 }
jlaskey@3 456 sb.append("] ");
jlaskey@3 457 } else {
jlaskey@3 458 sb.append(d)
jlaskey@3 459 .append('{')
jlaskey@3 460 .append(Integer.toHexString(System.identityHashCode(d)))
jlaskey@3 461 .append('}');
jlaskey@3 462 }
jlaskey@3 463
jlaskey@3 464 if (i + 1 < data.length) {
jlaskey@3 465 sb.append(", ");
jlaskey@3 466 }
jlaskey@3 467 }
jlaskey@3 468
jlaskey@3 469 return sb.toString();
jlaskey@3 470 }
jlaskey@3 471
jlaskey@3 472 public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
lagergren@11 473 return addDebugPrintout(LOG, master, Integer.MAX_VALUE, false, str + ' ' + describe(args));
jlaskey@3 474 }
jlaskey@3 475
jlaskey@3 476 @Override
jlaskey@3 477 public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
jlaskey@3 478 final MethodHandle mh = super.filterArguments(target, pos, filters);
jlaskey@3 479 return debug(mh, "filterArguments", target, pos, filters);
jlaskey@3 480 }
jlaskey@3 481
jlaskey@3 482 @Override
jlaskey@3 483 public MethodHandle filterReturnValue(final MethodHandle target, final MethodHandle filter) {
jlaskey@3 484 final MethodHandle mh = super.filterReturnValue(target, filter);
jlaskey@3 485 return debug(mh, "filterReturnValue", target, filter);
jlaskey@3 486 }
jlaskey@3 487
jlaskey@3 488 @Override
jlaskey@3 489 public MethodHandle guardWithTest(final MethodHandle test, final MethodHandle target, final MethodHandle fallback) {
jlaskey@3 490 final MethodHandle mh = super.guardWithTest(test, target, fallback);
jlaskey@3 491 return debug(mh, "guardWithTest", test, target, fallback);
jlaskey@3 492 }
jlaskey@3 493
jlaskey@3 494 @Override
jlaskey@3 495 public MethodHandle insertArguments(final MethodHandle target, final int pos, final Object... values) {
jlaskey@3 496 final MethodHandle mh = super.insertArguments(target, pos, values);
jlaskey@3 497 return debug(mh, "insertArguments", target, pos, values);
jlaskey@3 498 }
jlaskey@3 499
jlaskey@3 500 @Override
jlaskey@3 501 public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
jlaskey@3 502 final MethodHandle mh = super.dropArguments(target, pos, values);
jlaskey@3 503 return debug(mh, "dropArguments", target, pos, values);
jlaskey@3 504 }
jlaskey@3 505
jlaskey@3 506 @Override
attila@29 507 public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
attila@29 508 final MethodHandle mh = super.dropArguments(target, pos, values);
attila@29 509 return debug(mh, "dropArguments", target, pos, values);
attila@29 510 }
attila@29 511
attila@29 512 @Override
jlaskey@3 513 public MethodHandle asType(final MethodHandle handle, final MethodType type) {
jlaskey@3 514 final MethodHandle mh = super.asType(handle, type);
jlaskey@3 515 return debug(mh, "asType", handle, type);
jlaskey@3 516 }
jlaskey@3 517
jlaskey@3 518 @Override
jlaskey@3 519 public MethodHandle bindTo(final MethodHandle handle, final Object x) {
jlaskey@3 520 final MethodHandle mh = super.bindTo(handle, x);
jlaskey@3 521 return debug(mh, "bindTo", handle, x);
jlaskey@3 522 }
jlaskey@3 523
jlaskey@3 524 @Override
jlaskey@3 525 public MethodHandle foldArguments(final MethodHandle target, final MethodHandle combiner) {
jlaskey@3 526 final MethodHandle mh = super.foldArguments(target, combiner);
jlaskey@3 527 return debug(mh, "foldArguments", target, combiner);
jlaskey@3 528 }
jlaskey@3 529
jlaskey@3 530 @Override
jlaskey@3 531 public MethodHandle explicitCastArguments(final MethodHandle target, final MethodType type) {
jlaskey@3 532 final MethodHandle mh = super.explicitCastArguments(target, type);
jlaskey@3 533 return debug(mh, "explicitCastArguments", target, type);
jlaskey@3 534 }
jlaskey@3 535
jlaskey@3 536 @Override
jlaskey@3 537 public MethodHandle arrayElementGetter(final Class<?> type) {
jlaskey@3 538 final MethodHandle mh = super.arrayElementGetter(type);
jlaskey@3 539 return debug(mh, "arrayElementGetter", type);
jlaskey@3 540 }
jlaskey@3 541
jlaskey@3 542 @Override
jlaskey@3 543 public MethodHandle arrayElementSetter(final Class<?> type) {
jlaskey@3 544 final MethodHandle mh = super.arrayElementSetter(type);
jlaskey@3 545 return debug(mh, "arrayElementSetter", type);
jlaskey@3 546 }
jlaskey@3 547
jlaskey@3 548 @Override
jlaskey@3 549 public MethodHandle throwException(final Class<?> returnType, final Class<? extends Throwable> exType) {
jlaskey@3 550 final MethodHandle mh = super.throwException(returnType, exType);
jlaskey@3 551 return debug(mh, "throwException", returnType, exType);
jlaskey@3 552 }
jlaskey@3 553
jlaskey@3 554 @Override
jlaskey@3 555 public MethodHandle constant(final Class<?> type, final Object value) {
jlaskey@3 556 final MethodHandle mh = super.constant(type, value);
jlaskey@3 557 return debug(mh, "constant", type, value);
jlaskey@3 558 }
jlaskey@3 559
jlaskey@3 560 @Override
jlaskey@3 561 public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
jlaskey@3 562 final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength);
jlaskey@3 563 return debug(mh, "asCollector", handle, arrayType, arrayLength);
jlaskey@3 564 }
jlaskey@3 565
jlaskey@3 566 @Override
jlaskey@3 567 public MethodHandle asSpreader(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
sundar@546 568 final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength);
jlaskey@3 569 return debug(mh, "asSpreader", handle, arrayType, arrayLength);
jlaskey@3 570 }
jlaskey@3 571
jlaskey@3 572 @Override
jlaskey@3 573 public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 574 final MethodHandle mh = super.getter(explicitLookup, clazz, name, type);
jlaskey@3 575 return debug(mh, "getter", explicitLookup, clazz, name, type);
jlaskey@3 576 }
jlaskey@3 577
jlaskey@3 578 @Override
jlaskey@3 579 public MethodHandle staticGetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 580 final MethodHandle mh = super.staticGetter(explicitLookup, clazz, name, type);
jlaskey@3 581 return debug(mh, "static getter", explicitLookup, clazz, name, type);
jlaskey@3 582 }
jlaskey@3 583
jlaskey@3 584 @Override
jlaskey@3 585 public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 586 final MethodHandle mh = super.setter(explicitLookup, clazz, name, type);
jlaskey@3 587 return debug(mh, "setter", explicitLookup, clazz, name, type);
jlaskey@3 588 }
jlaskey@3 589
jlaskey@3 590 @Override
jlaskey@3 591 public MethodHandle staticSetter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) {
jlaskey@3 592 final MethodHandle mh = super.staticSetter(explicitLookup, clazz, name, type);
jlaskey@3 593 return debug(mh, "static setter", explicitLookup, clazz, name, type);
jlaskey@3 594 }
jlaskey@3 595
jlaskey@3 596 @Override
jlaskey@3 597 public MethodHandle find(final Method method) {
jlaskey@3 598 final MethodHandle mh = super.find(method);
jlaskey@3 599 return debug(mh, "find", method);
jlaskey@3 600 }
jlaskey@3 601
jlaskey@3 602 @Override
jlaskey@3 603 public MethodHandle findStatic(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
jlaskey@3 604 final MethodHandle mh = super.findStatic(explicitLookup, clazz, name, type);
jlaskey@3 605 return debug(mh, "findStatic", explicitLookup, clazz, name, type);
jlaskey@3 606 }
jlaskey@3 607
jlaskey@3 608 @Override
jlaskey@3 609 public MethodHandle findVirtual(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final MethodType type) {
jlaskey@3 610 final MethodHandle mh = super.findVirtual(explicitLookup, clazz, name, type);
jlaskey@3 611 return debug(mh, "findVirtual", explicitLookup, clazz, name, type);
jlaskey@3 612 }
jlaskey@3 613
jlaskey@3 614 @Override
jlaskey@3 615 public SwitchPoint createSwitchPoint() {
jlaskey@3 616 final SwitchPoint sp = super.createSwitchPoint();
lagergren@211 617 LOG.log(TRACE_LEVEL, "createSwitchPoint ", sp);
jlaskey@3 618 return sp;
jlaskey@3 619 }
jlaskey@3 620
jlaskey@3 621 @Override
jlaskey@3 622 public MethodHandle guardWithTest(final SwitchPoint sp, final MethodHandle before, final MethodHandle after) {
jlaskey@3 623 final MethodHandle mh = super.guardWithTest(sp, before, after);
jlaskey@3 624 return debug(mh, "guardWithTest", sp, before, after);
jlaskey@3 625 }
jlaskey@3 626
jlaskey@3 627 @Override
jlaskey@3 628 public MethodType type(final Class<?> returnType, final Class<?>... paramTypes) {
jlaskey@3 629 final MethodType mt = super.type(returnType, paramTypes);
lagergren@211 630 LOG.log(TRACE_LEVEL, "methodType ", returnType, " ", Arrays.toString(paramTypes), " ", mt);
jlaskey@3 631 return mt;
jlaskey@3 632 }
jlaskey@3 633 }
jlaskey@3 634
jlaskey@3 635 /**
jlaskey@3 636 * Class used for debugging Nashorn generated method handles
jlaskey@3 637 */
jlaskey@3 638 private static class TraceCreateMethodHandleFunctionality extends TraceMethodHandleFunctionality {
jlaskey@3 639 @Override
jlaskey@3 640 public MethodHandle debug(final MethodHandle master, final String str, final Object... args) {
lagergren@211 641 LOG.log(TRACE_LEVEL, str, " ", describe(args));
lagergren@11 642 stacktrace(LOG);
jlaskey@3 643 return master;
jlaskey@3 644 }
jlaskey@3 645 }
jlaskey@3 646 }

mercurial