use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class Simplifier method getField.
private static DefUseEffect getField(Instruction s, OptOptions opts) {
if (opts.SIMPLIFY_FIELD_OPS) {
Operand ref = GetField.getRef(s);
if (VM.VerifyAssertions && ref.isNullConstant()) {
// Simplify to an unreachable operand, this instruction is dead code
// guarded by a nullcheck that should already have been simplified
RegisterOperand result = GetField.getClearResult(s);
Move.mutate(s, IRTools.getMoveOp(result.getType()), result, new UnreachableOperand());
return DefUseEffect.MOVE_FOLDED;
} else if (opts.SIMPLIFY_CHASE_FINAL_FIELDS && ref.isObjectConstant()) {
// A constant object references this field which is
// final. As the reference is final the constructor
// of the referred object MUST have already completed.
// This also implies that the type MUST have been resolved.
RVMField field = GetField.getLocation(s).getFieldRef().resolve();
if (field.isFinal() && field.getDeclaringClass().isInitialized()) {
try {
ConstantOperand op = StaticFieldReader.getFieldValueAsConstant(field, ref.asObjectConstant().value);
Move.mutate(s, IRTools.getMoveOp(field.getType()), GetField.getClearResult(s), op);
return DefUseEffect.MOVE_FOLDED;
} catch (NoSuchFieldException e) {
if (VM.runningVM) {
// this is unexpected
throw new Error("Unexpected exception", e);
} else {
// Field not found during bootstrap due to chasing a field
// only valid in the bootstrap JVM
}
}
}
}
}
return DefUseEffect.UNCHANGED;
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class FieldAnalysis method perform.
/**
* Record field analysis information for an IR.
*
* @param ir the governing IR
*/
@Override
public void perform(IR ir) {
// BOTTOM if the concrete type is unknown.
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (PutField.conforms(s)) {
LocationOperand l = PutField.getLocation(s);
RVMField f = l.getFieldRef().peekResolvedField();
if (f == null)
continue;
if (!isCandidate(f.getType()))
continue;
// gleaned from context, does not hold everywhere
if (s.position().getMethod() != ir.method) {
continue;
}
Operand value = PutField.getValue(s);
if (value.isRegister()) {
if (value.asRegister().isPreciseType()) {
TypeReference type = value.asRegister().getType();
recordConcreteType(ir.method, f, type);
} else {
recordBottom(ir.method, f);
}
}
} else if (PutStatic.conforms(s)) {
LocationOperand l = PutStatic.getLocation(s);
RVMField f = l.getFieldRef().peekResolvedField();
if (f == null)
continue;
if (!isCandidate(f.getType()))
continue;
// gleaned from context, does not hold everywhere
if (s.position().getMethod() != ir.method) {
continue;
}
Operand value = PutStatic.getValue(s);
if (value.isRegister()) {
if (value.asRegister().isPreciseType()) {
TypeReference type = value.asRegister().getType();
recordConcreteType(ir.method, f, type);
} else {
recordBottom(ir.method, f);
}
}
}
}
}
use of org.jikesrvm.classloader.RVMField 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;
}
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class StaticFieldReader method getJDKField.
/**
* Converts a RVMField to a java.lang.reflect.Field.
*
* @param field the internal field representation
* @return the java.lang field representation
* @throws NoSuchFieldException when the field could not be found
*/
private static Field getJDKField(RVMField field) throws NoSuchFieldException {
try {
String cn = field.getDeclaringClass().toString();
if (VM.BuildForGnuClasspath && field.getDeclaringClass().getClassForType().equals(java.lang.reflect.Proxy.class) && field.getName().toString().equals("proxyClasses")) {
// Avoid confusing bootstrap JVM and classpath fields
throw new NoSuchFieldException(field.toString());
}
Field f = Class.forName(cn).getDeclaredField(field.getName().toString());
f.setAccessible(true);
return f;
} catch (NoSuchFieldError e) {
throwNoSuchFieldExceptionWithCause(field, e);
} catch (ClassNotFoundException e) {
throwNoSuchFieldExceptionWithCause(field, e);
} catch (NoClassDefFoundError e) {
throwNoSuchFieldExceptionWithCause(field, e);
} catch (IllegalAccessError e) {
throwNoSuchFieldExceptionWithCause(field, e);
} catch (UnsatisfiedLinkError e) {
throwNoSuchFieldExceptionWithCause(field, e);
}
assertNotReached();
return null;
}
use of org.jikesrvm.classloader.RVMField 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;
}
}
Aggregations