use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genPopParametersAndPushReturnValue.
// push return value of method "m" from register to operand stack.
private void genPopParametersAndPushReturnValue(boolean hasImplicitThisArg, MethodReference m) {
TypeReference t = m.getReturnType();
discardSlots(m.getParameterWords() + (hasImplicitThisArg ? 1 : 0));
if (!t.isVoidType()) {
if (t.isLongType()) {
pushLong(FIRST_VOLATILE_GPR, VM.BuildFor64Addr ? FIRST_VOLATILE_GPR : (FIRST_VOLATILE_GPR.nextGPR()));
} else if (t.isFloatType()) {
pushFloat(FIRST_VOLATILE_FPR);
} else if (t.isDoubleType()) {
pushDouble(FIRST_VOLATILE_FPR);
} else if (t.isIntLikeType()) {
pushInt(FIRST_VOLATILE_GPR);
} else {
// t is object
pushAddr(FIRST_VOLATILE_GPR);
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method emit_unresolved_putfield.
@Override
protected void emit_unresolved_putfield(FieldReference fieldRef) {
// JMM: could be volatile (pre-barrier when second operation)
// StoreStore barrier.
asm.emitSYNC();
TypeReference fieldType = fieldRef.getFieldContentsType();
// T2 = field offset from emitDynamicLinkingSequence()
emitDynamicLinkingSequence(T2, fieldRef, true);
if (fieldType.isReferenceType()) {
// 32/64bit reference store
if (NEEDS_OBJECT_PUTFIELD_BARRIER) {
// NOTE: offset is in T2 from emitDynamicLinkingSequence
Barriers.compilePutfieldBarrier(this, fieldRef.getId());
discardSlots(2);
} else {
// T0 = address value
popAddr(T0);
// T1 = object reference
popAddr(T1);
asm.emitSTAddrX(T0, T1, T2);
}
} else if (NEEDS_BOOLEAN_PUTFIELD_BARRIER && fieldType.isBooleanType()) {
Barriers.compilePutfieldBarrierBoolean(this, fieldRef.getId());
} else if (NEEDS_BYTE_PUTFIELD_BARRIER && fieldType.isByteType()) {
Barriers.compilePutfieldBarrierByte(this, fieldRef.getId());
} else if (NEEDS_CHAR_PUTFIELD_BARRIER && fieldType.isCharType()) {
Barriers.compilePutfieldBarrierChar(this, fieldRef.getId());
} else if (NEEDS_DOUBLE_PUTFIELD_BARRIER && fieldType.isDoubleType()) {
Barriers.compilePutfieldBarrierDouble(this, fieldRef.getId());
} else if (NEEDS_FLOAT_PUTFIELD_BARRIER && fieldType.isFloatType()) {
Barriers.compilePutfieldBarrierFloat(this, fieldRef.getId());
} else if (NEEDS_INT_PUTFIELD_BARRIER && fieldType.isIntType()) {
Barriers.compilePutfieldBarrierInt(this, fieldRef.getId());
} else if (NEEDS_LONG_PUTFIELD_BARRIER && fieldType.isLongType()) {
Barriers.compilePutfieldBarrierLong(this, fieldRef.getId());
} else if (NEEDS_SHORT_PUTFIELD_BARRIER && fieldType.isShortType()) {
Barriers.compilePutfieldBarrierShort(this, fieldRef.getId());
} else if (NEEDS_WORD_PUTFIELD_BARRIER && fieldType.isWordType()) {
Barriers.compilePutfieldBarrierWord(this, fieldRef.getId());
} else if (NEEDS_ADDRESS_PUTFIELD_BARRIER && fieldType.isAddressType()) {
Barriers.compilePutfieldBarrierAddress(this, fieldRef.getId());
} else if (NEEDS_OFFSET_PUTFIELD_BARRIER && fieldType.isOffsetType()) {
Barriers.compilePutfieldBarrierOffset(this, fieldRef.getId());
} else if (NEEDS_EXTENT_PUTFIELD_BARRIER && fieldType.isExtentType()) {
Barriers.compilePutfieldBarrierExtent(this, fieldRef.getId());
} else if (fieldType.isWordLikeType()) {
// 32/64bit word store
// T0 = value
popAddr(T0);
// T1 = object reference
popAddr(T1);
asm.emitSTAddrX(T0, T1, T2);
} else if (fieldType.isBooleanType() || fieldType.isByteType()) {
// 8bit store
// T0 = value
popInt(T0);
// T1 = object reference
popAddr(T1);
asm.emitSTBX(T0, T1, T2);
} else if (fieldType.isShortType() || fieldType.isCharType()) {
// 16bit store
// T0 = value
popInt(T0);
// T1 = object reference
popAddr(T1);
asm.emitSTHX(T0, T1, T2);
} else if (fieldType.isIntType() || fieldType.isFloatType()) {
// 32bit store
// T0 = value
popInt(T0);
// T1 = object reference
popAddr(T1);
asm.emitSTWX(T0, T1, T2);
} else {
// 64bit store
if (VM.VerifyAssertions)
VM._assert(fieldType.isLongType() || fieldType.isDoubleType());
// F0 = doubleword value
popDouble(F0);
// T1 = object reference
popAddr(T1);
asm.emitSTFDX(F0, T1, T2);
}
// JMM: Could be volatile; post-barrier when first operation
// StoreLoad barrier.
asm.emitHWSYNC();
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class BaselineCompilerImpl method genMoveParametersToLocals.
// parameter stuff //
// store parameters from registers into local variables of current method.
private void genMoveParametersToLocals() {
int spillOff = frameSize + STACKFRAME_HEADER_SIZE;
short gp = FIRST_VOLATILE_GPR.value();
short fp = FIRST_VOLATILE_FPR.value();
int localIndex = 0;
short srcLocation;
short dstLocation;
byte type;
if (!method.isStatic()) {
if (gp > LAST_VOLATILE_GPR.value()) {
spillOff += BYTES_IN_STACKSLOT;
srcLocation = offsetToLocation(spillOff);
} else {
srcLocation = gp++;
}
type = ADDRESS_TYPE;
dstLocation = getGeneralLocalLocation(localIndex++);
copyByLocation(type, srcLocation, type, dstLocation);
}
TypeReference[] types = method.getParameterTypes();
for (int i = 0; i < types.length; i++, localIndex++) {
TypeReference t = types[i];
if (t.isLongType()) {
type = LONG_TYPE;
dstLocation = getGeneralLocalLocation(localIndex++);
if (gp > LAST_VOLATILE_GPR.value()) {
spillOff += (VM.BuildFor64Addr ? BYTES_IN_STACKSLOT : 2 * BYTES_IN_STACKSLOT);
srcLocation = offsetToLocation(spillOff);
copyByLocation(type, srcLocation, type, dstLocation);
} else {
srcLocation = gp++;
if (VM.BuildFor32Addr) {
gp++;
if (srcLocation == LAST_VOLATILE_GPR.value()) {
// low memory, low reg
copyByLocation(INT_TYPE, srcLocation, LONGHALF_TYPE, dstLocation);
spillOff += BYTES_IN_STACKSLOT;
// high mem, high reg
copyByLocation(LONGHALF_TYPE, offsetToLocation(spillOff), INT_TYPE, dstLocation);
continue;
}
}
copyByLocation(type, srcLocation, type, dstLocation);
}
} else if (t.isFloatType()) {
type = FLOAT_TYPE;
dstLocation = getFloatLocalLocation(localIndex);
if (fp > LAST_VOLATILE_FPR.value()) {
spillOff += BYTES_IN_STACKSLOT;
srcLocation = offsetToLocation(spillOff);
} else {
srcLocation = fp++;
}
copyByLocation(type, srcLocation, type, dstLocation);
} else if (t.isDoubleType()) {
type = DOUBLE_TYPE;
dstLocation = getFloatLocalLocation(localIndex++);
if (fp > LAST_VOLATILE_FPR.value()) {
spillOff += (VM.BuildFor64Addr ? BYTES_IN_STACKSLOT : 2 * BYTES_IN_STACKSLOT);
srcLocation = offsetToLocation(spillOff);
} else {
srcLocation = fp++;
}
copyByLocation(type, srcLocation, type, dstLocation);
} else if (t.isIntLikeType()) {
type = INT_TYPE;
dstLocation = getGeneralLocalLocation(localIndex);
if (gp > LAST_VOLATILE_GPR.value()) {
spillOff += BYTES_IN_STACKSLOT;
srcLocation = offsetToLocation(spillOff);
} else {
srcLocation = gp++;
}
copyByLocation(type, srcLocation, type, dstLocation);
} else {
// t is object
type = ADDRESS_TYPE;
dstLocation = getGeneralLocalLocation(localIndex);
if (gp > LAST_VOLATILE_GPR.value()) {
spillOff += BYTES_IN_STACKSLOT;
srcLocation = offsetToLocation(spillOff);
} else {
srcLocation = gp++;
}
copyByLocation(type, srcLocation, type, dstLocation);
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class GenerationContext method createChildContext.
/**
* Creates a child generation context from this context
* and callerBB to generate IR for callsite.
*
* @param ebag the enclosing exception handlers (null if none)
* @param callee the callee method to be inlined
* (may _not_ be equal to Call.getMethod(callSite).method)
* @param callSite the Call instruction to be inlined.
* @return the child context
*/
public GenerationContext createChildContext(ExceptionHandlerBasicBlockBag ebag, NormalMethod callee, Instruction callSite) {
// Note: In this method, use "this" explicitly to refer to parent fields in order
// to avoid confusing parent/child fields.
GenerationContext child = new GenerationContext();
child.method = callee;
if (this.options.frequencyCounters() || this.options.inverseFrequencyCounters()) {
child.branchProfiles = EdgeCounts.getBranchProfiles(callee);
}
child.parent = this;
child.original_cm = this.original_cm;
// Some state gets directly copied to the child
child.options = this.options;
child.temps = this.temps;
child._ncGuards = this._ncGuards;
child.exit = this.exit;
child.inlinePlan = this.inlinePlan;
// Now inherit state based on callSite
child.inlineSequence = new InlineSequence(child.method, callSite.position(), callSite);
child.enclosingHandlers = ebag;
child.arguments = new Operand[Call.getNumberOfParams(callSite)];
for (int i = 0; i < child.arguments.length; i++) {
// copy instead
child.arguments[i] = Call.getParam(callSite, i).copy();
// of clearing in case inlining aborts.
}
if (Call.hasResult(callSite)) {
child.resultReg = Call.getResult(callSite).copyD2D().getRegister();
// it will...
child.resultReg.setSpansBasicBlock();
}
// Initialize the child CFG, prologue, and epilogue blocks
child.cfg = new ControlFlowGraph(this.cfg.numberOfNodes());
child.prologue = new BasicBlock(PROLOGUE_BCI, child.inlineSequence, child.cfg);
child.prologue.setExceptionHandlers(ebag);
child.epilogue = new BasicBlock(EPILOGUE_BCI, child.inlineSequence, child.cfg);
child.epilogue.setExceptionHandlers(ebag);
child.cfg.addLastInCodeOrder(child.prologue);
child.cfg.addLastInCodeOrder(child.epilogue);
// Set up the local pool
child.initLocalPool();
// Insert moves from child.arguments to child's locals in prologue
TypeReference[] params = child.method.getParameterTypes();
int numParams = params.length;
int argIdx = 0;
int localNum = 0;
if (!child.method.isStatic()) {
Operand receiver = child.arguments[argIdx];
argIdx++;
RegisterOperand local = null;
if (receiver.isRegister()) {
RegisterOperand objPtr = receiver.asRegister();
if (ClassLoaderProxy.includesType(child.method.getDeclaringClass().getTypeRef(), objPtr.getType()) != YES) {
// narrow type of actual to match formal static type implied by method
// Can be precise but not assignable if enough classes aren't loaded
objPtr.clearPreciseType();
objPtr.setDeclaredType();
objPtr.setType(child.method.getDeclaringClass().getTypeRef());
}
local = child.makeLocal(localNum, objPtr);
localNum++;
// Avoid confusion in BC2IR of callee
child.arguments[0] = local;
// when objPtr is a local in the caller.
} else if (receiver.isConstant()) {
local = child.makeLocal(localNum, receiver.getType());
localNum++;
local.setPreciseType();
// Constants trivially non-null
RegisterOperand guard = child.makeNullCheckGuard(local.getRegister());
BC2IR.setGuardForRegOp(local, guard);
child.prologue.appendInstruction(Move.create(GUARD_MOVE, guard.copyRO(), new TrueGuardOperand()));
} else {
OptimizingCompilerException.UNREACHABLE("Unexpected receiver operand");
}
Instruction s = Move.create(REF_MOVE, local, receiver);
s.setSourcePosition(PROLOGUE_BCI, callSite.position());
child.prologue.appendInstruction(s);
}
for (int paramIdx = 0; paramIdx < numParams; paramIdx++, argIdx++) {
TypeReference argType = params[paramIdx];
RegisterOperand formal;
Operand actual = child.arguments[argIdx];
if (actual.isRegister()) {
RegisterOperand rActual = actual.asRegister();
if (ClassLoaderProxy.includesType(argType, rActual.getType()) != YES) {
// narrow type of actual to match formal static type implied by method
// Can be precise but not
rActual.clearPreciseType();
// assignable if enough classes aren't loaded
rActual.setDeclaredType();
rActual.setType(argType);
}
formal = child.makeLocal(localNum, rActual);
localNum++;
// Avoid confusion in BC2IR of
child.arguments[argIdx] = formal;
// callee when arg is a local in the caller.
} else {
formal = child.makeLocal(localNum, argType);
localNum++;
}
Instruction s = Move.create(IRTools.getMoveOp(argType), formal, actual);
s.setSourcePosition(PROLOGUE_BCI, callSite.position());
child.prologue.appendInstruction(s);
if (argType.isLongType() || argType.isDoubleType()) {
// longs and doubles take two local words
localNum++;
}
}
child.completePrologue(false);
child.completeEpilogue(false);
child.completeExceptionHandlers(false);
return child;
}
use of org.jikesrvm.classloader.TypeReference 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;
}
Aggregations