diff --git a/README.md b/README.md index fdb6b0a..ea1968f 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ ### 配置日志输出级别 修改 `simplelogger.properties` 文件中的内容。配置日志输出级别,一般使用 `debug`、`info` +在 debug 级别下运行将会非常友好的输出 JVM 正在执行的栈信息 +![](/readme/20230721180520.png) + ### 配置 rt.jar 修改 `haidnorJVM.properties` 文件中的内容。配置 rt.jar 的绝对路径,例如`rt.jar=D:/Program Files/Java/jdk1.8.0_361/jre/lib/rt.jar` diff --git a/readme/20230721180520.png b/readme/20230721180520.png new file mode 100644 index 0000000..926a0a4 Binary files /dev/null and b/readme/20230721180520.png differ diff --git a/src/main/java/haidnor/jvm/Main.java b/src/main/java/haidnor/jvm/Main.java index 4f2f5ad..bcb85ef 100644 --- a/src/main/java/haidnor/jvm/Main.java +++ b/src/main/java/haidnor/jvm/Main.java @@ -9,10 +9,11 @@ import haidnor.jvm.runtime.JvmThread; import haidnor.jvm.util.JavaClassUtil; import haidnor.jvm.util.JvmThreadHolder; import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.cli.*; -@Slf4j +/** + * @author wang xiang + */ public class Main { @SneakyThrows diff --git a/src/main/java/haidnor/jvm/classloader/BootstrapClassLoader.java b/src/main/java/haidnor/jvm/classloader/BootstrapClassLoader.java deleted file mode 100644 index 7230ee5..0000000 --- a/src/main/java/haidnor/jvm/classloader/BootstrapClassLoader.java +++ /dev/null @@ -1,8 +0,0 @@ -package haidnor.jvm.classloader; - -/** - * @author wang xiang - */ -public class BootstrapClassLoader { - -} diff --git a/src/main/java/haidnor/jvm/core/Interpreter.java b/src/main/java/haidnor/jvm/core/Interpreter.java index a563928..4e26bf8 100644 --- a/src/main/java/haidnor/jvm/core/Interpreter.java +++ b/src/main/java/haidnor/jvm/core/Interpreter.java @@ -13,37 +13,49 @@ import java.util.Map; /** * 字节码执行解释器 + * + * @author wang xiang */ @Slf4j public class Interpreter { + private static int frameCount = -1; + @SneakyThrows public static void executeFrame(Frame frame) { - log.debug("------------------------------ Frame START {}", frame.hashCode()); + frameCount++; + StringBuilder blank = new StringBuilder(); + blank.append(" ".repeat(Math.max(0, frameCount))); + int index = 0; + for (int i = 0; i < frameCount; i++) { + blank.replace(index, index + 1, "│"); + index += 20; + } + + log.debug("{}┌──────────────────[{}] {} | {} ", blank, frameCount + 1, frame.aKlass.getClassName(), frame.getMethod()); Map instructionMap = new HashMap<>(); // 解析方法中的字节码指令 - log.debug(">>>>>>>>>>>>>>>> PARSE INST START"); CodeStream codeStream = frame.getCodeStream(); while (codeStream.available() > 0) { Instruction instruction = InstructionFactory.creatInstruction(codeStream); - log.debug("{}", instruction); + // log.debug("{}│>{}", blank, instruction); instructionMap.put(instruction.index(), instruction); } - log.debug(">>>>>>>>>>>>>>>> PARSE INST END"); + // log.debug("{}├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌", blank); - // 执行方法中的字节码指令 - // int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“ + // 执行方法中的字节码指令 tip:(int i, 相当于程序计数器, 记录当前执行到的字节码指令的”行号“) for (int i = 0; i < frame.getCodeLength(); ) { Instruction instruction = instructionMap.get(i); - log.debug("{}", instruction); + log.debug("{}│ {}", blank, instruction); instruction.execute(frame); if (instruction instanceof RETURN) { break; } i += instruction.offSet(); } - log.debug("------------------------------ Frame End {}", frame.hashCode()); + log.debug("{}└──────────────────", blank); + frameCount--; } } \ No newline at end of file diff --git a/src/main/java/haidnor/jvm/rtda/heap/ArrayInstance.java b/src/main/java/haidnor/jvm/rtda/heap/ArrayInstance.java index 53e00fc..accbc7a 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/ArrayInstance.java +++ b/src/main/java/haidnor/jvm/rtda/heap/ArrayInstance.java @@ -1,5 +1,8 @@ package haidnor.jvm.rtda.heap; +/** + * @author wang xiang + */ public abstract class ArrayInstance extends Instance { public final int size; diff --git a/src/main/java/haidnor/jvm/rtda/heap/BasicTypeArray.java b/src/main/java/haidnor/jvm/rtda/heap/BasicTypeArray.java index 41ced9a..defc19c 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/BasicTypeArray.java +++ b/src/main/java/haidnor/jvm/rtda/heap/BasicTypeArray.java @@ -1,5 +1,8 @@ package haidnor.jvm.rtda.heap; +/** + * @author wang xiang + */ public class BasicTypeArray extends ArrayInstance { public int[] ints; diff --git a/src/main/java/haidnor/jvm/rtda/heap/Instance.java b/src/main/java/haidnor/jvm/rtda/heap/Instance.java index ee67354..53c33e5 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/Instance.java +++ b/src/main/java/haidnor/jvm/rtda/heap/Instance.java @@ -7,6 +7,8 @@ import java.util.Objects; /** * JVM 中的 Java 对象实例 + * + * @author wang xiang */ public class Instance { diff --git a/src/main/java/haidnor/jvm/rtda/heap/InstanceArray.java b/src/main/java/haidnor/jvm/rtda/heap/InstanceArray.java index d036024..3118ec2 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/InstanceArray.java +++ b/src/main/java/haidnor/jvm/rtda/heap/InstanceArray.java @@ -1,5 +1,8 @@ package haidnor.jvm.rtda.heap; +/** + * @author wang xiang + */ public class InstanceArray extends ArrayInstance { public final Instance[] items; diff --git a/src/main/java/haidnor/jvm/rtda/heap/Klass.java b/src/main/java/haidnor/jvm/rtda/heap/Klass.java index b70afe7..5e59c74 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/Klass.java +++ b/src/main/java/haidnor/jvm/rtda/heap/Klass.java @@ -15,6 +15,8 @@ import java.util.Map; /** * 类元信息 + * + * @author wang xiang */ public class Klass { diff --git a/src/main/java/haidnor/jvm/rtda/heap/KlassField.java b/src/main/java/haidnor/jvm/rtda/heap/KlassField.java index cf971aa..332e617 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/KlassField.java +++ b/src/main/java/haidnor/jvm/rtda/heap/KlassField.java @@ -6,6 +6,8 @@ import org.apache.bcel.classfile.Field; /** * 类元信息字段 + * + * @author wang xiang */ public class KlassField { diff --git a/src/main/java/haidnor/jvm/rtda/heap/KlassMethod.java b/src/main/java/haidnor/jvm/rtda/heap/KlassMethod.java index be51c10..917703e 100644 --- a/src/main/java/haidnor/jvm/rtda/heap/KlassMethod.java +++ b/src/main/java/haidnor/jvm/rtda/heap/KlassMethod.java @@ -4,6 +4,8 @@ import org.apache.bcel.classfile.Method; /** * 类元信息方法 + * + * @author wang xiang */ public class KlassMethod { diff --git a/src/main/java/haidnor/jvm/rtda/metaspace/Metaspace.java b/src/main/java/haidnor/jvm/rtda/metaspace/Metaspace.java index 863977f..2a58ce9 100644 --- a/src/main/java/haidnor/jvm/rtda/metaspace/Metaspace.java +++ b/src/main/java/haidnor/jvm/rtda/metaspace/Metaspace.java @@ -7,6 +7,8 @@ import java.util.concurrent.ConcurrentHashMap; /** * 元空间 + * + * @author wang xiang */ public class Metaspace { diff --git a/src/main/java/haidnor/jvm/runtime/Frame.java b/src/main/java/haidnor/jvm/runtime/Frame.java index 91f5b4a..4db8136 100644 --- a/src/main/java/haidnor/jvm/runtime/Frame.java +++ b/src/main/java/haidnor/jvm/runtime/Frame.java @@ -14,6 +14,8 @@ import java.util.Stack; /** * JVM 线程栈帧 + * + * @author wang xiang */ public class Frame { /** diff --git a/src/main/java/haidnor/jvm/runtime/JvmThread.java b/src/main/java/haidnor/jvm/runtime/JvmThread.java index 02ce178..4ce1942 100644 --- a/src/main/java/haidnor/jvm/runtime/JvmThread.java +++ b/src/main/java/haidnor/jvm/runtime/JvmThread.java @@ -4,6 +4,8 @@ import java.util.Stack; /** * JVM 线程 + * + * @author wang xiang */ public class JvmThread extends Thread { @@ -25,7 +27,7 @@ public class JvmThread extends Thread { } public int stackSize() { - return this.stack.size(); + return this.stack.size(); } } diff --git a/src/main/java/haidnor/jvm/runtime/Slot.java b/src/main/java/haidnor/jvm/runtime/Slot.java index 426e5bb..8dc909f 100644 --- a/src/main/java/haidnor/jvm/runtime/Slot.java +++ b/src/main/java/haidnor/jvm/runtime/Slot.java @@ -1,6 +1,8 @@ package haidnor.jvm.runtime; - +/** + * @author wang xiang + */ public class Slot { public Integer num; public Object ref; diff --git a/src/main/java/haidnor/jvm/runtime/StackValue.java b/src/main/java/haidnor/jvm/runtime/StackValue.java index 39a3bef..27406b5 100644 --- a/src/main/java/haidnor/jvm/runtime/StackValue.java +++ b/src/main/java/haidnor/jvm/runtime/StackValue.java @@ -4,6 +4,8 @@ import lombok.Data; /** * 操作数栈中的值对象 + * + * @author wang xiang */ @Data public class StackValue { diff --git a/src/main/java/haidnor/jvm/util/CodeStream.java b/src/main/java/haidnor/jvm/util/CodeStream.java index 0caf9a6..cbb927f 100644 --- a/src/main/java/haidnor/jvm/util/CodeStream.java +++ b/src/main/java/haidnor/jvm/util/CodeStream.java @@ -6,6 +6,9 @@ import org.apache.bcel.classfile.Code; import java.io.DataInputStream; +/** + * @author wang xiang + */ public class CodeStream { /** diff --git a/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java b/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java index a37f8d8..6523800 100644 --- a/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java +++ b/src/main/java/haidnor/jvm/util/ConstantPoolUtil.java @@ -3,7 +3,7 @@ package haidnor.jvm.util; import org.apache.bcel.classfile.*; /** - * ConstantPoolUtil + * @author wang xiang */ public class ConstantPoolUtil { @@ -29,6 +29,14 @@ public class ConstantPoolUtil { return cp.getConstant(constantNameAndTypeIndex); } + + // + + public ConstantPool getCp() { + return cp; + } + + // ConstantClass --------------------------------------------------------------------------------------------------- /** @@ -38,6 +46,14 @@ public class ConstantPoolUtil { ConstantUtf8 constantUtf8 = cp.getConstant(constantClass.getNameIndex()); return constantUtf8.getBytes(); } + /** + * 获取长类名, 例如 java/lang/String + */ + public String getClassName(int index) { + ConstantClass constantClass = cp.getConstant(index); + return getClassName(constantClass); + } + // ConstantFieldref ------------------------------------------------------------------------------------------------ diff --git a/src/main/java/haidnor/jvm/util/IoUtil.java b/src/main/java/haidnor/jvm/util/IoUtil.java index 05b8355..bd59036 100644 --- a/src/main/java/haidnor/jvm/util/IoUtil.java +++ b/src/main/java/haidnor/jvm/util/IoUtil.java @@ -3,6 +3,9 @@ package haidnor.jvm.util; import java.io.ByteArrayInputStream; import java.io.DataInputStream; +/** + * @author wang xiang + */ public abstract class IoUtil { public static DataInputStream getDataInputStream(byte[] bytes) { diff --git a/src/main/java/haidnor/jvm/util/JavaClassUtil.java b/src/main/java/haidnor/jvm/util/JavaClassUtil.java index 501e4a5..23193b8 100644 --- a/src/main/java/haidnor/jvm/util/JavaClassUtil.java +++ b/src/main/java/haidnor/jvm/util/JavaClassUtil.java @@ -4,6 +4,9 @@ import haidnor.jvm.rtda.heap.Klass; import haidnor.jvm.rtda.heap.KlassMethod; import org.apache.bcel.classfile.JavaClass; +/** + * @author wang xiang + */ public abstract class JavaClassUtil { /** diff --git a/src/main/java/haidnor/jvm/util/JvmThreadHolder.java b/src/main/java/haidnor/jvm/util/JvmThreadHolder.java index 21cc38f..dd7e2e9 100644 --- a/src/main/java/haidnor/jvm/util/JvmThreadHolder.java +++ b/src/main/java/haidnor/jvm/util/JvmThreadHolder.java @@ -2,6 +2,9 @@ package haidnor.jvm.util; import haidnor.jvm.runtime.JvmThread; +/** + * @author wang xiang + */ public abstract class JvmThreadHolder { private static final ThreadLocal holder = new ThreadLocal<>(); diff --git a/src/main/java/haidnor/jvm/util/SignatureUtil.java b/src/main/java/haidnor/jvm/util/SignatureUtil.java index 66b58ec..05117f0 100644 --- a/src/main/java/haidnor/jvm/util/SignatureUtil.java +++ b/src/main/java/haidnor/jvm/util/SignatureUtil.java @@ -3,6 +3,9 @@ package haidnor.jvm.util; import lombok.SneakyThrows; import org.apache.bcel.classfile.Utility; +/** + * @author wang xiang + */ public abstract class SignatureUtil { /** diff --git a/src/test/java/haidnor/jvm/test/clazz/Student.java b/src/test/java/haidnor/jvm/test/clazz/Student.java index 4ede095..869fb71 100644 --- a/src/test/java/haidnor/jvm/test/clazz/Student.java +++ b/src/test/java/haidnor/jvm/test/clazz/Student.java @@ -1,5 +1,5 @@ package haidnor.jvm.test.clazz; public class Student extends Human { - public static String school = "家里蹲大学"; + public static String school = "Hello World!"; }