--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2019-12-19 16:53:37.508940400 +0900
+++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/CommandProcessor.java 2019-12-19 16:53:37.252190100 +0900
@@ -24,6 +24,9 @@
package sun.jvm.hotspot;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.nio.file.Path;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
@@ -34,14 +37,20 @@
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.Set;
import java.util.Stack;
+import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import sun.jvm.hotspot.api.Command;
+import sun.jvm.hotspot.api.Tokens;
import sun.jvm.hotspot.ci.ciEnv;
import sun.jvm.hotspot.code.CodeBlob;
import sun.jvm.hotspot.code.CodeCacheVisitor;
@@ -138,132 +147,41 @@
}
}
- static class Tokens {
- final String input;
- int i;
- String[] tokens;
- int length;
-
- String[] splitWhitespace(String cmd) {
- String[] t = cmd.split("\\s");
- if (t.length == 1 && t[0].length() == 0) {
- return new String[0];
- }
- return t;
- }
-
- void add(String s, ArrayList t) {
- if (s.length() > 0) {
- t.add(s);
- }
- }
-
- Tokens(String cmd) {
- input = cmd;
-
- // check for quoting
- int quote = cmd.indexOf('"');
- ArrayList t = new ArrayList();
- if (quote != -1) {
- while (cmd.length() > 0) {
- if (quote != -1) {
- int endquote = cmd.indexOf('"', quote + 1);
- if (endquote == -1) {
- throw new RuntimeException("mismatched quotes: " + input);
- }
-
- String before = cmd.substring(0, quote).trim();
- String quoted = cmd.substring(quote + 1, endquote);
- cmd = cmd.substring(endquote + 1).trim();
- if (before.length() > 0) {
- String[] w = splitWhitespace(before);
- for (int i = 0; i < w.length; i++) {
- add(w[i], t);
- }
- }
- add(quoted, t);
- quote = cmd.indexOf('"');
- } else {
- String[] w = splitWhitespace(cmd);
- for (int i = 0; i < w.length; i++) {
- add(w[i], t);
- }
- cmd = "";
-
- }
- }
- } else {
- String[] w = splitWhitespace(cmd);
- for (int i = 0; i < w.length; i++) {
- add(w[i], t);
- }
- }
- tokens = (String[])t.toArray(new String[0]);
- i = 0;
- length = tokens.length;
-
- //for (int i = 0; i < tokens.length; i++) {
- // System.out.println("\"" + tokens[i] + "\"");
- //}
- }
-
- String nextToken() {
- return tokens[i++];
- }
- boolean hasMoreTokens() {
- return i < length;
- }
- int countTokens() {
- return length - i;
- }
- void trim(int n) {
- if (length >= n) {
- length -= n;
- } else {
- throw new IndexOutOfBoundsException(String.valueOf(n));
- }
- }
- String join(String sep) {
- StringBuffer result = new StringBuffer();
- for (int w = i; w < length; w++) {
- result.append(tokens[w]);
- if (w + 1 < length) {
- result.append(sep);
- }
- }
- return result.toString();
- }
-
- String at(int i) {
- if (i < 0 || i >= length) {
- throw new IndexOutOfBoundsException(String.valueOf(i));
- }
- return tokens[i];
- }
- }
-
-
- abstract class Command {
- Command(String n, String u, boolean ok) {
+ abstract class ClhsdbCommand implements Command {
+ ClhsdbCommand(String n, String u, boolean ok) {
name = n;
usage = u;
okIfDisconnected = ok;
}
- Command(String n, boolean ok) {
+ ClhsdbCommand(String n, boolean ok) {
name = n;
usage = n;
okIfDisconnected = ok;
}
- final String name;
- final String usage;
- final boolean okIfDisconnected;
- abstract void doit(Tokens t);
- void usage() {
- out.println("Usage: " + usage);
+ private final String name;
+ private final String usage;
+ private final boolean okIfDisconnected;
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String usage() {
+ return "Usage: " + usage;
+ }
+
+ @Override
+ public boolean okIfDisconnected() {
+ return okIfDisconnected;
}
+ @Override
+ public abstract void doit(Tokens t, PrintStream out);
+
void printOopValue(Oop oop) {
if (oop != null) {
Klass k = oop.getKlass();
@@ -390,8 +308,9 @@
}
private final Command[] commandList = {
- new Command("reattach", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("reattach", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0) {
usage();
@@ -402,8 +321,9 @@
postAttach();
}
},
- new Command("attach", "attach pid | exec core", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("attach", "attach pid | exec core", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens == 1) {
preAttach();
@@ -418,8 +338,9 @@
}
}
},
- new Command("detach", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("detach", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -427,7 +348,7 @@
}
}
},
- new Command("examine", "examine [ address/count ] | [ address,address]", false) {
+ new ClhsdbCommand("examine", "examine [ address/count ] | [ address,address]", false) {
Pattern args1 = Pattern.compile("^(0x[0-9a-f]+)(/([0-9]*)([a-z]*))?$");
Pattern args2 = Pattern.compile("^(0x[0-9a-f]+),(0x[0-9a-f]+)(/[a-z]*)?$");
@@ -442,7 +363,8 @@
return s;
}
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -501,11 +423,12 @@
}
}
},
- new Command("dumpreplaydata", "dumpreplaydata {
| -a | }", false) {
+ new ClhsdbCommand("dumpreplaydata", "dumpreplaydata { | -a | }", false) {
// This is used to dump replay data from ciInstanceKlass, ciMethodData etc
// default file name is replay.txt, also if java crashes in compiler
// thread, this file will be dumped in error processing.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
return;
@@ -552,12 +475,13 @@
}
}
},
- new Command("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
+ new ClhsdbCommand("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
// This is used to dump jar files of all the classes
// loaded in the core. Everything with null classloader
// will go in boot.jar and everything else will go in
// app.jar. boot.jar usually not needed, unless changed by jvmti.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tcount = t.countTokens();
if (tcount > 2) {
usage();
@@ -606,8 +530,9 @@
}
}
},
- new Command("findpc", "findpc address", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("findpc", "findpc address", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -617,8 +542,9 @@
}
}
},
- new Command("symbol", "symbol address", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("symbol", "symbol address", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -628,8 +554,9 @@
}
}
},
- new Command("flags", "flags [ flag | -nd ]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("flags", "flags [ flag | -nd ]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0 && tokens != 1) {
usage();
@@ -665,8 +592,9 @@
}
}
},
- new Command("help", "help [ command ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("help", "help [ command ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
Command cmd = null;
if (tokens == 1) {
@@ -685,13 +613,14 @@
});
for (int i = 0; i < keys.length; i++) {
out.print(" ");
- out.println(((Command)commands.get(keys[i])).usage);
+ out.println(((Command)commands.get(keys[i])).usage());
}
}
}
},
- new Command("history", "history", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("history", "history", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 0 && (tokens != 1 || !t.nextToken().equals("-h"))) {
usage();
@@ -705,8 +634,9 @@
}
},
// decode raw address
- new Command("dis", "dis address [length]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("dis", "dis address [length]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1 && tokens != 2) {
usage();
@@ -735,8 +665,9 @@
},
// decode codeblob or nmethod
- new Command("disassemble", "disassemble address", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("disassemble", "disassemble address", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
@@ -756,8 +687,9 @@
}
},
// print Java bytecode disassembly
- new Command("jdis", "jdis address", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("jdis", "jdis address", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1) {
usage();
@@ -769,8 +701,9 @@
out.println(html.genHTML(m));
}
},
- new Command("revptrs", "revptrs address", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("revptrs", "revptrs address", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
int tokens = t.countTokens();
if (tokens != 1 && (tokens != 2 || !t.nextToken().equals("-c"))) {
usage();
@@ -831,9 +764,10 @@
}
}
},
- new Command("printmdo", "printmdo [ -a | expression ]", false) {
+ new ClhsdbCommand("printmdo", "printmdo [ -a | expression ]", false) {
// Print every MDO in the heap or the one referenced by expression.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -867,9 +801,10 @@
}
}
},
- new Command("printall", "printall", false) {
+ new ClhsdbCommand("printall", "printall", false) {
// Print every MDO in the heap or the one referenced by expression.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -890,9 +825,10 @@
}
}
},
- new Command("dumpideal", "dumpideal { -a | id }", false) {
+ new ClhsdbCommand("dumpideal", "dumpideal { -a | id }", false) {
// Do a full dump of the nodes reachabile from root in each compiler thread.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -920,9 +856,10 @@
}
}
},
- new Command("dumpcfg", "dumpcfg { -a | id }", false) {
+ new ClhsdbCommand("dumpcfg", "dumpcfg { -a | id }", false) {
// Dump the PhaseCFG for every compiler thread that has one live.
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -948,9 +885,10 @@
}
}
},
- new Command("dumpilt", "dumpilt { -a | id }", false) {
+ new ClhsdbCommand("dumpilt", "dumpilt { -a | id }", false) {
// dumps the InlineTree of a C2 compile
- public void doit(Tokens t) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -978,8 +916,9 @@
}
}
},
- new Command("vmstructsdump", "vmstructsdump", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("vmstructsdump", "vmstructsdump", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
return;
@@ -1014,8 +953,9 @@
}
},
- new Command("inspect", "inspect expression", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("inspect", "inspect expression", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1054,14 +994,16 @@
}
}
},
- new Command("jhisto", "jhisto", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("jhisto", "jhisto", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
ObjectHistogram histo = new ObjectHistogram();
histo.run(out, err);
}
},
- new Command("jstack", "jstack [-v]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("jstack", "jstack [-v]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
@@ -1070,8 +1012,9 @@
jstack.run(out);
}
},
- new Command("print", "print expression", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("print", "print expression", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1081,8 +1024,9 @@
}
}
},
- new Command("printas", "printas type expression", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("printas", "printas type expression", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2) {
usage();
} else {
@@ -1096,8 +1040,9 @@
}
}
},
- new Command("printstatics", "printstatics [ type ]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("printstatics", "printstatics [ type ]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() > 1) {
usage();
} else {
@@ -1112,14 +1057,16 @@
}
}
},
- new Command("pmap", "pmap", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("pmap", "pmap", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
PMap pmap = new PMap();
pmap.run(out, debugger.getAgent().getDebugger());
}
},
- new Command("pstack", "pstack [-v]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("pstack", "pstack [-v]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
boolean verbose = false;
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
verbose = true;
@@ -1128,8 +1075,9 @@
pstack.run(out, debugger.getAgent().getDebugger());
}
},
- new Command("quit", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("quit", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1138,8 +1086,9 @@
}
}
},
- new Command("echo", "echo [ true | false ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("echo", "echo [ true | false ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() == 0) {
out.println("echo is " + doEcho);
} else if (t.countTokens() == 1) {
@@ -1149,8 +1098,9 @@
}
}
},
- new Command("versioncheck", "versioncheck [ true | false ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("versioncheck", "versioncheck [ true | false ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() == 0) {
out.println("versioncheck is " +
(System.getProperty("sun.jvm.hotspot.runtime.VM.disableVersionCheck") == null));
@@ -1165,8 +1115,9 @@
}
}
},
- new Command("scanoops", "scanoops start end [ type ]", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("scanoops", "scanoops start end [ type ]", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2 && t.countTokens() != 3) {
usage();
} else {
@@ -1201,8 +1152,9 @@
}
}
},
- new Command("intConstant", "intConstant [ name [ value ] ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("intConstant", "intConstant [ name [ value ] ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
@@ -1224,8 +1176,9 @@
}
}
},
- new Command("longConstant", "longConstant [ name [ value ] ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("longConstant", "longConstant [ name [ value ] ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 2) {
usage();
return;
@@ -1247,8 +1200,9 @@
}
}
},
- new Command("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("field", "field [ type [ name fieldtype isStatic offset address ] ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
@@ -1282,19 +1236,19 @@
Field f = (Field) i.next();
if (f.getName().equals(fieldName)) {
if (f.isStatic() != isStatic) {
- throw new RuntimeException("static/nonstatic mismatch: " + t.input);
+ throw new RuntimeException("static/nonstatic mismatch: " + t.getInput());
}
if (!isStatic) {
if (f.getOffset() != offset) {
- throw new RuntimeException("bad redefinition of field offset: " + t.input);
+ throw new RuntimeException("bad redefinition of field offset: " + t.getInput());
}
} else {
if (!f.getStaticFieldAddress().equals(staticAddress)) {
- throw new RuntimeException("bad redefinition of field location: " + t.input);
+ throw new RuntimeException("bad redefinition of field location: " + t.getInput());
}
}
if (f.getType() != fieldType) {
- throw new RuntimeException("bad redefinition of field type: " + t.input);
+ throw new RuntimeException("bad redefinition of field type: " + t.getInput());
}
return;
}
@@ -1312,15 +1266,17 @@
}
},
- new Command("tokenize", "tokenize ...", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("tokenize", "tokenize ...", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
while (t.hasMoreTokens()) {
out.println("\"" + t.nextToken() + "\"");
}
}
},
- new Command("type", "type [ type [ name super isOop isInteger isUnsigned size ] ]", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("type", "type [ type [ name super isOop isInteger isUnsigned size ] ]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1 && t.countTokens() != 0 && t.countTokens() != 6) {
usage();
return;
@@ -1343,35 +1299,35 @@
}
if (type != null) {
if (type.isOopType() != isOop) {
- throw new RuntimeException("oop mismatch in type definition: " + t.input);
+ throw new RuntimeException("oop mismatch in type definition: " + t.getInput());
}
if (type.isCIntegerType() != isInteger) {
- throw new RuntimeException("integer type mismatch in type definition: " + t.input);
+ throw new RuntimeException("integer type mismatch in type definition: " + t.getInput());
}
if (type.isCIntegerType() && (((CIntegerType)type).isUnsigned()) != isUnsigned) {
- throw new RuntimeException("unsigned mismatch in type definition: " + t.input);
+ throw new RuntimeException("unsigned mismatch in type definition: " + t.getInput());
}
if (type.getSuperclass() == null) {
if (superclassName != null) {
if (type.getSize() == -1) {
type.setSuperclass(agent.getTypeDataBase().lookupType(superclassName));
} else {
- throw new RuntimeException("unexpected superclass in type definition: " + t.input);
+ throw new RuntimeException("unexpected superclass in type definition: " + t.getInput());
}
}
} else {
if (superclassName == null) {
- throw new RuntimeException("missing superclass in type definition: " + t.input);
+ throw new RuntimeException("missing superclass in type definition: " + t.getInput());
}
if (!type.getSuperclass().getName().equals(superclassName)) {
- throw new RuntimeException("incorrect superclass in type definition: " + t.input);
+ throw new RuntimeException("incorrect superclass in type definition: " + t.getInput());
}
}
if (type.getSize() != size) {
if (type.getSize() == -1) {
type.setSize(size);
}
- throw new RuntimeException("size mismatch in type definition: " + t.input);
+ throw new RuntimeException("size mismatch in type definition: " + t.getInput());
}
return;
}
@@ -1407,8 +1363,9 @@
}
},
- new Command("source", "source filename", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("source", "source filename", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
return;
@@ -1430,8 +1387,9 @@
}
},
- new Command("search", "search [ heap | perm | rawheap | codecache | threads ] value", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("search", "search [ heap | perm | rawheap | codecache | threads ] value", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 2) {
usage();
return;
@@ -1536,8 +1494,9 @@
}
}
},
- new Command("dumpcodecache", "dumpcodecache", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("dumpcodecache", "dumpcodecache", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1558,8 +1517,9 @@
}
}
},
- new Command("where", "where { -a | id }", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("where", "where { -a | id }", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1588,8 +1548,9 @@
}
}
},
- new Command("thread", "thread { -a | id }", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("thread", "thread { -a | id }", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1614,8 +1575,8 @@
}
},
- new Command("threads", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("threads", false) {
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1631,8 +1592,9 @@
}
},
- new Command("livenmethods", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("livenmethods", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1658,8 +1620,9 @@
}
}
},
- new Command("g1regiondetails", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("g1regiondetails", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1673,8 +1636,9 @@
}
}
},
- new Command("universe", false) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("universe", false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 0) {
usage();
} else {
@@ -1684,8 +1648,9 @@
}
}
},
- new Command("verbose", "verbose true | false", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("verbose", "verbose true | false", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1693,8 +1658,9 @@
}
}
},
- new Command("assert", "assert true | false", true) {
- public void doit(Tokens t) {
+ new ClhsdbCommand("assert", "assert true | false", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
if (t.countTokens() != 1) {
usage();
} else {
@@ -1702,6 +1668,16 @@
}
}
},
+ new ClhsdbCommand("load_plugin", "load_plugin [path]", true) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
+ if (t.countTokens() != 1) {
+ usage();
+ } else {
+ registerCommand(Path.of(t.nextToken()));
+ }
+ }
+ },
};
private boolean verboseExceptions = false;
@@ -1780,8 +1756,9 @@
}
public void registerCommand(String cmd, String usage, final String func) {
- commands.put(cmd, new Command(cmd, usage, false) {
- public void doit(Tokens t) {
+ commands.put(cmd, new ClhsdbCommand(cmd, usage, false) {
+ @Override
+ public void doit(Tokens t, PrintStream out) {
final int len = t.countTokens();
Object[] args = new Object[len];
for (int i = 0; i < len; i++) {
@@ -1792,6 +1769,37 @@
});
}
+ public void registerCommand(Path path) {
+ Module saModule = this.getClass().getModule();
+ ModuleLayer saLayer = saModule.getLayer();
+
+ // Create new module for the path
+ ModuleFinder finder = ModuleFinder.of(path);
+ Set moduleNames = finder.findAll()
+ .stream()
+ .map(r -> r.descriptor().name())
+ .peek(m -> System.out.println("Module found: " + m))
+ .collect(Collectors.toSet());
+
+ Configuration conf = saLayer.configuration()
+ .resolveAndBind(finder, ModuleFinder.of(), moduleNames);
+ ModuleLayer layer = saLayer.defineModulesWithOneLoader(conf, saModule.getClassLoader());
+
+ // Export all SA packages to the new module
+ layer.modules()
+ .stream()
+ .forEach(m -> saModule.getPackages()
+ .stream()
+ .forEach(p -> saModule.addExports(p, m)));
+
+ // Register command in the new module
+ ServiceLoader.load(layer, Command.class)
+ .stream()
+ .map(ServiceLoader.Provider::get)
+ .peek(s -> System.out.println("Installing: " + s.name()))
+ .forEach(s -> commands.put(s.name(), s));
+ }
+
public void setOutput(PrintStream o) {
out = o;
}
@@ -1808,10 +1816,10 @@
this.err = err;
for (int i = 0; i < commandList.length; i++) {
Command c = commandList[i];
- if (commands.get(c.name) != null) {
- throw new InternalError(c.name + " has multiple definitions");
+ if (commands.get(c.name()) != null) {
+ throw new InternalError(c.name() + " has multiple definitions");
}
- commands.put(c.name, c);
+ commands.put(c.name(), c);
}
if (debugger.isAttached()) {
postAttach();
@@ -1979,11 +1987,11 @@
*/
if (doit == null) {
out.println("Unrecognized command. Try help...");
- } else if (!debugger.isAttached() && !doit.okIfDisconnected) {
+ } else if (!debugger.isAttached() && !doit.okIfDisconnected()) {
out.println("Command not valid until attached to a VM");
} else {
try {
- doit.doit(args);
+ doit.doit(args, out);
} catch (Exception e) {
out.println("Error: " + e);
if (verboseExceptions) {