Debug.java revision 1429:b4eb53200105
1/* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.nashorn.internal.runtime; 27 28import static jdk.nashorn.internal.parser.TokenType.EOF; 29 30import jdk.nashorn.api.scripting.NashornException; 31import jdk.nashorn.internal.parser.Lexer; 32import jdk.nashorn.internal.parser.Token; 33import jdk.nashorn.internal.parser.TokenStream; 34import jdk.nashorn.internal.parser.TokenType; 35 36/** 37 * Utilities for debugging Nashorn. 38 * 39 */ 40public final class Debug { 41 private Debug() { 42 } 43 44 /** 45 * Return the topmost JavaScript frame in a stack trace 46 * @param t throwable that contains the stack trace 47 * @return line describing the topmost JavaScript frame 48 */ 49 public static String firstJSFrame(final Throwable t) { 50 for (final StackTraceElement ste : t.getStackTrace()) { 51 if (ECMAErrors.isScriptFrame(ste)) { 52 return ste.toString(); 53 } 54 } 55 return "<native code>"; 56 } 57 58 /** 59 * Return the topmost JavaScript frame from the current 60 * continuation 61 * @return line describing the topmost JavaScript frame 62 */ 63 public static String firstJSFrame() { 64 return firstJSFrame(new Throwable()); 65 } 66 67 /** 68 * Return a formatted script stack trace string with frames information separated by '\n'. 69 * This is a shortcut for {@code NashornException.getScriptStackString(new Throwable())}. 70 * @return formatted stack trace string 71 */ 72 public static String scriptStack() { 73 return NashornException.getScriptStackString(new Throwable()); 74 } 75 76 /** 77 * Return the system identity hashcode for an object as a human readable 78 * string 79 * 80 * @param x object 81 * @return system identity hashcode as string 82 */ 83 public static String id(final Object x) { 84 return String.format("0x%08x", System.identityHashCode(x)); 85 } 86 87 /** 88 * Same as {@link Debug#id} but returns the identity hashcode as 89 * an integer 90 * 91 * @param x object 92 * @return system identity hashcode 93 */ 94 public static int intId(final Object x) { 95 return System.identityHashCode(x); 96 } 97 98 /** 99 * Return a stack trace element description at a depth from where we are not 100 * 101 * @param depth depth 102 * @return stack trace element as string 103 */ 104 public static String stackTraceElementAt(final int depth) { 105 return new Throwable().getStackTrace()[depth + 1].toString(); // add 1 to compensate for this method 106 } 107 108 /** 109 * Determine caller for tracing purposes. 110 * @param depth depth to trace 111 * @param count max depth 112 * @param ignores elements to ignore in stack trace 113 * @return caller 114 */ 115 public static String caller(final int depth, final int count, final String... ignores) { 116 String result = ""; 117 final StackTraceElement[] callers = Thread.currentThread().getStackTrace(); 118 119 int c = count; 120loop: 121 for (int i = depth + 1; i < callers.length && c != 0; i++) { 122 final StackTraceElement element = callers[i]; 123 final String method = element.getMethodName(); 124 125 for (final String ignore : ignores) { 126 if (method.compareTo(ignore) == 0) { 127 continue loop; 128 } 129 } 130 131 result += (method + ":" + element.getLineNumber() + 132 " ").substring(0, 30); 133 c--; 134 } 135 136 return result.isEmpty() ? "<no caller>" : result; 137 } 138 139 /** 140 * Dump a token stream to stdout 141 * 142 * TODO: most other bugging goes to stderr, change? 143 * 144 * @param source the source 145 * @param lexer the lexer 146 * @param stream the stream to dump 147 */ 148 public static void dumpTokens(final Source source, final Lexer lexer, final TokenStream stream) { 149 TokenType type; 150 int k = 0; 151 do { 152 while (k > stream.last()) { 153 // Get more tokens. 154 lexer.lexify(); 155 } 156 157 final long token = stream.get(k); 158 type = Token.descType(token); 159 System.out.println("" + k + ": " + Token.toString(source, token, true)); 160 k++; 161 } while(type != EOF); 162 } 163 164} 165