use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emitDynamicLinkingSequence.
/**
* Emit dynamic linking sequence placing the offset of the given member in reg
* @param asm assembler to generate code into
* @param reg register to hold offset to method
* @param ref method reference to be resolved
* @param couldBeZero could the value in the offsets table require resolving
*/
static void emitDynamicLinkingSequence(Assembler asm, GPR reg, MemberReference ref, boolean couldBeZero) {
int memberId = ref.getId();
Offset memberOffset = Offset.fromIntZeroExtend(memberId << 2);
Offset tableOffset = Entrypoints.memberOffsetsField.getOffset();
if (couldBeZero) {
// branch here after dynamic class loading
int retryLabel = asm.getMachineCodeIndex();
// reg is offsets table
asm.generateJTOCloadWord(reg, tableOffset);
if (VM.BuildFor32Addr) {
// reg is offset of member, or 0 if member's class isn't loaded
asm.emitMOV_Reg_RegDisp(reg, reg, memberOffset);
} else {
// reg is offset of member, or 0 if member's class isn't loaded
asm.emitMOVSXDQ_Reg_RegDisp(reg, reg, memberOffset);
}
if (NEEDS_DYNAMIC_LINK == 0) {
// reg ?= NEEDS_DYNAMIC_LINK, is field's class loaded?
asm.emitTEST_Reg_Reg(reg, reg);
} else {
// reg ?= NEEDS_DYNAMIC_LINK, is field's class loaded?
asm.emitCMP_Reg_Imm(reg, NEEDS_DYNAMIC_LINK);
}
// if so, skip call instructions
ForwardReference fr = asm.forwardJcc(NE);
// pass member's dictId
asm.emitPUSH_Imm(memberId);
// pass 1 parameter word
genParameterRegisterLoad(asm, 1);
Offset resolverOffset = Entrypoints.resolveMemberMethod.getOffset();
// does class loading as sideffect
asm.generateJTOCcall(resolverOffset);
// reload reg with valid value
asm.emitJMP_Imm(retryLabel);
// come from Jcc above.
fr.resolve(asm);
} else {
// reg is offsets table
asm.generateJTOCloadWord(reg, tableOffset);
if (VM.BuildFor32Addr) {
// reg is offset of member
asm.emitMOV_Reg_RegDisp(reg, reg, memberOffset);
} else {
// reg is offset of member
asm.emitMOVSXDQ_Reg_RegDisp(reg, reg, memberOffset);
}
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genMonitorEnter.
/**
* Generate instructions to acquire lock on entry to a method
*/
private void genMonitorEnter() {
try {
if (method.isStatic()) {
Offset klassOffset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass.getClassForType()));
// push java.lang.Class object for klass
asm.generateJTOCpush(klassOffset);
} else {
// push "this" object
asm.emitPUSH_RegDisp(ESP, localOffset(0));
}
// pass 1 parameter
genParameterRegisterLoad(asm, 1);
asm.generateJTOCcall(Entrypoints.lockMethod.getOffset());
// after this instruction, the method has the monitor
lockOffset = asm.getMachineCodeIndex();
} catch (UnreachableBytecodeException e) {
asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_ret.
@Override
protected void emit_ret(int index) {
try {
Offset offset = localOffset(index);
// Can be:
// asm.emitJMP_RegDisp(ESP, offset);
// but this will cause call-return branch prediction pairing to fail
asm.emitPUSH_RegDisp(ESP, offset);
asm.emitRET();
} catch (UnreachableBytecodeException e) {
asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_invoke_compiledmethod.
/**
* OSR routine to emit code to invoke a compiled method (with known jtoc
* offset). Treat it like a resolved invoke static, but take care of
* this object in the case.<p>
*
* I have not thought about GCMaps for invoke_compiledmethod.<p>
* TODO: Figure out what the above GCMaps comment means and fix it!
*/
@Override
protected void emit_invoke_compiledmethod(CompiledMethod cm) {
Offset methodOffset = cm.getOsrJTOCoffset();
boolean takeThis = !cm.method.isStatic();
MethodReference ref = cm.method.getMemberRef().asMethodReference();
genParameterRegisterLoad(ref, takeThis);
asm.generateJTOCcall(methodOffset);
genResultRegisterUnload(ref);
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_aload_resolved_getfield.
/**
* Emits code to load a reference local variable and then perform a field load
* @param index the local index to load
* @param fieldRef the referenced field
*/
@Override
protected void emit_aload_resolved_getfield(int index, FieldReference fieldRef) {
try {
Offset offset = localOffset(index);
TypeReference fieldType = fieldRef.getFieldContentsType();
RVMField field = fieldRef.peekResolvedField();
Offset fieldOffset = field.getOffset();
if (field.isReferenceType()) {
// 32/64bit reference load
if (NEEDS_OBJECT_GETFIELD_BARRIER && !field.isUntraced()) {
emit_regular_aload(index);
Barriers.compileGetfieldBarrierImm(asm, fieldOffset, fieldRef.getId());
} else {
// S0 is object reference
stackMoveHelper(S0, offset);
// place field value on stack
asm.emitPUSH_RegDisp(S0, fieldOffset);
}
} else if (fieldType.isBooleanType()) {
// 8bit unsigned load
// S0 is object reference
stackMoveHelper(S0, offset);
// T0 is field value
asm.emitMOVZX_Reg_RegDisp_Byte(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isByteType()) {
// 8bit signed load
// S0 is object reference
stackMoveHelper(S0, offset);
// T0 is field value
asm.emitMOVSX_Reg_RegDisp_Byte(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isShortType()) {
// 16bit signed load
// S0 is object reference
stackMoveHelper(S0, offset);
// T0 is field value
asm.emitMOVSX_Reg_RegDisp_Word(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isCharType()) {
// 16bit unsigned load
// S0 is object reference
stackMoveHelper(S0, offset);
// T0 is field value
asm.emitMOVZX_Reg_RegDisp_Word(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
} else if (fieldType.isIntType() || fieldType.isFloatType() || (VM.BuildFor32Addr && fieldType.isWordLikeType())) {
// 32bit load
// S0 is object reference
stackMoveHelper(S0, offset);
if (VM.BuildFor32Addr) {
// place value on stack
asm.emitPUSH_RegDisp(S0, fieldOffset);
} else {
// T0 is field value
asm.emitMOV_Reg_RegDisp(T0, S0, fieldOffset);
// place value on stack
asm.emitPUSH_Reg(T0);
}
} else {
// 64bit load
if (VM.VerifyAssertions) {
VM._assert(fieldType.isLongType() || fieldType.isDoubleType() || (VM.BuildFor64Addr && fieldType.isWordLikeType()));
}
// S0 is object reference
stackMoveHelper(S0, offset);
if (VM.BuildFor32Addr && field.isVolatile()) {
// as a slightly optimized Intel memory copy using the FPU
if (SSE2_BASE) {
// XMM0 is field value
asm.emitMOVQ_Reg_RegDisp(XMM0, S0, fieldOffset);
// adjust stack down to hold 64bit value
adjustStack(-2 * WORDSIZE, true);
// replace reference with value on stack
asm.emitMOVQ_RegInd_Reg(SP, XMM0);
} else {
// FP0 is field value
asm.emitFLD_Reg_RegDisp_Quad(FP0, S0, fieldOffset);
// adjust stack down to hold 64bit value
adjustStack(-2 * WORDSIZE, true);
// replace reference with value on stack
asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);
}
} else if (VM.BuildFor32Addr && !field.isVolatile()) {
// place high half on stack
asm.emitPUSH_RegDisp(S0, fieldOffset.plus(ONE_SLOT));
// place low half on stack
asm.emitPUSH_RegDisp(S0, fieldOffset);
} else {
if (!fieldType.isWordLikeType()) {
// add empty slot
adjustStack(-WORDSIZE, true);
}
// place value on stack
asm.emitPUSH_RegDisp(S0, fieldOffset);
}
}
} catch (UnreachableBytecodeException e) {
asm.emitINT_Imm(TRAP_UNREACHABLE_BYTECODE + RVM_TRAP_BASE);
}
}
Aggregations