From: <cap...@us...> - 2008-03-10 22:08:35
|
Revision: 14014 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14014&view=rev Author: captain5050 Date: 2008-03-10 15:08:33 -0700 (Mon, 10 Mar 2008) Log Message: ----------- RVM-253: Modify typechecks to define a result. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCSE.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCastOptimization.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ir/operand/RegisterOperand.java rvmroot/trunk/rvm/src-generated/opt-ir/InstructionFormatList.dat Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCSE.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCSE.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCSE.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -43,6 +43,7 @@ import static org.jikesrvm.compilers.opt.ir.Operators.MONITOREXIT_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.NULL_CHECK_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.READ_CEILING_opcode; +import static org.jikesrvm.compilers.opt.ir.Operators.REF_MOVE; import static org.jikesrvm.compilers.opt.ir.Operators.TRAP_IF_opcode; import static org.jikesrvm.compilers.opt.ir.Operators.WRITE_FLOOR_opcode; import org.jikesrvm.compilers.opt.ir.Register; @@ -411,7 +412,7 @@ AvailableExpression ae = cache.find(inst); if (ae != null) { // it's a duplicate; blow it away. - inst.remove(); + Move.mutate(inst, REF_MOVE, TypeCheck.getClearResult(inst), TypeCheck.getClearRef(inst)); } else { // did not find a match: insert new entry in cache cache.insert(inst); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCastOptimization.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCastOptimization.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/LocalCastOptimization.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -119,6 +119,7 @@ s.remove(); TypeCheck.mutate(s, CHECKCAST_NOTNULL, + TypeCheck.getClearResult(s), TypeCheck.getClearRef(s), TypeCheck.getClearType(s), NullCheck.getGuardResult(n).copy()); @@ -199,6 +200,7 @@ s.remove(); TypeCheck.mutate(s, CHECKCAST_NOTNULL, + TypeCheck.getClearResult(s), TypeCheck.getClearRef(s), TypeCheck.getClearType(s), IfCmp.getGuardResult(n).copyRO()); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/Simplifier.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -22,7 +22,10 @@ import java.lang.reflect.Method; import org.jikesrvm.VM; +import org.jikesrvm.classloader.VM_Atom; import org.jikesrvm.classloader.VM_Field; +import org.jikesrvm.classloader.VM_FieldReference; +import org.jikesrvm.classloader.VM_MemberReference; import org.jikesrvm.classloader.VM_Method; import org.jikesrvm.classloader.VM_Type; import org.jikesrvm.classloader.VM_TypeReference; @@ -70,6 +73,7 @@ import org.jikesrvm.compilers.opt.ir.operand.TypeOperand; import org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand; import org.jikesrvm.objectmodel.VM_TIB; +import org.jikesrvm.runtime.VM_Entrypoints; import org.jikesrvm.runtime.VM_Magic; import org.jikesrvm.runtime.VM_Reflection; import org.vmmagic.unboxed.Address; @@ -515,7 +519,7 @@ result = boundsCheck(s); break; case CALL_opcode: - result = call(s); + result = call(regpool, s); break; case GETFIELD_opcode: result = getField(s); @@ -673,8 +677,11 @@ private static DefUseEffect checkcast(Instruction s) { Operand ref = TypeCheck.getRef(s); if (ref.isNullConstant()) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; + Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref); + if (ref.isConstant()) + return DefUseEffect.MOVE_FOLDED; + else + return DefUseEffect.MOVE_REDUCED; } else if (ref.isConstant()) { s.operator = CHECKCAST_NOTNULL; return checkcastNotNull(s); @@ -683,8 +690,11 @@ VM_TypeReference rhsType = ref.getType(); byte ans = ClassLoaderProxy.includesType(lhsType, rhsType); if (ans == Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; + Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref); + if (ref.isConstant()) + return DefUseEffect.MOVE_FOLDED; + else + return DefUseEffect.MOVE_REDUCED; } else { // NOTE: Constants.NO can't help us because (T)null always succeeds return DefUseEffect.UNCHANGED; @@ -698,8 +708,11 @@ VM_TypeReference rhsType = ref.getType(); byte ans = ClassLoaderProxy.includesType(lhsType, rhsType); if (ans == Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; + Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref); + if (ref.isConstant()) + return DefUseEffect.MOVE_FOLDED; + else + return DefUseEffect.MOVE_REDUCED; } else if (ans == Constants.NO) { VM_Type rType = rhsType.peekType(); if (rType != null && rType.isClassType() && rType.asClass().isFinal()) { @@ -781,14 +794,16 @@ return DefUseEffect.MOVE_REDUCED; } } - if (ref.isConstant() && (arrayTypeRef == VM_TypeReference.JavaLangObjectArray)) { + final boolean refIsPrecise = ref.isConstant() || (ref.isRegister() && ref.asRegister().isPreciseType()); + if ((arrayTypeRef == VM_TypeReference.JavaLangObjectArray) && refIsPrecise) { // We know this to be an array of objects so any store must // be safe Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), StoreCheck.getClearGuard(s)); return DefUseEffect.MOVE_REDUCED; } - if (val.isConstant() && ref.isConstant()) { - // writing a constant value into a constant array + final boolean valIsPrecise = val.isConstant() || (val.isRegister() && val.asRegister().isPreciseType()); + if (refIsPrecise && valIsPrecise) { + // writing a known type of value into a known type of array byte ans = ClassLoaderProxy.includesType(arrayTypeRef.getArrayElementType(), val.getType()); if (ans == Constants.YES) { // all stores should succeed @@ -818,14 +833,16 @@ return DefUseEffect.MOVE_REDUCED; } } - if (ref.isConstant() && (arrayTypeRef == VM_TypeReference.JavaLangObjectArray)) { + final boolean refIsPrecise = ref.isConstant() || (ref.isRegister() && ref.asRegister().isPreciseType()); + if ((arrayTypeRef == VM_TypeReference.JavaLangObjectArray) && refIsPrecise) { // We know this to be an array of objects so any store must // be safe Move.mutate(s, GUARD_MOVE, StoreCheck.getClearGuardResult(s), StoreCheck.getClearGuard(s)); return DefUseEffect.MOVE_REDUCED; } - if (val.isConstant() && ref.isConstant()) { - // writing a constant value into a constant array + final boolean valIsPrecise = val.isConstant() || (val.isRegister() && val.asRegister().isPreciseType()); + if (refIsPrecise && valIsPrecise) { + // writing a known type of value into a known type of array byte ans = ClassLoaderProxy.includesType(arrayTypeRef.getArrayElementType(), val.getType()); if (ans == Constants.YES) { // all stores should succeed @@ -843,7 +860,7 @@ private static DefUseEffect mustImplementInterface(Instruction s) { Operand ref = TypeCheck.getRef(s); if (ref.isNullConstant()) { - // Possible sitatution from constant propagation. This operation + // Possible situation from constant propagation. This operation // is really a nop as a null_check should have happened already Trap.mutate(s, TRAP, null, TrapCodeOperand.NullPtr()); return DefUseEffect.TRAP_REDUCED; @@ -852,8 +869,11 @@ VM_TypeReference rhsType = ref.getType(); // our type byte ans = ClassLoaderProxy.includesType(lhsType, rhsType); if (ans == Constants.YES) { - Empty.mutate(s, NOP); - return DefUseEffect.REDUCED; + Move.mutate(s, REF_MOVE, TypeCheck.getResult(s), ref); + if (ref.isConstant()) + return DefUseEffect.MOVE_FOLDED; + else + return DefUseEffect.MOVE_REDUCED; } else if (ans == Constants.NO) { VM_Type rType = rhsType.peekType(); if (rType != null && rType.isClassType() && rType.asClass().isFinal()) { @@ -2045,7 +2065,7 @@ // There will be a LONG_ZERO_CHECK // guarding this instruction that will result in an // ArithmeticException. We - // should probabbly just remove the LONG_DIV as dead code. + // should probably just remove the LONG_DIV as dead code. return DefUseEffect.UNCHANGED; } if (op1.isLongConstant()) { @@ -2219,7 +2239,7 @@ // There will be a LONG_ZERO_CHECK // guarding this instruction that will result in an // ArithmeticException. We - // should probabbly just remove the LONG_REM as dead code. + // should probably just remove the LONG_REM as dead code. return DefUseEffect.UNCHANGED; } if (op1.isLongConstant()) { @@ -3102,10 +3122,13 @@ return DefUseEffect.UNCHANGED; } - private static DefUseEffect call(Instruction s) { + private static DefUseEffect call(AbstractRegisterPool regpool, Instruction s) { if (CF_FIELDS) { MethodOperand methOp = Call.getMethod(s); - if ((methOp != null) && methOp.isVirtual() && !methOp.hasPreciseTarget()) { + if (methOp == null) { + return DefUseEffect.UNCHANGED; + } + if (methOp.isVirtual() && !methOp.hasPreciseTarget()) { Operand calleeThis = Call.getParam(s, 0); if (calleeThis.isNullConstant()) { Trap.mutate(s, TRAP, NullCheck.getClearGuardResult(s), TrapCodeOperand.NullPtr()); @@ -3118,8 +3141,8 @@ } } } - // Look for a precise method call to a pure method with all constant arguments - if ((methOp != null) && methOp.hasPreciseTarget() && methOp.getTarget().isPure()) { + if (methOp.hasPreciseTarget() && methOp.getTarget().isPure()) { + // Look for a precise method call to a pure method with all constant arguments VM_Method method = methOp.getTarget(); int n = Call.getNumberOfParams(s); for(int i=0; i < n; i++) { @@ -3146,6 +3169,7 @@ } } Throwable t = null; + Method m = null; try { if (VM.runningVM) { result = VM_Reflection.invoke(method, thisArg, otherArgs, !methOp.isVirtual()); @@ -3154,7 +3178,7 @@ for(int i=0; i < n; i++) { argTypes[i] = Call.getParam(s,i).getType().resolve().getClassForType(); } - Method m = method.getDeclaringClass().getClassForType().getDeclaredMethod(method.getName().toString(), argTypes); + m = method.getDeclaringClass().getClassForType().getDeclaredMethod(method.getName().toString(), argTypes); result = m.invoke(thisArg, otherArgs); } } catch (Throwable e) { t = e;} @@ -3162,19 +3186,21 @@ // Call threw exception so leave in to generate at execution time return DefUseEffect.UNCHANGED; } + if (result == null) throw new OptimizingCompilerException("Method " + m + "/" + method + " returned null"); if(method.getReturnType().isVoidType()) { Empty.mutate(s, NOP); return DefUseEffect.REDUCED; } else { Operator moveOp = IRTools.getMoveOp(method.getReturnType()); Move.mutate(s,moveOp, Call.getClearResult(s), - boxConstantObjectAsOperand(result, method.getReturnType())); + boxConstantObjectAsOperand(result, method.getReturnType())); return DefUseEffect.MOVE_FOLDED; } } } return DefUseEffect.UNCHANGED; } + /** * Package up a constant operand as an object * @param op the constant operand to package @@ -3212,6 +3238,9 @@ */ private static ConstantOperand boxConstantObjectAsOperand(Object x, VM_TypeReference t){ if (VM.VerifyAssertions) VM._assert(!t.isUnboxedType()); + if (x == null) { + throw new Error("Field of type: " + t + " is null"); + } if (t.isIntType()) { return IC((Integer)x); } else if (t.isBooleanType()) { Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/bc2ir/BC2IR.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -113,6 +113,7 @@ import org.jikesrvm.runtime.VM_Entrypoints; import org.jikesrvm.runtime.VM_Magic; import org.vmmagic.pragma.NoInline; +import org.vmmagic.pragma.RuntimeFinal; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -2052,10 +2053,15 @@ // requiresImplementsTest is still true. // Note that at this point requiresImplementsTest => resolvedMethod != null if (requiresImplementsTest) { + RegisterOperand checkedReceiver = gc.temps.makeTemp(receiver); appendInstruction(TypeCheck.create(MUST_IMPLEMENT_INTERFACE, - receiver.copy(), - makeTypeOperand(resolvedMethod.getDeclaringClass()), - getCurrentGuard())); + checkedReceiver, + receiver.copy(), + makeTypeOperand(resolvedMethod.getDeclaringClass()), + getCurrentGuard())); + checkedReceiver.refine(resolvedMethod.getDeclaringClass().getTypeRef()); + Call.setParam(s, 0, checkedReceiver.copyRO()); + receiver = checkedReceiver; rectifyStateWithErrorHandler(); // Can raise incompatible class change error. } MethodOperand mop = MethodOperand.VIRTUAL(vmethRef, vmeth); @@ -2085,11 +2091,15 @@ return; } else { if (requiresImplementsTest) { + RegisterOperand checkedReceiver = gc.temps.makeTemp(receiver); appendInstruction(TypeCheck.create(MUST_IMPLEMENT_INTERFACE, - receiver.copy(), - makeTypeOperand(resolvedMethod.getDeclaringClass()), - getCurrentGuard())); - // don't have to rectify with error handlers; rectify call below subsusmes. + checkedReceiver, + receiver.copy(), + makeTypeOperand(resolvedMethod.getDeclaringClass()), + getCurrentGuard())); + checkedReceiver.refine(resolvedMethod.getDeclaringClass().getTypeRef()); + Call.setParam(s, 0, checkedReceiver.copyRO()); + // don't have to rectify with error handlers; rectify call below subsumes. } } } @@ -2209,24 +2219,21 @@ break; } } - + RegisterOperand refinedOp2 = gc.temps.makeTemp(op2); if (!gc.options.NO_CHECKCAST) { if (classLoading) { - s = TypeCheck.create(CHECKCAST_UNRESOLVED, op2, makeTypeOperand(typeRef)); + s = TypeCheck.create(CHECKCAST_UNRESOLVED, refinedOp2, op2.copy(), makeTypeOperand(typeRef)); } else { TypeOperand typeOp = makeTypeOperand(typeRef.peekType()); if (isNonNull(op2)) { - s = TypeCheck.create(CHECKCAST_NOTNULL, op2, typeOp, getGuard(op2)); + s = TypeCheck.create(CHECKCAST_NOTNULL, refinedOp2, op2.copy(), typeOp, getGuard(op2)); } else { - s = TypeCheck.create(CHECKCAST, op2, typeOp); + s = TypeCheck.create(CHECKCAST, refinedOp2, op2.copy(), typeOp); } } } - op2 = op2.copy(); - if (op2 instanceof RegisterOperand && !op2.asRegister().isPreciseType()) { - op2.asRegister().setType(typeRef); - } - push(op2); + refinedOp2.refine(typeRef); + push(refinedOp2.copyRO()); rectifyStateWithExceptionHandler(VM_TypeReference.JavaLangClassCastException); if (classLoading) rectifyStateWithErrorHandler(); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/hir2lir/DynamicTypeCheckExpansion.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -52,6 +52,7 @@ import static org.jikesrvm.compilers.opt.ir.Operators.INT_MOVE; import static org.jikesrvm.compilers.opt.ir.Operators.INT_SHL; import static org.jikesrvm.compilers.opt.ir.Operators.REF_IFCMP; +import static org.jikesrvm.compilers.opt.ir.Operators.REF_MOVE; import static org.jikesrvm.compilers.opt.ir.Operators.TRAP; import static org.jikesrvm.compilers.opt.ir.Operators.USHORT_ALOAD; import static org.jikesrvm.compilers.opt.ir.Operators.USHORT_LOAD; @@ -250,6 +251,7 @@ BasicBlock failBlock = myBlock.createSubBlock(s.bcIndex, ir, .0001f); BasicBlock instanceOfBlock = myBlock.splitNodeAt(nullCond, ir); BasicBlock succBlock = instanceOfBlock.splitNodeAt(s, ir); + succBlock.firstInstruction().insertAfter(Move.create(REF_MOVE, TypeCheck.getClearResult(s), ref.copy())); IfCmp.setTarget(nullCond, succBlock.makeJumpTarget()); // fixup KLUDGE myBlock.insertOut(instanceOfBlock); myBlock.insertOut(succBlock); @@ -289,6 +291,7 @@ BasicBlock myBlock = s.getBasicBlock(); BasicBlock failBlock = myBlock.createSubBlock(s.bcIndex, ir, .0001f); BasicBlock succBlock = myBlock.splitNodeAt(s, ir); + succBlock.firstInstruction().insertAfter(Move.create(REF_MOVE, TypeCheck.getClearResult(s), ref.copy())); myBlock.insertOut(failBlock); myBlock.insertOut(succBlock); ir.cfg.linkInCodeOrder(myBlock, succBlock); @@ -328,6 +331,7 @@ BasicBlock myBlock = s.getBasicBlock(); BasicBlock failBlock = myBlock.createSubBlock(s.bcIndex, ir, .0001f); BasicBlock succBlock = myBlock.splitNodeAt(s, ir); + succBlock.firstInstruction().insertAfter(Move.create(REF_MOVE, TypeCheck.getClearResult(s), ref.copy())); myBlock.insertOut(failBlock); myBlock.insertOut(succBlock); ir.cfg.linkInCodeOrder(myBlock, succBlock); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/inlining/Inliner.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -260,12 +260,16 @@ requiresImplementsTest = doesImplement != Constants.YES; } if (requiresImplementsTest) { + RegisterOperand checkedReceiver = parent.temps.makeTemp(receiver); Instruction dtc = TypeCheck.create(MUST_IMPLEMENT_INTERFACE, - receiver.copy(), - new TypeOperand(interfaceType), - Call.getGuard(callSite).copy()); + checkedReceiver, + receiver.copy(), + new TypeOperand(interfaceType), + Call.getGuard(callSite).copy()); dtc.copyPosition(callSite); + checkedReceiver.refine(interfaceType.getTypeRef()); + Call.setParam(callSite, 0, checkedReceiver.copyRO()); testFailed.prependInstruction(dtc); } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ir/operand/RegisterOperand.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ir/operand/RegisterOperand.java 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/ir/operand/RegisterOperand.java 2008-03-10 22:08:33 UTC (rev 14014) @@ -553,4 +553,17 @@ public VM_TypeReference getType() { return type; } + + /** + * Refine the type of the register to t if t is a more precise type than the + * register currently holds + * + * @param t type to try to refine to + */ + public void refine(VM_TypeReference t) { + // TODO: see JIRA RVM-137 + if (!isPreciseType()) { + setType(t); + } + } } Modified: rvmroot/trunk/rvm/src-generated/opt-ir/InstructionFormatList.dat =================================================================== --- rvmroot/trunk/rvm/src-generated/opt-ir/InstructionFormatList.dat 2008-03-10 09:54:30 UTC (rev 14013) +++ rvmroot/trunk/rvm/src-generated/opt-ir/InstructionFormatList.dat 2008-03-10 22:08:33 UTC (rev 14014) @@ -105,8 +105,8 @@ TypeCheck -0 0 3 -"U Ref Operand" "U Type TypeOperand" "U Guard Operand opt" +1 0 3 +"D Result RegisterOperand" "U Ref Operand" "U Type TypeOperand" "U Guard Operand opt" InstanceOf This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |