X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FFlat%2FBuildFlat.java;h=148f089a0b678b9fe10b54b34717e6b0c4be07ed;hb=ab6d009292bac1b2eb2102c3c1926368496a3faa;hp=b25e5b0750cae687824830c843168368f2ae7b52;hpb=10ccc4e7490f7b674b14f8f952c1efb5aa92f457;p=IRC.git diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index b25e5b07..148f089a 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -1,6 +1,7 @@ package IR.Flat; import IR.*; import IR.Tree.*; + import java.util.*; public class BuildFlat { @@ -12,6 +13,9 @@ public class BuildFlat { HashSet breakset; HashSet continueset; FlatExit fe; + + // for synchronized blocks + Stack lockStack; public BuildFlat(State st, TypeUtil typeutil) { state=st; @@ -19,6 +23,7 @@ public class BuildFlat { this.typeutil=typeutil; this.breakset=new HashSet(); this.continueset=new HashSet(); + this.lockStack = new Stack(); } public Hashtable getMap() { @@ -53,6 +58,7 @@ public class BuildFlat { } FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.PRE); + ffan.setNumLine(bn.getNumLine()); ffan.addNext(fn); FlatMethod fm=new FlatMethod(td, fe); @@ -114,97 +120,159 @@ public class BuildFlat { FlatAtomicEnterNode curran=null; + private FlatNode spliceReturn(FlatNode fn) { + FlatReturnNode rnflat=null; + if (currmd.getReturnType()==null||currmd.getReturnType().isVoid()) { + rnflat=new FlatReturnNode(null); + fn.addNext(rnflat); + } else { + TempDescriptor tmp=TempDescriptor.tempFactory("rettmp",currmd.getReturnType()); + Object o=null; + if (currmd.getReturnType().isPtr()) { + o=null; + } else if (currmd.getReturnType().isByte()) { + o=new Byte((byte)0); + } else if (currmd.getReturnType().isShort()) { + o=new Short((short)0); + } else if (currmd.getReturnType().isChar()) { + o=new Character('\0'); + } else if (currmd.getReturnType().isInt()) { + o=new Integer(0); + } else if (currmd.getReturnType().isLong()) { + o=new Long(0); + } else if (currmd.getReturnType().isBoolean()) { + o=new Boolean(false); + } else if (currmd.getReturnType().isFloat()) { + o=new Float(0.0); + } else if (currmd.getReturnType().isDouble()) { + o=new Double(0.0); + } + + + FlatLiteralNode fln=new FlatLiteralNode(currmd.getReturnType(),o,tmp); + rnflat=new FlatReturnNode(tmp); + fln.addNext(rnflat); + fn.addNext(fln); + } + return rnflat; + } + private void flattenClass(ClassDescriptor cn) { Iterator methodit=cn.getMethods(); while(methodit.hasNext()) { currmd=(MethodDescriptor)methodit.next(); - // if MLP is on, splice a special SESE in to - // enclose the main method, and a special SESE - // in around every other method that statically - // represents the SESE instance that will call - // that method at runtime + // if OOOJava is on, splice a special SESE in to + // enclose the main method + boolean spliceInImplicitMain = + state.OOOJAVA && + currmd.equals( typeutil.getMain() ); + FlatSESEEnterNode spliceSESE = null; FlatSESEExitNode spliceExit = null; - if( state.MLP ) { - if( currmd.equals( typeutil.getMain() ) ) { - SESENode mainTree = new SESENode( "main" ); - spliceSESE = new FlatSESEEnterNode( mainTree ); - spliceExit = new FlatSESEExitNode ( mainTree ); - spliceSESE.setFlatExit ( spliceExit ); - spliceExit.setFlatEnter( spliceSESE ); - } else { - SESENode callerSESETree = new SESENode( "caller SESE placeholder" ); - spliceSESE = new FlatSESEEnterNode( callerSESETree ); - spliceSESE.setCallerSESEplaceholder(); - spliceExit = new FlatSESEExitNode ( callerSESETree ); - spliceSESE.setFlatExit ( spliceExit ); - spliceExit.setFlatEnter( spliceSESE ); - } - } + + if( spliceInImplicitMain ) { + SESENode mainTree = new SESENode( "main" ); + spliceSESE = new FlatSESEEnterNode( mainTree ); + spliceExit = new FlatSESEExitNode ( mainTree ); + spliceSESE.setFlatExit ( spliceExit ); + spliceExit.setFlatEnter( spliceSESE ); + spliceSESE.setIsMainSESE(); + } + fe=new FlatExit(); BlockNode bn=state.getMethodBody(currmd); if (state.DSM&&currmd.getModifiers().isAtomic()) { - curran=new FlatAtomicEnterNode(); + FlatAtomicEnterNode faen=new FlatAtomicEnterNode(); + faen.setNumLine(bn.getNumLine()); + curran = faen; } else curran=null; + if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { + TempDescriptor thistd = null; + if(currmd.getModifiers().isStatic()) { + // need to lock the Class object + thistd=new TempDescriptor("classobj", cn); + } else { + // lock this object + thistd=getTempforVar(currmd.getThis()); + } + if(!this.lockStack.isEmpty()) { + throw new Error("The lock stack for synchronized blocks/methods is not empty!"); + } + this.lockStack.push(thistd); + } NodePair np=flattenBlockNode(bn); FlatNode fn=np.getBegin(); - if (state.THREAD&&currmd.getModifiers().isSynchronized()) { + if ((state.THREAD||state.MGC)&&currmd.getModifiers().isSynchronized()) { MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); - TempDescriptor thistd=getTempforVar(currmd.getThis()); - FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]); - fc.addNext(fn); - fn=fc; + FlatNode first = null; + FlatNode end = null; + for(int j = 0; j < this.lockStack.size(); j++) { + TempDescriptor thistd = this.lockStack.elementAt(j); + FlatCall fc = new FlatCall(memd, null, thistd, new TempDescriptor[0]); + fc.setNumLine(bn.getNumLine()); + if(first == null) { + first = end = fc; + } else { + end.addNext(fc); + end = fc; + } + } + end.addNext(fn); + fn=first; + end = np.getEnd(); if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); - FlatCall fcunlock=new FlatCall(memdex, null, thistd, new TempDescriptor[0]); - np.getEnd().addNext(fcunlock); - FlatReturnNode rnflat=new FlatReturnNode(null); - fcunlock.addNext(rnflat); + while(!this.lockStack.isEmpty()) { + TempDescriptor thistd = this.lockStack.pop(); + FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]); + fcunlock.setNumLine(bn.getNumLine()); + end.addNext(fcunlock); + end = fcunlock; + } + FlatNode rnflat=spliceReturn(end); rnflat.addNext(fe); - } + } else { + this.lockStack.clear(); + } } else if (state.DSM&&currmd.getModifiers().isAtomic()) { curran.addNext(fn); fn=curran; if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { FlatAtomicExitNode aen=new FlatAtomicExitNode(curran); np.getEnd().addNext(aen); - FlatReturnNode rnflat=new FlatReturnNode(null); - aen.addNext(rnflat); + FlatNode rnflat=spliceReturn(aen); rnflat.addNext(fe); } } else if (np.getEnd()!=null&&np.getEnd().kind()!=FKind.FlatReturnNode) { - FlatReturnNode rnflat=new FlatReturnNode(null); - // splice implicit SESE exit after method body - if( state.MLP ) { + FlatNode rnflat=null; + if( spliceInImplicitMain ) { np.getEnd().addNext(spliceExit); - spliceExit.addNext(rnflat); + rnflat=spliceReturn(spliceExit); } else { - np.getEnd().addNext(rnflat); + rnflat=spliceReturn(np.getEnd()); } rnflat.addNext(fe); - } else if (np.getEnd()!=null) { - // splice implicit SESE exit after method body - if( state.MLP ) { + if( spliceInImplicitMain ) { FlatReturnNode rnflat=(FlatReturnNode)np.getEnd(); np.getEnd().addNext(spliceExit); spliceExit.addNext(fe); } } - // splice an implicit SESE enter before method body - if( state.MLP ) { + if( spliceInImplicitMain ) { spliceSESE.addNext(fn); fn=spliceSESE; } FlatMethod fm=new FlatMethod(currmd, fe); + fm.setNumLine(bn.getNumLine()); fm.addNext(fn); if (!currmd.isStatic()) fm.addParameterTemp(getTempforParam(currmd.getThis())); @@ -252,17 +320,20 @@ public class BuildFlat { TempDescriptor tmp=TempDescriptor.tempFactory("tocast",cn.getExpression().getType()); NodePair np=flattenExpressionNode(cn.getExpression(), tmp); FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp); + fcn.setNumLine(cn.getNumLine()); np.getEnd().addNext(fcn); return new NodePair(np.getBegin(),fcn); } private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) { FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp); + fln.setNumLine(ln.getNumLine()); return new NodePair(fln,fln); } private NodePair flattenOffsetNode(OffsetNode ofn, TempDescriptor out_temp) { FlatOffsetNode fln = new FlatOffsetNode(ofn.getClassType(), ofn.getField(), out_temp); + fln.setNumLine(ofn.getNumLine()); return new NodePair(fln, fln); } @@ -278,7 +349,9 @@ public class BuildFlat { if (fd.getType().iswrapper()) { TempDescriptor wrap_tmp=TempDescriptor.tempFactory("wrapper_obj",fd.getType()); FlatNode fnwrapper=new FlatNew(fd.getType(), wrap_tmp, con.isGlobal()); + fnwrapper.setNumLine(con.getNumLine()); FlatSetFieldNode fsfn=new FlatSetFieldNode(out_temp, fd, wrap_tmp); + fsfn.setNumLine(con.getNumLine()); last.addNext(fnwrapper); fnwrapper.addNext(fsfn); last=fsfn; @@ -299,11 +372,13 @@ public class BuildFlat { MethodDescriptor md=con.getConstructor(); //Call to constructor FlatCall fc=new FlatCall(md, null, out_temp, temps); + fc.setNumLine(con.getNumLine()); last.addNext(fc); last=fc; if (td.getClassDesc().hasFlags()) { // if (con.getFlagEffects()!=null) { FlatFlagActionNode ffan=new FlatFlagActionNode(FlatFlagActionNode.NEWOBJECT); + ffan.setNumLine(con.getNumLine()); FlagEffects fes=con.getFlagEffects(); TempDescriptor flagtemp=out_temp; if (fes!=null) { @@ -325,6 +400,7 @@ public class BuildFlat { } return new NodePair(fn,last); } else { + if(con.getArrayInitializer() == null) { FlatNode first=null; FlatNode last=null; TempDescriptor[] temps=new TempDescriptor[con.numArgs()]; @@ -355,6 +431,11 @@ public class BuildFlat { return new NodePair(first,np.getEnd()); } else return new NodePair(first, fn); + } else if(state.MGC) { + // array creation with initializers + return flattenArrayInitializerNode(con.getArrayInitializer(), out_temp); + } + return null; } } @@ -410,7 +491,11 @@ public class BuildFlat { TempDescriptor thisarg=null; if (min.getExpression()!=null) { - thisarg=TempDescriptor.tempFactory("thisarg",min.getExpression().getType()); + TypeDescriptor mtd = min.getExpression().getType(); + if(state.MGC && mtd.isClass() && mtd.getClassDesc().isEnum()) { + mtd = new TypeDescriptor(TypeDescriptor.INT); + } + thisarg=TempDescriptor.tempFactory("thisarg", mtd); NodePair np=flattenExpressionNode(min.getExpression(),thisarg); first=np.getBegin(); last=np.getEnd(); @@ -419,7 +504,11 @@ public class BuildFlat { //Build arguments for(int i=0; i slnv = sbn.getSwitchConditions(); + FlatNode cond_begin = null; + NodePair prev_fnp = null; + for(int j = 0; j < slnv.size(); j++) { + SwitchLabelNode sln = slnv.elementAt(j); + NodePair left = null; + NodePair false_np = null; + if(sln.isDefault()) { + left = body; + } else { + TempDescriptor cond_tmp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN)); + TempDescriptor temp_left=TempDescriptor.tempFactory("leftop", sln.getCondition().getType()); + Operation op=new Operation(Operation.EQUAL); + left=flattenExpressionNode(sln.getCondition(), temp_left); + FlatOpNode fon=new FlatOpNode(cond_tmp, temp_left, cond_temp, op); + fon.setNumLine(sln.getNumLine()); + left.getEnd().addNext(fon); + + FlatCondBranch fcb=new FlatCondBranch(cond_tmp); + fcb.setNumLine(bn.getNumLine()); + fcb.setTrueProb(State.TRUEPROB); + + FlatNop nop=new FlatNop(); + false_np=new NodePair(nop,nop); + + fon.addNext(fcb); + fcb.addTrueNext(body.getBegin()); + fcb.addFalseNext(false_np.getBegin()); + } + if((prev_fnp != null) && (prev_fnp.getEnd() != null)) { + prev_fnp.getEnd().addNext(left.getBegin()); + } + prev_fnp = false_np; + + if (begin==null) { + begin = left.getBegin(); + } + if(cond_begin == null) { + cond_begin = left.getBegin(); + } + } + if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) { + prev_false_branch.getEnd().addNext(cond_begin); + } + prev_false_branch = prev_fnp; + if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) { + prev_true_branch.getEnd().addNext(body.getBegin()); + } + prev_true_branch = body; + for(Iterator breakit=breakset.iterator();breakit.hasNext();) { + FlatNode fn=(FlatNode)breakit.next(); + breakit.remove(); + fn.addNext(endnode); + } + breakset=oldbs; + } + if((prev_true_branch != null) && (prev_true_branch.getEnd() != null)) { + prev_true_branch.getEnd().addNext(endnode); + } + if((prev_false_branch != null) && (prev_false_branch.getEnd() != null)) { + prev_false_branch.getEnd().addNext(endnode); + } + if(begin == null) { + end=begin=new FlatNop(); + } + return new NodePair(begin,end); + } + private NodePair flattenLoopNode(LoopNode ln) { HashSet oldbs=breakset; HashSet oldcs=continueset; @@ -999,6 +1282,7 @@ public class BuildFlat { NodePair body=flattenBlockNode(ln.getBody()); FlatNode begin=initializer.getBegin(); FlatCondBranch fcb=new FlatCondBranch(cond_temp); + fcb.setNumLine(ln.getNumLine()); fcb.setTrueProb(State.TRUEPROB); fcb.setLoop(); FlatNop nopend=new FlatNop(); @@ -1033,6 +1317,7 @@ public class BuildFlat { NodePair body=flattenBlockNode(ln.getBody()); FlatNode begin=condition.getBegin(); FlatCondBranch fcb=new FlatCondBranch(cond_temp); + fcb.setNumLine(ln.getNumLine()); fcb.setTrueProb(State.TRUEPROB); fcb.setLoop(); FlatNop nopend=new FlatNop(); @@ -1065,6 +1350,7 @@ public class BuildFlat { NodePair body=flattenBlockNode(ln.getBody()); FlatNode begin=body.getBegin(); FlatCondBranch fcb=new FlatCondBranch(cond_temp); + fcb.setNumLine(ln.getNumLine()); fcb.setTrueProb(State.TRUEPROB); fcb.setLoop(); FlatNop nopend=new FlatNop(); @@ -1102,14 +1388,23 @@ public class BuildFlat { } FlatReturnNode rnflat=new FlatReturnNode(retval); + rnflat.setNumLine(rntree.getNumLine()); rnflat.addNext(fe); FlatNode ln=rnflat; - if (state.THREAD&&currmd.getModifiers().isSynchronized()) { - MethodDescriptor memd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); - TempDescriptor thistd=getTempforVar(currmd.getThis()); - FlatCall fc=new FlatCall(memd, null, thistd, new TempDescriptor[0]); - fc.addNext(ln); - ln=fc; + if ((state.THREAD||state.MGC)&&!this.lockStack.isEmpty()) { + FlatNode end = null; + MethodDescriptor memdex=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); + for(int j = this.lockStack.size(); j > 0; j--) { + TempDescriptor thistd = this.lockStack.elementAt(j-1); + FlatCall fcunlock = new FlatCall(memdex, null, thistd, new TempDescriptor[0]); + fcunlock.setNumLine(rntree.getNumLine()); + if(end != null) { + end.addNext(fcunlock); + } + end = fcunlock; + } + end.addNext(ln); + ln=end; } if (state.DSM&&currmd.getModifiers().isAtomic()) { FlatAtomicExitNode faen=new FlatAtomicExitNode(curran); @@ -1131,6 +1426,7 @@ public class BuildFlat { NodePair fcn=flattenConstraintCheck(ten.getChecks()); ffan.addNext(fcn.getBegin()); FlatReturnNode rnflat=new FlatReturnNode(null); + rnflat.setNumLine(ten.getNumLine()); rnflat.addNext(fe); fcn.getEnd().addNext(rnflat); return new NodePair(ffan, null); @@ -1168,34 +1464,66 @@ public class BuildFlat { } private NodePair flattenSynchronizedNode(SynchronizedNode sbn) { - TempDescriptor montmp=TempDescriptor.tempFactory("monitor",sbn.getExpr().getType()); - NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp); + TempDescriptor montmp=null; + FlatNode first = null; + FlatNode end = null; + if(sbn.getExpr() instanceof ClassTypeNode) { + montmp=new TempDescriptor("classobj", ((ClassTypeNode)sbn.getExpr()).getType().getClassDesc()); + } else { + montmp = TempDescriptor.tempFactory("monitor",sbn.getExpr().getType()); + NodePair npexp=flattenExpressionNode(sbn.getExpr(), montmp); + first = npexp.getBegin(); + end = npexp.getEnd(); + } + this.lockStack.push(montmp); NodePair npblock=flattenBlockNode(sbn.getBlockNode()); MethodDescriptor menmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorEnter"); FlatCall fcen=new FlatCall(menmd, null, montmp, new TempDescriptor[0]); + fcen.setNumLine(sbn.getNumLine()); MethodDescriptor mexmd=(MethodDescriptor)typeutil.getClass("Object").getMethodTable().get("MonitorExit"); FlatCall fcex=new FlatCall(mexmd, null, montmp, new TempDescriptor[0]); + fcex.setNumLine(sbn.getNumLine()); + + this.lockStack.pop(); - npexp.getEnd().addNext(fcen); + if(first != null) { + end.addNext(fcen); + } else { + first = fcen; + } fcen.addNext(npblock.getBegin()); - npblock.getEnd().addNext(fcex); - return new NodePair(npexp.getBegin(), fcex); + + if (npblock.getEnd()!=null&&npblock.getEnd().kind()!=FKind.FlatReturnNode) { + npblock.getEnd().addNext(fcex); + } + + /*if(npblock.getEnd() != null) { + npblock.getEnd().addNext(fcex); + }*/ + return new NodePair(first, fcex); } private NodePair flattenAtomicNode(AtomicNode sbn) { NodePair np=flattenBlockNode(sbn.getBlockNode()); FlatAtomicEnterNode faen=new FlatAtomicEnterNode(); + faen.setNumLine(sbn.getNumLine()); FlatAtomicExitNode faexn=new FlatAtomicExitNode(faen); faen.addNext(np.getBegin()); np.getEnd().addNext(faexn); return new NodePair(faen, faexn); } + private NodePair flattenGenReachNode( GenReachNode grn ) { + FlatGenReachNode fgrn = new FlatGenReachNode( grn.getGraphName() ); + return new NodePair( fgrn, fgrn ); + } + private NodePair flattenSESENode(SESENode sn) { if( sn.isStart() ) { FlatSESEEnterNode fsen=new FlatSESEEnterNode(sn); + fsen.setNumLine(sn.getNumLine()); sn.setFlatEnter(fsen); return new NodePair(fsen, fsen); } @@ -1222,48 +1550,53 @@ public class BuildFlat { TempDescriptor expr_temp=TempDescriptor.tempFactory("expr",tn.getExpr().getType()); NodePair cond=flattenExpressionNode(tn.getExpr(), expr_temp); FlatInstanceOfNode fion=new FlatInstanceOfNode(tn.getExprType(), expr_temp, out_temp); + fion.setNumLine(tn.getNumLine()); cond.getEnd().addNext(fion); return new NodePair(cond.getBegin(),fion); } private NodePair flattenArrayInitializerNode(ArrayInitializerNode ain, TempDescriptor out_temp) { - /* - TempDescriptor expr_temp=TempDescriptor.tempFactory("arry_init",ain.getType()); + boolean isGlobal = false; + String disjointId = null; + // get the type the array to be initialized + TypeDescriptor td = ain.getType(); // create a new array of size equal to the array initializer - //FlatNode first=null; - //FlatNode last=null; - TempDescriptor[] temps=new TempDescriptor[ain.numVarInitializers()]; - - for (int i=0; i