8244668: Remove SA's javascript support

Reviewed-by: sspitsyn, sundar
This commit is contained in:
Chris Plummer 2020-05-28 17:12:14 -07:00
parent de34e258ef
commit e0d03881d0
43 changed files with 2 additions and 7179 deletions

View File

@ -315,7 +315,7 @@ jdk.compiler_CLEAN_FILES += $(wildcard \
jdk.hotspot.agent_DISABLED_WARNINGS += rawtypes serial cast static overrides \
fallthrough
jdk.hotspot.agent_COPY += .gif .png sa.js .properties
jdk.hotspot.agent_COPY += .gif .png .properties
################################################################################

View File

@ -192,18 +192,6 @@ This is cross platform Solaris pmap-like utility.
</td>
</tr>
<tr>
<td>
soqlproc.sh,
soqlproc64.sh,
soqlwindbg.bat
soqlwindbg64.bat
</td>
<td>
This is command line SOQL - Simple Object Query Language tool.
SOQL is SQL-like query language to query Java heap.
</td>
<tr>
<td>
start-debug-server-proc.sh,
start-debug-server-proc64.sh,

File diff suppressed because it is too large Load Diff

View File

@ -104,9 +104,6 @@ import sun.jvm.hotspot.utilities.ReversePtrs;
import sun.jvm.hotspot.utilities.ReversePtrsAnalysis;
import sun.jvm.hotspot.utilities.RobustOopDeterminator;
import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
import sun.jvm.hotspot.utilities.soql.JSJavaFactory;
import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl;
import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine;
public class CommandProcessor {
@ -1846,7 +1843,6 @@ public class CommandProcessor {
private DebuggerInterface debugger;
private HotSpotAgent agent;
private JSJavaScriptEngine jsengine;
private BufferedReader in;
private PrintStream out;
private PrintStream err;
@ -1858,65 +1854,7 @@ public class CommandProcessor {
// called after debuggee attach
private void postAttach() {
/*
* JavaScript engine no longer works. For now disable it. Eventually we will remove it.
// create JavaScript engine and start it
try {
jsengine = new JSJavaScriptEngine() {
private ObjectReader reader = new ObjectReader();
private JSJavaFactory factory = new JSJavaFactoryImpl();
public ObjectReader getObjectReader() {
return reader;
}
public JSJavaFactory getJSJavaFactory() {
return factory;
}
protected void quit() {
debugger.detach();
quit = true;
}
protected BufferedReader getInputReader() {
return in;
}
protected PrintStream getOutputStream() {
return out;
}
protected PrintStream getErrorStream() {
return err;
}
};
try {
jsengine.defineFunction(this,
this.getClass().getMethod("registerCommand",
new Class[] {
String.class, String.class, String.class
}));
} catch (NoSuchMethodException exp) {
// should not happen, see below...!!
exp.printStackTrace();
}
jsengine.start();
}
catch (Exception ex) {
System.out.println("Warning! JS Engine can't start, some commands will not be available.");
if (verboseExceptions) {
ex.printStackTrace(out);
}
}
*/
}
public void registerCommand(String cmd, String usage, final String func) {
commands.put(cmd, new Command(cmd, usage, false) {
public void doit(Tokens t) {
final int len = t.countTokens();
Object[] args = new Object[len];
for (int i = 0; i < len; i++) {
args[i] = t.nextToken();
}
jsengine.call(func, args);
}
});
// nothing for now..
}
public void setOutput(PrintStream o) {

View File

@ -276,15 +276,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
item.setMnemonic(KeyEvent.VK_D);
toolsMenu.add(item);
item = createMenuItem("Find Object by Query",
new ActionListener() {
public void actionPerformed(ActionEvent e) {
showFindByQueryPanel();
}
});
item.setMnemonic(KeyEvent.VK_Q);
toolsMenu.add(item);
item = createMenuItem("Find Pointer",
new ActionListener() {
@ -1531,10 +1522,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
showPanel("Command Line", new CommandProcessorPanel(new CommandProcessor(di, null, null, null)));
}
private void showFindByQueryPanel() {
showPanel("Find Object by Query", new FindByQueryPanel());
}
private void showFindPanel() {
showPanel("Find Pointer", new FindPanel());
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.tools.soql;
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.soql.*;
/** This is command line JavaScript debugger console */
public class JSDB extends Tool {
public JSDB() {
super();
}
public JSDB(JVMDebugger d) {
super(d);
}
public static void main(String[] args) {
JSDB jsdb = new JSDB();
jsdb.execute(args);
}
public void run() {
JSJavaScriptEngine engine = new JSJavaScriptEngine() {
private ObjectReader objReader = new ObjectReader();
private JSJavaFactory factory = new JSJavaFactoryImpl();
public ObjectReader getObjectReader() {
return objReader;
}
public JSJavaFactory getJSJavaFactory() {
return factory;
}
};
engine.startConsole();
}
}

View File

@ -1,223 +0,0 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.tools.soql;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.soql.*;
/**
This is command line SOQL (Simple Object Query Language) interpreter.
*/
public class SOQL extends Tool {
public static void main(String[] args) {
SOQL soql = new SOQL();
soql.execute(args);
}
public SOQL() {
super();
}
public SOQL(JVMDebugger d) {
super(d);
}
protected SOQLEngine soqlEngine;
protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
protected PrintStream out = System.out;
static protected String prompt = "soql> ";
static protected String secondPrompt = "> ";
public void run() {
soqlEngine = SOQLEngine.getEngine();
while (true) {
try {
out.print(prompt);
String line = in.readLine();
if (line == null) {
return;
}
StringTokenizer st = new StringTokenizer(line);
if (st.hasMoreTokens()) {
String cmd = st.nextToken();
if (cmd.equals("select")) {
handleSelect(line);
} else if (cmd.equals("classes")) {
handleClasses(line);
} else if (cmd.equals("class")) {
handleClass(line);
} else if (cmd.equals("object")) {
handleObject(line);
} else if (cmd.equals("quit")) {
out.println("Bye!");
return;
} else if (cmd.equals("")) {
// do nothing ...
} else {
handleUnknown(line);
}
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
protected void handleSelect(String query) {
StringBuffer buf = new StringBuffer(query);
String tmp = null;
while (true) {
out.print(secondPrompt);
try {
tmp = in.readLine();
} catch (IOException ioe) {
break;
}
if (tmp.equals("") || tmp.equals("go"))
break;
buf.append('\n');
buf.append(tmp);
}
query = buf.toString();
try {
soqlEngine.executeQuery(query,
new ObjectVisitor() {
public void visit(Object o) {
if (o != null && o instanceof JSJavaObject) {
String oopAddr = ((JSJavaObject)o).getOop().getHandle().toString();
out.println(oopAddr);
} else {
out.println((o == null)? "null" : o.toString());
}
}
});
} catch (SOQLException se) {
se.printStackTrace();
}
}
protected void handleClasses(String line) {
// just list all InstanceKlasses
InstanceKlass[] klasses = SystemDictionaryHelper.getAllInstanceKlasses();
for (int i = 0; i < klasses.length; i++) {
out.print(klasses[i].getName().asString().replace('/', '.'));
out.print(" @");
out.println(klasses[i].getAddress());
}
}
protected void handleClass(String line) {
StringTokenizer st = new StringTokenizer(line);
st.nextToken(); // ignore "class"
if (st.hasMoreTokens()) {
String className = st.nextToken();
InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
if (klass == null) {
out.println("class " + className + " not found");
} else {
// klass.iterate(new OopPrinter(out), true);
// base class
InstanceKlass base = (InstanceKlass) klass.getSuper();
if (base != null) {
out.println("super");
out.print("\t");
out.println(base.getName().asString().replace('/', '.'));
}
// list immediate fields only
U2Array fields = klass.getFields();
int numFields = (int) fields.length();
ConstantPool cp = klass.getConstants();
out.println("fields");
if (numFields != 0) {
for (int f = 0; f < numFields; f++){
Symbol f_name = klass.getFieldName(f);
Symbol f_sig = klass.getFieldSignature(f);
StringBuffer sigBuf = new StringBuffer();
new SignatureConverter(f_sig, sigBuf).dispatchField();
out.print('\t');
out.print(sigBuf.toString().replace('/', '.'));
out.print(' ');
out.println(f_name.asString());
}
} else {
out.println("\tno fields in this class");
}
}
} else {
out.println("usage: class <name of the class>");
}
}
protected Oop getOopAtAddress(Address addr) {
OopHandle oopHandle = addr.addOffsetToAsOopHandle(0);
return VM.getVM().getObjectHeap().newOop(oopHandle);
}
protected void handleObject(String line) {
StringTokenizer st = new StringTokenizer(line);
st.nextToken(); // ignore "object"
if (st.hasMoreTokens()) {
String addrStr = st.nextToken();
Address addr = null;
Debugger dbg = VM.getVM().getDebugger();
try {
addr = dbg.parseAddress(addrStr);
} catch (Exception e) {
out.println("invalid address : " + e.getMessage());
return;
}
Oop oop = null;
try {
oop = getOopAtAddress(addr);
} catch (Exception e) {
out.println("invalid object : " + e.getMessage());
}
if (oop != null) {
oop.iterate(new OopPrinter(out), true);
} else {
out.println("null object!");
}
} else {
out.println("usage: object <address>");
}
}
protected void handleUnknown(String line) {
out.println("Unknown command!");
}
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.ui;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.ui.tree.*;
import sun.jvm.hotspot.utilities.soql.*;
public class FindByQueryPanel extends SAPanel {
private JTextArea queryEditor;
private JEditorPane objectsEditor;
private SOQLEngine queryEngine;
public FindByQueryPanel() {
queryEngine = SOQLEngine.getEngine();
HyperlinkListener hyperListener = new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
VM vm = VM.getVM();
OopHandle handle = vm.getDebugger().parseAddress(e.getDescription()).addOffsetToAsOopHandle(0);
showInspector(vm.getObjectHeap().newOop(handle));
}
}
};
objectsEditor = new JEditorPane();
objectsEditor.setContentType("text/html");
objectsEditor.setEditable(false);
objectsEditor.addHyperlinkListener(hyperListener);
queryEditor = new JTextArea();
JButton queryButton = new JButton("Execute");
queryButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final StringBuffer buf = new StringBuffer();
buf.append("<html><body>");
try {
queryEngine.executeQuery(queryEditor.getText(),
new ObjectVisitor() {
public void visit(Object o) {
if (o != null && o instanceof JSJavaObject) {
String oopAddr = ((JSJavaObject)o).getOop().getHandle().toString();
buf.append("<a href='");
buf.append(oopAddr);
buf.append("'>");
buf.append(oopAddr);
buf.append("</a>");
} else {
buf.append((o == null)? "null" : o.toString());
}
buf.append("<br>");
}
});
} catch (Exception e) {
e.printStackTrace();
buf.append("<b>");
buf.append(e.getMessage());
buf.append("</b>");
}
buf.append("</body></html>");
objectsEditor.setText(buf.toString());
}
});
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
topPanel.add(new JLabel("SOQL Query :"), BorderLayout.WEST);
topPanel.add(new JScrollPane(queryEditor), BorderLayout.CENTER);
topPanel.add(queryButton, BorderLayout.EAST);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
bottomPanel.add(new JScrollPane(objectsEditor), BorderLayout.CENTER);
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topPanel, bottomPanel);
splitPane.setDividerLocation(0.3);
setLayout(new BorderLayout());
add(splitPane, BorderLayout.CENTER);
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
import javax.script.ScriptException;
/**
* This interface is used to represent "function" valued
* properties in ScriptObjects.
*/
public interface Callable {
/**
* Call the underlying function passing the given
* arguments and return the result.
*/
public Object call(Object[] args) throws ScriptException;
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
/**
* Dummy implementation for ScriptObject interface. This class
* supports empty set of named and indexed properties. Returns
* false always for "has" calls. And ignores "delete" and "put"
* calls.
*/
public class DefaultScriptObject implements ScriptObject {
public Object[] getIds() {
return EMPTY_ARRAY;
}
public Object get(String name) {
return UNDEFINED;
}
public Object get(int index) {
return UNDEFINED;
}
public void put(String name, Object value) {
}
public void put(int index, Object value) {
}
public boolean has(String name) {
return false;
}
public boolean has(int index) {
return false;
}
public boolean delete(String name) {
return false;
}
public boolean delete(int index) {
return false;
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
import javax.script.Invocable;
import javax.script.ScriptException;
/**
* This Callable implementation invokes a script
* function of given name when called. If the target
* object is non-null, script "method" is invoked, else
* a "global" script function is invoked.
*/
public class InvocableCallable implements Callable {
private Object target;
private String name;
private Invocable invocable;
public InvocableCallable(Object target, String name,
Invocable invocable) {
this.target = target;
this.name = name;
this.invocable = invocable;
}
public Object call(Object[] args) throws ScriptException {
try {
if (target == null) {
return invocable.invokeFunction(name, args);
} else {
return invocable.invokeMethod(target, name, args);
}
} catch (NoSuchMethodException nme) {
throw new ScriptException(nme);
}
}
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.*;
/**
This is JavaScript wrapper for Java Array.
*/
public abstract class JSJavaArray extends JSJavaObject {
public JSJavaArray(Array array, JSJavaFactory fac) {
super(array, fac);
type = (JSJavaArrayKlass) fac.newJSJavaKlass(array.getKlass());
}
public final Array getArray() {
return (Array) getOop();
}
public final JSJavaClass getJSJavaClass() {
return type.getJSJavaClass();
}
public Object get(String name) {
if (name.equals("length")) {
return (int) getArray().getLength();
} else {
return super.get(name);
}
}
public Object get(int index) {
return (isInRange(index)) ? type.getFieldValue(index, getArray())
: super.get(index);
}
public Object[] getIds() {
Object[] superFields = super.getIds();
final int len = (int) getArray().getLength();
Object[] res = new Object[superFields.length + len];
for (int i = 0; i < len; i++) {
res[i] = i;
}
System.arraycopy(superFields, 0, res, len, superFields.length);
return res;
}
public boolean has(String name) {
if (name.equals("length")) {
return true;
} else {
return super.has(name);
}
}
public boolean has(int index) {
if (isInRange(index)) {
return true;
} else {
return super.has(index);
}
}
public void put(String name, Object value) {
if (! name.equals("length")) {
super.put(name, value);
}
}
public void put(int index, Object value) {
if (! isInRange(index)) {
super.put(index, value);
}
}
//-- Internals only below this point
private boolean isInRange(int index) {
return index >= 0 && index < getArray().getLength();
}
private JSJavaArrayKlass type;
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
/**
This is JavaScript wrapper for Java ArrayKlass.
*/
public abstract class JSJavaArrayKlass extends JSJavaKlass {
public JSJavaArrayKlass(ArrayKlass kls, JSJavaFactory fac) {
super(kls, fac);
}
public final ArrayKlass getArrayKlass() {
return (ArrayKlass) getKlass();
}
public Object getMetaClassFieldValue(String name) {
if (name.equals("dimension")) {
return getArrayKlass().getDimension();
} else {
return super.getMetaClassFieldValue(name);
}
}
public boolean hasMetaClassField(String name) {
if (name.equals("dimension")) {
return true;
} else {
return super.hasMetaClassField(name);
}
}
public boolean isArray() {
return true;
}
public String[] getMetaClassFieldNames() {
String[] superFields = super.getMetaClassFieldNames();
String[] res = new String[superFields.length + 1];
System.arraycopy(superFields, 0, res, 0, superFields.length);
res[superFields.length] = "dimension";
return res;
}
public abstract Object getFieldValue(int index, Array array);
}

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
public class JSJavaClass extends JSJavaInstance {
public JSJavaClass(Instance instance, JSJavaKlass jk, JSJavaFactory fac) {
super(instance, fac);
this.jklass = jk;
}
public JSJavaKlass getJSJavaKlass() {
return jklass;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Class (address=");
buf.append(getOop().getHandle());
buf.append(", name=");
buf.append(jklass.getName());
buf.append(')');
return buf.toString();
}
protected Object getFieldValue(String name) {
return jklass.getMetaClassFieldValue(name);
}
protected String[] getFieldNames() {
return jklass.getMetaClassFieldNames();
}
protected boolean hasField(String name) {
return jklass.hasMetaClassField(name);
}
private JSJavaKlass jklass;
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
public interface JSJavaFactory {
public JSJavaObject newJSJavaObject(Oop oop);
public JSJavaKlass newJSJavaKlass(Klass klass);
public JSJavaField newJSJavaField(Field f);
public JSJavaThread newJSJavaThread(JavaThread jt);
public JSJavaFrame newJSJavaFrame(JavaVFrame vf);
public JSJavaMethod newJSJavaMethod(Method m);
public JSList newJSList(List l);
public JSMap newJSMap(Map m);
public JSJavaHeap newJSJavaHeap();
public JSJavaVM newJSJavaVM();
// checks for one of the above special cases
public Object newJSJavaWrapper(Object o);
}

View File

@ -1,197 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.lang.ref.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
public class JSJavaFactoryImpl implements JSJavaFactory {
public JSJavaObject newJSJavaObject(Oop oop) {
if (oop == null) return null;
SoftReference sref = (SoftReference) om.get(oop);
JSJavaObject res = (sref != null)? (JSJavaObject) sref.get() : null;
if (res == null) {
if (oop instanceof TypeArray) {
res = new JSJavaTypeArray((TypeArray)oop, this);
} else if (oop instanceof ObjArray) {
res = new JSJavaObjArray((ObjArray)oop, this);
} else if (oop instanceof Instance) {
res = newJavaInstance((Instance) oop);
}
}
if (res != null) {
om.put(oop, new SoftReference<>(res));
}
return res;
}
public JSJavaKlass newJSJavaKlass(Klass klass) {
JSJavaKlass res = null;
if (klass instanceof InstanceKlass) {
res = new JSJavaInstanceKlass((InstanceKlass) klass, this);
} else if (klass instanceof ObjArrayKlass) {
res = new JSJavaObjArrayKlass((ObjArrayKlass) klass, this);
} else if (klass instanceof TypeArrayKlass) {
res = new JSJavaTypeArrayKlass((TypeArrayKlass) klass, this);
}
if (res != null) {
om.put(klass, new SoftReference<>(res));
}
return res;
}
public JSJavaMethod newJSJavaMethod(Method method) {
JSJavaMethod res = new JSJavaMethod(method, this);
if (res != null) {
om.put(method, new SoftReference<>(res));
}
return res;
}
public JSJavaField newJSJavaField(Field field) {
if (field == null) return null;
return new JSJavaField(field, this);
}
public JSJavaThread newJSJavaThread(JavaThread jthread) {
if (jthread == null) return null;
return new JSJavaThread(jthread, this);
}
public JSJavaFrame newJSJavaFrame(JavaVFrame jvf) {
if (jvf == null) return null;
return new JSJavaFrame(jvf, this);
}
public JSList newJSList(List list) {
if (list == null) return null;
return new JSList(list, this);
}
public JSMap newJSMap(Map map) {
if (map == null) return null;
return new JSMap(map, this);
}
public Object newJSJavaWrapper(Object item) {
if (item == null) return null;
if (item instanceof Oop) {
return newJSJavaObject((Oop) item);
} else if (item instanceof Field) {
return newJSJavaField((Field) item);
} else if (item instanceof JavaThread) {
return newJSJavaThread((JavaThread) item);
} else if (item instanceof JavaVFrame) {
return newJSJavaFrame((JavaVFrame) item);
} else if (item instanceof List) {
return newJSList((List) item);
} else if (item instanceof Map) {
return newJSMap((Map) item);
} else {
// not-a-special-type, just return the input item
return item;
}
}
public JSJavaHeap newJSJavaHeap() {
return new JSJavaHeap(this);
}
public JSJavaVM newJSJavaVM() {
return new JSJavaVM(this);
}
// -- Internals only below this point
private String javaLangString() {
if (javaLangString == null) {
javaLangString = "java/lang/String";
}
return javaLangString;
}
private String javaLangThread() {
if (javaLangThread == null) {
javaLangThread = "java/lang/Thread";
}
return javaLangThread;
}
private String javaLangClass() {
if (javaLangClass == null) {
javaLangClass = "java/lang/Class";
}
return javaLangClass;
}
private JSJavaObject newJavaInstance(Instance instance) {
// look for well-known classes
Symbol className = instance.getKlass().getName();
if (Assert.ASSERTS_ENABLED) {
Assert.that(className != null, "Null class name");
}
JSJavaObject res = null;
if (className.equals(javaLangString())) {
res = new JSJavaString(instance, this);
} else if (className.equals(javaLangThread())) {
res = new JSJavaThread(instance, this);
} else if (className.equals(javaLangClass())) {
Klass reflectedType = java_lang_Class.asKlass(instance);
if (reflectedType != null) {
JSJavaKlass jk = newJSJavaKlass(reflectedType);
// we don't support mirrors of VM internal Klasses
if (jk == null) return null;
res = new JSJavaClass(instance, jk, this);
} else {
// for primitive Classes, the reflected type is null
return null;
}
} else {
// not a well-known class. But the base class may be
// one of the known classes.
Klass kls = instance.getKlass().getSuper();
while (kls != null) {
className = kls.getName();
// java.lang.Class and java.lang.String are final classes
if (className.equals(javaLangThread())) {
res = new JSJavaThread(instance, this);
break;
}
kls = kls.getSuper();
}
}
if (res == null) {
res = new JSJavaInstance(instance, this);
}
return res;
}
private Map<Object, SoftReference<?>> om = new HashMap<>();
private String javaLangString;
private String javaLangThread;
private String javaLangClass;
}

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
public class JSJavaField extends DefaultScriptObject {
private static final int FIELD_NAME = 0;
private static final int FIELD_SIGNATURE = 1;
private static final int FIELD_HOLDER = 2;
private static final int FIELD_IS_PRIVATE = 3;
private static final int FIELD_IS_PUBLIC = 4;
private static final int FIELD_IS_PROTECTED = 5;
private static final int FIELD_IS_PACKAGE_PRIVATE = 6;
private static final int FIELD_IS_STATIC = 7;
private static final int FIELD_IS_FINAL = 8;
private static final int FIELD_IS_VOLATILE = 9;
private static final int FIELD_IS_TRANSIENT = 10;
private static final int FIELD_IS_SYNTHETIC = 11;
private static final int FIELD_UNDEFINED = -1;
public JSJavaField(Field f, JSJavaFactory fac) {
this.field = f;
this.factory = fac;
}
public Object get(String name) {
int fieldID = getFieldID(name);
switch (fieldID) {
case FIELD_NAME:
return field.getID().getName();
case FIELD_SIGNATURE:
return field.getSignature().asString();
case FIELD_HOLDER:
return getFieldHolder();
case FIELD_IS_PRIVATE:
return Boolean.valueOf(field.isPrivate());
case FIELD_IS_PUBLIC:
return Boolean.valueOf(field.isPublic());
case FIELD_IS_PROTECTED:
return Boolean.valueOf(field.isProtected());
case FIELD_IS_PACKAGE_PRIVATE:
return Boolean.valueOf(field.isPackagePrivate());
case FIELD_IS_STATIC:
return Boolean.valueOf(field.isStatic());
case FIELD_IS_FINAL:
return Boolean.valueOf(field.isFinal());
case FIELD_IS_VOLATILE:
return Boolean.valueOf(field.isVolatile());
case FIELD_IS_TRANSIENT:
return Boolean.valueOf(field.isTransient());
case FIELD_IS_SYNTHETIC:
return Boolean.valueOf(field.isSynthetic());
case FIELD_UNDEFINED:
default:
return super.get(name);
}
}
public Object[] getIds() {
Object[] fieldNames = fields.keySet().toArray();
Object[] superFields = super.getIds();
Object[] res = new Object[fieldNames.length + superFields.length];
System.arraycopy(fieldNames, 0, res, 0, fieldNames.length);
System.arraycopy(superFields, 0, res, fieldNames.length, superFields.length);
return res;
}
public boolean has(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (getFieldID(name) == FIELD_UNDEFINED) {
super.put(name, value);
}
}
public boolean equals(Object o) {
if (o == null || !(o instanceof JSJavaField)) {
return false;
}
JSJavaField other = (JSJavaField) o;
return field.equals(other.field);
}
public int hashCode() {
return field.hashCode();
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Field ");
buf.append(field.getFieldHolder().getName().asString().replace('/', '.'));
buf.append('.');
buf.append(field.getID().getName());
return buf.toString();
}
//-- Internals only below this point
private JSJavaObject getFieldHolder() {
return factory.newJSJavaKlass(field.getFieldHolder()).getJSJavaClass();
}
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("name", FIELD_NAME);
addField("signature", FIELD_SIGNATURE);
addField("holder", FIELD_HOLDER);
addField("isPrivate", FIELD_IS_PRIVATE);
addField("isPublic", FIELD_IS_PUBLIC);
addField("isProtected", FIELD_IS_PROTECTED);
addField("isPackagePrivate", FIELD_IS_PACKAGE_PRIVATE);
addField("isStatic", FIELD_IS_STATIC);
addField("isFinal", FIELD_IS_FINAL);
addField("isVolatile", FIELD_IS_VOLATILE);
addField("isTransient", FIELD_IS_TRANSIENT);
addField("isSynthetic", FIELD_IS_SYNTHETIC);
}
private final Field field;
private final JSJavaFactory factory;
}

View File

@ -1,225 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
public class JSJavaFrame extends DefaultScriptObject {
private static final int FIELD_METHOD = 0;
private static final int FIELD_BCI = 1;
private static final int FIELD_LINE_NUMBER = 2;
private static final int FIELD_LOCALS = 3;
private static final int FIELD_THIS_OBJECT = 4;
private static final int FIELD_THREAD = 5;
private static final int FIELD_UNDEFINED = -1;
public JSJavaFrame(JavaVFrame jvf, JSJavaFactory fac) {
this.jvf = jvf;
this.factory = fac;
}
public Object get(String name) {
int fieldID = getFieldID(name);
switch (fieldID) {
case FIELD_METHOD:
return getMethod();
case FIELD_BCI:
return getBCI();
case FIELD_LINE_NUMBER:
return getLineNumber();
case FIELD_LOCALS:
return getLocals();
case FIELD_THIS_OBJECT:
return getThisObject();
case FIELD_THREAD:
return getThread();
case FIELD_UNDEFINED:
default:
return super.get(name);
}
}
public Object[] getIds() {
Object[] fieldNames = fields.keySet().toArray();
Object[] superFields = super.getIds();
Object[] res = new Object[fieldNames.length + superFields.length];
System.arraycopy(fieldNames, 0, res, 0, fieldNames.length);
System.arraycopy(superFields, 0, res, fieldNames.length, superFields.length);
return res;
}
public boolean has(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (getFieldID(name) == FIELD_UNDEFINED) {
super.put(name, value);
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Frame (method=");
buf.append(jvf.getMethod().externalNameAndSignature());
buf.append(", bci=");
buf.append(getBCI());
buf.append(", line=");
buf.append(getLineNumber());
buf.append(')');
return buf.toString();
}
//-- Internals only below this point
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("method", FIELD_METHOD);
addField("bci", FIELD_BCI);
addField("line", FIELD_LINE_NUMBER);
addField("locals", FIELD_LOCALS);
addField("thisObject", FIELD_THIS_OBJECT);
addField("thread", FIELD_THREAD);
}
private JSJavaMethod getMethod() {
return factory.newJSJavaMethod(jvf.getMethod());
}
private int getBCI() {
return jvf.getBCI();
}
private int getLineNumber() {
int bci = jvf.getBCI();
if (bci == -1) {
return 0;
} else {
int lineNum = jvf.getMethod().getLineNumberFromBCI(bci);
return (lineNum <= 0)? 0 : lineNum;
}
}
private synchronized JSMap getLocals() {
if (localsCache == null) {
Map<String, Object> map = new HashMap<>();
localsCache = factory.newJSMap(map);
StackValueCollection values = jvf.getLocals();
Method method = jvf.getMethod();
if (method.isNative() || ! method.hasLocalVariableTable() ||
values == null) {
return localsCache;
}
LocalVariableTableElement[] localVars = method.getLocalVariableTable();
int bci = getBCI();
List<LocalVariableTableElement> visibleVars = new ArrayList<>(0);
for (int i = 0; i < localVars.length; i++) {
LocalVariableTableElement cur = localVars[i];
int startBCI = cur.getStartBCI();
if (startBCI <= bci && bci < startBCI + cur.getLength()) {
visibleVars.add(cur);
}
}
OopHandle handle = null;
ObjectHeap heap = VM.getVM().getObjectHeap();
for (Iterator varItr = visibleVars.iterator(); varItr.hasNext();) {
LocalVariableTableElement cur = (LocalVariableTableElement) varItr.next();
String name = method.getConstants().getSymbolAt(cur.getNameCPIndex()).asString();
int slot = cur.getSlot();
String signature = method.getConstants().getSymbolAt(cur.getDescriptorCPIndex()).asString();
BasicType variableType = BasicType.charToBasicType(signature.charAt(0));
Object value = null;
if (variableType == BasicType.T_BOOLEAN) {
value = values.booleanAt(slot);
} else if (variableType == BasicType.T_CHAR) {
value = values.charAt(slot);
} else if (variableType == BasicType.T_FLOAT) {
value = values.floatAt(slot);
} else if (variableType == BasicType.T_DOUBLE) {
value = values.doubleAt(slot);
} else if (variableType == BasicType.T_BYTE) {
value = values.byteAt(slot);
} else if (variableType == BasicType.T_SHORT) {
value = values.shortAt(slot);
} else if (variableType == BasicType.T_INT) {
value = values.intAt(slot);
} else if (variableType == BasicType.T_LONG) {
value = values.longAt(slot);
} else if (variableType == BasicType.T_OBJECT ||
variableType == BasicType.T_ARRAY) {
handle = values.oopHandleAt(slot);
value = factory.newJSJavaObject(heap.newOop(handle));
} else {
// ignore
}
map.put(name, value);
}
}
return localsCache;
}
private JSJavaObject getThisObject() {
Method method = jvf.getMethod();
if (method.isStatic()) {
return null;
}
StackValueCollection values = jvf.getLocals();
if (values != null) {
// 'this' at index 0.
OopHandle handle = values.oopHandleAt(0);
ObjectHeap heap = VM.getVM().getObjectHeap();
return factory.newJSJavaObject(heap.newOop(handle));
} else {
// can't get locals, return null.
return null;
}
}
private JSJavaThread getThread() {
return factory.newJSJavaThread(jvf.getThread());
}
private final JavaVFrame jvf;
private final JSJavaFactory factory;
private JSMap localsCache;
}

View File

@ -1,265 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import javax.script.ScriptException;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.classfile.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
import java.lang.reflect.Method;
public class JSJavaHeap extends DefaultScriptObject {
private static final int FIELD_CAPACITY = 0;
private static final int FIELD_USED = 1;
private static final int FIELD_FOR_EACH_OBJECT = 2;
private static final int FIELD_FOR_EACH_CLASS = 3;
private static final int FIELD_UNDEFINED = -1;
public JSJavaHeap(JSJavaFactory fac) {
this.factory = fac;
}
public Object get(String name) {
int fieldID = getFieldID(name);
switch (fieldID) {
case FIELD_CAPACITY:
return getCapacity();
case FIELD_USED:
return getUsed();
case FIELD_FOR_EACH_OBJECT:
return new MethodCallable(this, forEachObjectMethod);
case FIELD_FOR_EACH_CLASS:
return new MethodCallable(this, forEachClassMethod);
case FIELD_UNDEFINED:
default:
return super.get(name);
}
}
public Object[] getIds() {
Object[] superIds = super.getIds();
Object[] tmp = fields.keySet().toArray();
Object[] res = new Object[superIds.length + tmp.length];
System.arraycopy(tmp, 0, res, 0, tmp.length);
System.arraycopy(superIds, 0, res, tmp.length, superIds.length);
return res;
}
public boolean has(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (getFieldID(name) == FIELD_UNDEFINED) {
super.put(name, value);
}
}
public void forEachObject(Object[] args) {
boolean subtypes = true;
Klass kls = null;
Callable func = null;
switch (args.length) {
case 3: {
Object b = args[2];
if (b != null && b instanceof Boolean) {
subtypes = ((Boolean)b).booleanValue();
}
}
case 2: {
Object k = args[1];
if (k == null) return;
if (k instanceof JSJavaKlass) {
kls = ((JSJavaKlass)k).getKlass();
} else if (k instanceof String) {
kls = SystemDictionaryHelper.findInstanceKlass((String)k);
if (kls == null) return;
}
}
case 1: {
Object f = args[0];
if (f != null && f instanceof Callable) {
func = (Callable) f;
} else {
// unknown target - just return
return ;
}
}
break;
default:
return;
}
final Callable finalFunc = func;
HeapVisitor visitor = new DefaultHeapVisitor() {
public boolean doObj(Oop oop) {
JSJavaObject jo = factory.newJSJavaObject(oop);
if (jo != null) {
try {
finalFunc.call(new Object[] { jo });
} catch (ScriptException exp) {
throw new RuntimeException(exp);
}
}
return false;
}
};
ObjectHeap heap = VM.getVM().getObjectHeap();
if (kls == null) {
kls = SystemDictionaryHelper.findInstanceKlass("java.lang.Object");
}
heap.iterateObjectsOfKlass(visitor, kls, subtypes);
}
public void forEachClass(Object[] args) {
boolean withLoader = false;
Callable func = null;
switch (args.length) {
case 2: {
Object b = args[1];
if (b instanceof Boolean) {
withLoader = ((Boolean)b).booleanValue();
}
}
case 1: {
Object f = args[0];
if (f instanceof Callable) {
func = (Callable) f;
} else {
return;
}
}
break;
default:
return;
}
final Callable finalFunc = func;
ClassLoaderDataGraph cldg = VM.getVM().getClassLoaderDataGraph();
if (withLoader) {
cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
public void visit(Klass kls) {
JSJavaKlass jk = factory.newJSJavaKlass(kls);
Oop loader = kls.getClassLoader();
if (jk == null) {
return;
}
JSJavaObject k = jk.getJSJavaClass();
JSJavaObject l = factory.newJSJavaObject(loader);
if (k != null) {
if (l != null) {
try {
finalFunc.call(new Object[] { k, l });
} catch (ScriptException exp) {
throw new RuntimeException(exp);
}
}
}
}
});
} else {
cldg.classesDo(new ClassLoaderDataGraph.ClassVisitor() {
public void visit(Klass kls) {
JSJavaKlass jk = factory.newJSJavaKlass(kls);
if (jk == null) {
return;
}
JSJavaClass k = jk.getJSJavaClass();
if (k != null) {
if (k != null) {
try {
finalFunc.call(new Object[] { k });
} catch (ScriptException exp) {
throw new RuntimeException(exp);
}
}
}
}
});
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Java Heap (capacity=");
buf.append(getCapacity());
buf.append(", used=");
buf.append(getUsed());
buf.append(")");
return buf.toString();
}
//-- Internals only below this point
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("capacity", FIELD_CAPACITY);
addField("used", FIELD_USED);
addField("forEachObject", FIELD_FOR_EACH_OBJECT);
addField("forEachClass", FIELD_FOR_EACH_CLASS);
try {
Class<?> myClass = JSJavaHeap.class;
forEachObjectMethod = myClass.getMethod("forEachObject",
new Class[] { Object[].class });
forEachClassMethod = myClass.getMethod("forEachClass",
new Class[] {Object[].class });
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
private long getCapacity() {
return VM.getVM().getUniverse().heap().capacity();
}
private long getUsed() {
return VM.getVM().getUniverse().heap().used();
}
private final JSJavaFactory factory;
private static Method forEachObjectMethod;
private static Method forEachClassMethod;
}

View File

@ -1,93 +0,0 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.*;
/** This is JavaScript wrapper for Java Instance in debuggee.*/
public class JSJavaInstance extends JSJavaObject {
public JSJavaInstance(Instance instance, JSJavaFactory fac) {
super(instance, fac);
this.type = (JSJavaInstanceKlass) fac.newJSJavaKlass(instance.getKlass());
}
public final Instance getInstance() {
return (Instance) getOop();
}
public final JSJavaClass getJSJavaClass() {
return type.getJSJavaClass();
}
public Object get(String name) {
if (hasField(name)) {
return getFieldValue(name);
} else {
return super.get(name);
}
}
public Object[] getIds() {
String[] fieldNames = getFieldNames();
Object[] superFields = super.getIds();
Object[] res = new Object[fieldNames.length + superFields.length];
System.arraycopy(fieldNames, 0, res, 0, fieldNames.length);
System.arraycopy(superFields, 0, res, fieldNames.length, superFields.length);
return res;
}
public boolean has(String name) {
if (hasField(name)) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (! hasField(name)) {
super.put(name, value);
}
}
protected Object getFieldValue(String name) {
try {
return type.getInstanceFieldValue(name, getInstance());
} catch (NoSuchFieldException exp) {
return UNDEFINED;
}
}
protected String[] getFieldNames() {
return type.getInstanceFieldNames();
}
protected boolean hasField(String name) {
return type.hasInstanceField(name);
}
protected final JSJavaInstanceKlass type;
}

View File

@ -1,381 +0,0 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
/**
This is JavaScript wrapper for InstanceKlass.
*/
public class JSJavaInstanceKlass extends JSJavaKlass {
private static final int FIELD_SOURCE_FILE = 1;
private static final int FIELD_INTERFACES = 2;
private static final int FIELD_FIELDS = 3;
private static final int FIELD_METHODS = 4;
private static final int FIELD_IS_PRIVATE = 5;
private static final int FIELD_IS_PUBLIC = 6;
private static final int FIELD_IS_PROTECTED = 7;
private static final int FIELD_IS_PACKAGE_PRIVATE = 8;
private static final int FIELD_IS_STATIC = 9;
private static final int FIELD_IS_FINAL = 10;
private static final int FIELD_IS_ABSTRACT = 11;
private static final int FIELD_IS_STRICT = 12;
private static final int FIELD_IS_SYNTHETIC = 13;
private static final int FIELD_IS_INTERFACE = 14;
private static final int FIELD_CLASS_LOADER = 15;
private static final int FIELD_STATICS = 18;
private static final int FIELD_UNDEFINED = -1;
public JSJavaInstanceKlass(InstanceKlass kls, JSJavaFactory fac) {
super(kls, fac);
this.instanceFields = new HashMap<>();
this.staticFields = new HashMap<>();
}
public final InstanceKlass getInstanceKlass() {
return (InstanceKlass) getKlass();
}
public Object getMetaClassFieldValue(String name) {
int fieldID = getFieldID(name);
InstanceKlass ik = getInstanceKlass();
switch (fieldID) {
case FIELD_SOURCE_FILE: {
Symbol sourceFile = ik.getSourceFileName();
return (sourceFile != null)? sourceFile.asString() : "<unknown>";
}
case FIELD_INTERFACES:
return getInterfaces();
case FIELD_FIELDS:
return factory.newJSList(ik.getImmediateFields());
case FIELD_METHODS:
return factory.newJSList(ik.getImmediateMethods());
case FIELD_IS_PRIVATE:
return Boolean.valueOf(getAccessFlags().isPrivate());
case FIELD_IS_PUBLIC:
return Boolean.valueOf(getAccessFlags().isPublic());
case FIELD_IS_PROTECTED:
return Boolean.valueOf(getAccessFlags().isProtected());
case FIELD_IS_PACKAGE_PRIVATE: {
AccessFlags acc = getAccessFlags();
return Boolean.valueOf(!acc.isPrivate() && !acc.isPublic() && !acc.isProtected());
}
case FIELD_IS_STATIC:
return Boolean.valueOf(getAccessFlags().isStatic());
case FIELD_IS_FINAL:
return Boolean.valueOf(getAccessFlags().isFinal());
case FIELD_IS_ABSTRACT:
return Boolean.valueOf(getAccessFlags().isAbstract());
case FIELD_IS_STRICT:
return Boolean.valueOf(getAccessFlags().isStrict());
case FIELD_IS_SYNTHETIC:
return Boolean.valueOf(getAccessFlags().isSynthetic());
case FIELD_IS_INTERFACE:
return Boolean.valueOf(ik.isInterface());
case FIELD_CLASS_LOADER:
return factory.newJSJavaObject(ik.getClassLoader());
case FIELD_STATICS:
return getStatics();
case FIELD_UNDEFINED:
default:
return super.getMetaClassFieldValue(name);
}
}
public boolean hasMetaClassField(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.hasMetaClassField(name);
}
}
public String getName() {
return getInstanceKlass().getName().asString().replace('/', '.');
}
public boolean isArray() {
return false;
}
public String[] getMetaClassFieldNames() {
String[] superFields = super.getMetaClassFieldNames();
Set k = fields.keySet();
String[] res = new String[k.size() + superFields.length];
System.arraycopy(superFields, 0, res, 0, superFields.length);
int i = superFields.length;
for (Iterator itr = k.iterator(); itr.hasNext();) {
res[i] = (String) itr.next();
i++;
}
return res;
}
public Object getInstanceFieldValue(String name, Instance instance) throws NoSuchFieldException {
Field fld = findInstanceField(name);
if (fld != null) {
return getFieldValue(fld, name, instance);
} else {
throw new NoSuchFieldException(name + " is not field of "
+ getInstanceKlass().getName().asString().replace('/', '.'));
}
}
public Object getStaticFieldValue(String name) throws NoSuchFieldException {
Field fld = findStaticField(name);
if (fld != null) {
return getFieldValue(fld, name, getInstanceKlass());
} else {
throw new NoSuchFieldException(name + " is not field of "
+ getInstanceKlass().getName().asString().replace('/', '.'));
}
}
public String[] getInstanceFieldNames() {
if (instanceFieldNames == null) {
InstanceKlass current = getInstanceKlass();
while (current != null) {
List<Field> tmp = current.getImmediateFields();
for (Iterator<Field> itr = tmp.iterator(); itr.hasNext();) {
Field fld = itr.next();
if (!fld.isStatic()) {
String name = fld.getID().getName();
if (instanceFields.get(name) == null) {
instanceFields.put(name, fld);
}
}
}
current = (InstanceKlass) current.getSuper();
}
Set s = instanceFields.keySet();
instanceFieldNames = new String[s.size()];
int i = 0;
for (Iterator itr = s.iterator(); itr.hasNext(); i++) {
instanceFieldNames[i] = (String) itr.next();
}
}
return instanceFieldNames;
}
public boolean hasInstanceField(String name) {
Field fld = findInstanceField(name);
return (fld != null)? true: false;
}
public String[] getStaticFieldNames() {
if (staticFieldNames == null) {
InstanceKlass current = getInstanceKlass();
List<Field> tmp = current.getImmediateFields();
for (Iterator<Field> itr = tmp.iterator(); itr.hasNext();) {
Field fld = itr.next();
if (fld.isStatic()) {
staticFields.put(fld.getID().getName(), fld);
}
}
Set s = staticFields.keySet();
staticFieldNames = new String[s.size()];
int i = 0;
for (Iterator itr = s.iterator(); itr.hasNext(); i++) {
staticFieldNames[i] = (String) itr.next();
}
}
return staticFieldNames;
}
public boolean hasStaticField(String name) {
Field fld = findStaticField(name);
return (fld != null)? true: false;
}
//-- Intenals only below this point
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("sourceFile", FIELD_SOURCE_FILE);
addField("interfaces", FIELD_INTERFACES);
addField("fields", FIELD_FIELDS);
addField("methods", FIELD_METHODS);
addField("isPrivate", FIELD_IS_PRIVATE);
addField("isPublic", FIELD_IS_PUBLIC);
addField("isProtected", FIELD_IS_PROTECTED);
addField("isPackagePrivate", FIELD_IS_PACKAGE_PRIVATE);
addField("isStatic", FIELD_IS_STATIC);
addField("isFinal", FIELD_IS_FINAL);
addField("isAbstract", FIELD_IS_ABSTRACT);
addField("isStrict", FIELD_IS_STRICT);
addField("isSynthetic", FIELD_IS_SYNTHETIC);
addField("isInterface", FIELD_IS_INTERFACE);
addField("classLoader", FIELD_CLASS_LOADER);
addField("statics", FIELD_STATICS);
}
private AccessFlags getAccessFlags() {
if (accFlags == null) {
accFlags = new AccessFlags(getInstanceKlass().computeModifierFlags());
}
return accFlags;
}
private Object getFieldValue(Field fld, String name, Oop oop) {
FieldType fd = fld.getFieldType();
if (fd.isObject() || fd.isArray()) {
return factory.newJSJavaObject(((OopField)fld).getValue(oop));
} else if (fd.isByte()) {
return ((ByteField) fld).getValue(oop);
} else if (fd.isChar()) {
return new String(new char[] { ((CharField)fld).getValue(oop) });
} else if (fd.isDouble()) {
return ((DoubleField) fld).getValue(oop);
} else if (fd.isFloat()) {
return ((FloatField) fld).getValue(oop);
} else if (fd.isInt()) {
return ((IntField) fld).getValue(oop);
} else if (fd.isLong()) {
return ((LongField) fld).getValue(oop);
} else if (fd.isShort()) {
return ((ShortField) fld).getValue(oop);
} else if (fd.isBoolean()) {
return ((BooleanField) fld).getValue(oop);
} else {
if (Assert.ASSERTS_ENABLED) {
Assert.that(false, "invalid field type for " + name);
}
return null;
}
}
private Object getFieldValue(Field fld, String name, InstanceKlass oop) {
FieldType fd = fld.getFieldType();
if (fd.isObject() || fd.isArray()) {
return factory.newJSJavaObject(((OopField)fld).getValue(oop));
} else if (fd.isByte()) {
return ((ByteField) fld).getValue(oop);
} else if (fd.isChar()) {
return new String(new char[] { ((CharField)fld).getValue(oop) });
} else if (fd.isDouble()) {
return ((DoubleField) fld).getValue(oop);
} else if (fd.isFloat()) {
return ((FloatField) fld).getValue(oop);
} else if (fd.isInt()) {
return ((IntField) fld).getValue(oop);
} else if (fd.isLong()) {
return ((LongField) fld).getValue(oop);
} else if (fd.isShort()) {
return ((ShortField) fld).getValue(oop);
} else if (fd.isBoolean()) {
return ((BooleanField) fld).getValue(oop);
} else {
if (Assert.ASSERTS_ENABLED) {
Assert.that(false, "invalid field type for " + name);
}
return null;
}
}
private Field findInstanceField(String name) {
Field fld = (Field) instanceFields.get(name);
if (fld != null) {
return fld;
} else {
InstanceKlass current = getInstanceKlass();
while (current != null) {
List<Field> tmp = current.getImmediateFields();
for (Iterator<Field> itr = tmp.iterator(); itr.hasNext();) {
fld = itr.next();
if (fld.getID().getName().equals(name) && !fld.isStatic()) {
instanceFields.put(name, fld);
return fld;
}
}
// lookup in super class.
current = (InstanceKlass) current.getSuper();
}
}
// no match
return null;
}
private Field findStaticField(String name) {
Field fld = (Field) staticFields.get(name);
if (fld != null) {
return fld;
} else {
// static fields are searched only in current.
// Direct/indirect super classes and interfaces
// are not included in search.
InstanceKlass current = getInstanceKlass();
List<Field> tmp = current.getImmediateFields();
for (Iterator<Field> itr = tmp.iterator(); itr.hasNext();) {
fld = itr.next();
if (fld.getID().getName().equals(name) && fld.isStatic()) {
staticFields.put(name, fld);
return fld;
}
}
// no match
return null;
}
}
private JSList getInterfaces() {
InstanceKlass ik = getInstanceKlass();
List<Klass> intfs = ik.getDirectImplementedInterfaces();
List<Instance> res = new ArrayList<>(0);
for (Iterator<Klass> itr = intfs.iterator(); itr.hasNext();) {
Klass k = itr.next();
res.add(k.getJavaMirror());
}
return factory.newJSList(res);
}
private JSMap getStatics() {
String[] names = getStaticFieldNames();
Map<String, Object> map = new HashMap<>();
for (int i=0; i < names.length; i++) {
try {
map.put(names[i], getStaticFieldValue(names[i]));
} catch (NoSuchFieldException exp) {}
}
return factory.newJSMap(map);
}
private Map<String, Field> instanceFields;
private Map<String, Field> staticFields;
private String[] instanceFieldNames;
private String[] staticFieldNames;
private AccessFlags accFlags;
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
/**
This is JavaScript wrapper for Klass.
*/
public abstract class JSJavaKlass {
private static final int FIELD_SUPER_CLASS = 0;
private static final int FIELD_NAME = 1;
private static final int FIELD_IS_ARRAY_CLASS = 2;
private static final int FIELD_UNDEFINED = -1;
public JSJavaKlass(Klass klass, JSJavaFactory factory) {
this.factory = factory;
this.klass = klass;
}
public final Klass getKlass() {
return klass;
}
public JSJavaClass getJSJavaClass() {
return (JSJavaClass) factory.newJSJavaObject(getKlass().getJavaMirror());
}
public Object getMetaClassFieldValue(String name) {
int fieldID = getFieldID(name);
switch (fieldID) {
case FIELD_SUPER_CLASS: {
JSJavaKlass jk = factory.newJSJavaKlass(getKlass().getSuper());
return (jk != null) ? jk.getJSJavaClass() : null;
}
case FIELD_NAME:
return getName();
case FIELD_IS_ARRAY_CLASS:
return Boolean.valueOf(isArray());
case FIELD_UNDEFINED:
default:
return ScriptObject.UNDEFINED;
}
}
public boolean hasMetaClassField(String name) {
return getFieldID(name) != FIELD_UNDEFINED;
}
public String[] getMetaClassFieldNames() {
String[] res = { "name", "superClass", "isArrayClass" };
return res;
}
public abstract String getName();
public abstract boolean isArray();
//-- Internals only below this point
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("base", FIELD_SUPER_CLASS);
addField("baseClass", FIELD_SUPER_CLASS);
addField("superClass", FIELD_SUPER_CLASS);
addField("name", FIELD_NAME);
addField("isArrayClass", FIELD_IS_ARRAY_CLASS);
}
protected final JSJavaFactory factory;
private final Klass klass;
}

View File

@ -1,165 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
/**
* Wraps a Method* from the debuggee VM.
*/
public class JSJavaMethod extends JSMetadata {
private static final int FIELD_NAME = 0;
private static final int FIELD_SIGNATURE = 1;
private static final int FIELD_HOLDER = 2;
private static final int FIELD_IS_PRIVATE = 3;
private static final int FIELD_IS_PUBLIC = 4;
private static final int FIELD_IS_PROTECTED = 5;
private static final int FIELD_IS_PACKAGE_PRIVATE = 6;
private static final int FIELD_IS_STATIC = 7;
private static final int FIELD_IS_FINAL = 8;
private static final int FIELD_IS_SYNCHRONIZED = 9;
private static final int FIELD_IS_NATIVE = 10;
private static final int FIELD_IS_ABSTRACT = 11;
private static final int FIELD_IS_STRICT = 12;
private static final int FIELD_IS_SYNTHETIC = 13;
private static final int FIELD_IS_OBSOLETE = 14;
private static final int FIELD_UNDEFINED = -1;
public JSJavaMethod(Method m, JSJavaFactory fac) {
super(m, fac);
}
public final Method getMethod() {
return (Method) getMetadata();
}
public Object get(String name) {
int fieldID = getFieldID(name);
Method method = getMethod();
switch (fieldID) {
case FIELD_NAME:
return method.getName().asString();
case FIELD_SIGNATURE:
return method.getSignature().asString();
case FIELD_HOLDER:
return getMethodHolder();
case FIELD_IS_PRIVATE:
return Boolean.valueOf(method.isPrivate());
case FIELD_IS_PUBLIC:
return Boolean.valueOf(method.isPublic());
case FIELD_IS_PROTECTED:
return Boolean.valueOf(method.isProtected());
case FIELD_IS_PACKAGE_PRIVATE:
return Boolean.valueOf(method.isPackagePrivate());
case FIELD_IS_STATIC:
return Boolean.valueOf(method.isStatic());
case FIELD_IS_FINAL:
return Boolean.valueOf(method.isFinal());
case FIELD_IS_SYNCHRONIZED:
return Boolean.valueOf(method.isSynchronized());
case FIELD_IS_NATIVE:
return Boolean.valueOf(method.isNative());
case FIELD_IS_ABSTRACT:
return Boolean.valueOf(method.isAbstract());
case FIELD_IS_STRICT:
return Boolean.valueOf(method.isStrict());
case FIELD_IS_SYNTHETIC:
return Boolean.valueOf(method.isSynthetic());
case FIELD_IS_OBSOLETE:
return Boolean.valueOf(method.isObsolete());
case FIELD_UNDEFINED:
default:
return super.get(name);
}
}
public Object[] getIds() {
Object[] fieldNames = fields.keySet().toArray();
Object[] superFields = super.getIds();
Object[] res = new Object[fieldNames.length + superFields.length];
System.arraycopy(fieldNames, 0, res, 0, fieldNames.length);
System.arraycopy(superFields, 0, res, fieldNames.length, superFields.length);
return res;
}
public boolean has(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return;
} else {
super.put(name, value);
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Method ");
buf.append(getMethod().externalNameAndSignature());
return buf.toString();
}
//-- Internals only below this point
private JSJavaObject getMethodHolder() {
Klass k = getMethod().getMethodHolder();
return factory.newJSJavaKlass(k).getJSJavaClass();
}
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("name", FIELD_NAME);
addField("signature", FIELD_SIGNATURE);
addField("holder", FIELD_HOLDER);
addField("isPrivate", FIELD_IS_PRIVATE);
addField("isPublic", FIELD_IS_PUBLIC);
addField("isProtected", FIELD_IS_PROTECTED);
addField("isPackagePrivate", FIELD_IS_PACKAGE_PRIVATE);
addField("isStatic", FIELD_IS_STATIC);
addField("isFinal", FIELD_IS_FINAL);
addField("isSynchronized", FIELD_IS_SYNCHRONIZED);
addField("isNative", FIELD_IS_NATIVE);
addField("isAbstract", FIELD_IS_ABSTRACT);
addField("isStrict", FIELD_IS_STRICT);
addField("isSynthetic", FIELD_IS_SYNTHETIC);
addField("isObsolete", FIELD_IS_OBSOLETE);
}
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.ObjArray;
/**
This is JavaScript wrapper for Java Object Array.
*/
public class JSJavaObjArray extends JSJavaArray {
public JSJavaObjArray(ObjArray array, JSJavaFactory fac) {
super(array, fac);
}
public final ObjArray getObjArray() {
return (ObjArray) getArray();
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
/**
This is JavaScript wrapper for ObjArrayKlass.
*/
public class JSJavaObjArrayKlass extends JSJavaArrayKlass {
public JSJavaObjArrayKlass(ObjArrayKlass kls, JSJavaFactory fac) {
super(kls, fac);
}
public ObjArrayKlass getObjArrayKlass() {
return (ObjArrayKlass) getArrayKlass();
}
public String getName() {
Klass botKls = getObjArrayKlass().getBottomKlass();
int dimension = (int) getObjArrayKlass().getDimension();
StringBuffer buf = new StringBuffer();
if (botKls instanceof TypeArrayKlass) {
dimension--;
}
buf.append(factory.newJSJavaKlass(botKls).getName());
for (int i = 0; i < dimension; i++) {
buf.append("[]");
}
return buf.toString();
}
public Object getFieldValue(int index, Array array) {
Oop obj = ((ObjArray)array).getObjAt(index);
return factory.newJSJavaObject(obj);
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.Oop;
/** This is JavaScript wrapper for a Java Object in debuggee.*/
public abstract class JSJavaObject extends DefaultScriptObject {
public JSJavaObject(Oop oop, JSJavaFactory factory) {
this.oop = oop;
this.factory = factory;
}
public final Oop getOop() {
return oop;
}
public boolean equals(Object o) {
if (o == null || !(o instanceof JSJavaObject)) {
return false;
}
JSJavaObject other = (JSJavaObject) o;
return oop.equals(other.oop);
}
public int hashCode() {
return oop.hashCode();
}
public String toString() {
return "Object " + oop.getHandle().toString();
}
private final Oop oop;
protected final JSJavaFactory factory;
}

View File

@ -1,653 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.io.*;
import java.util.*;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.tools.jcore.*;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Simple wrapper around jsr-223 JavaScript script engine.
* In addition to wrapping useful functionality of jsr-223 engine,
* this class exposed certain "global" functions to the script.
*/
public abstract class JSJavaScriptEngine extends MapScriptObject {
/**
* Start a read-eval-print loop with this engine.
*/
public void startConsole() {
start(true);
}
/**
* Initialize the engine so that we can "eval" strings
* and files later.
*/
public void start() {
start(false);
}
/**
* Define a global function that invokes given Method.
*/
public void defineFunction(Object target, Method method) {
putFunction(target, method, false);
}
/**
* Call the script function of given name passing the
* given arguments.
*/
public Object call(String name, Object[] args) {
Invocable invocable = (Invocable)engine;
try {
return invocable.invokeFunction(name, args);
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
/**
address function returns address of JSJavaObject as String. For other
type of objects, the result is undefined.
*/
public Object address(Object[] args) {
if (args.length != 1) return UNDEFINED;
Object o = args[0];
if (o != null && o instanceof JSJavaObject) {
return ((JSJavaObject)o).getOop().getHandle().toString();
} else {
return UNDEFINED;
}
}
/**
classof function gets type of given JSJavaInstance or JSJavaArray. Or
given a string class name, this function gets the class object. For
other type of objects, the result is undefined.
*/
public Object classof(Object[] args) {
if (args.length != 1) {
return UNDEFINED;
}
Object o = args[0];
if (o != null) {
if (o instanceof JSJavaObject) {
if (o instanceof JSJavaInstance) {
return ((JSJavaInstance)o).getJSJavaClass();
} else if (o instanceof JSJavaArray) {
return ((JSJavaArray)o).getJSJavaClass();
} else {
return UNDEFINED;
}
} else if (o instanceof String) {
InstanceKlass ik = SystemDictionaryHelper.findInstanceKlass((String) o);
return getJSJavaFactory().newJSJavaKlass(ik).getJSJavaClass();
} else {
return UNDEFINED;
}
} else {
return UNDEFINED;
}
}
/**
* dumpClass function creates a .class file for a given Class object.
* On success, returns true. Else, returns false. Second optional argument
* specifies the directory in which .class content is dumped. This defaults
* to '.'
*/
public Object dumpClass(Object[] args) {
if (args.length == 0) {
return Boolean.FALSE;
}
Object clazz = args[0];
if (clazz == null) {
return Boolean.FALSE;
}
InstanceKlass ik = null;
if (clazz instanceof String) {
String name = (String) clazz;
if (name.startsWith("0x")) {
// treat it as address
VM vm = VM.getVM();
Address addr = vm.getDebugger().parseAddress(name);
Metadata metadata = Metadata.instantiateWrapperFor(addr.addOffsetTo(0));
if (metadata instanceof InstanceKlass) {
ik = (InstanceKlass) metadata;
} else {
return Boolean.FALSE;
}
} else {
ik = SystemDictionaryHelper.findInstanceKlass((String) clazz);
}
} else if (clazz instanceof JSJavaClass) {
JSJavaKlass jk = ((JSJavaClass)clazz).getJSJavaKlass();
if (jk != null && jk instanceof JSJavaInstanceKlass) {
ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
}
} else {
return Boolean.FALSE;
}
if (ik == null) return Boolean.FALSE;
StringBuffer buf = new StringBuffer();
if (args.length > 1) {
buf.append(args[1].toString());
} else {
buf.append('.');
}
buf.append(File.separatorChar);
buf.append(ik.getName().asString().replace('/', File.separatorChar));
buf.append(".class");
String fileName = buf.toString();
File file = new File(fileName);
try {
int index = fileName.lastIndexOf(File.separatorChar);
File dir = new File(fileName.substring(0, index));
dir.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
ClassWriter cw = new ClassWriter(ik, fos);
cw.write();
fos.close();
} catch (IOException exp) {
printError(exp.toString(), exp);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* dumpHeap function creates a heap dump file.
* On success, returns true. Else, returns false.
*/
public Object dumpHeap(Object[] args) {
String fileName = "heap.bin";
if (args.length > 0) {
fileName = args[0].toString();
}
return new JMap().writeHeapHprofBin(fileName)? Boolean.TRUE: Boolean.FALSE;
}
/**
help function prints help message for global functions and variables.
*/
public void help(Object[] args) {
println("Function/Variable Description");
println("================= ===========");
println("address(jobject) returns the address of the Java object");
println("classof(jobject) returns the class object of the Java object");
println("dumpClass(jclass,[dir]) writes .class for the given Java Class");
println("dumpHeap([file]) writes heap in hprof binary format");
println("help() prints this help message");
println("identityHash(jobject) returns the hashCode of the Java object");
println("mirror(jobject) returns a local mirror of the Java object");
println("load([file1, file2,...]) loads JavaScript file(s). With no files, reads <stdin>");
println("object(string) converts a string address into Java object");
println("owner(jobject) returns the owner thread of this monitor or null");
println("sizeof(jobject) returns the size of Java object in bytes");
println("staticof(jclass, field) returns a static field of the given Java class");
println("read([prompt]) reads a single line from standard input");
println("quit() quits the interactive load call");
println("jvm the target jvm that is being debugged");
}
/**
identityHash function gets identity hash code value of given
JSJavaObject. For other type of objects, the result is undefined.
*/
public Object identityHash(Object[] args) {
if (args.length != 1) return UNDEFINED;
Object o = args[0];
if (o != null && o instanceof JSJavaObject) {
return ((JSJavaObject) o).getOop().identityHash();
} else {
return UNDEFINED;
}
}
/**
* Load and execute a set of JavaScript source files.
* This method is defined as a JavaScript function.
*/
public void load(Object[] args) {
for (int i = 0; i < args.length; i++) {
processSource(args[i].toString());
}
}
/**
mirror function creats local copy of the Oop wrapper supplied.
if mirror can not be created, return undefined. For other types,
mirror is undefined.
*/
public Object mirror(Object[] args) {
Object o = args[0];
Object res = UNDEFINED;
if (o != null) {
if (o instanceof JSJavaObject) {
Oop oop = ((JSJavaObject)o).getOop();
try {
res = getObjectReader().readObject(oop);
} catch (Exception e) {
if (debug) e.printStackTrace(getErrorStream());
}
} else if (o instanceof JSMetadata) {
Metadata metadata = ((JSMetadata)o).getMetadata();
try {
if (metadata instanceof InstanceKlass) {
res = getObjectReader().readClass((InstanceKlass) metadata);
}
} catch (Exception e) {
if (debug) e.printStackTrace(getErrorStream());
}
}
}
return res;
}
/**
owner function gets owning thread of given JSJavaObjec, if any, else
returns null. For other type of objects, the result is undefined.
*/
public Object owner(Object[] args) {
Object o = args[0];
if (o != null && o instanceof JSJavaObject) {
return getOwningThread((JSJavaObject)o);
} else {
return UNDEFINED;
}
}
/**
object function takes a string address and returns a JSJavaObject.
For other type of objects, the result is undefined.
*/
public Object object(Object[] args) {
Object o = args[0];
if (o != null && o instanceof String) {
VM vm = VM.getVM();
Address addr = vm.getDebugger().parseAddress((String)o);
Oop oop = vm.getObjectHeap().newOop(addr.addOffsetToAsOopHandle(0));
return getJSJavaFactory().newJSJavaObject(oop);
} else {
return UNDEFINED;
}
}
/**
sizeof function returns size of a Java object in bytes. For other type
of objects, the result is undefined.
*/
public Object sizeof(Object[] args) {
if (args.length != 1) return UNDEFINED;
Object o = args[0];
if (o != null && o instanceof JSJavaObject) {
return ((JSJavaObject) o).getOop().getObjectSize();
} else {
return UNDEFINED;
}
}
/**
staticof function gets static field of given class. Both class and
field name are specified as strings. undefined is returned if there is
no such named field.
*/
public Object staticof(Object[] args) {
Object classname = args[0];
Object fieldname = args[1];
if (fieldname == null || classname == null ||
!(fieldname instanceof String)) {
return UNDEFINED;
}
InstanceKlass ik = null;
if (classname instanceof JSJavaClass) {
JSJavaClass jclass = (JSJavaClass) classname;
JSJavaKlass jk = jclass.getJSJavaKlass();
if (jk != null && jk instanceof JSJavaInstanceKlass) {
ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
}
} else if (classname instanceof String) {
ik = SystemDictionaryHelper.findInstanceKlass((String)classname);
} else {
return UNDEFINED;
}
if (ik == null) {
return UNDEFINED;
}
JSJavaFactory factory = getJSJavaFactory();
try {
return ((JSJavaInstanceKlass) factory.newJSJavaKlass(ik)).getStaticFieldValue((String)fieldname);
} catch (NoSuchFieldException e) {
return UNDEFINED;
}
}
/**
* read function reads a single line of input from standard input
*/
public Object read(Object[] args) {
BufferedReader in = getInputReader();
if (in == null) {
return null;
}
if (args.length > 0) {
print(args[0].toString());
print(":");
}
try {
return in.readLine();
} catch (IOException exp) {
exp.printStackTrace();
throw new RuntimeException(exp);
}
}
/**
* Quit the shell.
* This only affects the interactive mode.
*/
public void quit(Object[] args) {
quit();
}
public void writeln(Object[] args) {
for (int i = 0; i < args.length; i++) {
print(args[i].toString());
print(" ");
}
println("");
}
public void write(Object[] args) {
for (int i = 0; i < args.length; i++) {
print(args[i].toString());
print(" ");
}
}
//-- Internals only below this point
protected void start(boolean console) {
ScriptContext context = engine.getContext();
OutputStream out = getOutputStream();
if (out != null) {
context.setWriter(new PrintWriter(out));
}
OutputStream err = getErrorStream();
if (err != null) {
context.setErrorWriter(new PrintWriter(err));
}
// load "sa.js" initialization file
loadInitFile();
// load "~/jsdb.js" (if found) to perform user specific
// initialization steps, if any.
loadUserInitFile();
JSJavaFactory fac = getJSJavaFactory();
JSJavaVM jvm = (fac != null)? fac.newJSJavaVM() : null;
// call "main" function from "sa.js" -- main expects
// 'this' object and jvm object
call("main", new Object[] { this, jvm });
// if asked, start read-eval-print console
if (console) {
processSource(null);
}
}
protected JSJavaScriptEngine(boolean debug) {
this.debug = debug;
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("javascript");
if (engine == null) {
throw new RuntimeException("can't load JavaScript engine");
}
Method[] methods = getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (! Modifier.isPublic(m.getModifiers())) {
continue;
}
Class[] argTypes = m.getParameterTypes();
if (argTypes.length == 1 &&
argTypes[0] == Object[].class) {
putFunction(this, m);
}
}
}
protected JSJavaScriptEngine() {
this(false);
}
protected abstract ObjectReader getObjectReader();
protected abstract JSJavaFactory getJSJavaFactory();
protected void printPrompt(String str) {
System.err.print(str);
System.err.flush();
}
protected void loadInitFile() {
InputStream is = JSJavaScriptEngine.class.getResourceAsStream("sa.js");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
evalReader(reader, "sa.js");
}
protected void loadUserInitFile() {
File initFile = new File(getUserInitFileDir(), getUserInitFileName());
if (initFile.exists() && initFile.isFile()) {
// load the init script
processSource(initFile.getAbsolutePath());
}
}
protected String getUserInitFileDir() {
return System.getProperty("user.home");
}
protected String getUserInitFileName() {
return "jsdb.js";
}
protected BufferedReader getInputReader() {
if (inReader == null) {
inReader = new BufferedReader(new InputStreamReader(System.in));
}
return inReader;
}
protected PrintStream getOutputStream() {
return System.out;
}
protected PrintStream getErrorStream() {
return System.err;
}
protected void print(String name) {
getOutputStream().print(name);
}
protected void println(String name) {
getOutputStream().println(name);
}
protected void printError(String message) {
printError(message, null);
}
protected void printError(String message, Exception exp) {
getErrorStream().println(message);
if (exp != null && debug) {
exp.printStackTrace(getErrorStream());
}
}
protected boolean isQuitting() {
return quitting;
}
protected void quit() {
quitting = true;
}
protected ScriptEngine getScriptEngine() {
return engine;
}
private JSJavaThread getOwningThread(JSJavaObject jo) {
Oop oop = jo.getOop();
Mark mark = oop.getMark();
ObjectMonitor mon = null;
Address owner = null;
JSJavaThread owningThread = null;
// check for heavyweight monitor
if (! mark.hasMonitor()) {
// check for lightweight monitor
if (mark.hasLocker()) {
owner = mark.locker().getAddress(); // save the address of the Lock word
}
// implied else: no owner
} else {
// this object has a heavyweight monitor
mon = mark.monitor();
// The owner field of a heavyweight monitor may be NULL for no
// owner, a JavaThread * or it may still be the address of the
// Lock word in a JavaThread's stack. A monitor can be inflated
// by a non-owning JavaThread, but only the owning JavaThread
// can change the owner field from the Lock word to the
// JavaThread * and it may not have done that yet.
owner = mon.owner();
}
// find the owning thread
if (owner != null) {
JSJavaFactory factory = getJSJavaFactory();
owningThread = (JSJavaThread) factory.newJSJavaThread(VM.getVM().getThreads().owningThreadFromMonitor(owner));
}
return owningThread;
}
/**
* Evaluate JavaScript source.
* @param filename the name of the file to compile, or null
* for interactive mode.
*/
private void processSource(String filename) {
if (filename == null) {
BufferedReader in = getInputReader();
String sourceName = "<stdin>";
int lineno = 0;
boolean hitEOF = false;
do {
int startline = lineno;
printPrompt("jsdb> ");
Object source = read(EMPTY_ARRAY);
if (source == null) {
hitEOF = true;
break;
}
lineno++;
Object result = evalString(source.toString(), sourceName, startline);
if (result != null) {
printError(result.toString());
}
if (isQuitting()) {
// The user executed the quit() function.
break;
}
} while (!hitEOF);
} else {
Reader in = null;
try {
in = new BufferedReader(new FileReader(filename));
evalReader(in, filename);
} catch (FileNotFoundException ex) {
println("File '" + filename + "' not found");
throw new RuntimeException(ex);
}
}
}
protected Object evalString(String source, String filename, int lineNum) {
try {
engine.put(ScriptEngine.FILENAME, filename);
return engine.eval(source);
} catch (ScriptException sexp) {
printError(sexp.toString(), sexp);
} catch (Exception exp) {
printError(exp.toString(), exp);
}
return null;
}
private Object evalReader(Reader in, String filename) {
try {
engine.put(ScriptEngine.FILENAME, filename);
return engine.eval(in);
} catch (ScriptException sexp) {
System.err.println(sexp);
printError(sexp.toString(), sexp);
} finally {
try {
in.close();
} catch (IOException ioe) {
printError(ioe.toString(), ioe);
}
}
return null;
}
// lazily initialized input reader
private BufferedReader inReader;
// debug mode or not
protected final boolean debug;
private boolean quitting;
// underlying jsr-223 script engine
private ScriptEngine engine;
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.*;
/**
* Wraps a java.lang.String instance of the target VM.
*/
public class JSJavaString extends JSJavaInstance {
public JSJavaString(Instance instance, JSJavaFactory fac) {
super(instance, fac);
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("String (address=");
buf.append(getOop().getHandle());
buf.append(", value=");
buf.append("'");
buf.append(getString());
buf.append('\'');
buf.append(')');
return buf.toString();
}
protected Object getFieldValue(String name) {
if (name.equals("stringValue")) {
return getString();
} else {
return super.getFieldValue(name);
}
}
protected String[] getFieldNames() {
String[] fields = super.getFieldNames();
String[] res = new String[fields.length + 1];
System.arraycopy(fields, 0, res, 0, fields.length);
res[fields.length] = "stringValue";
return res;
}
protected boolean hasField(String name) {
if (name.equals("stringValue")) {
return true;
} else {
return super.hasField(name);
}
}
//-- Internals only below this point
private String getString() {
return OopUtilities.stringOopToString(getOop());
}
}

View File

@ -1,190 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
/**
* Wraps a JavaThread instance in the target VM.
*/
public class JSJavaThread extends JSJavaInstance {
public JSJavaThread(Instance threadOop, JSJavaFactory fac) {
super(threadOop, fac);
// JavaThread retrieved from java.lang.Thread instance may be null.
// This is the case for threads not-started and for zombies. Wherever
// appropriate, check for null instead of resulting in NullPointerException.
this.jthread = OopUtilities.threadOopGetJavaThread(threadOop);
}
public JSJavaThread(JavaThread jt, JSJavaFactory fac) {
super((Instance) jt.getThreadObj(), fac);
this.jthread = jt;
}
public String toString() {
String name = getName();
StringBuffer buf = new StringBuffer();
buf.append("Thread (address=");
buf.append(getOop().getHandle());
buf.append(", name=");
if (name != null) {
buf.append(name);
} else {
buf.append("<unnamed>");
}
buf.append(')');
return buf.toString();
}
protected Object getFieldValue(String name) {
if (name.equals("name")) {
return getName();
} else if (name.equals("frames")) {
return getFrames();
} else if (name.equals("monitors")) {
return getOwnedMonitors();
} else {
return super.getFieldValue(name);
}
}
protected String[] getFieldNames() {
String[] flds = super.getFieldNames();
String[] res = new String[flds.length + 2];
System.arraycopy(flds, 0, res, 0, flds.length);
res[flds.length] = "frames";
res[flds.length + 1] = "monitors";
return res;
}
protected boolean hasField(String name) {
if (name.equals("frames") || name.equals("monitors")) {
return true;
} else {
return super.hasField(name);
}
}
//-- Internals only below this point
private String getName() {
return OopUtilities.threadOopGetName(getOop());
}
private synchronized JSList getFrames() {
if (framesCache == null) {
final List<JavaVFrame> list = new ArrayList<>(0);
if (jthread != null) {
JavaVFrame jvf = jthread.getLastJavaVFrameDbg();
while (jvf != null) {
list.add(jvf);
jvf = jvf.javaSender();
}
}
framesCache = factory.newJSList(list);
}
return framesCache;
}
private synchronized JSList getOwnedMonitors() {
if (monitorsCache == null) {
final List<Oop> ownedMonitors = new ArrayList<>(0);
if (jthread != null) {
List<OopHandle> lockedObjects = new ArrayList<>();
ObjectMonitor waitingMonitor = jthread.getCurrentWaitingMonitor();
OopHandle waitingObj = null;
if (waitingMonitor != null) {
// save object of current wait() call (if any) for later comparison
waitingObj = waitingMonitor.object();
}
ObjectMonitor pendingMonitor = jthread.getCurrentPendingMonitor();
OopHandle pendingObj = null;
if (pendingMonitor != null) {
// save object of current enter() call (if any) for later comparison
pendingObj = pendingMonitor.object();
}
JavaVFrame frame = jthread.getLastJavaVFrameDbg();
while (frame != null) {
List<MonitorInfo> frameMonitors = frame.getMonitors();
for (Iterator<MonitorInfo> miItr = frameMonitors.iterator(); miItr.hasNext(); ) {
MonitorInfo mi = miItr.next();
if (mi.eliminated() && frame.isCompiledFrame()) {
continue; // skip eliminated monitor
}
OopHandle obj = mi.owner();
if (obj == null) {
// this monitor doesn't have an owning object so skip it
continue;
}
if (obj.equals(waitingObj)) {
// the thread is waiting on this monitor so it isn't really owned
continue;
}
if (obj.equals(pendingObj)) {
// the thread is pending on this monitor so it isn't really owned
continue;
}
boolean found = false;
for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
// check for recursive locks
if (obj.equals(loItr.next())) {
found = true;
break;
}
}
if (found) {
// already have this object so don't include it
continue;
}
// add the owning object to our list
lockedObjects.add(obj);
}
frame = (JavaVFrame) frame.javaSender();
}
// now convert List<OopHandle> to List<Oop>
ObjectHeap heap = VM.getVM().getObjectHeap();
for (Iterator loItr = lockedObjects.iterator(); loItr.hasNext(); ) {
ownedMonitors.add(heap.newOop((OopHandle)loItr.next()));
}
}
monitorsCache = factory.newJSList(ownedMonitors);
}
return monitorsCache;
}
private JavaThread jthread;
private JSList framesCache;
private JSList monitorsCache;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.TypeArray;
/**
This is JavaScript wrapper for Java Primitive Array.
*/
public class JSJavaTypeArray extends JSJavaArray {
public JSJavaTypeArray(TypeArray array, JSJavaFactory fac) {
super(array, fac);
}
public final TypeArray getTypeArray() {
return (TypeArray) getArray();
}
}

View File

@ -1,98 +0,0 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.utilities.*;
/**
This is JavaScript wrapper for TypeArrayKlass.
*/
public class JSJavaTypeArrayKlass extends JSJavaArrayKlass {
public JSJavaTypeArrayKlass(TypeArrayKlass kls, JSJavaFactory fac) {
super(kls, fac);
}
public final TypeArrayKlass getTypeArrayKlass() {
return (TypeArrayKlass) getArrayKlass();
}
public String getName() {
int type = (int) getTypeArrayKlass().getElementType();
switch (type) {
case TypeArrayKlass.T_BOOLEAN:
return "boolean[]";
case TypeArrayKlass.T_CHAR:
return "char[]";
case TypeArrayKlass.T_FLOAT:
return "float[]";
case TypeArrayKlass.T_DOUBLE:
return "double[]";
case TypeArrayKlass.T_BYTE:
return "byte[]";
case TypeArrayKlass.T_SHORT:
return "short[]";
case TypeArrayKlass.T_INT:
return "int[]";
case TypeArrayKlass.T_LONG:
return "long[]";
default:
if (Assert.ASSERTS_ENABLED) {
Assert.that(false, "Unknown primitive array type");
}
return null;
}
}
public Object getFieldValue(int index, Array array) {
TypeArray typeArr = (TypeArray) array;
int type = (int) getTypeArrayKlass().getElementType();
switch (type) {
case TypeArrayKlass.T_BOOLEAN:
return typeArr.getBooleanAt(index);
case TypeArrayKlass.T_CHAR:
return new String(new char[] { typeArr.getCharAt(index) });
case TypeArrayKlass.T_FLOAT:
return typeArr.getFloatAt(index);
case TypeArrayKlass.T_DOUBLE:
return typeArr.getDoubleAt(index);
case TypeArrayKlass.T_BYTE:
return typeArr.getByteAt(index);
case TypeArrayKlass.T_SHORT:
return typeArr.getShortAt(index);
case TypeArrayKlass.T_INT:
return typeArr.getIntAt(index);
case TypeArrayKlass.T_LONG:
return typeArr.getLongAt(index);
default:
if (Assert.ASSERTS_ENABLED) {
Assert.that(false, "Unknown primitive array type");
}
return null;
}
}
}

View File

@ -1,227 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
public class JSJavaVM extends DefaultScriptObject {
private static final int FIELD_ADDRESS_SIZE = 0;
private static final int FIELD_BUILD_INFO = 1;
private static final int FIELD_CPU = 2;
private static final int FIELD_FLAGS = 3;
private static final int FIELD_HEAP = 4;
private static final int FIELD_OS = 5;
private static final int FIELD_SYS_PROPS = 6;
private static final int FIELD_THREADS = 7;
private static final int FIELD_TYPE = 8;
private static final int FIELD_VERSION = 9;
private static final int FIELD_CLASS_PATH = 10;
private static final int FIELD_BOOT_CLASS_PATH = 11;
private static final int FIELD_USER_DIR = 12;
private static final int FIELD_UNDEFINED = -1;
public JSJavaVM(JSJavaFactory factory) {
this.factory = factory;
this.vm = VM.getVM();
}
public Object get(String name) {
int fieldID = getFieldID(name);
switch (fieldID) {
case FIELD_ADDRESS_SIZE:
return getVMBit();
case FIELD_BUILD_INFO:
return vm.getVMInternalInfo();
case FIELD_CPU:
return vm.getCPU();
case FIELD_FLAGS:
return getFlags();
case FIELD_HEAP:
return getHeap();
case FIELD_OS:
return vm.getOS();
case FIELD_SYS_PROPS:
return getSysProps();
case FIELD_THREADS:
return getThreads();
case FIELD_TYPE:
return getType();
case FIELD_VERSION:
return vm.getVMRelease();
case FIELD_CLASS_PATH:
return getClassPath();
case FIELD_USER_DIR:
return getUserDir();
case FIELD_UNDEFINED:
default:
return super.get(name);
}
}
public Object[] getIds() {
Object[] superIds = super.getIds();
Object[] tmp = fields.keySet().toArray();
Object[] res = new Object[superIds.length + tmp.length];
System.arraycopy(tmp, 0, res, 0, tmp.length);
System.arraycopy(superIds, 0, res, tmp.length, superIds.length);
return res;
}
public boolean has(String name) {
if (getFieldID(name) != FIELD_UNDEFINED) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (getFieldID(name) == FIELD_UNDEFINED) {
super.put(name, value);
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Java Hotspot ");
buf.append(getType());
buf.append(' ');
buf.append(getVMBit());
buf.append(" bit VM (build ");
buf.append(vm.getVMRelease());
buf.append(")");
return buf.toString();
}
//-- Internals only below this point
private static Map<String, Integer> fields = new HashMap<>();
private static void addField(String name, int fieldId) {
fields.put(name, fieldId);
}
private static int getFieldID(String name) {
Integer res = (Integer) fields.get(name);
return (res != null)? res.intValue() : FIELD_UNDEFINED;
}
static {
addField("addressSize", FIELD_ADDRESS_SIZE);
addField("buildInfo", FIELD_BUILD_INFO);
addField("cpu", FIELD_CPU);
addField("flags", FIELD_FLAGS);
addField("heap", FIELD_HEAP);
addField("os", FIELD_OS);
addField("sysProps", FIELD_SYS_PROPS);
addField("threads", FIELD_THREADS);
addField("type", FIELD_TYPE);
addField("version", FIELD_VERSION);
addField("classPath", FIELD_CLASS_PATH);
addField("userDir", FIELD_USER_DIR);
}
private long getVMBit() {
// address size in bits
return vm.getAddressSize() * 8;
}
private synchronized JSMap getFlags() {
if (flagsCache == null) {
VM.Flag[] flags = vm.getCommandLineFlags();
Map<String, String> map = new HashMap<>();
if (flags != null) {
for (int f = 0; f < flags.length; f++) {
VM.Flag flag = flags[f];
map.put(flag.getName(), flag.getValue());
}
}
flagsCache = factory.newJSMap(map);
}
return flagsCache;
}
private synchronized JSJavaHeap getHeap() {
if (heapCache == null) {
heapCache = factory.newJSJavaHeap();
}
return heapCache;
}
private synchronized JSMap getSysProps() {
if (sysPropsCache == null) {
Properties props = vm.getSystemProperties();
Map<String, String> map = new HashMap<>();
if (props != null) {
Enumeration e = props.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
map.put(key, props.getProperty(key));
}
}
sysPropsCache = factory.newJSMap(map);
}
return sysPropsCache;
}
private synchronized JSList getThreads() {
if (threadsCache == null) {
List<JavaThread> threadsList = new ArrayList<>(0);
threadsCache = factory.newJSList(threadsList);
Threads threads = VM.getVM().getThreads();
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
JavaThread thread = threads.getJavaThreadAt(i);
threadsList.add(thread);
}
}
return threadsCache;
}
private String getType() {
if (vm.isClientCompiler()) {
return "Client";
} else if (vm.isServerCompiler()) {
return "Server";
} else {
return "Core";
}
}
private String getClassPath() {
return vm.getSystemProperty("java.class.path");
}
private String getUserDir() {
return vm.getSystemProperty("user.dir");
}
private JSMap flagsCache;
private JSJavaHeap heapCache;
private JSMap sysPropsCache;
private JSList threadsCache;
private final JSJavaFactory factory;
private final VM vm;
}

View File

@ -1,120 +0,0 @@
/*
* Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
/**
This is JavaScript wrapper for Java List.
*/
public class JSList extends DefaultScriptObject {
public JSList(List list, JSJavaFactory fac) {
this.list = list;
this.factory = fac;
}
public Object get(String name) {
if (name.equals("length")) {
return list.size();
} else {
return super.get(name);
}
}
public Object get(int index) {
if (isInRange(index)) {
Object item = list.get(index);
return wrapObject(item);
} else {
return super.get(index);
}
}
public Object[] getIds() {
Object[] superIds = super.getIds();
final int size = list.size();
Object[] res = new Object[superIds.length + size];
for (int i = 0; i < size; i++) {
res[i] = i;
}
System.arraycopy(superIds, 0, res, size, superIds.length);
return res;
}
public boolean has(String name) {
if (name.equals("length")) {
return true;
} else {
return super.has(name);
}
}
public boolean has(int index) {
if (isInRange(index)) {
return true;
} else {
return super.has(index);
}
}
public void put(String name, Object value) {
if (! name.equals("length")) {
super.put(name, value);
}
}
public void put(int index, Object value) {
if (! isInRange(index)) {
super.put(index, value);
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append('[');
for (Iterator itr = list.iterator(); itr.hasNext();) {
buf.append(wrapObject(itr.next()));
if (itr.hasNext()) {
buf.append(", ");
}
}
buf.append(']');
return buf.toString();
}
//-- Internals only below this point
private boolean isInRange(int index) {
return index >= 0 && index < list.size();
}
private Object wrapObject(Object obj) {
return factory.newJSJavaWrapper(obj);
}
private final List list;
private final JSJavaFactory factory;
}

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
/**
This is JavaScript wrapper for a Map.
*/
public class JSMap extends DefaultScriptObject {
public JSMap(Map map, JSJavaFactory fac) {
this.map = map;
this.factory = fac;
}
public Object get(String name) {
if (map.containsKey(name)) {
return wrapObject(map.get(name));
} else {
return super.get(name);
}
}
public Object[] getIds() {
Object[] superIds = super.getIds();
Object[] tmp = map.keySet().toArray();
Object[] res = new Object[superIds.length + tmp.length];
System.arraycopy(tmp, 0, res, 0, tmp.length);
System.arraycopy(superIds, 0, res, tmp.length, superIds.length);
return res;
}
public boolean has(String name) {
if (map.containsKey(name)) {
return true;
} else {
return super.has(name);
}
}
public void put(String name, Object value) {
if (! map.containsKey(name)) {
super.put(name, value);
}
}
public String toString() {
StringBuffer buf = new StringBuffer();
Set keys = map.keySet();
buf.append('{');
for (Iterator itr = keys.iterator(); itr.hasNext();) {
Object key = itr.next();
buf.append(key);
buf.append('=');
buf.append(wrapObject(map.get(key)));
if (itr.hasNext()) {
buf.append(", ");
}
}
buf.append('}');
return buf.toString();
}
private Object wrapObject(Object obj) {
return factory.newJSJavaWrapper(obj);
}
private final Map map;
private final JSJavaFactory factory;
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import sun.jvm.hotspot.oops.Metadata;
/** This is JavaScript wrapper for a metadata object in debuggee.*/
public abstract class JSMetadata extends DefaultScriptObject {
public JSMetadata(Metadata metadata, JSJavaFactory factory) {
this.metadata = metadata;
this.factory = factory;
}
public final Metadata getMetadata() {
return metadata;
}
public boolean equals(Object o) {
if (o == null || !(o instanceof JSMetadata)) {
return false;
}
JSMetadata other = (JSMetadata) o;
return metadata.equals(other.metadata);
}
public int hashCode() {
return metadata.hashCode();
}
public String toString() {
return "Metadata " + metadata.getAddress().toString();
}
private final Metadata metadata;
protected final JSJavaFactory factory;
}

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import javax.script.Invocable;
/**
* Simple implementation of ScriptObject interface
* with property storage backed by a Map. This class
* can be extended to override any of the methods, in
* particular to add "function" valued properties.
*/
public class MapScriptObject implements ScriptObject {
// map to store the properties
private Map<Object, Object> map;
public MapScriptObject() {
this(new HashMap<>());
}
public MapScriptObject(Map<Object, Object> map) {
// make it synchronized
this.map = Collections.synchronizedMap(map);
}
public Object[] getIds() {
return map.keySet().toArray();
}
public Object get(String name) {
if (has(name)) {
return map.get(name);
} else {
return UNDEFINED;
}
}
public Object get(int index) {
if (has(index)) {
Object key = Integer.valueOf(index);
return map.get(key);
} else {
return UNDEFINED;
}
}
public void put(String name, Object value) {
map.put(name, value);
}
public void put(int index, Object value) {
map.put(Integer.valueOf(index), value);
}
public boolean has(String name) {
return map.containsKey(name);
}
public boolean has(int index) {
return map.containsKey(Integer.valueOf(index));
}
public boolean delete(String name) {
if (map.containsKey(name)) {
map.remove(name);
return true;
} else {
return false;
}
}
public boolean delete(int index) {
Object key = Integer.valueOf(index);
if (map.containsKey(key)) {
map.remove(key);
return true;
} else {
return false;
}
}
// add a function valued property that invokes given Method
protected void putFunction(Object target, Method method) {
putFunction(target, method, true);
}
// add a function valued property that invokes given Method
protected void putFunction(Object target, Method method, boolean wrapArgs) {
map.put(method.getName(), new MethodCallable(target, method, wrapArgs));
}
// add a function valued property that invokes given script function
protected void putFunction(Object target, String name, Invocable invocable) {
map.put(name, new InvocableCallable(target, name, invocable));
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
import java.lang.reflect.Method;
import javax.script.ScriptException;
/**
* An implementation of Callable interface that
* invokes an instance or static Java method when
* called.
*/
public class MethodCallable implements Callable {
private Object target;
private Method method;
private boolean wrapArgs;
// "wrapArgs" tells whether the underlying java Method
// accepts one Object[] argument or it wants usual way of
// passing arguments. The former method is used when you
// want to implement a Callable that is variadic.
public MethodCallable(Object target, Method method, boolean wrapArgs) {
this.method = method;
this.target = target;
this.wrapArgs = wrapArgs;
}
public MethodCallable(Object target, Method method) {
this(target, method, true);
}
public Object call(Object[] args) throws ScriptException {
try {
if (wrapArgs) {
return method.invoke(target, new Object[] { args });
} else {
return method.invoke(target, args);
}
} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new ScriptException(exp);
}
}
}

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
/**
This visitor is supplied to SOQLEngine.executeQuery
to receive result set objects one by one.
*/
public interface ObjectVisitor {
public void visit(Object o);
}

View File

@ -1,265 +0,0 @@
/*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
/**
* This is SOQL (Simple Object Query Language) engine. This
* uses JavaScript engine for the "select" and "where" expression
* parts.
*/
public class SOQLEngine extends JSJavaScriptEngine {
public static synchronized SOQLEngine getEngine() {
if (soleInstance == null) {
soleInstance = new SOQLEngine();
}
return soleInstance;
}
/**
Query is of the form
select &lt;java script code to select&gt;
[ from [instanceof] &lt;class name&gt; [&lt;identifier&gt;]
[ where &lt;java script boolean expression&gt; ]
]
*/
public synchronized void executeQuery(String query, ObjectVisitor visitor)
throws SOQLException {
debugPrint("query : " + query);
StringTokenizer st = new StringTokenizer(query);
if (st.hasMoreTokens()) {
String first = st.nextToken();
if (! first.equals("select") ) {
throw new SOQLException("query syntax error: no 'select' clause");
}
} else {
throw new SOQLException("query syntax error: no 'select' clause");
}
int selectStart = query.indexOf("select");
int fromStart = query.indexOf("from");
String selectExpr = null;
String className = null;
boolean isInstanceOf = false;
String whereExpr = null;
String identifier = null;
if (fromStart != -1) {
selectExpr = query.substring(selectStart + "select".length(), fromStart);
st = new StringTokenizer(query.substring(fromStart + "from".length()));
if (st.hasMoreTokens()) {
String tmp = st.nextToken();
if (tmp.equals("instanceof")) {
isInstanceOf = true;
if (! st.hasMoreTokens()) {
throw new SOQLException("no class name after 'instanceof'");
}
className = st.nextToken();
} else {
className = tmp;
}
} else {
throw new SOQLException("query syntax error: class name must follow 'from'");
}
if (st.hasMoreTokens()) {
identifier = st.nextToken();
if (identifier.equals("where")) {
throw new SOQLException("query syntax error: identifier should follow class name");
}
if (st.hasMoreTokens()) {
String tmp = st.nextToken();
if (! tmp.equals("where")) {
throw new SOQLException("query syntax error: 'where' clause expected after 'from' clause");
}
int whereEnd = query.lastIndexOf("where") + 5; // "where".length
whereExpr = query.substring(whereEnd);
}
} else {
throw new SOQLException("query syntax error: identifier should follow class name");
}
} else { // no from clause
selectExpr = query.substring(selectStart + "select".length(), query.length());
}
executeQuery(new SOQLQuery(selectExpr, isInstanceOf, className, identifier, whereExpr), visitor);
}
private void executeQuery(SOQLQuery q, ObjectVisitor visitor) throws SOQLException {
InstanceKlass kls = null;
if (q.className != null) {
kls = SystemDictionaryHelper.findInstanceKlass(q.className);
if (kls == null) {
throw new SOQLException(q.className + " is not found!");
}
}
StringBuffer buf = new StringBuffer();
buf.append("function result(");
if (q.identifier != null) {
buf.append(q.identifier);
}
buf.append(") { return ");
buf.append(q.selectExpr.replace('\n', ' '));
buf.append("; }");
String selectCode = buf.toString();
debugPrint(selectCode);
String whereCode = null;
if (q.whereExpr != null) {
buf = new StringBuffer();
buf.append("function filter(");
buf.append(q.identifier);
buf.append(") { return ");
buf.append(q.whereExpr.replace('\n', ' '));
buf.append("; }");
whereCode = buf.toString();
debugPrint(whereCode);
} else {
whereCode = "filter = null;";
}
beginQuery();
// compile select expression and where condition
evalString(selectCode, "", 1);
evalString(whereCode, "", 1);
// iterate thru heap, if needed
if (q.className != null) {
try {
iterateOops(kls, visitor, q.isInstanceOf);
} finally {
endQuery();
}
} else {
// simple "select <expr>" query
try {
Object select = call("result", new Object[] {});
visitor.visit(select);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void dispatchObject(Oop oop, ObjectVisitor visitor, boolean filterExists) {
JSJavaObject jsObj = factory.newJSJavaObject(oop);
Object[] args = new Object[] { jsObj };
boolean b = true;
try {
if (filterExists) {
Object res = call("filter", args);
if (res instanceof Boolean) {
b = ((Boolean)res).booleanValue();
} else if (res instanceof Number) {
b = ((Number)res).intValue() != 0;
} else {
b = (res != null);
}
}
if (b) {
Object select = call("result", args);
visitor.visit(select);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void iterateOops(final InstanceKlass ik, final ObjectVisitor visitor,
boolean includeSubtypes) {
ObjectHeap oh = VM.getVM().getObjectHeap();
oh.iterateObjectsOfKlass(new HeapVisitor() {
boolean filterExists;
public void prologue(long usedSize) {
filterExists = getScriptEngine().get("filter") != null;
}
public boolean doObj(Oop obj) {
dispatchObject(obj, visitor, filterExists);
return false;
}
public void epilogue() {}
}, ik, includeSubtypes);
}
// we create fresh ObjectReader and factory to avoid
// excessive cache across queries.
private void beginQuery() {
objReader = new ObjectReader();
factory = new JSJavaFactoryImpl();
}
// at the end of query we clear object reader cache
// and factory cache
private void endQuery() {
objReader = null;
factory = null;
}
protected ObjectReader getObjectReader() {
return objReader;
}
protected JSJavaFactory getJSJavaFactory() {
return factory;
}
protected boolean isQuitting() {
return false;
}
protected void quit() {
// do nothing
}
private static void debugPrint(String msg) {
if (debug) System.out.println(msg);
}
private static final boolean debug;
static {
debug = System.getProperty("sun.jvm.hotspot.utilities.soql.SOQLEngine.debug") != null;
}
protected SOQLEngine() {
super(debug);
start();
}
private ObjectReader objReader;
private JSJavaFactory factory;
private static SOQLEngine soleInstance;
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
public class SOQLException extends Exception {
public SOQLException(String msg) {
super(msg);
}
public SOQLException(String msg, Throwable cause) {
super(msg, cause);
}
public SOQLException(Throwable cause) {
super(cause);
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.utilities.soql;
class SOQLQuery {
SOQLQuery(String selectExpr, boolean isInstanceOf,
String className, String identifier, String whereExpr) {
this.selectExpr = selectExpr;
this.isInstanceOf = isInstanceOf;
this.className = className;
this.identifier = identifier;
this.whereExpr = whereExpr;
}
String selectExpr;
boolean isInstanceOf;
String className;
String identifier;
String whereExpr;
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvm.hotspot.utilities.soql;
/**
* Any Java object supporting this interface can be
* accessed from scripts with "simpler" access pattern.
* For example, a script engine may support natural
* property/field access syntax for the properties exposed
* via this interface. We use this interface so that we
* can dynamically add/delete/modify fields exposed to
* scripts. If we stick to JavaBean pattern, then property
* set is fixed.
*/
public interface ScriptObject {
// special sentinel to denote no-result -- so that
// null could be used as proper value
public static final Object UNDEFINED = new Object();
// empty object array
public static final Object[] EMPTY_ARRAY = new Object[0];
/*
* Returns all property names supported by this object.
* Property "name" is either a String or an Integer".
*/
public Object[] getIds();
/**
* Get the value of the named property.
*/
public Object get(String name);
/**
* Get the value of the "indexed" property.
* Returns UNDEFINED if the property does not exist.
*/
public Object get(int index);
/**
* Set the value of the named property.
*/
public void put(String name, Object value);
/**
* Set the value of the indexed property.
*/
public void put(int index, Object value);
/**
* Returns whether the named property exists or not.
*/
public boolean has(String name);
/**
* Returns whether the indexed property exists or not.
*/
public boolean has(int index);
/**
* Deletes the named property. Returns true on success.
*/
public boolean delete(String name);
/**
* Deletes the indexed property. Returns true on success.
*/
public boolean delete(int index);
}

View File

@ -1,910 +0,0 @@
/*
* Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// shorter names for SA packages
// SA package name abbreviations are kept in 'sapkg' object
// to avoid global namespace pollution
var sapkg = new Object();
sapkg.hotspot = Packages.sun.jvm.hotspot;
sapkg.asm = sapkg.hotspot.asm;
sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;
// 'debugger' is a JavaScript keyword, but ES5 relaxes the
// restriction of using keywords as property name
sapkg.debugger = sapkg.hotspot.debugger;
sapkg.interpreter = sapkg.hotspot.interpreter;
sapkg.jdi = sapkg.hotspot.jdi;
sapkg.memory = sapkg.hotspot.memory;
sapkg.oops = sapkg.hotspot.oops;
sapkg.runtime = sapkg.hotspot.runtime;
sapkg.tools = sapkg.hotspot.tools;
sapkg.types = sapkg.hotspot.types;
sapkg.ui = sapkg.hotspot.ui;
sapkg.utilities = sapkg.hotspot.utilities;
// SA singletons are kept in 'sa' object
var sa = new Object();
sa.vm = sapkg.runtime.VM.getVM();
sa.dbg = sa.vm.getDebugger();
sa.cdbg = sa.dbg.CDebugger;
sa.heap = sa.vm.universe.heap();
sa.systemDictionary = sa.vm.systemDictionary;
sa.sysDict = sa.systemDictionary;
sa.symbolTable = sa.vm.symbolTable;
sa.symTbl = sa.symbolTable;
sa.threads = sa.vm.threads;
sa.interpreter = sa.vm.interpreter;
sa.typedb = sa.vm.typeDataBase;
sa.codeCache = sa.vm.codeCache;
// 'objHeap' is different from 'heap'!.
// This is SA's Oop factory and heap-walker
sa.objHeap = sa.vm.objectHeap;
// few useful global variables
var OS = sa.vm.OS;
var CPU = sa.vm.CPU;
var LP64 = sa.vm.LP64;
var isClient = sa.vm.clientCompiler;
var isServer = sa.vm.serverCompiler;
var isCore = sa.vm.isCore();
var addressSize = sa.vm.addressSize;
var oopSize = sa.vm.oopSize;
// this "main" function is called immediately
// after loading this script file
function main(globals, jvmarg) {
// wrap a sun.jvm.hotspot.utilities.soql.ScriptObject
// object so that the properties of it can be accessed
// in natural object.field syntax.
function wrapScriptObject(so) {
function unwrapScriptObject(wso) {
var objType = typeof(wso);
if ((objType == 'object' ||
objType == 'function')
&& "__wrapped__" in wso) {
return wso.__wrapped__;
} else {
return wso;
}
}
function prepareArgsArray(array) {
var args = new Array(array.length);
for (var a = 0; a < array.length; a++) {
var elem = array[a];
elem = unwrapScriptObject(elem);
if (typeof(elem) == 'function') {
args[a] = new sapkg.utilities.soql.Callable() {
call: function(myargs) {
var tmp = new Array(myargs.length);
for (var i = 0; i < myargs.length; i++) {
tmp[i] = wrapScriptObject(myargs[i]);
}
return elem.apply(this, tmp);
}
}
} else {
args[a] = elem;
}
}
return args;
}
// Handle __has__ specially to avoid metacircularity problems
// when called from __get__.
// Calling
// this.__has__(name)
// will in turn call
// this.__call__('__has__', name)
// which is not handled below
function __has__(name) {
if (typeof(name) == 'number') {
return so["has(int)"](name);
} else {
if (name == '__wrapped__') {
return true;
} else if (so["has(java.lang.String)"](name)) {
return true;
} else if (name.equals('toString')) {
return true;
} else {
return false;
}
}
}
if (so instanceof sapkg.utilities.soql.ScriptObject) {
return new JSAdapter() {
__getIds__: function() {
return so.getIds();
},
__has__ : __has__,
__delete__ : function(name) {
if (typeof(name) == 'number') {
return so["delete(int)"](name);
} else {
return so["delete(java.lang.String)"](name);
}
},
__get__ : function(name) {
// don't call this.__has__(name); see comments above function __has__
if (! __has__.call(this, name)) {
return undefined;
}
if (typeof(name) == 'number') {
return wrapScriptObject(so["get(int)"](name));
} else {
if (name == '__wrapped__') {
return so;
} else {
var value = so["get(java.lang.String)"](name);
if (value instanceof sapkg.utilities.soql.Callable) {
return function() {
var args = prepareArgsArray(arguments);
var r;
try {
r = value.call(Java.to(args, 'java.lang.Object[]'));
} catch (e) {
println("call to " + name + " failed!");
throw e;
}
return wrapScriptObject(r);
}
} else if (name == 'toString') {
return function() {
return so.toString();
}
} else {
return wrapScriptObject(value);
}
}
}
}
};
} else {
return so;
}
}
// set "jvm" global variable that wraps a
// sun.jvm.hotspot.utilities.soql.JSJavaVM instance
if (jvmarg != null) {
jvm = wrapScriptObject(jvmarg);
// expose "heap" global variable
heap = jvm.heap;
}
// expose all "function" type properties of
// sun.jvm.hotspot.utilitites.soql.JSJavaScriptEngine
// as global functions here.
globals = wrapScriptObject(globals);
for (var prop in globals) {
if (typeof(globals[prop]) == 'function') {
this[prop] = globals[prop];
}
}
// define "writeln" and "write" if not defined
if (typeof(println) == 'undefined') {
println = function (str) {
java.lang.System.out.println(String(str));
}
}
if (typeof(print) == 'undefined') {
print = function (str) {
java.lang.System.out.print(String(str));
}
}
if (typeof(writeln) == 'undefined') {
writeln = println;
}
if (typeof(write) == 'undefined') {
write = print;
}
// "registerCommand" function is defined if we
// are running as part of "CLHSDB" tool. CLHSDB
// tool exposes Unix-style commands.
// if "registerCommand" function is defined
// then register few global functions as "commands".
if (typeof(registerCommand) == 'function') {
this.jclass = function(name) {
if (typeof(name) == "string") {
var clazz = sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
if (clazz) {
writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString());
} else {
writeln("class not found: " + name);
}
} else {
writeln("Usage: class name");
}
}
registerCommand("class", "class name", "jclass");
this.jclasses = function() {
forEachKlass(function (clazz) {
writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString());
});
}
registerCommand("classes", "classes", "jclasses");
this.dclass = function(clazz, dir) {
if (!clazz) {
writeln("Usage: dumpclass { address | name } [ directory ]");
} else {
if (!dir) { dir = "."; }
dumpClass(clazz, dir);
}
}
registerCommand("dumpclass", "dumpclass { address | name } [ directory ]", "dclass");
registerCommand("dumpheap", "dumpheap [ file ]", "dumpHeap");
this.jseval = function(str) {
if (!str) {
writeln("Usage: jseval script");
} else {
var res = eval(str);
if (res) { writeln(res); }
}
}
registerCommand("jseval", "jseval script", "jseval");
this.jsload = function(file) {
if (!file) {
writeln("Usage: jsload file");
} else {
load(file);
}
}
registerCommand("jsload", "jsload file", "jsload");
this.printMem = function(addr, len) {
if (!addr) {
writeln("Usage: mem [ length ]");
} else {
mem(addr, len);
}
}
registerCommand("mem", "mem address [ length ]", "printMem");
this.sysProps = function() {
for (var i in jvm.sysProps) {
writeln(i + ' = ' + jvm.sysProps[i]);
}
}
registerCommand("sysprops", "sysprops", "sysProps");
this.printWhatis = function(addr) {
if (!addr) {
writeln("Usage: whatis address");
} else {
writeln(whatis(addr));
}
}
registerCommand("whatis", "whatis address", "printWhatis");
}
}
// debugger functionality
// string-to-Address
function str2addr(str) {
return sa.dbg.parseAddress(str);
}
// number-to-Address
if (addressSize == 4) {
eval("function num2addr(num) { \
return str2addr('0x' + java.lang.Integer.toHexString(0xffffffff & num)); \
}");
} else {
eval("function num2addr(num) { \
return str2addr('0x' + java.lang.Long.toHexString(num)); \
}");
}
// generic any-type-to-Address
// use this convenience function to accept address in any
// format -- number, string or an Address instance.
function any2addr(addr) {
var type = typeof(addr);
if (type == 'number') {
return num2addr(addr);
} else if (type == 'string') {
return str2addr(addr);
} else {
return addr;
}
}
// Address-to-string
function addr2str(addr) {
if (addr == null) {
return (addressSize == 4)? '0x00000000' : '0x0000000000000000';
} else {
return addr + '';
}
}
// Address-to-number
function addr2num(addr) {
return sa.dbg.getAddressValue(addr);
}
// symbol-to-Address
function sym2addr(dso, sym) {
return sa.dbg.lookup(dso, sym);
}
function loadObjectContainingPC(addr) {
if (sa.cdbg == null) {
// no CDebugger support, return null
return null;
}
return sa.cdbg.loadObjectContainingPC(addr);
}
// returns the ClosestSymbol or null
function closestSymbolFor(addr) {
var dso = loadObjectContainingPC(addr);
if (dso != null) {
return dso.closestSymbolToPC(addr);
}
return null;
}
// Address-to-symbol
// returns nearest symbol as string if found
// else returns address as string
function addr2sym(addr) {
var sym = closestSymbolFor(addr);
if (sym != null) {
return sym.name + '+' + sym.offset;
} else {
return addr2str(addr);
}
}
// read 'num' words at 'addr' and return an array as result.
// returns Java long[] type result and not a JavaScript array.
function readWordsAt(addr, num) {
addr = any2addr(addr);
var res = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, num);
var i;
for (i = 0; i < num; i++) {
res[i] = addr2num(addr.getAddressAt(i * addressSize));
}
return res;
}
// read the 'C' string at 'addr'
function readCStrAt(addr) {
addr = any2addr(addr);
return sapkg.utilities.CStringUtilities.getString(addr);
}
// read the length of the 'C' string at 'addr'
function readCStrLen(addr) {
addr = any2addr(addr);
return sapkg.utilities.CStringUtilities.getStringLength(addr);
}
// iterate through ThreadList of CDebugger
function forEachThread(callback) {
if (sa.cdbg == null) {
// no CDebugger support
return;
} else {
var itr = sa.cdbg.threadList.iterator();
while (itr.hasNext()) {
if (callback(itr.next()) == false) return;
}
}
}
// read register set of a ThreadProxy as name-value pairs
function readRegs(threadProxy) {
var ctx = threadProxy.context;
var num = ctx.numRegisters;
var res = new Object();
var i;
for (i = 0; i < num; i++) {
res[ctx.getRegisterName(i)]= addr2str(ctx.getRegisterAsAddress(i));
}
return res;
}
// print register set for a given ThreaProxy
function regs(threadProxy) {
var res = readRegs(threadProxy);
for (i in res) {
writeln(i, '=', res[i]);
}
}
// iterate through each CFrame of a given ThreadProxy
function forEachCFrame(threadProxy, callback) {
if (sa.cdbg == null) {
// no CDebugger support
return;
} else {
var cframe = sa.cdbg.topFrameForThread(threadProxy);
while (cframe != null) {
if (callback(cframe) == false) return;
cframe = cframe.sender();
}
}
}
// iterate through list of load objects (DLLs, DSOs)
function forEachLoadObject(callback) {
if (sa.cdbg == null) {
// no CDebugger support
return;
} else {
var itr = sa.cdbg.loadObjectList.iterator();
while (itr.hasNext()) {
if (callback(itr.next()) == false) return;
}
}
}
// print 'num' words at 'addr'
function mem(addr, num) {
if (num == undefined) {
num = 1;
}
addr = any2addr(addr);
var i;
for (i = 0; i < num; i++) {
var value = addr.getAddressAt(0);
writeln(addr2sym(addr) + ':', addr2str(value));
addr = addr.addOffsetTo(addressSize);
}
writeln();
}
// System dictionary functions
// find InstanceKlass by name
function findInstanceKlass(name) {
return sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
}
// get Java system loader (i.e., application launcher loader)
function systemLoader() {
return sa.sysDict.javaSystemLoader();
}
// iterate class loader data for each 'Klass'
function forEachKlass(callback) {
var VisitorClass = sapkg.classfile.ClassLoaderDataGraph.ClassVisitor;
var visitor = new VisitorClass() { visit: callback };
sa.sysDict["classesDo(sun.jvm.hotspot.classfile.ClassLoaderDataGraph.ClassVisitor)"](visitor);
}
// iterate system dictionary for each 'Klass' and initiating loader
function forEachKlassAndLoader(callback) {
var VisitorClass = sapkg.classfile.ClassLoaderDataGraph.ClassAndLoaderVisitor;
var visitor = new VisitorClass() { visit: callback };
sa.sysDict["allEntriesDo(sun.jvm.hotspot.classfile.ClassLoaderDataGraph.ClassAndLoaderVisitor)"](visitor);
}
// 'oop' to higher-level java object wrapper in which for(i in o)
// works by iterating java level fields and javaobject.javafield
// syntax works.
function oop2obj(oop) {
return object(addr2str(oop.handle));
}
// higher level java object wrapper to oop
function obj2oop(obj) {
return addr2oop(str2addr(address(obj)));
}
// Java heap iteration
// iterates Java heap for each Oop
function forEachOop(callback) {
function empty() { }
sa.objHeap.iterate(new sapkg.oops.HeapVisitor() {
prologue: empty,
doObj: callback,
epilogue: empty
});
}
// iterates Java heap for each Oop of given 'klass'.
// 'includeSubtypes' tells whether to include objects
// of subtypes of 'klass' or not
function forEachOopOfKlass(callback, klass, includeSubtypes) {
if (klass == undefined) {
klass = findInstanceKlass("java.lang.Object");
}
if (includeSubtypes == undefined) {
includeSubtypes = true;
}
function empty() { }
sa.objHeap.iterateObjectsOfKlass(
new sapkg.oops.HeapVisitor() {
prologue: empty,
doObj: callback,
epilogue: empty
},
klass, includeSubtypes);
}
// Java thread
// iterates each Thread
function forEachJavaThread(callback) {
var threads = sa.threads;
var thread = threads.first();
while (thread != null) {
if (callback(thread) == false) return;
thread = thread.next();
}
}
// iterate Frames of a given thread
function forEachFrame(javaThread, callback) {
var fr = javaThread.getLastFrameDbg();
while (fr != null) {
if (callback(fr) == false) return;
fr = fr.sender();
}
}
// iterate JavaVFrames of a given JavaThread
function forEachVFrame(javaThread, callback) {
var vfr = javaThread.getLastJavaVFrameDbg();
while (vfr != null) {
if (callback(vfr) == false) return;
vfr = vfr.javaSender();
}
}
function printStackTrace(javaThread) {
write("Thread ");
javaThread.printThreadIDOn(java.lang.System.out);
writeln();
forEachVFrame(javaThread, function (vf) {
var method = vf.method;
write(' - ', method.externalNameAndSignature(), '@bci =', vf.getBCI());
var line = method.getLineNumberFromBCI(vf.getBCI());
if (line != -1) { write(', line=', line); }
if (vf.isCompiledFrame()) { write(" (Compiled Frame)"); }
if (vf.isInterpretedFrame()) { write(" (Interpreted Frame)"); }
writeln();
});
writeln();
writeln();
}
// print Java stack trace for all threads
function where(javaThread) {
if (javaThread == undefined) {
forEachJavaThread(function (jt) { printStackTrace(jt); });
} else {
printStackTrace(javaThread);
}
}
// vmStructs access -- type database functions
// find a VM type
function findVMType(typeName) {
return sa.typedb.lookupType(typeName);
}
// iterate VM types
function forEachVMType(callback) {
var itr = sa.typedb.types;
while (itr.hasNext()) {
if (callback(itr.next()) == false) return;
}
}
// find VM int constant
function findVMIntConst(name) {
return sa.typedb.lookupIntConstant(name);
}
// find VM long constant
function findVMLongConst(name) {
return sa.typedb.lookupLongConstant(name);
}
// iterate VM int constants
function forEachVMIntConst(callback) {
var itr = sa.typedb.intConstants;
while (itr.hasNext()) {
if (callback(itr.next()) == false) return;
}
}
// iterate VM long constants
function forEachVMLongConst(callback) {
var itr = sa.typedb.longConstants;
while (itr.hasNext()) {
if (callback(itr.next()) == false) return;
}
}
// returns VM Type at address
function vmTypeof(addr) {
addr = any2addr(addr);
return sa.typedb.guessTypeForAddress(addr);
}
// does the given 'addr' points to an object of given 'type'?
// OR any valid Type at all (if type is undefined)
function isOfVMType(addr, type) {
addr = any2addr(addr);
if (type == undefined) {
return vmTypeof(addr) != null;
} else {
if (typeof(type) == 'string') {
type = findVMType(type);
}
return sa.typedb.addressTypeIsEqualToType(addr, type);
}
}
// reads static field value
function readVMStaticField(field) {
var type = field.type;
if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
return field.value;
} else if (type.isPointerType()) {
return field.address;
} else if (type.isOopType()) {
return field.oopHandle;
} else {
return field.staticFieldAddress;
}
}
// reads given instance field of VM object at 'addr'
function readVMInstanceField(field, addr) {
var type = field.type;
if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
return field.getValue(addr);
} else if (type.isPointerType()) {
return field.getAddress(addr);
} else if (type.isOopType()) {
return field.getOopHandle(addr);
} else {
return addr.addOffsetTo(field.offset);
}
}
// returns name-value of pairs of VM type at given address.
// If address is unspecified, reads static fields as name-value pairs.
function readVMType(type, addr) {
if (typeof(type) == 'string') {
type = findVMType(type);
}
if (addr != undefined) {
addr = any2addr(addr);
}
var result = new Object();
var staticOnly = (addr == undefined);
while (type != null) {
var itr = type.fields;
while (itr.hasNext()) {
var field = itr.next();
var isStatic = field.isStatic();
if (staticOnly && isStatic) {
result[field.name] = readVMStaticField(field);
} else if (!staticOnly && !isStatic) {
result[field.name] = readVMInstanceField(field, addr);
}
}
type = type.superclass;
}
return result;
}
function printVMType(type, addr) {
if (typeof(type) == 'string') {
type = findVMType(type);
}
var obj = readVMType(type, addr);
while (type != null) {
var itr = type.fields;
while (itr.hasNext()) {
var field = itr.next();
var name = field.name;
var value = obj[name];
if (value != undefined) {
writeln(field.type.name, type.name + '::' + name, '=', value);
}
}
type = type.superclass;
}
}
// define readXXX and printXXX functions for each VM struct/class Type
tmp = new Object();
tmp.itr = sa.typedb.types;
while (tmp.itr.hasNext()) {
tmp.type = tmp.itr.next();
tmp.name = tmp.type.name;
if (tmp.type.isPointerType() || tmp.type.isOopType() ||
tmp.type.isCIntegerType() || tmp.type.isJavaPrimitiveType() ||
tmp.name.equals('address') ||
tmp.name.equals("<opaque>")) {
// ignore;
continue;
} else {
// some type names have ':', '<', '>', '*', ' '. replace to make it as a
// JavaScript identifier
tmp.name = ("" + tmp.name).replace(/[:<>* ]/g, '_');
eval("function read" + tmp.name + "(addr) {" +
" return readVMType('" + tmp.name + "', addr);}");
eval("function print" + tmp.name + "(addr) {" +
" printVMType('" + tmp.name + "', addr); }");
/* FIXME: do we need this?
if (typeof(registerCommand) != 'undefined') {
var name = "print" + tmp.name;
registerCommand(name, name + " [address]", name);
}
*/
}
}
//clean-up the temporary
delete tmp;
// VMObject factory
// VM type to SA class map
var vmType2Class = new Object();
// C2 only classes
try{
vmType2Class["ExceptionBlob"] = sapkg.code.ExceptionBlob;
vmType2Class["UncommonTrapBlob"] = sapkg.code.UncommonTrapBlob;
} catch(e) {
// Ignore exception. C2 specific objects might be not
// available in client VM
}
// This is *not* exhaustive. Add more if needed.
// code blobs
vmType2Class["BufferBlob"] = sapkg.code.BufferBlob;
vmType2Class["nmethod"] = sapkg.code.NMethod;
vmType2Class["RuntimeStub"] = sapkg.code.RuntimeStub;
vmType2Class["SafepointBlob"] = sapkg.code.SafepointBlob;
vmType2Class["C2IAdapter"] = sapkg.code.C2IAdapter;
vmType2Class["DeoptimizationBlob"] = sapkg.code.DeoptimizationBlob;
vmType2Class["I2CAdapter"] = sapkg.code.I2CAdapter;
vmType2Class["OSRAdapter"] = sapkg.code.OSRAdapter;
vmType2Class["PCDesc"] = sapkg.code.PCDesc;
// interpreter
vmType2Class["InterpreterCodelet"] = sapkg.interpreter.InterpreterCodelet;
// Java Threads
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
// gc
vmType2Class["GenCollectedHeap"] = sapkg.memory.GenCollectedHeap;
vmType2Class["DefNewGeneration"] = sapkg.memory.DefNewGeneration;
vmType2Class["TenuredGeneration"] = sapkg.memory.TenuredGeneration;
// generic VMObject factory for a given address
// This is equivalent to VirtualConstructor.
function newVMObject(addr) {
addr = any2addr(addr);
var result = null;
forEachVMType(function (type) {
if (isOfVMType(addr, type)) {
var clazz = vmType2Class[type.name];
if (clazz != undefined) {
result = new clazz(addr);
}
return false;
} else {
return true;
}
});
return result;
}
function vmobj2addr(vmobj) {
return vmobj.address;
}
function addr2vmobj(addr) {
return newVMObject(addr);
}
// Miscellaneous utilities
// returns PointerLocation that describes the given pointer
function findPtr(addr) {
addr = any2addr(addr);
return sapkg.utilities.PointerFinder.find(addr);
}
// is given address a valid Oop?
function isOop(addr) {
addr = any2addr(addr);
var oopHandle = addr.addOffsetToAsOopHandle(0);
return sapkg.utilities.RobustOopDeterminator.oopLooksValid(oopHandle);
}
// returns description of given pointer as a String
function whatis(addr) {
addr = any2addr(addr);
var ptrLoc = findPtr(addr);
if (!ptrLoc.isUnknown()) {
return ptrLoc.toString();
}
var vmType = vmTypeof(addr);
if (vmType != null) {
return "pointer to " + vmType.name;
}
var dso = loadObjectContainingPC(addr);
if (dso == null) {
return ptrLoc.toString();
}
var sym = dso.closestSymbolToPC(addr);
if (sym != null) {
return sym.name + '+' + sym.offset;
}
var s = dso.getName();
var p = s.lastIndexOf("/");
var base = dso.getBase();
return s.substring(p+1, s.length) + '+' + addr.minus(base);
}