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 26 package jdk.nashorn.internal.objects; 27 28 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 29 30 import java.io.PrintWriter; 31 import java.util.Objects; 32 import jdk.nashorn.internal.objects.annotations.Attribute; 33 import jdk.nashorn.internal.objects.annotations.Function; 34 import jdk.nashorn.internal.objects.annotations.ScriptClass; 35 import jdk.nashorn.internal.objects.annotations.Where; 36 import jdk.nashorn.internal.runtime.Context; 37 import jdk.nashorn.internal.runtime.PropertyListenerManager; 38 import jdk.nashorn.internal.runtime.PropertyMap; 39 import jdk.nashorn.internal.runtime.ScriptFunction; 40 import jdk.nashorn.internal.runtime.ScriptObject; 41 import jdk.nashorn.internal.runtime.linker.LinkerCallSite; 42 43 /** 44 * Nashorn specific debug utils. This is meant for Nashorn developers. 45 * The interface is subject to change without notice!! 46 * 47 */ 48 @ScriptClass("Debug") 49 public final class NativeDebug extends ScriptObject { 50 51 // initialized by nasgen 52 @SuppressWarnings("unused") 53 private static PropertyMap $nasgenmap$; 54 55 private NativeDebug() { 56 // don't create me! 57 throw new UnsupportedOperationException(); 58 } 59 60 @Override 61 public String getClassName() { 62 return "Debug"; 63 } 64 65 /** 66 * Nashorn extension: get context, context utility 67 * 68 * @param self self reference 69 * @return context 70 */ 71 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 72 public static Object getContext(final Object self) { 73 final SecurityManager sm = System.getSecurityManager(); 74 if (sm != null) { 75 sm.checkPermission(new RuntimePermission(Context.NASHORN_GET_CONTEXT)); 76 } 77 return Global.getThisContext(); 78 } 79 80 /** 81 * Nashorn extension: get map from {@link ScriptObject} 82 * 83 * @param self self reference 84 * @param obj script object 85 * @return the map for the current ScriptObject 86 */ 87 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 88 public static Object map(final Object self, final Object obj) { 89 if (obj instanceof ScriptObject) { 90 return ((ScriptObject)obj).getMap(); 91 } 92 return UNDEFINED; 93 } 94 95 /** 96 * Nashorn extension: get spill vector from {@link ScriptObject} 97 * 98 * @param self self reference 99 * @param obj script object 100 * @return the spill vector for the given ScriptObject 101 */ 102 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 103 public static Object spill(final Object self, final Object obj) { 104 if (obj instanceof ScriptObject) { 105 return ((ScriptObject)obj).spill; 106 } 107 return UNDEFINED; 108 } 109 110 /** 111 * Check object identity comparison regardless of type 112 * 113 * @param self self reference 114 * @param obj1 first object in comparison 115 * @param obj2 second object in comparison 116 * @return true if reference identity 117 */ 118 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 119 public static Object identical(final Object self, final Object obj1, final Object obj2) { 120 return obj1 == obj2; 121 } 122 123 /** 124 * Object util - getClass 125 * 126 * @param self self reference 127 * @param obj object 128 * @return class of {@code obj} 129 */ 130 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 131 public static Object getClass(final Object self, final Object obj) { 132 if (obj != null) { 133 return obj.getClass(); 134 } 135 return UNDEFINED; 136 } 137 138 /** 139 * Object util - equals 140 * 141 * @param self self reference 142 * @param obj1 first object in comparison 143 * @param obj2 second object in comparison 144 * @return return {@link Object#equals(Object)} for objects. 145 */ 146 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 147 public static Object equals(final Object self, final Object obj1, final Object obj2) { 148 return Objects.equals(obj1, obj2); 149 } 150 151 /** 152 * Object util - toJavaString 153 * 154 * @param self self reference 155 * @param obj object to represent as a string 156 * @return Java string representation of {@code obj} 157 */ 158 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 159 public static Object toJavaString(final Object self, final Object obj) { 160 return Objects.toString(obj); 161 } 162 163 /** 164 * Do not call overridden toString -- use default toString impl 165 * 166 * @param self self reference 167 * @param obj object to represent as a string 168 * @return string representation 169 */ 170 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 171 public static Object toIdentString(final Object self, final Object obj) { 172 if (obj == null) { 173 return "null"; 174 } 175 176 final int hash = System.identityHashCode(obj); 177 return obj.getClass() + "@" + Integer.toHexString(hash); 178 } 179 180 /** 181 * Returns the property listener count for a script object 182 * 183 * @param self self reference 184 * @param obj script object whose listener count is returned 185 * @return listener count 186 */ 187 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 188 public static Object getListenerCount(final Object self, final Object obj) { 189 return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0; 190 } 191 192 /** 193 * Dump all Nashorn debug mode counters. Calling this may be better if 194 * you want to print all counters. This way you can avoid too many callsites 195 * due to counter access itself!! 196 * @param self self reference 197 * @return undefined 198 */ 199 @SuppressWarnings("resource") 200 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 201 public static Object dumpCounters(final Object self) { 202 final PrintWriter out = Context.getCurrentErr(); 203 204 out.println("ScriptObject count " + ScriptObject.getCount()); 205 out.println("Scope count " + ScriptObject.getScopeCount()); 206 out.println("ScriptObject listeners added " + PropertyListenerManager.getListenersAdded()); 207 out.println("ScriptObject listeners removed " + PropertyListenerManager.getListenersRemoved()); 208 out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount()); 209 out.println("ScriptFunction invokes " + ScriptFunction.getInvokes()); 210 out.println("ScriptFunction allocations " + ScriptFunction.getAllocations()); 211 out.println("PropertyMap count " + PropertyMap.getCount()); 212 out.println("PropertyMap cloned " + PropertyMap.getClonedCount()); 213 out.println("PropertyMap shared " + PropertyMap.getSharedCount()); 214 out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount()); 215 out.println("PropertyMap history hit " + PropertyMap.getHistoryHit()); 216 out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations()); 217 out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit()); 218 out.println("PropertyMap setProtoNewMapCount " + PropertyMap.getSetProtoNewMapCount()); 219 out.println("Callsite count " + LinkerCallSite.getCount()); 220 out.println("Callsite misses " + LinkerCallSite.getMissCount()); 221 out.println("Callsite misses by site at " + LinkerCallSite.getMissSamplingPercentage() + "%"); 222 223 LinkerCallSite.getMissCounts(out); 224 225 return UNDEFINED; 226 } 227 }