src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java
Print this page
@@ -20,50 +20,43 @@
*
* 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 jdk.internal.jshell.jdi;
+package jdk.jshell;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Objects;
-import com.sun.jdi.ReferenceType;
-import java.util.List;
-import com.sun.jdi.VirtualMachine;
+import jdk.jshell.spi.ExecutionControl.ClassBytecodes;
/**
* Tracks the state of a class.
*/
class ClassTracker {
- private final VirtualMachine vm;
private final HashMap<String, ClassInfo> map;
- ClassTracker(VirtualMachine vm) {
- this.vm = vm;
+ ClassTracker() {
this.map = new HashMap<>();
}
/**
- * Associates a class name, class bytes, and ReferenceType.
+ * Associates a class name, class bytes (current and loaded).
*/
class ClassInfo {
- // The name of the class -- always set
+ // The name of the class
private final String className;
// The corresponding compiled class bytes when a load or redefine
// is started. May not be the loaded bytes. May be null.
- private byte[] bytes;
+ private byte[] currentBytes;
// The class bytes successfully loaded/redefined into the remote VM.
private byte[] loadedBytes;
- // The corresponding JDI ReferenceType. Used by redefineClasses and
- // acts as indicator of successful load (null if not loaded).
- private ReferenceType rt;
-
private ClassInfo(String className) {
this.className = className;
}
String getClassName() {
@@ -72,38 +65,32 @@
byte[] getLoadedBytes() {
return loadedBytes;
}
- byte[] getBytes() {
- return bytes;
+ byte[] getCurrentBytes() {
+ return currentBytes;
}
- private void setBytes(byte[] potentialBytes) {
- this.bytes = potentialBytes;
+ void setCurrentBytes(byte[] bytes) {
+ this.currentBytes = bytes;
}
- // The class has been successful loaded redefined. The class bytes
- // sent are now actually loaded.
- void markLoaded() {
- loadedBytes = bytes;
+ void setLoadedBytes(byte[] bytes) {
+ this.loadedBytes = bytes;
}
- // Ask JDI for the ReferenceType, null if not loaded.
- ReferenceType getReferenceTypeOrNull() {
- if (rt == null) {
- rt = nameToRef(className);
- }
- return rt;
+ boolean isLoaded() {
+ return loadedBytes != null;
}
- private ReferenceType nameToRef(String name) {
- List<ReferenceType> rtl = vm.classesByName(name);
- if (rtl.size() != 1) {
- return null;
+ boolean isCurrent() {
+ return Arrays.equals(currentBytes, loadedBytes);
}
- return rtl.get(0);
+
+ ClassBytecodes toClassBytecodes() {
+ return new ClassBytecodes(className, currentBytes);
}
@Override
public boolean equals(Object o) {
return o instanceof ClassInfo
@@ -114,15 +101,29 @@
public int hashCode() {
return Objects.hashCode(this.className);
}
}
+ void markLoaded(ClassBytecodes[] cbcs) {
+ for (ClassBytecodes cbc : cbcs) {
+ get(cbc.name).setLoadedBytes(cbc.bytecodes);
+ }
+ }
+
+ void markLoaded(ClassBytecodes[] cbcs, boolean[] isLoaded) {
+ for (int i = 0; i < cbcs.length; ++i) {
+ if (isLoaded[i]) {
+ ClassBytecodes cbc = cbcs[i];
+ get(cbc.name).setLoadedBytes(cbc.bytecodes);
+ }
+ }
+ }
+
// Map a class name to the current compiled class bytes.
- ClassInfo classInfo(String className, byte[] bytes) {
+ void setCurrentBytes(String className, byte[] bytes) {
ClassInfo ci = get(className);
- ci.setBytes(bytes);
- return ci;
+ ci.setCurrentBytes(bytes);
}
// Lookup the ClassInfo by class name, create if it does not exist.
ClassInfo get(String className) {
return map.computeIfAbsent(className, k -> new ClassInfo(k));