Tue, 23 Jul 2013 14:32:37 +0200
8011888: sa.js: TypeError: [object JSAdapter] has no such function "__has__"
Reviewed-by: sla, sundar, kmo
Contributed-by: yunda.mly@taobao.com
agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Wed Aug 21 13:18:52 2013 +0200 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Tue Jul 23 14:32:37 2013 +0200 1.3 @@ -35,8 +35,9 @@ 1.4 sapkg.code = sapkg.hotspot.code; 1.5 sapkg.compiler = sapkg.hotspot.compiler; 1.6 1.7 -// 'debugger' is a JavaScript keyword :-( 1.8 -// sapkg.debugger = sapkg.hotspot.debugger; 1.9 +// 'debugger' is a JavaScript keyword, but ES5 relaxes the 1.10 +// restriction of using keywords as property name 1.11 +sapkg.debugger = sapkg.hotspot.debugger; 1.12 1.13 sapkg.interpreter = sapkg.hotspot.interpreter; 1.14 sapkg.jdi = sapkg.hotspot.jdi; 1.15 @@ -116,27 +117,36 @@ 1.16 return args; 1.17 } 1.18 1.19 + // Handle __has__ specially to avoid metacircularity problems 1.20 + // when called from __get__. 1.21 + // Calling 1.22 + // this.__has__(name) 1.23 + // will in turn call 1.24 + // this.__call__('__has__', name) 1.25 + // which is not handled below 1.26 + function __has__(name) { 1.27 + if (typeof(name) == 'number') { 1.28 + return so["has(int)"](name); 1.29 + } else { 1.30 + if (name == '__wrapped__') { 1.31 + return true; 1.32 + } else if (so["has(java.lang.String)"](name)) { 1.33 + return true; 1.34 + } else if (name.equals('toString')) { 1.35 + return true; 1.36 + } else { 1.37 + return false; 1.38 + } 1.39 + } 1.40 + } 1.41 + 1.42 if (so instanceof sapkg.utilities.soql.ScriptObject) { 1.43 return new JSAdapter() { 1.44 - __getIds__: function() { 1.45 - return so.getIds(); 1.46 + __getIds__: function() { 1.47 + return so.getIds(); 1.48 }, 1.49 1.50 - __has__ : function(name) { 1.51 - if (typeof(name) == 'number') { 1.52 - return so["has(int)"](name); 1.53 - } else { 1.54 - if (name == '__wrapped__') { 1.55 - return true; 1.56 - } else if (so["has(java.lang.String)"](name)) { 1.57 - return true; 1.58 - } else if (name.equals('toString')) { 1.59 - return true; 1.60 - } else { 1.61 - return false; 1.62 - } 1.63 - } 1.64 - }, 1.65 + __has__ : __has__, 1.66 1.67 __delete__ : function(name) { 1.68 if (typeof(name) == 'number') { 1.69 @@ -147,7 +157,8 @@ 1.70 }, 1.71 1.72 __get__ : function(name) { 1.73 - if (! this.__has__(name)) { 1.74 + // don't call this.__has__(name); see comments above function __has__ 1.75 + if (! __has__.call(this, name)) { 1.76 return undefined; 1.77 } 1.78 if (typeof(name) == 'number') { 1.79 @@ -162,7 +173,7 @@ 1.80 var args = prepareArgsArray(arguments); 1.81 var r; 1.82 try { 1.83 - r = value.call(args); 1.84 + r = value.call(Java.to(args, 'java.lang.Object[]')); 1.85 } catch (e) { 1.86 println("call to " + name + " failed!"); 1.87 throw e; 1.88 @@ -204,6 +215,18 @@ 1.89 } 1.90 1.91 // define "writeln" and "write" if not defined 1.92 + if (typeof(println) == 'undefined') { 1.93 + println = function (str) { 1.94 + java.lang.System.out.println(String(str)); 1.95 + } 1.96 + } 1.97 + 1.98 + if (typeof(print) == 'undefined') { 1.99 + print = function (str) { 1.100 + java.lang.System.out.print(String(str)); 1.101 + } 1.102 + } 1.103 + 1.104 if (typeof(writeln) == 'undefined') { 1.105 writeln = println; 1.106 } 1.107 @@ -235,7 +258,7 @@ 1.108 1.109 this.jclasses = function() { 1.110 forEachKlass(function (clazz) { 1.111 - writeln(clazz.getName().asString() + " @" + clazz.getHandle().toString()); 1.112 + writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString()); 1.113 }); 1.114 } 1.115 registerCommand("classes", "classes", "jclasses"); 1.116 @@ -490,14 +513,14 @@ 1.117 function forEachKlass(callback) { 1.118 var VisitorClass = sapkg.memory.SystemDictionary.ClassVisitor; 1.119 var visitor = new VisitorClass() { visit: callback }; 1.120 - sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary$ClassVisitor)"](visitor); 1.121 + sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassVisitor)"](visitor); 1.122 } 1.123 1.124 // iterate system dictionary for each 'Klass' and initiating loader 1.125 function forEachKlassAndLoader(callback) { 1.126 var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor; 1.127 var visitor = new VisitorClass() { visit: callback }; 1.128 - sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary$ClassAndLoaderVisitor)"](visitor); 1.129 + sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassAndLoaderVisitor)"](visitor); 1.130 } 1.131 1.132 // iterate system dictionary for each primitive array klass 1.133 @@ -522,7 +545,12 @@ 1.134 1.135 // iterates Java heap for each Oop 1.136 function forEachOop(callback) { 1.137 - sa.objHeap.iterate(new sapkg.oops.HeapVisitor() { doObj: callback }); 1.138 + function empty() { } 1.139 + sa.objHeap.iterate(new sapkg.oops.HeapVisitor() { 1.140 + prologue: empty, 1.141 + doObj: callback, 1.142 + epilogue: empty 1.143 + }); 1.144 } 1.145 1.146 // iterates Java heap for each Oop of given 'klass'. 1.147 @@ -536,8 +564,14 @@ 1.148 if (includeSubtypes == undefined) { 1.149 includeSubtypes = true; 1.150 } 1.151 + 1.152 + function empty() { } 1.153 sa.objHeap.iterateObjectsOfKlass( 1.154 - new sapkg.oops.HeapVisitor() { doObj: callback }, 1.155 + new sapkg.oops.HeapVisitor() { 1.156 + prologue: empty, 1.157 + doObj: callback, 1.158 + epilogue: empty 1.159 + }, 1.160 klass, includeSubtypes); 1.161 } 1.162 1.163 @@ -746,9 +780,9 @@ 1.164 // ignore; 1.165 continue; 1.166 } else { 1.167 - // some type names have ':'. replace to make it as a 1.168 + // some type names have ':', '<', '>', '*', ' '. replace to make it as a 1.169 // JavaScript identifier 1.170 - tmp.name = tmp.name.replace(':', '_').replace('<', '_').replace('>', '_').replace('*', '_').replace(' ', '_'); 1.171 + tmp.name = ("" + tmp.name).replace(/[:<>* ]/g, '_'); 1.172 eval("function read" + tmp.name + "(addr) {" + 1.173 " return readVMType('" + tmp.name + "', addr);}"); 1.174 eval("function print" + tmp.name + "(addr) {" +