8244668: Remove SA's javascript support
Reviewed-by: sspitsyn, sundar
This commit is contained in:
parent
de34e258ef
commit
e0d03881d0
@ -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
|
||||
|
||||
################################################################################
|
||||
|
||||
|
@ -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
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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!");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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 <java script code to select>
|
||||
[ from [instanceof] <class name> [<identifier>]
|
||||
[ where <java script boolean expression> ]
|
||||
]
|
||||
*/
|
||||
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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user