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 \
|
jdk.hotspot.agent_DISABLED_WARNINGS += rawtypes serial cast static overrides \
|
||||||
fallthrough
|
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>
|
</td>
|
||||||
</tr>
|
</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>
|
<td>
|
||||||
start-debug-server-proc.sh,
|
start-debug-server-proc.sh,
|
||||||
start-debug-server-proc64.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.ReversePtrsAnalysis;
|
||||||
import sun.jvm.hotspot.utilities.RobustOopDeterminator;
|
import sun.jvm.hotspot.utilities.RobustOopDeterminator;
|
||||||
import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
|
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 {
|
public class CommandProcessor {
|
||||||
|
|
||||||
@ -1846,7 +1843,6 @@ public class CommandProcessor {
|
|||||||
|
|
||||||
private DebuggerInterface debugger;
|
private DebuggerInterface debugger;
|
||||||
private HotSpotAgent agent;
|
private HotSpotAgent agent;
|
||||||
private JSJavaScriptEngine jsengine;
|
|
||||||
private BufferedReader in;
|
private BufferedReader in;
|
||||||
private PrintStream out;
|
private PrintStream out;
|
||||||
private PrintStream err;
|
private PrintStream err;
|
||||||
@ -1858,65 +1854,7 @@ public class CommandProcessor {
|
|||||||
|
|
||||||
// called after debuggee attach
|
// called after debuggee attach
|
||||||
private void postAttach() {
|
private void postAttach() {
|
||||||
/*
|
// nothing for now..
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutput(PrintStream o) {
|
public void setOutput(PrintStream o) {
|
||||||
|
@ -276,15 +276,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
|||||||
item.setMnemonic(KeyEvent.VK_D);
|
item.setMnemonic(KeyEvent.VK_D);
|
||||||
toolsMenu.add(item);
|
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",
|
item = createMenuItem("Find Pointer",
|
||||||
new ActionListener() {
|
new ActionListener() {
|
||||||
@ -1531,10 +1522,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
|||||||
showPanel("Command Line", new CommandProcessorPanel(new CommandProcessor(di, null, null, null)));
|
showPanel("Command Line", new CommandProcessorPanel(new CommandProcessor(di, null, null, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showFindByQueryPanel() {
|
|
||||||
showPanel("Find Object by Query", new FindByQueryPanel());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showFindPanel() {
|
private void showFindPanel() {
|
||||||
showPanel("Find Pointer", new FindPanel());
|
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