src/jdk.jshell/share/classes/jdk/jshell/ClassTracker.java

Print this page

        

*** 20,69 **** * * 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; import java.util.HashMap; import java.util.Objects; ! import com.sun.jdi.ReferenceType; ! import java.util.List; ! import com.sun.jdi.VirtualMachine; /** * Tracks the state of a class. */ class ClassTracker { - private final VirtualMachine vm; private final HashMap<String, ClassInfo> map; ! ClassTracker(VirtualMachine vm) { ! this.vm = vm; this.map = new HashMap<>(); } /** ! * Associates a class name, class bytes, and ReferenceType. */ class ClassInfo { ! // The name of the class -- always set 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; // 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() { --- 20,62 ---- * * 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.jshell; + import java.util.Arrays; import java.util.HashMap; import java.util.Objects; ! import jdk.jshell.spi.ExecutionControl.ClassBytecodes; /** * Tracks the state of a class. */ class ClassTracker { private final HashMap<String, ClassInfo> map; ! ClassTracker() { this.map = new HashMap<>(); } /** ! * Associates a class name, class bytes (current and loaded). */ class ClassInfo { ! // 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[] currentBytes; // The class bytes successfully loaded/redefined into the remote VM. private byte[] loadedBytes; private ClassInfo(String className) { this.className = className; } String getClassName() {
*** 72,109 **** byte[] getLoadedBytes() { return loadedBytes; } ! byte[] getBytes() { ! return bytes; } ! private void setBytes(byte[] potentialBytes) { ! this.bytes = potentialBytes; } ! // The class has been successful loaded redefined. The class bytes ! // sent are now actually loaded. ! void markLoaded() { ! loadedBytes = bytes; } ! // Ask JDI for the ReferenceType, null if not loaded. ! ReferenceType getReferenceTypeOrNull() { ! if (rt == null) { ! rt = nameToRef(className); ! } ! return rt; } ! private ReferenceType nameToRef(String name) { ! List<ReferenceType> rtl = vm.classesByName(name); ! if (rtl.size() != 1) { ! return null; } ! return rtl.get(0); } @Override public boolean equals(Object o) { return o instanceof ClassInfo --- 65,96 ---- byte[] getLoadedBytes() { return loadedBytes; } ! byte[] getCurrentBytes() { ! return currentBytes; } ! void setCurrentBytes(byte[] bytes) { ! this.currentBytes = bytes; } ! void setLoadedBytes(byte[] bytes) { ! this.loadedBytes = bytes; } ! boolean isLoaded() { ! return loadedBytes != null; } ! boolean isCurrent() { ! return Arrays.equals(currentBytes, loadedBytes); } ! ! ClassBytecodes toClassBytecodes() { ! return new ClassBytecodes(className, currentBytes); } @Override public boolean equals(Object o) { return o instanceof ClassInfo
*** 114,128 **** public int hashCode() { return Objects.hashCode(this.className); } } // Map a class name to the current compiled class bytes. ! ClassInfo classInfo(String className, byte[] bytes) { ClassInfo ci = get(className); ! ci.setBytes(bytes); ! return ci; } // Lookup the ClassInfo by class name, create if it does not exist. ClassInfo get(String className) { return map.computeIfAbsent(className, k -> new ClassInfo(k)); --- 101,129 ---- 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. ! void setCurrentBytes(String className, byte[] bytes) { ClassInfo ci = get(className); ! 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));