This commit is contained in:
wangxiang
2023-07-21 18:09:23 +08:00
parent f360ac0e3f
commit c9fb612b1b
24 changed files with 88 additions and 22 deletions

View File

@@ -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`

BIN
readme/20230721180520.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

View File

@@ -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

View File

@@ -1,8 +0,0 @@
package haidnor.jvm.classloader;
/**
* @author wang xiang
*/
public class BootstrapClassLoader {
}

View File

@@ -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<Integer, Instruction> 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--;
}
}

View File

@@ -1,5 +1,8 @@
package haidnor.jvm.rtda.heap;
/**
* @author wang xiang
*/
public abstract class ArrayInstance extends Instance {
public final int size;

View File

@@ -1,5 +1,8 @@
package haidnor.jvm.rtda.heap;
/**
* @author wang xiang
*/
public class BasicTypeArray extends ArrayInstance {
public int[] ints;

View File

@@ -7,6 +7,8 @@ import java.util.Objects;
/**
* JVM 中的 Java 对象实例
*
* @author wang xiang
*/
public class Instance {

View File

@@ -1,5 +1,8 @@
package haidnor.jvm.rtda.heap;
/**
* @author wang xiang
*/
public class InstanceArray extends ArrayInstance {
public final Instance[] items;

View File

@@ -15,6 +15,8 @@ import java.util.Map;
/**
* 类元信息
*
* @author wang xiang
*/
public class Klass {

View File

@@ -6,6 +6,8 @@ import org.apache.bcel.classfile.Field;
/**
* 类元信息字段
*
* @author wang xiang
*/
public class KlassField {

View File

@@ -4,6 +4,8 @@ import org.apache.bcel.classfile.Method;
/**
* 类元信息方法
*
* @author wang xiang
*/
public class KlassMethod {

View File

@@ -7,6 +7,8 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* 元空间
*
* @author wang xiang
*/
public class Metaspace {

View File

@@ -14,6 +14,8 @@ import java.util.Stack;
/**
* JVM 线程栈帧
*
* @author wang xiang
*/
public class Frame {
/**

View File

@@ -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();
}
}

View File

@@ -1,6 +1,8 @@
package haidnor.jvm.runtime;
/**
* @author wang xiang
*/
public class Slot {
public Integer num;
public Object ref;

View File

@@ -4,6 +4,8 @@ import lombok.Data;
/**
* 操作数栈中的值对象
*
* @author wang xiang
*/
@Data
public class StackValue {

View File

@@ -6,6 +6,9 @@ import org.apache.bcel.classfile.Code;
import java.io.DataInputStream;
/**
* @author wang xiang
*/
public class CodeStream {
/**

View File

@@ -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 ------------------------------------------------------------------------------------------------

View File

@@ -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) {

View File

@@ -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 {
/**

View File

@@ -2,6 +2,9 @@ package haidnor.jvm.util;
import haidnor.jvm.runtime.JvmThread;
/**
* @author wang xiang
*/
public abstract class JvmThreadHolder {
private static final ThreadLocal<JvmThread> holder = new ThreadLocal<>();

View File

@@ -3,6 +3,9 @@ package haidnor.jvm.util;
import lombok.SneakyThrows;
import org.apache.bcel.classfile.Utility;
/**
* @author wang xiang
*/
public abstract class SignatureUtil {
/**

View File

@@ -1,5 +1,5 @@
package haidnor.jvm.test.clazz;
public class Student extends Human {
public static String school = "家里蹲大学";
public static String school = "Hello World!";
}