Search in sources :

Example 36 with RVMField

use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.

the class GenerateInterfaceDeclarations method emitCDeclarationsForJavaType.

static void emitCDeclarationsForJavaType(String Cname, RVMClass cls) {
    // How many instance fields are there?
    // 
    RVMField[] allFields = cls.getDeclaredFields();
    int fieldCount = 0;
    for (RVMField field : allFields) {
        if (!field.isStatic()) {
            fieldCount++;
        }
    }
    RVMField[] fields = new RVMField[fieldCount];
    for (int i = 0, j = 0; i < allFields.length; i++) {
        if (!allFields[i].isStatic()) {
            fields[j++] = allFields[i];
        }
    }
    Arrays.sort(fields, new AscendingOffsetComparator());
    // Emit field declarations
    // 
    pln("struct " + Cname + " {");
    // Set up cursor - scalars will waste 4 bytes on 64-bit arch
    // 
    boolean needsAlign = VM.BuildFor64Addr;
    int addrSize = VM.BuildFor32Addr ? 4 : 8;
    // Header Space for objects
    int startOffset = ObjectModel.objectStartOffset(cls);
    Offset current = Offset.fromIntSignExtend(startOffset);
    for (int i = 0; current.sLT(fields[0].getOffset()); i++) {
        pln("  uint32_t    headerPadding" + i + ";");
        current = current.plus(4);
    }
    for (int i = 0; i < fields.length; i++) {
        RVMField field = fields[i];
        TypeReference t = field.getType();
        Offset offset = field.getOffset();
        String name = field.getName().toString();
        // Align by blowing 4 bytes if needed
        if (needsAlign && current.plus(4).EQ(offset)) {
            pln("  uint32_t    padding" + i + ";");
            current = current.plus(4);
        }
        if (!current.EQ(offset)) {
            System.err.printf("current (%s) and offset (%s) are neither identical nor differ by 4", unboxedValueString(current), unboxedValueString(offset));
            System.exit(1);
        }
        if (t.isIntType()) {
            current = current.plus(4);
            pln("   uint32_t " + name + ";");
        } else if (t.isLongType()) {
            current = current.plus(8);
            pln("   uint64_t " + name + ";");
        } else if (t.isWordLikeType()) {
            pln("   Address " + name + ";");
            current = current.plus(addrSize);
        } else if (t.isArrayType() && t.getArrayElementType().isWordLikeType()) {
            pln("   Address * " + name + ";");
            current = current.plus(addrSize);
        } else if (t.isArrayType() && t.getArrayElementType().isIntType()) {
            pln("   unsigned int * " + name + ";");
            current = current.plus(addrSize);
        } else if (t.isReferenceType()) {
            pln("   Address " + name + ";");
            current = current.plus(addrSize);
        } else {
            System.err.println("Unexpected field " + name + " with type " + t);
            throw new RuntimeException("unexpected field type");
        }
    }
    pln("};");
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Services.unboxedValueString(org.jikesrvm.util.Services.unboxedValueString) Offset(org.vmmagic.unboxed.Offset)

Example 37 with RVMField

use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.

the class EntrypointHelper method verifyPresenceOfEntrypointAnnotation.

private static void verifyPresenceOfEntrypointAnnotation(RVMMember member) {
    if (VM.VerifyAssertions && !(member.isAnnotationPresent(Entrypoint.class))) {
        // For certain methods, it's clear that they're accessed by the
        // compiler, so an annotation is not required:
        boolean annotationRequired = true;
        if (member instanceof RVMMethod) {
            RVMMethod m = (RVMMethod) member;
            RVMClass declClass = m.getDeclaringClass();
            if (declClass.getTypeRef().isMagicType() || declClass.getTypeRef().isUnboxedType() || // it's the VM's job to handle those correctly
            declClass.getPackageName().startsWith("java.lang")) {
                annotationRequired = false;
            }
        }
        // Don't require annotations on fields for the class library.
        if (member instanceof RVMField) {
            RVMField field = (RVMField) member;
            RVMClass declClass = field.getDeclaringClass();
            if (declClass.getPackageName().startsWith("java.lang")) {
                annotationRequired = false;
            }
        }
        if (annotationRequired) {
            String msg = "WARNING: MISSING @Entrypoint ANNOTATION: " + member + " is missing an @Entrypoint annotation!";
            throw new Error(msg);
        }
    }
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Entrypoint(org.vmmagic.pragma.Entrypoint) RVMField(org.jikesrvm.classloader.RVMField) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 38 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) {
    RVMField field = fieldRef.peekResolvedField();
    TypeReference fieldType = fieldRef.getFieldContentsType();
    Offset fieldOffset = field.getOffset();
    if (NEEDS_OBJECT_GETFIELD_BARRIER && fieldType.isReferenceType() && !field.isUntraced()) {
        Barriers.compileGetfieldBarrierImm(this, fieldOffset, fieldRef.getId());
        discardSlots(1);
        pushAddr(T0);
    } else {
        // T1 = object reference
        popAddr(T1);
        if (fieldType.isReferenceType() || fieldType.isWordLikeType()) {
            // 32/64bit reference/word load
            asm.emitLAddrOffset(T0, T1, fieldOffset);
            pushAddr(T0);
        } else if (fieldType.isBooleanType()) {
            // 8bit unsigned load
            asm.emitLBZoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isByteType()) {
            // 8bit signed load
            asm.emitLBZoffset(T0, T1, fieldOffset);
            // sign extend
            asm.emitEXTSB(T0, T0);
            pushInt(T0);
        } else if (fieldType.isShortType()) {
            // 16bit signed load
            asm.emitLHAoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isCharType()) {
            // 16bit unsigned load
            asm.emitLHZoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isIntType() || fieldType.isFloatType()) {
            // 32bit load
            asm.emitLIntOffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else {
            // 64bit load
            if (VM.VerifyAssertions)
                VM._assert(fieldType.isLongType() || fieldType.isDoubleType());
            asm.emitLFDoffset(F0, T1, fieldOffset);
            pushDouble(F0);
        }
    }
    if (field.isVolatile()) {
        // JMM: post-barrier when first operation
        // LoadLoad and LoadStore barriers.
        asm.emitHWSYNC();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 39 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();
    TypeReference fieldType = fieldRef.getFieldContentsType();
    if (NEEDS_OBJECT_GETSTATIC_BARRIER && fieldType.isReferenceType() && !field.isUntraced()) {
        Barriers.compileGetstaticBarrierImm(this, fieldOffset, fieldRef.getId());
        pushAddr(T0);
    } else if (fieldRef.getSize() <= BYTES_IN_INT) {
        // field is one word
        asm.emitLIntToc(T0, fieldOffset);
        pushInt(T0);
    } else {
        // field is two words (double or long ( or address on PPC64))
        if (VM.VerifyAssertions)
            VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
        if (VM.BuildFor64Addr && fieldRef.getNumberOfStackSlots() == 1) {
            // address only 1 stackslot!!!
            asm.emitLAddrToc(T0, fieldOffset);
            pushAddr(T0);
        } else {
            asm.emitLFDtoc(F0, fieldOffset, T0);
            pushDouble(F0);
        }
    }
    if (field.isVolatile()) {
        // JMM: post-barrier when first operation
        // LoadLoad and LoadStore barriers.
        asm.emitHWSYNC();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 40 with RVMField

use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.

the class GenerateMachineSpecificMagic method generateMagic.

/**
 * "Semantic inlining" of methods of the Magic class.
 * Based on the methodName, generate a sequence of opt instructions
 * that implement the magic, updating the stack as necessary
 *
 * @param bc2ir the bc2ir object generating the ir containing this magic
 * @param gc == bc2ir.gc
 * @param meth the RVMMethod that is the magic method
 * @return {@code true} if and only if magic was generated
 */
public static boolean generateMagic(BC2IR bc2ir, GenerationContext gc, MethodReference meth) throws MagicNotImplementedException {
    Atom methodName = meth.getName();
    PhysicalRegisterSet phys = gc.getTemps().getPhysicalRegisterSet().asIA32();
    if (methodName == MagicNames.getESIAsThread) {
        RegisterOperand rop = gc.getTemps().makeTROp();
        bc2ir.markGuardlessNonNull(rop);
        bc2ir.push(rop);
    } else if (methodName == MagicNames.setESIAsThread) {
        Operand val = bc2ir.popRef();
        if (val instanceof RegisterOperand) {
            bc2ir.appendInstruction(Move.create(REF_MOVE, gc.getTemps().makeTROp(), val));
        } else {
            String msg = " Unexpected operand Magic.setESIAsThread";
            throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    } else if (methodName == MagicNames.getFramePointer) {
        gc.forceFrameAllocation();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        RVMField f = ArchEntrypoints.framePointerField;
        RegisterOperand pr = new RegisterOperand(phys.getESI(), TypeReference.Address);
        bc2ir.appendInstruction(GetField.create(GETFIELD, val, pr.copy(), new AddressConstantOperand(f.getOffset()), new LocationOperand(f), new TrueGuardOperand()));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getJTOC || methodName == MagicNames.getTocPointer) {
        TypeReference t = (methodName == MagicNames.getJTOC ? TypeReference.IntArray : TypeReference.Address);
        RegisterOperand val = gc.getTemps().makeTemp(t);
        AddressConstantOperand addr = new AddressConstantOperand(Magic.getTocPointer());
        bc2ir.appendInstruction(Move.create(REF_MOVE, val, addr));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.synchronizeInstructionCache) {
    // nothing required on Intel
    } else if (methodName == MagicNames.prefetch) {
        bc2ir.appendInstruction(CacheOp.create(PREFETCH, bc2ir.popAddress()));
    } else if (methodName == MagicNames.pause) {
        bc2ir.appendInstruction(Empty.create(PAUSE));
    } else if (methodName == MagicNames.illegalInstruction) {
        bc2ir.appendInstruction(Empty.create(ILLEGAL_INSTRUCTION));
    } else if (methodName == MagicNames.getCallerFramePointer) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCallerFramePointer) {
        Operand val = bc2ir.popAddress();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
    } else if (methodName == MagicNames.getCompiledMethodID) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Load.create(INT_LOAD, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCompiledMethodID) {
        Operand val = bc2ir.popInt();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(INT_STORE, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
    } else if (methodName == MagicNames.getReturnAddressLocation) {
        Operand fp = bc2ir.popAddress();
        Instruction s = bc2ir._binaryHelper(REF_ADD, fp, offsetOperand(STACKFRAME_RETURN_ADDRESS_OFFSET), TypeReference.Address);
        bc2ir.appendInstruction(s);
    } else {
        // Distinguish between magics that we know we don't implement
        // (and never plan to implement) and those (usually new ones)
        // that we want to be warned that we don't implement.
        String msg = " Magic method not implemented: " + meth;
        if (methodName == MagicNames.returnToNewStack) {
            throw MagicNotImplementedException.EXPECTED(msg);
        } else {
            return false;
        // throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    }
    return true;
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IRTools.offsetOperand(org.jikesrvm.compilers.opt.ir.IRTools.offsetOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Atom(org.jikesrvm.classloader.Atom) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

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