x86bytecodevisitor.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 2,035 行 · 第 1/5 页
JAVA
2,035 行
final int imtIndex = selector % ObjectLayout.IMT_LENGTH;
final int argSlotCount = count - 1;
final Label noCollLabel = new Label(this.curInstrLabel + "NoCollision");
final Label findSelectorLabel = new Label(this.curInstrLabel
+ "FindSelector");
final Label endLabel = new Label(this.curInstrLabel + "End");
// Get objectref -> EBX
os.writeMOV(INTSIZE, Register.EBX, SP, argSlotCount * slotSize);
/*
* // methodRef -> EDX os.writeMOV_Const(Register.EDX, methodRef); //
* methodRef.selector -> ecx os.writeMOV(INTSIZE, Register.ECX,
* Register.EDX,
* context.getVmConstIMethodRefSelectorField().getOffset()); //
* methodRef.selector -> eax os.writeMOV(INTSIZE, Register.EAX,
* Register.ECX); // Clear edx os.writeXOR(Register.EDX, Register.EDX); //
* IMT_LENGTH -> ESI os.writeMOV_Const(Register.ESI,
* ObjectLayout.IMT_LENGTH); // selector % IMT_LENGTH -> edx
*/
os.writeMOV_Const(ECX, selector);
os.writeMOV_Const(EDX, imtIndex);
// Output: EBX=objectref, ECX=selector, EDX=imtIndex
/* objectref.TIB -> ebx */
os.writeMOV(INTSIZE, Register.EBX, Register.EBX, ObjectLayout.TIB_SLOT
* slotSize);
/* boolean[] imtCollisions -> esi */
os.writeMOV(INTSIZE, Register.ESI, Register.EBX,
(VmArray.DATA_OFFSET + TIBLayout.IMTCOLLISIONS_INDEX)
* slotSize);
/* Has collision at imt[index] ? */
os.writeMOV(INTSIZE, Register.EAX, Register.ESI, Register.EDX, 1,
VmArray.DATA_OFFSET * slotSize);
os.writeTEST_AL(0xFF);
/* Object[] imt -> esi */
os.writeMOV(INTSIZE, Register.ESI, Register.EBX,
(VmArray.DATA_OFFSET + TIBLayout.IMT_INDEX) * slotSize);
/* selector -> ebx */
os.writeMOV(INTSIZE, Register.EBX, Register.ECX);
os.writeJCC(noCollLabel, X86Constants.JZ);
// We have a collision
/* imt[index] (=collisionList) -> esi */
os.writeMOV(INTSIZE, Register.ESI, Register.ESI, Register.EDX, 4,
VmArray.DATA_OFFSET * slotSize);
/* collisionList.length -> ecx */
os.writeMOV(INTSIZE, Register.ECX, Register.ESI, VmArray.LENGTH_OFFSET
* slotSize);
/* &collisionList[0] -> esi */
os.writeLEA(Register.ESI, Register.ESI, VmArray.DATA_OFFSET * slotSize);
os.setObjectRef(findSelectorLabel);
/* collisionList[index] -> eax */
os.writeLODSD();
/* collisionList[index].selector == selector? */
os.writeMOV(INTSIZE, Register.EDX, Register.EAX, context
.getVmMethodSelectorField().getOffset());
os.writeCMP(Register.EBX, Register.EDX);
os.writeJCC(endLabel, X86Constants.JE);
try {
os.writeLOOP(findSelectorLabel);
} catch (UnresolvedObjectRefException ex) {
throw new CompileError(ex);
}
/* Force a NPE further on */
os.writeXOR(Register.EAX, Register.EAX);
os.writeJMP(endLabel);
os.setObjectRef(noCollLabel);
/* imt[index] -> eax */
os.writeMOV(INTSIZE, Register.EAX, Register.ESI, Register.EDX, 4,
VmArray.DATA_OFFSET * slotSize);
os.setObjectRef(endLabel);
/** Now invoke the method */
helper.invokeJavaMethod(methodRef.getSignature());
}
/**
* @param methodRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_invokespecial(org.jnode.vm.classmgr.VmConstMethodRef)
*/
public final void visit_invokespecial(VmConstMethodRef methodRef) {
methodRef.resolve(loader);
try {
final VmMethod sm = methodRef.getResolvedVmMethod();
// Get method from statics table
helper.writeGetStaticsEntry(curInstrLabel, EAX, sm);
helper.invokeJavaMethod(methodRef.getSignature());
} catch (ClassCastException ex) {
System.out.println(methodRef.getResolvedVmMethod().getClass()
.getName()
+ "#" + methodRef.getName());
throw ex;
}
/*
* methodRef.resolve(loader);
* writeResolveAndLoadClassToEAX(methodRef.getConstClass(), S0);
* writeResolveAndLoadMethodToEAX(methodRef, S0);
*/
}
/**
* @param methodRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_invokestatic(org.jnode.vm.classmgr.VmConstMethodRef)
*/
public final void visit_invokestatic(VmConstMethodRef methodRef) {
methodRef.resolve(loader);
final VmStaticMethod sm = (VmStaticMethod) methodRef
.getResolvedVmMethod();
// Get method from statics table
helper.writeGetStaticsEntry(curInstrLabel, EAX, sm);
helper.invokeJavaMethod(methodRef.getSignature());
}
/**
* @param methodRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_invokevirtual(org.jnode.vm.classmgr.VmConstMethodRef)
*/
public final void visit_invokevirtual(VmConstMethodRef methodRef) {
methodRef.resolve(loader);
final VmMethod mts = methodRef.getResolvedVmMethod();
if (mts.isStatic()) { throw new IncompatibleClassChangeError(
"Static method in invokevirtual"); }
final VmInstanceMethod method = (VmInstanceMethod) mts;
final int tibOffset = method.getTibOffset();
final int argSlotCount = Signature.getArgSlotCount(methodRef
.getSignature());
/* Get objectref -> S0 */
os.writeMOV(INTSIZE, S0, SP, argSlotCount * slotSize);
/* Get VMT of objectef -> S0 */
os.writeMOV(INTSIZE, S0, S0, ObjectLayout.TIB_SLOT * slotSize);
/* Get entry in VMT -> EAX */
os.writeMOV(INTSIZE, EAX, S0, (VmArray.DATA_OFFSET + tibOffset)
* slotSize);
/* Now invoke the method */
helper.invokeJavaMethod(methodRef.getSignature());
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ior()
*/
public final void visit_ior() {
helper.writePOP(T0); // value2
helper.writePOP(S0); // value 1
os.writeOR(S0, T0);
helper.writePUSH(S0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_irem()
*/
public final void visit_irem() {
helper.writePOP(S0); // Value2
helper.writePOP(EAX); // Value1
os.writeCDQ();
os.writeIDIV_EAX(S0); // EAX = EDX:EAX / S0
helper.writePUSH(EDX); // Remainder
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ireturn()
*/
public final void visit_ireturn() {
helper.writePOP(T0);
visit_return();
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ishl()
*/
public final void visit_ishl() {
helper.writePOP(ECX);
helper.writePOP(EAX);
os.writeSAL_CL(EAX);
helper.writePUSH(EAX);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ishr()
*/
public final void visit_ishr() {
helper.writePOP(ECX);
helper.writePOP(EAX);
os.writeSAR_CL(EAX);
helper.writePUSH(EAX);
}
/**
* @param index
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_istore(int)
*/
public final void visit_istore(int index) {
int ebpOfs = stackFrame.getEbpOffset(index);
helper.writePOP(FP, ebpOfs);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_isub()
*/
public final void visit_isub() {
helper.writePOP(T0);
helper.writePOP(S0);
os.writeSUB(S0, T0);
helper.writePUSH(S0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iushr()
*/
public final void visit_iushr() {
helper.writePOP(Register.ECX);
helper.writePOP(Register.EAX);
os.writeSHR_CL(Register.EAX);
helper.writePUSH(Register.EAX);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ixor()
*/
public final void visit_ixor() {
helper.writePOP(T0);
helper.writePOP(S0);
os.writeXOR(S0, T0);
helper.writePUSH(S0);
}
/**
* @param address
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_jsr(int)
*/
public final void visit_jsr(int address) {
os.writeCALL(helper.getInstrLabel(address));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_l2d()
*/
public final void visit_l2d() {
os.writeFILD64(SP, 0);
os.writeFSTP64(SP, 0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_l2f()
*/
public final void visit_l2f() {
os.writeFILD64(SP, 0);
os.writeLEA(SP, SP, 4);
os.writeFSTP32(SP, 0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_l2i()
*/
public final void visit_l2i() {
helper.writePOP64(T0, T1);
helper.writePUSH(T0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ladd()
*/
public final void visit_ladd() {
helper.writePOP64(T0, T1); // Value 2
helper.writePOP64(S0, S1); // Value 1
os.writeADD(S0, T0);
os.writeADC(S1, T1);
helper.writePUSH64(S0, S1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_laload()
*/
public final void visit_laload() {
helper.writePOP(T0); // Index
helper.writePOP(S0); // Arrayref
checkBounds(S0, T0);
os.writeLEA(S0, S0, T0, 8, VmArray.DATA_OFFSET * 4);
os.writeMOV(INTSIZE, T0, S0, 0);
os.writeMOV(INTSIZE, T1, S0, 4);
helper.writePUSH64(T0, T1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_land()
*/
public final void visit_land() {
helper.writePOP64(T0, T1); // Value 2
helper.writePOP64(S0, S1); // Value 1
os.writeAND(S0, T0);
os.writeAND(S1, T1);
helper.writePUSH64(S0, S1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lastore()
*/
public final void visit_lastore() {
os.writeMOV(INTSIZE, T0, SP, 8); // Index
os.writeMOV(INTSIZE, S0, SP, 12); // Arrayref
checkBounds(S0, T0);
os.writeLEA(S0, S0, T0, 8, VmArray.DATA_OFFSET * 4);
helper.writePOP64(T0, T1); // Value
os.writeMOV(INTSIZE, S0, 0, T0);
os.writeMOV(INTSIZE, S0, 4, T1);
os.writeLEA(SP, SP, 8); // Remove index, arrayref
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lcmp()
*/
public final void visit_lcmp() {
helper.writePOP64(Register.EBX, Register.ECX); // Value 2
helper.writePOP64(Register.EAX, Register.EDX); // Value 1
Label ltLabel = new Label(curInstrLabel + "lt");
Label endLabel = new Label(curInstrLabel + "end");
os.writeXOR(Register.ESI, Register.ESI);
os.writeSUB(Register.EAX, Register.EBX);
os.writeSBB(Register.EDX, Register.ECX);
os.writeJCC(ltLabel, X86Constants.JL); // JL
os.writeOR(Register.EAX, Register.EDX);
os.writeJCC(endLabel, X86Constants.JZ); // value1 == value2
/** GT */
os.writeINC(Register.ESI);
os.writeJMP(endLabel);
/** LT */
os.setObjectRef(ltLabel);
os.writeDEC(Register.ESI);
os.setObjectRef(endLabel);
helper.writePUSH(Register.ESI);
}
/**
* @param v
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lconst(long)
*/
public final void visit_lconst(long v) {
final int lsb = (int) (v & 0xFFFFFFFFL);
final int msb = (int) ((v >>> 32) & 0xFFFFFFFFL);
//log.debug("lconst v=" + NumberUtils.hex(v,16) + ",lsb=" +
// NumberUtils.hex(lsb, 8) +
// ",msb=" + NumberUtils.hex(msb, 8));
os.writeMOV_Const(T0, lsb);
os.writeMOV_Const(T1, msb);
helper.writePUSH64(T0, T1);
}
/**
* @param value
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ldc(VmConstString)
*/
public final void visit_ldc(VmConstString value) {
// Get string constant
helper.writeGetStaticsEntry(curInstrLabel, T0, value);
helper.writePUSH(T0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ldiv()
*/
public final void visit_ldiv() {
helper.invokeJavaMethod(context.getLdivMethod());
}
/**
* @param index
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lload(int)
*/
public final void visit_lload(int index) {
int ebpOfs = stackFrame.getWideEbpOffset(index);
os.writeMOV(INTSIZE, T0, FP, ebpOfs);
os.writeMOV(INTSIZE, T1, FP, ebpOfs + 4);
helper.writePUSH64(T0, T1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lmul()
*/
public final void visit_lmul() {
helper.writePOP64(Register.EBX, Register.ECX); // Value 2
helper.writePOP64(Register.ESI, Register.EDI); // Value 1
Label tmp1 = new Label(curInstrLabel + "$tmp1");
Label tmp2 = new Label(curInstrLabel + "$tmp2");
os.writeMOV(INTSIZE, Register.EAX, Register.EDI); // hi2
os.writeOR(Register.EAX, Register.ECX); // hi1 | hi2
os.writeJCC(tmp1, X86Constants.JNZ);
os.writeMOV(INTSIZE, Register.EAX, Register.ESI); // lo2
os.writeMUL_EAX(Register.EBX); // lo1*lo2
os.writeJMP(tmp2);
os.setObjectRef(tmp1);
os.writeMOV(INTSIZE, Register.EAX, Register.ESI); // lo2
os.writeMUL_EAX(Register.ECX); // hi1*lo2
os.writeMOV(INTSIZE, Register.ECX, Register.EAX);
os.writeMOV(INTSIZE, Register.EAX, Register.EDI); // hi2
os.writeMUL_EAX(Register.EBX); // hi2*lo1
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?