use of org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand in project JikesRVM by JikesRVM.
the class GenerationContext method completeExceptionHandlers.
/**
* If the method is synchronized then we wrap it in a
* synthetic exception handler that unlocks & rethrows
* PRECONDITION: cfg, arguments & temps have been setup/initialized.
*
* @param isOutermost is this the outermost context (i.e. not an inlined context)
*/
private void completeExceptionHandlers(boolean isOutermost) {
if (method.isSynchronized() && !options.ESCAPE_INVOKEE_THREAD_LOCAL) {
ExceptionHandlerBasicBlock rethrow = new ExceptionHandlerBasicBlock(SYNTH_CATCH_BCI, inlineSequence, new TypeOperand(RVMType.JavaLangThrowableType), cfg);
rethrow.setExceptionHandlers(enclosingHandlers);
RegisterOperand ceo = temps.makeTemp(TypeReference.JavaLangThrowable);
Instruction s = Nullary.create(GET_CAUGHT_EXCEPTION, ceo);
appendInstruction(rethrow, s, SYNTH_CATCH_BCI);
Operand lockObject = getLockObject();
RVMMethod target = Entrypoints.unlockAndThrowMethod;
MethodOperand methodOp = MethodOperand.STATIC(target);
// Used to keep cfg correct
methodOp.setIsNonReturningCall(true);
s = Call.create2(CALL, null, new AddressConstantOperand(target.getOffset()), methodOp, lockObject, ceo.copyD2U());
appendInstruction(rethrow, s, RUNTIME_SERVICES_BCI);
cfg.insertBeforeInCodeOrder(epilogue, rethrow);
// (if enclosed by another catch of Throwable...)
if (enclosingHandlers != null) {
for (Enumeration<BasicBlock> e = enclosingHandlers.enumerator(); e.hasMoreElements(); ) {
BasicBlock eh = e.nextElement();
rethrow.insertOut(eh);
}
}
rethrow.setCanThrowExceptions();
rethrow.setMayThrowUncaughtException();
rethrow.insertOut(exit);
// save a reference to this block so we can discard it if unused.
unlockAndRethrow = rethrow;
ExceptionHandlerBasicBlock[] sh = new ExceptionHandlerBasicBlock[1];
sh[0] = rethrow;
enclosingHandlers = new ExceptionHandlerBasicBlockBag(sh, enclosingHandlers);
generatedExceptionHandlers = true;
}
}
use of org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand 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;
}
use of org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand in project JikesRVM by JikesRVM.
the class MinimalBURS method buildTree.
// //////////////////////////////
// Implementation
// //////////////////////////////
/**
* Build a BURS Tree for each Instruction.
* Complete BURS trees by adding leaf nodes as needed, and
* creating tree edges by calling insertChild1() or insertChild2()
* This step is also where we introduce intermediate tree nodes for
* any LIR instruction that has > 2 "real" operands e.g., a CALL.
*
* @param s The instruction for which a tree must be built
* @return the root of the newly constructed tree
*/
private AbstractBURS_TreeNode buildTree(Instruction s) {
AbstractBURS_TreeNode root = AbstractBURS_TreeNode.create(new DepGraphNode(s));
AbstractBURS_TreeNode cur = root;
for (Enumeration<Operand> uses = s.getUses(); uses.hasMoreElements(); ) {
Operand op = uses.nextElement();
if (op == null)
continue;
// Set child = AbstractBURS_TreeNode for operand op
AbstractBURS_TreeNode child;
if (op instanceof RegisterOperand) {
if (op.asRegister().getRegister().isValidation())
continue;
child = Register;
} else if (op instanceof IntConstantOperand) {
child = new BURS_IntConstantTreeNode(((IntConstantOperand) op).value);
} else if (op instanceof LongConstantOperand) {
child = LongConstant;
} else if (op instanceof AddressConstantOperand) {
child = AddressConstant;
} else if (op instanceof BranchOperand && s.isCall()) {
child = BranchTarget;
} else if (op instanceof InlinedOsrTypeInfoOperand && s.isYieldPoint()) {
child = NullTreeNode;
} else {
continue;
}
// Attach child as child of cur_parent in correct position
if (cur.child1 == null) {
cur.child1 = child;
} else if (cur.child2 == null) {
cur.child2 = child;
} else {
// Create auxiliary node so as to represent
// a instruction with arity > 2 in a binary tree.
AbstractBURS_TreeNode child1 = cur.child2;
AbstractBURS_TreeNode aux = AbstractBURS_TreeNode.create(OTHER_OPERAND_opcode);
cur.child2 = aux;
cur = aux;
cur.child1 = child1;
cur.child2 = child;
}
}
// patch for calls & return
switch(s.getOpcode()) {
case CALL_opcode:
case SYSCALL_opcode:
case YIELDPOINT_OSR_opcode:
if (cur.child2 == null) {
cur.child2 = NullTreeNode;
}
// fall through
case RETURN_opcode:
if (cur.child1 == null) {
cur.child1 = NullTreeNode;
}
}
return root;
}
use of org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand 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;
}
}
use of org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand 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);
}
}
}
Aggregations