use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class OptTestHarness method processOptionString.
private void processOptionString(String[] args) {
for (int i = 0, n = args.length; i < n; i++) {
try {
String arg = args[i];
if (arg.startsWith("-oc:") && options.processAsOption("-X:irc:", arg.substring(4))) {
// handled in processAsOption
} else if ("-useBootOptions".equals(arg)) {
OptimizingCompiler.setBootOptions(options);
} else if ("-longcommandline".equals(arg)) {
// the -longcommandline option reads options from a file.
String fileName = args[++i];
String[] optionString = fileAccess.readOptionStringFromFile(fileName);
processOptionString(optionString);
} else if ("+baseline".equals(arg)) {
useBaselineCompiler = true;
} else if ("-baseline".equals(arg)) {
useBaselineCompiler = false;
} else if ("-load".equals(arg)) {
loadClass(args[++i]);
} else if ("-class".equals(arg)) {
RVMClass klass = loadClass(args[++i]);
processClass(klass, options);
duplicateOptions();
} else if ("-method".equals(arg) || "-methodOpt".equals(arg) || "-methodBase".equals(arg)) {
// Default for this method is determined by BASELINE var
boolean isBaseline = useBaselineCompiler;
// Unless specified by these options
if ("-methodOpt".equals(arg)) {
isBaseline = false;
}
if ("-methodBase".equals(arg)) {
isBaseline = true;
}
RVMClass klass = null;
try {
klass = loadClass(args[++i]);
} catch (Exception e) {
output.sysErrPrintln("WARNING: Skipping method from " + args[i]);
}
if (klass == null)
continue;
String name = args[++i];
String desc = args[++i];
RVMMethod method = findDeclaredOrFirstMethod(klass, name, desc);
if (method == null || method.isAbstract() || method.isNative()) {
output.sysErrPrintln("WARNING: Skipping method " + args[i - 2] + "." + name);
} else {
processMethod(method, options, isBaseline);
}
duplicateOptions();
} else if ("-performance".equals(arg)) {
perf = new Performance(output);
} else if ("-disableClassLoading".equals(arg)) {
disableClassloading = true;
} else if ("-er".equals(arg)) {
executeWithReflection = true;
RVMClass klass = loadClass(args[++i]);
String name = args[++i];
String desc = args[++i];
NormalMethod method = (NormalMethod) findDeclaredOrFirstMethod(klass, name, desc);
CompiledMethod cm = null;
if (method == null) {
output.sysErrPrintln("Canceling further option processing to prevent assertion failures.");
return;
}
if (useBaselineCompiler) {
cm = BaselineCompiler.compile(method);
} else {
CompilationPlan cp = new CompilationPlan(method, OptimizationPlanner.createOptimizationPlan(options), null, options);
try {
cm = OptimizingCompiler.compile(cp);
} catch (Throwable e) {
output.sysErrPrintln("SKIPPING method:" + method + "Due to exception: " + e);
}
}
if (cm != null) {
method.replaceCompiledMethod(cm);
if (printCodeAddress) {
output.sysOutPrintln(compiledMethodMessage(method));
}
}
TypeReference[] argDesc = method.getDescriptor().parseForParameterTypes(klass.getClassLoader());
Object[] reflectMethodArgs = new Object[argDesc.length];
i = parseMethodArgs(argDesc, args, i, reflectMethodArgs);
java.lang.reflect.Method reflectoid = java.lang.reflect.JikesRVMSupport.createMethod(method);
reflectoidVector.add(reflectoid);
reflectMethodVector.add(method);
reflectMethodArgsVector.add(reflectMethodArgs);
duplicateOptions();
} else if ("-main".equals(arg)) {
executeMainMethod = true;
i++;
mainClass = loadClass(args[i]);
i++;
mainArgs = new String[args.length - i];
for (int j = 0, z = mainArgs.length; j < z; j++) {
mainArgs[j] = args[i + j];
}
break;
} else {
output.sysErrPrintln("Unrecognized argument: " + arg + " - ignored");
}
} catch (ArrayIndexOutOfBoundsException e) {
output.sysErrPrintln("Uncaught ArrayIndexOutOfBoundsException, possibly" + " not enough command-line arguments - aborting");
printFormatString();
e.printStackTrace(output.getSystemErr());
break;
} catch (Exception e) {
output.sysErrPrintln(e.toString());
e.printStackTrace(output.getSystemErr());
break;
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class DynamicTypeCheckExpansion method instanceOf.
/**
* Expand an instanceof instruction into the LIR sequence that implements
* the dynamic type check. Ref may contain a null ptr at runtime.
*
* @param s an INSTANCEOF or INSTANCEOF_UNRESOLVED instruction to expand
* @param ir the enclosing IR
* @return the last Instruction in the generated LIR sequence.
*/
static Instruction instanceOf(Instruction s, IR ir) {
RegisterOperand result = InstanceOf.getClearResult(s);
TypeReference LHStype = InstanceOf.getType(s).getTypeRef();
Operand ref = InstanceOf.getClearRef(s);
Instruction next = s.nextInstructionInCodeOrder();
if (next.operator() == INT_IFCMP && IfCmp.getVal1(next) instanceof RegisterOperand && result.similar(IfCmp.getVal1(next))) {
// The result of instanceof is being consumed by a conditional branch.
// Optimize this case by generating a branching type check
// instead of producing a value.
// TODO: This is really not safe: suppose the if is NOT the
// only use of the result of the instanceof.
// The way to fix this is to add ifInstanceOf and ifNotInstanceOf
// operators to the IR and have Simple transform
// instanceof, intIfCmp based on the U/D chains.
// See defect 2114.
Operand val2 = IfCmp.getVal2(next);
if (VM.VerifyAssertions)
VM._assert(val2.isIntConstant());
int ival2 = ((IntConstantOperand) val2).value;
ConditionOperand cond = IfCmp.getCond(next);
boolean branchCondition = (((ival2 == 0) && (cond.isNOT_EQUAL() || cond.isLESS_EQUAL())) || ((ival2 == 1) && (cond.isEQUAL() || cond.isGREATER_EQUAL())));
BasicBlock branchBB = next.getBranchTarget();
RegisterOperand oldGuard = IfCmp.getGuardResult(next);
next.remove();
BasicBlock fallThroughBB = fallThroughBB(s, ir);
BasicBlock falseBranch = branchCondition ? fallThroughBB : branchBB;
BasicBlock trueBranch = branchCondition ? branchBB : fallThroughBB;
BranchProfileOperand bp = IfCmp.getClearBranchProfile(next);
if (branchCondition)
bp = bp.flip();
Instruction nullComp = IfCmp.create(REF_IFCMP, oldGuard.copyRO(), ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), falseBranch.makeJumpTarget(), BranchProfileOperand.unlikely());
s.insertBefore(nullComp);
BasicBlock myBlock = s.getBasicBlock();
BasicBlock instanceOfBlock = myBlock.splitNodeAt(nullComp, ir);
myBlock.insertOut(instanceOfBlock);
myBlock.insertOut(falseBranch);
ir.cfg.linkInCodeOrder(myBlock, instanceOfBlock);
Operand RHStib = getTIB(s, ir, ref, oldGuard.copyRO());
return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, trueBranch, falseBranch, oldGuard.copy().asRegister(), bp);
} else {
// Not a branching pattern
RegisterOperand guard = ir.regpool.makeTempValidation();
BasicBlock instanceOfBlock = s.getBasicBlock().segregateInstruction(s, ir);
BasicBlock prevBB = instanceOfBlock.prevBasicBlockInCodeOrder();
BasicBlock nextBB = instanceOfBlock.nextBasicBlockInCodeOrder();
BasicBlock nullCaseBB = instanceOfBlock.createSubBlock(s.getBytecodeIndex(), ir, .01f);
prevBB.appendInstruction(IfCmp.create(REF_IFCMP, guard, ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), nullCaseBB.makeJumpTarget(), BranchProfileOperand.unlikely()));
nullCaseBB.appendInstruction(Move.create(INT_MOVE, result.copyD2D(), IC(0)));
nullCaseBB.appendInstruction(Goto.create(GOTO, nextBB.makeJumpTarget()));
// Stitch together the CFG; add nullCaseBB to the end of code array.
prevBB.insertOut(nullCaseBB);
nullCaseBB.insertOut(nextBB);
ir.cfg.addLastInCodeOrder(nullCaseBB);
Operand RHStib = getTIB(s, ir, ref, guard.copyD2U());
return generateValueProducingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, result);
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class ExpandRuntimeServices method perform.
/**
* Given an HIR, expand operators that are implemented as calls to
* runtime service methods. This method should be called as one of the
* first steps in lowering HIR into LIR.
*
* @param ir The HIR to expand
*/
@Override
public void perform(IR ir) {
// resync generation context -- yuck...
ir.getGc().resync();
for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = next) {
next = inst.nextInstructionInCodeOrder();
int opcode = inst.getOpcode();
switch(opcode) {
case NEW_opcode:
{
TypeOperand Type = New.getClearType(inst);
RVMClass cls = (RVMClass) Type.getVMType();
IntConstantOperand hasFinalizer = IRTools.IC(cls.hasFinalizer() ? 1 : 0);
RVMMethod callSite = inst.position().getMethod();
IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(cls, callSite));
IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(cls));
IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(cls, false));
Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Type);
if (VM.BuildForIA32 && VM.runningVM) {
// shield BC2IR from address constants
RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
tib = tmp.copyRO();
}
IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
RVMMethod target = Entrypoints.resolvedNewScalarMethod;
Call.mutate7(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(cls.getInstanceSize()), tib, hasFinalizer, allocator, align, offset, site);
next = inst.prevInstructionInCodeOrder();
if (ir.options.H2L_INLINE_NEW) {
if (inst.getBasicBlock().getInfrequent())
container.counter1++;
container.counter2++;
if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
inline(inst, ir);
}
}
}
break;
case NEW_UNRESOLVED_opcode:
{
int typeRefId = New.getType(inst).getTypeRef().getId();
RVMMethod target = Entrypoints.unresolvedNewScalarMethod;
IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
Call.mutate2(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(typeRefId), site);
}
break;
case NEWARRAY_opcode:
{
TypeOperand Array = NewArray.getClearType(inst);
RVMArray array = (RVMArray) Array.getVMType();
Operand numberElements = NewArray.getClearSize(inst);
boolean inline = numberElements instanceof IntConstantOperand;
Operand width = IRTools.IC(array.getLogElementSize());
Operand headerSize = IRTools.IC(ObjectModel.computeArrayHeaderSize(array));
RVMMethod callSite = inst.position().getMethod();
IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(array, callSite));
IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(array));
IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(array, false));
Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Array);
if (VM.BuildForIA32 && VM.runningVM) {
// shield BC2IR from address constants
RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
tib = tmp.copyRO();
}
IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
RVMMethod target = Entrypoints.resolvedNewArrayMethod;
Call.mutate8(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, width, headerSize, tib, allocator, align, offset, site);
next = inst.prevInstructionInCodeOrder();
if (inline && ir.options.H2L_INLINE_NEW) {
if (inst.getBasicBlock().getInfrequent())
container.counter1++;
container.counter2++;
if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
inline(inst, ir);
}
}
}
break;
case NEWARRAY_UNRESOLVED_opcode:
{
int typeRefId = NewArray.getType(inst).getTypeRef().getId();
Operand numberElements = NewArray.getClearSize(inst);
RVMMethod target = Entrypoints.unresolvedNewArrayMethod;
IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
Call.mutate3(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, IRTools.IC(typeRefId), site);
}
break;
case NEWOBJMULTIARRAY_opcode:
{
int dimensions = Multianewarray.getNumberOfDimensions(inst);
RVMMethod callSite = inst.position().getMethod();
int typeRefId = Multianewarray.getType(inst).getTypeRef().getId();
if (dimensions == 2) {
RVMMethod target = Entrypoints.optNew2DArrayMethod;
Call.mutate4(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), Multianewarray.getClearDimension(inst, 0), Multianewarray.getClearDimension(inst, 1), IRTools.IC(typeRefId));
} else {
// Step 1: Create an int array to hold the dimensions.
TypeOperand dimArrayType = new TypeOperand(RVMArray.IntArray);
RegisterOperand dimArray = ir.regpool.makeTemp(TypeReference.IntArray);
dimArray.setPreciseType();
next = NewArray.create(NEWARRAY, dimArray, dimArrayType, new IntConstantOperand(dimensions));
inst.insertBefore(next);
// Step 2: Assign the dimension values to dimArray
for (int i = 0; i < dimensions; i++) {
LocationOperand loc = new LocationOperand(TypeReference.Int);
inst.insertBefore(AStore.create(INT_ASTORE, Multianewarray.getClearDimension(inst, i), dimArray.copyD2U(), IRTools.IC(i), loc, IRTools.TG()));
}
// Step 3. Plant call to OptLinker.newArrayArray
RVMMethod target = Entrypoints.optNewArrayArrayMethod;
Call.mutate3(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), dimArray.copyD2U(), IRTools.IC(typeRefId));
}
}
break;
case ATHROW_opcode:
{
RVMMethod target = Entrypoints.athrowMethod;
MethodOperand methodOp = MethodOperand.STATIC(target);
// Record the fact that this is a non-returning call.
methodOp.setIsNonReturningCall(true);
Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), methodOp, Athrow.getClearValue(inst));
}
break;
case MONITORENTER_opcode:
{
Operand ref = MonitorOp.getClearRef(inst);
RVMType refType = ref.getType().peekType();
if (refType != null && !refType.getThinLockOffset().isMax()) {
RVMMethod target = Entrypoints.inlineLockMethod;
Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
next = inst.prevInstructionInCodeOrder();
if (inst.getBasicBlock().getInfrequent())
container.counter1++;
container.counter2++;
if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
inline(inst, ir);
}
} else {
RVMMethod target = Entrypoints.lockMethod;
Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
}
}
break;
case MONITOREXIT_opcode:
{
Operand ref = MonitorOp.getClearRef(inst);
RVMType refType = ref.getType().peekType();
if (refType != null && !refType.getThinLockOffset().isMax()) {
RVMMethod target = Entrypoints.inlineUnlockMethod;
Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
next = inst.prevInstructionInCodeOrder();
if (inst.getBasicBlock().getInfrequent())
container.counter1++;
container.counter2++;
if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
inline(inst, ir);
}
} else {
RVMMethod target = Entrypoints.unlockMethod;
Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
}
}
break;
case REF_ASTORE_opcode:
{
if (NEEDS_OBJECT_ASTORE_BARRIER) {
RVMMethod target = Entrypoints.objectArrayWriteBarrierMethod;
Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), AStore.getClearGuard(inst), AStore.getArray(inst).copy(), AStore.getIndex(inst).copy(), AStore.getValue(inst).copy());
replaceInstructionWithBarrier(inst, wb);
if (ir.options.H2L_INLINE_WRITE_BARRIER) {
inline(wb, ir, true);
}
}
}
break;
case BYTE_ASTORE_opcode:
{
if (NEEDS_BYTE_ASTORE_BARRIER) {
primitiveArrayStoreHelper(Entrypoints.byteArrayWriteBarrierMethod, inst, ir);
}
}
break;
case DOUBLE_ASTORE_opcode:
{
if (NEEDS_DOUBLE_ASTORE_BARRIER) {
primitiveArrayStoreHelper(Entrypoints.doubleArrayWriteBarrierMethod, inst, ir);
}
}
break;
case FLOAT_ASTORE_opcode:
{
if (NEEDS_FLOAT_ASTORE_BARRIER) {
primitiveArrayStoreHelper(Entrypoints.floatArrayWriteBarrierMethod, inst, ir);
}
}
break;
case INT_ASTORE_opcode:
{
if (NEEDS_INT_ASTORE_BARRIER) {
primitiveArrayStoreHelper(Entrypoints.intArrayWriteBarrierMethod, inst, ir);
}
}
break;
case LONG_ASTORE_opcode:
{
if (NEEDS_LONG_ASTORE_BARRIER) {
primitiveArrayStoreHelper(Entrypoints.longArrayWriteBarrierMethod, inst, ir);
}
}
break;
case SHORT_ASTORE_opcode:
{
TypeReference type = AStore.getLocation(inst).getElementType();
if (NEEDS_SHORT_ASTORE_BARRIER && type.isShortType()) {
primitiveArrayStoreHelper(Entrypoints.shortArrayWriteBarrierMethod, inst, ir);
} else if (NEEDS_CHAR_ASTORE_BARRIER) {
if (VM.VerifyAssertions)
VM._assert(type.isCharType());
primitiveArrayStoreHelper(Entrypoints.charArrayWriteBarrierMethod, inst, ir);
}
}
break;
case REF_ALOAD_opcode:
{
if (NEEDS_OBJECT_ALOAD_BARRIER) {
RVMMethod target = Entrypoints.objectArrayReadBarrierMethod;
Instruction rb = Call.create2(CALL, ALoad.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), ALoad.getClearGuard(inst), ALoad.getArray(inst).copy(), ALoad.getIndex(inst).copy());
replaceInstructionWithBarrier(inst, rb);
inline(rb, ir, true);
}
}
break;
case PUTFIELD_opcode:
{
if (NEEDS_OBJECT_PUTFIELD_BARRIER) {
LocationOperand loc = PutField.getLocation(inst);
FieldReference fieldRef = loc.getFieldRef();
if (!fieldRef.getFieldContentsType().isPrimitiveType()) {
// reference PUTFIELD
RVMField field = fieldRef.peekResolvedField();
if (field == null || !field.isUntraced()) {
RVMMethod target = Entrypoints.objectFieldWriteBarrierMethod;
Instruction wb = Call.create4(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutField.getClearGuard(inst), PutField.getRef(inst).copy(), PutField.getValue(inst).copy(), PutField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
replaceInstructionWithBarrier(inst, wb);
if (ir.options.H2L_INLINE_WRITE_BARRIER) {
inline(wb, ir, true);
}
}
} else {
// primitive PUTFIELD
if (NEEDS_BOOLEAN_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isBooleanType()) {
primitiveObjectFieldStoreHelper(Entrypoints.booleanFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_BYTE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isByteType()) {
primitiveObjectFieldStoreHelper(Entrypoints.byteFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_CHAR_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isCharType()) {
primitiveObjectFieldStoreHelper(Entrypoints.charFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_DOUBLE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isDoubleType()) {
primitiveObjectFieldStoreHelper(Entrypoints.doubleFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_FLOAT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isFloatType()) {
primitiveObjectFieldStoreHelper(Entrypoints.floatFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_INT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isIntType()) {
primitiveObjectFieldStoreHelper(Entrypoints.intFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_LONG_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isLongType()) {
primitiveObjectFieldStoreHelper(Entrypoints.longFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_SHORT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isShortType()) {
primitiveObjectFieldStoreHelper(Entrypoints.shortFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_WORD_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isWordType()) {
primitiveObjectFieldStoreHelper(Entrypoints.wordFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_ADDRESS_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isAddressType()) {
primitiveObjectFieldStoreHelper(Entrypoints.addressFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_EXTENT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isExtentType()) {
primitiveObjectFieldStoreHelper(Entrypoints.extentFieldWriteBarrierMethod, inst, ir, fieldRef);
} else if (NEEDS_OFFSET_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isOffsetType()) {
primitiveObjectFieldStoreHelper(Entrypoints.offsetFieldWriteBarrierMethod, inst, ir, fieldRef);
}
}
}
}
break;
case GETFIELD_opcode:
{
if (NEEDS_OBJECT_GETFIELD_BARRIER) {
LocationOperand loc = GetField.getLocation(inst);
FieldReference fieldRef = loc.getFieldRef();
if (GetField.getResult(inst).getType().isReferenceType()) {
RVMField field = fieldRef.peekResolvedField();
if (field == null || !field.isUntraced()) {
RVMMethod target = Entrypoints.objectFieldReadBarrierMethod;
Instruction rb = Call.create3(CALL, GetField.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetField.getClearGuard(inst), GetField.getRef(inst).copy(), GetField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
replaceInstructionWithBarrier(inst, rb);
inline(rb, ir, true);
}
}
}
}
break;
case PUTSTATIC_opcode:
{
if (NEEDS_OBJECT_PUTSTATIC_BARRIER) {
LocationOperand loc = PutStatic.getLocation(inst);
FieldReference field = loc.getFieldRef();
if (!field.getFieldContentsType().isPrimitiveType()) {
RVMMethod target = Entrypoints.objectStaticWriteBarrierMethod;
Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutStatic.getValue(inst).copy(), PutStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
replaceInstructionWithBarrier(inst, wb);
if (ir.options.H2L_INLINE_WRITE_BARRIER) {
inline(wb, ir, true);
}
}
}
}
break;
case GETSTATIC_opcode:
{
if (NEEDS_OBJECT_GETSTATIC_BARRIER) {
LocationOperand loc = GetStatic.getLocation(inst);
FieldReference field = loc.getFieldRef();
if (!field.getFieldContentsType().isPrimitiveType()) {
RVMMethod target = Entrypoints.objectStaticReadBarrierMethod;
Instruction rb = Call.create2(CALL, GetStatic.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
replaceInstructionWithBarrier(inst, rb);
inline(rb, ir, true);
}
}
}
break;
default:
break;
}
}
// If we actually inlined anything, clean up the mess
if (didSomething) {
if (branchOpts == null) {
branchOpts = new BranchOptimizations(-1, true, true);
}
branchOpts.perform(ir, true);
if (_os == null) {
_os = new Simple(1, false, false, false, false);
}
_os.perform(ir);
}
// signal that we do not intend to use the gc in other phases anymore.
ir.getGc().close();
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class Reflection method outOfLineInvoke.
private static Object outOfLineInvoke(RVMMethod method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {
// the class must be initialized before we can invoke a method
//
RVMClass klass = method.getDeclaringClass();
if (!klass.isInitialized()) {
RuntimeEntrypoints.initializeClassForDynamicLink(klass);
}
// remember return type
// Determine primitive type-ness early to avoid call (possible yield)
// later while refs are possibly being held in int arrays.
//
TypeReference returnType = method.getReturnType();
boolean returnIsPrimitive = returnType.isPrimitiveType();
// decide how to pass parameters
//
int triple = 0;
if (VM.BuildForIA32) {
triple = org.jikesrvm.ia32.MachineReflection.countParameters(method);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
triple = org.jikesrvm.ppc.MachineReflection.countParameters(method);
}
int gprs = triple & REFLECTION_GPRS_MASK;
WordArray GPRs = (gprs > 0) ? WordArray.create(gprs) : emptyWordArray;
int fprs = (triple >> REFLECTION_GPRS_BITS) & 0x1F;
double[] FPRs = (fprs > 0) ? new double[fprs] : emptyDoubleArray;
byte[] FPRmeta;
if (BuildForSSE2Full) {
FPRmeta = (fprs > 0) ? new byte[fprs] : emptyByteArray;
} else {
FPRmeta = null;
}
int spillCount = triple >> (REFLECTION_GPRS_BITS + REFLECTION_FPRS_BITS);
WordArray Spills = (spillCount > 0) ? WordArray.create(spillCount) : emptyWordArray;
if (firstUse) {
// force dynamic link sites in unwrappers to get resolved,
// before disabling gc.
// this is a bit silly, but I can't think of another way to do it [--DL]
unwrapBoolean(wrapBoolean(0));
unwrapByte(wrapByte((byte) 0));
unwrapChar(wrapChar((char) 0));
unwrapShort(wrapShort((short) 0));
unwrapInt(wrapInt(0));
unwrapLong(wrapLong(0));
unwrapFloat(wrapFloat(0));
unwrapDouble(wrapDouble(0));
firstUse = false;
}
// choose actual method to be called
//
RVMMethod targetMethod;
if (isNonvirtual || method.isStatic() || method.isObjectInitializer()) {
targetMethod = method;
} else {
RVMClass C = Magic.getObjectType(thisArg).asClass();
if (!method.getDeclaringClass().isInterface()) {
int tibIndex = method.getOffset().toInt() >>> LOG_BYTES_IN_ADDRESS;
targetMethod = C.getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];
} else {
RVMClass I = method.getDeclaringClass();
if (!RuntimeEntrypoints.isAssignableWith(I, C))
throw new IncompatibleClassChangeError();
targetMethod = C.findVirtualMethod(method.getName(), method.getDescriptor());
if (targetMethod == null)
throw new IncompatibleClassChangeError();
}
}
// getCurrentCompiledMethod is synchronized but Unpreemptible.
// Therefore there are no possible yieldpoints from the time
// the compiledMethod is loaded in getCurrentCompiledMethod
// to when we disable GC below.
// We can't allow any yieldpoints between these points because of the way in which
// we GC compiled code. Once a method is marked as obsolete, if it is not
// executing on the stack of some thread, then the process of collecting the
// code and meta-data might be initiated.
targetMethod.compile();
CompiledMethod cm = targetMethod.getCurrentCompiledMethod();
while (cm == null) {
targetMethod.compile();
cm = targetMethod.getCurrentCompiledMethod();
}
RVMThread.getCurrentThread().disableYieldpoints();
CodeArray code = cm.getEntryCodeArray();
if (VM.BuildForIA32) {
org.jikesrvm.ia32.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
org.jikesrvm.ppc.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
}
// critical: no yieldpoints/GCpoints between here and the invoke of code!
// We may have references hidden in the GPRs and Spills arrays!!!
RVMThread.getCurrentThread().enableYieldpoints();
if (!returnIsPrimitive) {
return Magic.invokeMethodReturningObject(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isVoidType()) {
Magic.invokeMethodReturningVoid(code, GPRs, FPRs, FPRmeta, Spills);
return null;
}
if (returnType.isBooleanType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return x == 1;
}
if (returnType.isByteType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (byte) x;
}
if (returnType.isShortType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (short) x;
}
if (returnType.isCharType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (char) x;
}
if (returnType.isIntType()) {
return Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isLongType()) {
return Magic.invokeMethodReturningLong(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isFloatType()) {
return Magic.invokeMethodReturningFloat(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isDoubleType()) {
return Magic.invokeMethodReturningDouble(code, GPRs, FPRs, FPRmeta, Spills);
}
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
return null;
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class RuntimeEntrypoints method instanceOf.
// ---------------------------------------------------------------//
// Type Checking. //
// ---------------------------------------------------------------//
/**
* Test if object is instance of target class/array or
* implements target interface.
* @param object object to be tested
* @param targetID type reference id corresponding to target
* class/array/interface
* @return true iff is object instance of target type?
*/
@Entrypoint
static boolean instanceOf(Object object, int targetID) throws NoClassDefFoundError {
/* Here, LHS and RHS refer to the way we would treat these if they were
arguments to an assignment operator and we were testing for
assignment-compatibility. In Java, "rhs instanceof lhs" means that
the operation "lhs = rhs" would succeed. This of course is backwards
if one is looking at it from the point of view of the "instanceof"
operator. */
TypeReference tRef = TypeReference.getTypeRef(targetID);
RVMType lhsType = tRef.peekType();
if (lhsType == null) {
lhsType = tRef.resolve();
}
if (!lhsType.isResolved()) {
// forces loading/resolution of super class/interfaces
lhsType.resolve();
}
/* Test for null only AFTER we have resolved the type of targetID. */
if (object == null) {
// null is not an instance of any type
return false;
}
RVMType rhsType = ObjectModel.getObjectType(object);
/* RHS must already be resolved, since we have a non-null object that is
an instance of RHS */
if (VM.VerifyAssertions)
VM._assert(rhsType.isResolved());
if (VM.VerifyAssertions)
VM._assert(lhsType.isResolved());
return lhsType == rhsType || DynamicTypeCheck.instanceOfResolved(lhsType, rhsType);
}
Aggregations