Search in sources :

Example 76 with TypeReference

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

the class Operand method meet.

/**
 * Meet two operands based on their positions in the operand lattice.
 * For the purposes of doing dataflow analysis, Operands can be
 * thought of as forming a lattice.
 * This function takes two operands and returns their meet (glb).
 * We use <code>null</code> to stand for bottom (the meet of
 * the two operands is an illegal value).  For exmaple,
 * meet(5.0, "hi") would evalaute to bottom.
 * Meet returns op1 iff conservativelyApproximates(op1, op2):
 * this is exploited in BC2IR to avoid doing redundant
 * work.
 * <p>
 * Unfortunately there is a fair amount of code duplication
 * between {@link #conservativelyApproximates} and
 * {@link #meet}, but factoring out the common control logic
 * is a non-trivial task.
 *
 * @param op1  the first operand to meet
 * @param op2  the second operand to meet
 * @param reg  the <code>Register</code> to use to
 *             create a new <code>RegisterOperand</code>
 *             if meeting op1 and op2 requires doing so.
 * @return the Operand that is the meet of op1 and op2.
 *         This function will return <code>null</code> when
 *         the meet evaluates to bottom.  It will return
 *         op1 when conservativelyApproximates(op1, op2)
 *         evaluates to <code>true</code>.
 */
public static Operand meet(Operand op1, Operand op2, Register reg) {
    // Step 1: Handler pointer equality and bottom
    if (op1 == op2) {
        if (DBG_OPERAND_LATTICE) {
            if (op1 == null) {
                VM.sysWriteln("Both operands are bottom");
            } else {
                VM.sysWriteln("Operands are identical");
            }
        }
        return op1;
    }
    if (op1 == null) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Op1 was already bottom");
        }
        return op1;
    }
    if (op2 == null) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Op2 is bottom (but op1 was not)");
        }
        return op2;
    }
    // Step 2: op1 is <null> (the null constant)
    if (op1 instanceof NullConstantOperand) {
        if (op2 instanceof NullConstantOperand) {
            if (DBG_OPERAND_LATTICE) {
                VM.sysWriteln("Both operands are <null>");
            }
            return op1;
        } else {
            /*
         * XXX Opt compiler guru please check :)
         *
         * Protect this code from crashing if op2 is DUMMY.  As I understand
         * the calling code this shouldn't happen, but the case for RegisterOperand
         * handles it so I guess it's not too bad for a NullConstantOperand
         * to do so.
         *
         * -- Robin Garner 1 Feb 7
         */
            if (op2 instanceof ReturnAddressOperand || op2 == BC2IR.DUMMY) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Incompatabily typed operands");
                }
                // bottom
                return null;
            }
            TypeReference type2 = op2.getType();
            if (type2.isReferenceType()) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("op1 is <null>, but op2 is other ref type");
                }
                return new RegisterOperand(reg, type2);
            } else {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("op1 is <null>, but op2 is not a ref type");
                }
                // bottom
                return null;
            }
        }
    }
    // Step 3: op1 is some other constant
    if (op1.isConstant()) {
        if (op1.similar(op2)) {
            if (DBG_OPERAND_LATTICE) {
                VM.sysWriteln("op1 and op2 are similar constants");
            }
            return op1;
        } else {
            TypeReference superType = ClassLoaderProxy.findCommonSuperclass(op1.getType(), op2.getType());
            if (superType == null) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("op1 and op2 have incompatible types");
                }
                // bottom
                return null;
            } else {
                return new RegisterOperand(reg, superType);
            }
        }
    }
    // the various Flag bits are considered as well....
    if (op1.isRegister()) {
        RegisterOperand rop1 = op1.asRegister();
        TypeReference type1 = rop1.getType();
        if (op2.isRegister()) {
            RegisterOperand rop2 = op2.asRegister();
            TypeReference type2 = rop2.getType();
            if (type1 == type2) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Identically typed register operands, checking flags...");
                }
                if (rop1.hasLessConservativeFlags(rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("mismatch");
                    }
                    RegisterOperand res = new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
                    if (rop1.getGuard() instanceof Operand && rop2.getGuard() instanceof Operand && (rop1.getGuard().similar((rop2.getGuard())))) {
                        // compatible, so preserve onto res
                        res.setGuard(rop1.getGuard());
                    }
                    res.meetInheritableFlags(rop2);
                    return res;
                } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are registers of identical type with compatible flags but with incompatible non-null guards");
                    }
                    // by not setting guard we mark as possible null
                    return new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("match");
                    }
                    return op1;
                }
            } else if (compatiblePrimitives(type1, type2) || ClassLoaderProxy.includesType(type1, type2) == YES) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWrite("Compatibly typed register operands, checking flags...");
                }
                if (rop1.isPreciseType() || rop1.hasLessConservativeFlags(rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("mismatch");
                    }
                    RegisterOperand res = new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
                    res.meetInheritableFlags(rop2);
                    // even if both op1 & op2 are precise,
                    // op1.type != op2.type, so clear it on res
                    res.clearPreciseType();
                    if (rop1.getGuard() instanceof Operand && rop2.getGuard() instanceof Operand && (rop1.getGuard().similar((rop2.getGuard())))) {
                        // it matched, so preserve onto res.
                        res.setGuard(rop1.getGuard());
                    }
                    return res;
                } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are registers of compatible type and flags but with incompatible non-null guards");
                    }
                    return new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("match");
                    }
                    return op1;
                }
            } else {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Incompatibly typed register operands...(" + type1 + ", " + type2 + ")...");
                }
                TypeReference resType = ClassLoaderProxy.findCommonSuperclass(type1, type2);
                if (resType == null) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("no common supertype, returning bottom");
                    }
                    // bottom
                    return null;
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("found common supertype");
                    }
                    RegisterOperand res = new RegisterOperand(reg, resType, rop1.getFlags(), false, false);
                    res.meetInheritableFlags(rop2);
                    // invalid on res
                    res.clearPreciseType();
                    // invalid on res
                    res.clearDeclaredType();
                    if (rop1.getGuard() instanceof Operand && rop2.getGuard() instanceof Operand && (rop1.getGuard().similar((rop2.getGuard())))) {
                        // it matched, so preserve onto res.
                        res.setGuard(rop1.getGuard());
                    }
                    return res;
                }
            }
        } else {
            if (op2 instanceof ReturnAddressOperand || op2 == BC2IR.DUMMY) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWrite("Incompatibly typed operands");
                }
                // bottom
                return null;
            }
            TypeReference type2 = op2.getType();
            if (type1 == type2 || compatiblePrimitives(type1, type2) || (ClassLoaderProxy.includesType(type1, type2) == YES)) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWrite("Compatibly typed register & other operand, checking flags...");
                }
                RegisterOperand res = rop1;
                if (res.isPreciseType() && type1 != type2) {
                    res = res.copyU2U();
                    res.clearPreciseType();
                }
                if ((rop1.getGuard() instanceof Operand) && ((type2 == TypeReference.NULL_TYPE) || (type2.isIntLikeType() && op2.asIntConstant().value == 0) || (type2.isWordLikeType() && op2.asAddressConstant().value.isZero()) || (type2.isLongType() && op2.asLongConstant().value == 0L))) {
                    res = res.copyU2U();
                    res.setGuard(null);
                }
                if (DBG_OPERAND_LATTICE) {
                    if (res == rop1) {
                        VM.sysWriteln("match");
                    } else {
                        VM.sysWriteln("mismatch");
                    }
                }
                return res;
            } else {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWrite("Incompatibly typed register & other operand...(" + type1 + ", " + type2 + ")...");
                }
                TypeReference resType = ClassLoaderProxy.findCommonSuperclass(type1, type2);
                if (resType == null) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("no common supertype, returning bottom");
                    }
                    // bottom
                    return null;
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("found common supertype");
                    }
                    return new RegisterOperand(reg, resType);
                }
            }
        }
    }
    // Step 5: op1 is some IRGEN operand
    if (op1.similar(op2)) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Compatible BC2IR.* operands");
        }
        return op1;
    } else {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Incompatible BC2IR.* operands, returning bottom");
        }
        // bottom
        return null;
    }
}
Also used : ReturnAddressOperand(org.jikesrvm.compilers.opt.bc2ir.ReturnAddressOperand) ReturnAddressOperand(org.jikesrvm.compilers.opt.bc2ir.ReturnAddressOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 77 with TypeReference

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

the class Operand method conservativelyApproximates.

/**
 * Compare two operands based on their positions in the operand lattice.
 * For the purposes of doing dataflow analysis, Operands can be
 * thought of as forming a lattice.
 * This function compares two operands and returns whether or
 * not op1 is a conservative approximation of op2.
 * Or in other words, if conservativelyApproximates(op1, op2)
 * then meet(op1, op2) = op1.
 * Note that lattices are partial orders, so it is quite
 * possible for both conservativelyApproximates(op1, op2)
 * and conservativelyApproximates(op2, op1) to return false.
 *
 * @param op1 the first operand to compare
 * @param op2 the second operand to compare
 * @return <code>true</code> if op1 conservatively approximates op2 or
 *         <code>false</code> if it does not.
 */
public static boolean conservativelyApproximates(Operand op1, Operand op2) {
    // Step 1: Handle pointer equality and bottom
    if (op1 == op2) {
        if (DBG_OPERAND_LATTICE) {
            if (op2 == null) {
                VM.sysWriteln("operands are both bottom therefore trivially true");
            } else {
                VM.sysWriteln("operands are identical therefore trivially true");
            }
        }
        return true;
    }
    if (op1 == null) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("op1 is bottom, therefore trivially true");
        }
        return true;
    }
    if (op2 == null) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("op2 is bottom, therefore trivially false");
        }
        return false;
    }
    // Step 2: op1 is a constant but op2 is not the same constant
    if (op1.isConstant()) {
        if (op1.similar(op2)) {
            if (DBG_OPERAND_LATTICE) {
                VM.sysWriteln("operands are similar constants");
            }
            return true;
        } else {
            if (DBG_OPERAND_LATTICE) {
                VM.sysWriteln("op1 is a constant but op2 is not the same constant");
            }
            return false;
        }
    }
    // various Flag bits are considered as well....
    if (op1.isRegister()) {
        RegisterOperand rop1 = op1.asRegister();
        TypeReference type1 = rop1.getType();
        if (op2.isRegister()) {
            RegisterOperand rop2 = op2.asRegister();
            TypeReference type2 = rop2.getType();
            if (type1 == type2) {
                if (rop1.hasLessConservativeFlags(rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are registers of identical type, but incompatible flags");
                    }
                    return false;
                } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are registers of identical type, but with incompatible non-null guards");
                    }
                    return false;
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are compatible register operands");
                    }
                    return true;
                }
            } else if (compatiblePrimitives(type1, type2) || ClassLoaderProxy.includesType(type1, type2) == YES) {
                // types are ok, only have to worry about the flags
                if (rop1.isPreciseType() || rop1.hasLessConservativeFlags(rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Flag mismatch between type compatible register operands");
                    }
                    return false;
                } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Non-null guard mismatch between type compatible register operands");
                    }
                    return false;
                } else {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("Operands are compatible register operands");
                    }
                    return true;
                }
            } else {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Operands are type incompatible register operands");
                }
                return false;
            }
        } else {
            // op2 is not a register
            if (op2 instanceof ReturnAddressOperand || op2 == BC2IR.DUMMY) {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Operands are incompatibale values");
                }
                return false;
            }
            TypeReference type2 = op2.getType();
            if (type1 == type2 || compatiblePrimitives(type1, type2) || (ClassLoaderProxy.includesType(type1, type2) == YES)) {
                // only have to consider state of op1's flags.  Types are ok.
                if (rop1.isPreciseType() && (type1 != type2)) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("op1 preciseType bit will be incorrect");
                    }
                    return false;
                }
                if ((rop1.getGuard() instanceof Operand) && ((type2 == TypeReference.NULL_TYPE) || (type2.isIntLikeType() && op2.asIntConstant().value == 0) || (type2.isWordLikeType() && op2.asAddressConstant().value.EQ(Address.zero())) || (type2.isLongType() && op2.asLongConstant().value == 0L))) {
                    if (DBG_OPERAND_LATTICE) {
                        VM.sysWriteln("op1 non null guard will be incorrect");
                    }
                    return false;
                }
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("(Constant) op2 was compatible with register op1");
                }
                return true;
            } else {
                if (DBG_OPERAND_LATTICE) {
                    VM.sysWriteln("Op2 not compatible with register op1");
                }
                return false;
            }
        }
    }
    // Step 4: op1 is a IRGEN operand of some form
    if (op1.similar(op2)) {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Compatible BC2IR.* operands");
        }
        return true;
    } else {
        if (DBG_OPERAND_LATTICE) {
            VM.sysWriteln("Incompatible BC2IR.* operands");
        }
        return false;
    }
}
Also used : ReturnAddressOperand(org.jikesrvm.compilers.opt.bc2ir.ReturnAddressOperand) ReturnAddressOperand(org.jikesrvm.compilers.opt.bc2ir.ReturnAddressOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 78 with TypeReference

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

the class StaticFieldReader method getIntStaticFieldValue.

/**
 * Returns the current contents of an int-like static field.
 *
 * @param field a static field
 * @return the current value of the field
 * @throws NoSuchFieldException when the field could not be found
 */
public static int getIntStaticFieldValue(RVMField field) throws NoSuchFieldException {
    if (VM.runningVM) {
        return Statics.getSlotContentsAsInt(field.getOffset());
    } else {
        try {
            Field f = getJDKField(field);
            TypeReference fieldType = field.getType();
            if (fieldType.isBooleanType()) {
                boolean val = f.getBoolean(null);
                return val ? 1 : 0;
            } else if (fieldType.isByteType()) {
                return f.getByte(null);
            } else if (fieldType.isShortType()) {
                return f.getShort(null);
            } else if (fieldType.isIntType()) {
                return f.getInt(null);
            } else if (fieldType.isCharType()) {
                return f.getChar(null);
            } else {
                throw new OptimizingCompilerException("Unsupported type " + field + "\n");
            }
        } catch (IllegalAccessException e) {
            throwOptimizingCompilerExceptionBecauseOfIllegalAccess(field, e);
        } catch (IllegalArgumentException e) {
            throwOptimizingCompilerExceptionBecauseOfIllegalAccess(field, e);
        }
        assertNotReached();
        return 0;
    }
}
Also used : Field(java.lang.reflect.Field) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 79 with TypeReference

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

the class StaticFieldReader method getFieldValueAsConstant.

public static ConstantOperand getFieldValueAsConstant(RVMField field, Object obj) throws NoSuchFieldException {
    if (VM.VerifyAssertions) {
        boolean isFinalField = field.isFinal();
        boolean isInitializedField = field.getDeclaringClass().isInitialized() || field.getDeclaringClass().isInBootImage();
        if (!(isFinalField && isInitializedField)) {
            String msg = "Error reading field " + field;
            VM._assert(VM.NOT_REACHED, msg);
        }
    }
    TypeReference type = field.getType();
    if (VM.runningVM) {
        if (type.isReferenceType() && (!type.isMagicType() || type.isUnboxedArrayType())) {
            Object value = field.getObjectValueUnchecked(obj);
            if (value != null) {
                return new ObjectConstantOperand(value, Offset.zero());
            } else {
                return new NullConstantOperand();
            }
        } else if (type.isWordLikeType()) {
            return new AddressConstantOperand(field.getWordValueUnchecked(obj).toAddress());
        } else if (type.isIntType()) {
            return new IntConstantOperand(field.getIntValueUnchecked(obj));
        } else if (type.isBooleanType()) {
            return new IntConstantOperand(field.getBooleanValueUnchecked(obj) ? 1 : 0);
        } else if (type.isByteType()) {
            return new IntConstantOperand(field.getByteValueUnchecked(obj));
        } else if (type.isCharType()) {
            return new IntConstantOperand(field.getCharValueUnchecked(obj));
        } else if (type.isDoubleType()) {
            return new DoubleConstantOperand(field.getDoubleValueUnchecked(obj));
        } else if (type.isFloatType()) {
            return new FloatConstantOperand(field.getFloatValueUnchecked(obj));
        } else if (type.isLongType()) {
            return new LongConstantOperand(field.getLongValueUnchecked(obj));
        } else if (type.isShortType()) {
            return new IntConstantOperand(field.getShortValueUnchecked(obj));
        } else {
            OptimizingCompilerException.UNREACHABLE("Unknown type " + type);
            return null;
        }
    } else {
        try {
            String cn = field.getDeclaringClass().toString();
            Field f = Class.forName(cn).getDeclaredField(field.getName().toString());
            f.setAccessible(true);
            if (type.isReferenceType() && (!type.isMagicType() || type.isUnboxedArrayType())) {
                Object value = f.get(obj);
                if (value != null) {
                    return new ObjectConstantOperand(value, Offset.zero());
                } else {
                    return new NullConstantOperand();
                }
            } else if (type.isWordLikeType()) {
                Object value = f.get(obj);
                if (type.equals(TypeReference.Word))
                    return new AddressConstantOperand((Word) value);
                else if (type.equals(TypeReference.Address))
                    return new AddressConstantOperand((Address) value);
                else if (type.equals(TypeReference.Offset))
                    return new AddressConstantOperand((Offset) value);
                else if (type.equals(TypeReference.Extent))
                    return new AddressConstantOperand((Extent) value);
                else {
                    OptimizingCompilerException.UNREACHABLE("Unknown word type " + type);
                    return null;
                }
            } else if (type.isIntType()) {
                return new IntConstantOperand(f.getInt(obj));
            } else if (type.isBooleanType()) {
                return new IntConstantOperand(f.getBoolean(obj) ? 1 : 0);
            } else if (type.isByteType()) {
                return new IntConstantOperand(f.getByte(obj));
            } else if (type.isCharType()) {
                return new IntConstantOperand(f.getChar(obj));
            } else if (type.isDoubleType()) {
                return new DoubleConstantOperand(f.getDouble(obj));
            } else if (type.isFloatType()) {
                return new FloatConstantOperand(f.getFloat(obj));
            } else if (type.isLongType()) {
                return new LongConstantOperand(f.getLong(obj));
            } else if (type.isShortType()) {
                return new IntConstantOperand(f.getShort(obj));
            } else {
                OptimizingCompilerException.UNREACHABLE(cn + "." + f.getName() + " has unknown type " + type);
                return null;
            }
        } catch (IllegalArgumentException e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        } catch (IllegalAccessException e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        } catch (NoSuchFieldError e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        } catch (ClassNotFoundException e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        } catch (NoClassDefFoundError e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        } catch (IllegalAccessError e) {
            throwNoSuchFieldExceptionWithCause(field, e);
        }
        assertNotReached();
        return null;
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Address(org.vmmagic.unboxed.Address) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Extent(org.vmmagic.unboxed.Extent) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) Field(java.lang.reflect.Field) RVMField(org.jikesrvm.classloader.RVMField) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 80 with TypeReference

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

the class StaticFieldReader method getStaticFieldValue.

/**
 * Returns a constant operand with the current value of a static field.
 *
 * @param field the static field whose current value we want to read
 * @return a constant operand representing the current value of the field.
 * @throws NoSuchFieldException when the field could not be found
 */
public static ConstantOperand getStaticFieldValue(RVMField field) throws NoSuchFieldException {
    if (VM.VerifyAssertions) {
        boolean fieldIsReady = field.getDeclaringClass().isInitialized() || field.getDeclaringClass().isInBootImage();
        boolean isFinalField = field.isFinal();
        boolean isStaticField = field.isStatic();
        if (!(isFinalField && isStaticField && fieldIsReady)) {
            String msg = "Error reading field " + field;
            VM._assert(VM.NOT_REACHED, msg);
        }
    }
    TypeReference fieldType = field.getType();
    Offset off = field.getOffset();
    if ((fieldType == TypeReference.Address) || (fieldType == TypeReference.Word) || (fieldType == TypeReference.Offset) || (fieldType == TypeReference.Extent)) {
        Address val = getAddressStaticFieldValue(field);
        return new AddressConstantOperand(val);
    } else if (fieldType.isIntLikeType()) {
        int val = getIntStaticFieldValue(field);
        return new IntConstantOperand(val);
    } else if (fieldType.isLongType()) {
        long val = getLongStaticFieldValue(field);
        return new LongConstantOperand(val);
    } else if (fieldType.isFloatType()) {
        float val = getFloatStaticFieldValue(field);
        return new FloatConstantOperand(val, off);
    } else if (fieldType.isDoubleType()) {
        double val = getDoubleStaticFieldValue(field);
        return new DoubleConstantOperand(val, off);
    } else {
        // Reference type
        if (VM.VerifyAssertions)
            VM._assert(fieldType.isReferenceType());
        Object val = getObjectStaticFieldValue(field);
        if (val == null) {
            return new NullConstantOperand();
        } else if (fieldType == TypeReference.JavaLangString) {
            return new StringConstantOperand((String) val, off);
        } else if (fieldType == TypeReference.JavaLangClass) {
            Class<?> klass = (Class<?>) getObjectStaticFieldValue(field);
            RVMType type;
            if (VM.runningVM) {
                type = java.lang.JikesRVMSupport.getTypeForClass(klass);
            } else {
                type = TypeReference.findOrCreate(klass).resolve();
            }
            return new ClassConstantOperand(type.getClassForType(), off);
        } else {
            return new ObjectConstantOperand(val, off);
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Address(org.vmmagic.unboxed.Address) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) Offset(org.vmmagic.unboxed.Offset) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Aggregations

TypeReference (org.jikesrvm.classloader.TypeReference)164 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)58 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)43 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)38 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)30 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)28 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)27 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)24 RVMClass (org.jikesrvm.classloader.RVMClass)23 RVMField (org.jikesrvm.classloader.RVMField)21 Register (org.jikesrvm.compilers.opt.ir.Register)21 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)21 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)21 Address (org.vmmagic.unboxed.Address)21 RVMType (org.jikesrvm.classloader.RVMType)18 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)18 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)18 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)18 RVMMethod (org.jikesrvm.classloader.RVMMethod)17