use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class JNIFunctions method SetLongField.
/**
* SetLongField: set an instance field of type long
* @param env A JREF index for the JNI environment object
* @param objJREF a JREF index for the target object
* @param fieldID the id for the RVMField that describes this field
* @param value long value to assign
*/
private static void SetLongField(JNIEnvironment env, int objJREF, int fieldID, long value) {
if (traceJNI)
VM.sysWriteln("JNI called: SetLongField");
RuntimeEntrypoints.checkJNICountDownToGC();
try {
Object obj = env.getJNIRef(objJREF);
RVMField field = MemberReference.getFieldRef(fieldID).resolve();
field.setLongValueUnchecked(obj, value);
} catch (Throwable unexpected) {
if (traceJNI)
unexpected.printStackTrace(System.err);
env.recordException(unexpected);
}
}
use of org.jikesrvm.classloader.RVMField 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);
}
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_putstatic.
@Override
protected void emit_resolved_putstatic(FieldReference fieldRef) {
RVMField field = fieldRef.peekResolvedField();
Offset fieldOffset = field.getOffset();
if (NEEDS_OBJECT_PUTSTATIC_BARRIER && field.isReferenceType() && !field.isUntraced()) {
Barriers.compilePutstaticBarrierImm(asm, fieldOffset, fieldRef.getId());
} else {
if (field.getSize() <= BYTES_IN_INT) {
// field is one word
if (VM.BuildFor32Addr) {
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset));
} else {
asm.emitPOP_Reg(T1);
asm.generateJTOCstoreInt(fieldOffset, T1);
}
} else {
// field is two words (double or long)
if (VM.VerifyAssertions)
VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
if (VM.BuildFor32Addr) {
// JMM: we need to guarantee atomic access for volatile fields
if (field.isVolatile()) {
if (SSE2_BASE) {
asm.emitMOVQ_Reg_RegInd(XMM0, SP);
asm.emitMOVQ_Abs_Reg(Magic.getTocPointer().plus(fieldOffset), XMM0);
} else {
asm.emitFLD_Reg_RegInd_Quad(FP0, SP);
asm.emitFSTP_Abs_Reg_Quad(Magic.getTocPointer().plus(fieldOffset), FP0);
}
adjustStack(2 * WORDSIZE, false);
} else {
// store low part
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset));
// store high part
asm.emitPOP_Abs(Magic.getTocPointer().plus(fieldOffset).plus(WORDSIZE));
}
} else {
asm.generateJTOCpop(fieldOffset);
if (fieldRef.getNumberOfStackSlots() != 1) {
adjustStack(WORDSIZE, true);
}
}
}
}
if (field.isVolatile()) {
asm.emitMFENCE();
}
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_getfield.
@Override
protected void emit_resolved_getfield(FieldReference fieldRef) {
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()) {
Barriers.compileGetfieldBarrierImm(asm, fieldOffset, fieldRef.getId());
} else {
// T0 is object reference
asm.emitPOP_Reg(T0);
// place field value on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
}
} else if (fieldType.isBooleanType()) {
// 8bit unsigned load
// S0 is object reference
asm.emitPOP_Reg(S0);
// 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
asm.emitPOP_Reg(S0);
// 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
asm.emitPOP_Reg(S0);
// 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
asm.emitPOP_Reg(S0);
// 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
asm.emitPOP_Reg(S0);
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()));
}
// T0 is object reference
asm.emitPOP_Reg(T0);
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, T0, 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, T0, 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(T0, fieldOffset.plus(ONE_SLOT));
// place low half on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
} else {
if (!fieldType.isWordLikeType()) {
// add empty slot
adjustStack(-WORDSIZE, true);
}
// place value on stack
asm.emitPUSH_RegDisp(T0, fieldOffset);
}
}
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_resolved_getstatic.
@Override
protected void emit_resolved_getstatic(FieldReference fieldRef) {
RVMField field = fieldRef.peekResolvedField();
Offset fieldOffset = field.getOffset();
if (NEEDS_OBJECT_GETSTATIC_BARRIER && !fieldRef.getFieldContentsType().isPrimitiveType() && !field.isUntraced()) {
Barriers.compileGetstaticBarrierImm(asm, fieldOffset, fieldRef.getId());
return;
}
if (fieldRef.getSize() <= BYTES_IN_INT) {
// field is one word
if (VM.BuildFor32Addr) {
asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset));
} else {
asm.generateJTOCloadInt(T0, fieldOffset);
asm.emitPUSH_Reg(T0);
}
} else {
// field is two words (double or long)
if (VM.VerifyAssertions)
VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
if (VM.BuildFor32Addr) {
// JMM: we need to guarantee atomic access for volatile fields
if (field.isVolatile()) {
if (SSE2_BASE) {
asm.emitMOVQ_Reg_Abs(XMM0, Magic.getTocPointer().plus(fieldOffset));
adjustStack(-2 * WORDSIZE, true);
asm.emitMOVQ_RegInd_Reg(SP, XMM0);
} else {
asm.emitFLD_Reg_Abs_Quad(FP0, Magic.getTocPointer().plus(fieldOffset));
adjustStack(-2 * WORDSIZE, true);
asm.emitFSTP_RegInd_Reg_Quad(SP, FP0);
}
} else {
// get high part
asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset).plus(WORDSIZE));
// get low part
asm.emitPUSH_Abs(Magic.getTocPointer().plus(fieldOffset));
}
} else {
if (fieldRef.getNumberOfStackSlots() != 1) {
adjustStack(-WORDSIZE, true);
}
asm.generateJTOCpush(fieldOffset);
}
}
}
Aggregations