Search in sources :

Example 21 with RVMField

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);
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField)

Example 22 with RVMField

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);
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 23 with RVMField

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();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) Offset(org.vmmagic.unboxed.Offset)

Example 24 with RVMField

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);
        }
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 25 with RVMField

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);
        }
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) Offset(org.vmmagic.unboxed.Offset)

Aggregations

RVMField (org.jikesrvm.classloader.RVMField)80 TypeReference (org.jikesrvm.classloader.TypeReference)21 Offset (org.vmmagic.unboxed.Offset)14 RVMClass (org.jikesrvm.classloader.RVMClass)12 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)9 Field (java.lang.reflect.Field)8 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)8 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 Atom (org.jikesrvm.classloader.Atom)7 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)6 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)6 RVMType (org.jikesrvm.classloader.RVMType)5 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)5 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)5 Address (org.vmmagic.unboxed.Address)5 FieldReference (org.jikesrvm.classloader.FieldReference)4 RVMMethod (org.jikesrvm.classloader.RVMMethod)4 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)4 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)4 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)4