From: bdemsky Date: Thu, 21 Apr 2011 08:59:10 +0000 (+0000) Subject: rest of new build strategrest of new build strategyy X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c03b08b2fb9e4b48c6da1ffec05c4415e5dee14b;p=IRC.git rest of new build strategrest of new build strategyy --- diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 4b7603a0..087415d0 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -14,7 +14,7 @@ public class BuildIR { } public void buildtree(ParseNode pn, Set toanalyze, String sourcefile) { - parseFile(pn, toanalyze,sourcefile); + parseFile(pn, toanalyze, sourcefile); // numering the interfaces int if_num = 0; @@ -32,8 +32,8 @@ public class BuildIR { NameDescriptor packages; /** Parse the classes in this file */ - public void parseFile(ParseNode pn, Set toanalyze,String sourcefile) { - singleimports= new Hashtable(); + public void parseFile(ParseNode pn, Set toanalyze, String sourcefile) { + singleimports=new Hashtable(); multiimports=new Vector(); ParseNode ipn=pn.getChild("imports").getChild("import_decls_list"); if (ipn!=null) { @@ -44,13 +44,13 @@ public class BuildIR { // TODO need to implement if (isNode(pnimport,"import_single")) if(!singleimports.containsKey(nd.getIdentifier())) { - //map name to full name (includes package/directory - singleimports.put(nd.getIdentifier(), nd.getPathFromRootToHere(nd.getIdentifier())); - } else { - throw new Error("Error: class " + nd.getIdentifier() + " is already more than once in a single type import inside "+sourcefile); - } + //map name to full name (includes package/directory + singleimports.put(nd.getIdentifier(), nd.getPathFromRootToHere(nd.getIdentifier())); + } else { + throw new Error("Error: class " + nd.getIdentifier() + " is already more than once in a single type import inside "+sourcefile); + } else - //TODO MULTI-IMPORTS! + //TODO MULTI-IMPORTS! multiimports.add(nd); } } @@ -71,7 +71,6 @@ public class BuildIR { continue; if (isNode(type_pn, "class_declaration")) { ClassDescriptor cn = parseTypeDecl(type_pn, packageName); - cn.setImports(singleimports, multiimports); cn.setSourceFileName(sourcefile); parseInitializers(cn); if (toanalyze != null) @@ -179,6 +178,7 @@ public class BuildIR { private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) { ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false); + ecd.setImports(singleimports, multiimports); ecd.setAsEnum(); if(cn != null) { ecd.setSurroundingClass(cn.getSymbol()); @@ -213,6 +213,7 @@ public class BuildIR { public ClassDescriptor parseInterfaceDecl(ParseNode pn) { ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true); + cn.setImports(singleimports, multiimports); //cn.setAsInterface(); if (!isEmpty(pn.getChild("superIF").getTerminal())) { /* parse inherited interface name */ @@ -454,6 +455,7 @@ public class BuildIR { String newClassname = packageName + "___________" + pn.getChild("name").getTerminal(); cn= new ClassDescriptor(packageName, newClassname.replaceAll("\\.", "___________") , false); } + cn.setImports(singleimports, multiimports); if (!isEmpty(pn.getChild("super").getTerminal())) { /* parse superclass name */ ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name"); @@ -587,6 +589,7 @@ public class BuildIR { private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) { ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false); + icn.setImports(singleimports, multiimports); icn.setAsInnerClass(); icn.setSurroundingClass(cn.getSymbol()); icn.setSurrounding(cn); @@ -861,6 +864,7 @@ public class BuildIR { TypeDescriptor td=parseTypeDescriptor(pn); innerCount++; ClassDescriptor cnnew=new ClassDescriptor(td.getSymbol()+"$"+innerCount, false); + cnnew.setImports(singleimports, multiimports); cnnew.setSuper(td.getSymbol()); parseClassBody(cnnew, pn.getChild("decl").getChild("classbody")); Vector args=parseArgumentList(pn); @@ -957,8 +961,8 @@ public class BuildIR { return aan; } else if (isNode(pn,"cast1")) { try { - CastNode cn=new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild())); - cn.setNumLine(pn.getLine()); + CastNode cn=new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild())); + cn.setNumLine(pn.getLine()); return cn; } catch (Exception e) { System.out.println(pn.PPrint(1,true)); diff --git a/Robust/src/IR/Tree/JavaBuilder.java b/Robust/src/IR/Tree/JavaBuilder.java index d9aabf11..3e6ba165 100644 --- a/Robust/src/IR/Tree/JavaBuilder.java +++ b/Robust/src/IR/Tree/JavaBuilder.java @@ -5,8 +5,9 @@ import IR.Flat.*; import java.util.*; import java.io.*; import Util.Pair; +import Analysis.CallGraph.CallGraph; -public class JavaBuilder { +public class JavaBuilder implements CallGraph { State state; HashSet checkedDesc=new HashSet(); HashMap classStatus=new HashMap(); @@ -19,6 +20,8 @@ public class JavaBuilder { BuildFlat bf; Stack toprocess=new Stack(); HashSet discovered=new HashSet(); + HashMap> canCall=new HashMap>(); + MethodDescriptor mainMethod; /* Maps class/interfaces to all instantiated classes that extend or * implement those classes or interfaces */ @@ -29,9 +32,82 @@ public class JavaBuilder { HashMap> callMap=new HashMap>(); + HashMap> revCallMap=new HashMap>(); + /* Invocation map */ HashMap>> invocationMap=new HashMap>>(); + + public Set getAllMethods(Descriptor d) { + HashSet tovisit=new HashSet(); + tovisit.add(d); + HashSet callable=new HashSet(); + while(!tovisit.isEmpty()) { + Descriptor md=(Descriptor)tovisit.iterator().next(); + tovisit.remove(md); + Set s=getCalleeSet(md); + + if (s!=null) { + for(Iterator it=s.iterator(); it.hasNext();) { + MethodDescriptor md2=(MethodDescriptor)it.next(); + if( !callable.contains(md2) ) { + callable.add(md2); + tovisit.add(md2); + } + } + } + } + return callable; + } + + public Set getMethods(MethodDescriptor md, TypeDescriptor type) { + if (canCall.containsKey(md)) + return canCall.get(md); + else + return new HashSet(); + } + + public Set getMethods(MethodDescriptor md) { + return getMethods(md, null); + } + + public Set getMethodCalls(Descriptor d) { + Set set=getAllMethods(d); + set.add(d); + return set; + } + public boolean isCalled(MethodDescriptor md) { + return !getMethods(md).isEmpty(); + } + + public boolean isCallable(MethodDescriptor md) { + return !getCallerSet(md).isEmpty()||md==mainMethod; + } + + public Set getCalleeSet(Descriptor d) { + Set calleeset=callMap.get((MethodDescriptor)d); + if (calleeset==null) + return new HashSet(); + else + return calleeset; + } + + public Set getCallerSet(MethodDescriptor md) { + Set callerset=revCallMap.get(md); + if (callerset==null) + return new HashSet(); + else + return callerset; + } + + public Set getFirstReachableMethodContainingSESE(Descriptor d, + Set methodsContainingSESEs) { + throw new Error(""); + } + + public boolean hasLayout(ClassDescriptor cd) { + return sc.hasLayout(cd); + } public JavaBuilder(State state) { this.state=state; @@ -50,10 +126,19 @@ public class JavaBuilder { } public void build() { + //Initialize Strings to keep runtime happy + ClassDescriptor stringClass=sc.getClass(null, TypeUtil.StringClass, SemanticCheck.INIT); + instantiateClass(stringClass); + ClassDescriptor mainClass=sc.getClass(null, state.main, SemanticCheck.INIT); - MethodDescriptor mainMethod=tu.getMain(); + mainMethod=tu.getMain(); + + canCall.put(mainMethod, new HashSet()); + canCall.get(mainMethod).add(mainMethod); + toprocess.push(mainMethod); computeFixPoint(); + tu.createFullTable(); } void checkMethod(MethodDescriptor md) { @@ -65,10 +150,20 @@ public class JavaBuilder { } } - void initClassDesc(ClassDescriptor cd) { - if (classStatus.get(cd)==null) { - classStatus.put(cd, CDINIT); - //TODO...LOOK FOR STATIC INITIALIZERS + public boolean isInit(ClassDescriptor cd) { + return classStatus.get(cd)!=null&&classStatus.get(cd)>=CDINIT; + } + + void initClassDesc(ClassDescriptor cd, int init) { + if (classStatus.get(cd)==null||classStatus.get(cd)!=init) { + if (classStatus.get(cd)==null) { + MethodDescriptor mdstaticinit = (MethodDescriptor)cd.getMethodTable().get("staticblocks"); + if (mdstaticinit!=null) { + discovered.add(mdstaticinit); + toprocess.push(mdstaticinit); + } + } + classStatus.put(cd, init); } } @@ -76,14 +171,21 @@ public class JavaBuilder { while(!toprocess.isEmpty()) { MethodDescriptor md=toprocess.pop(); checkMethod(md); - initClassDesc(md.getClassDesc()); + initClassDesc(md.getClassDesc(), CDINIT); bf.flattenMethod(md.getClassDesc(), md); processFlatMethod(md); } + + //make sure every called method descriptor has a flat method + for(MethodDescriptor callmd:canCall.keySet()) + bf.addJustFlatMethod(callmd); } void processCall(MethodDescriptor md, FlatCall fcall) { MethodDescriptor callmd=fcall.getMethod(); + //make sure we have a FlatMethod for the base method... + if (!canCall.containsKey(callmd)) + canCall.put(callmd, new HashSet()); //First handle easy cases... if (callmd.isStatic()||callmd.isConstructor()) { @@ -91,7 +193,11 @@ public class JavaBuilder { discovered.add(callmd); toprocess.push(callmd); } + if (!revCallMap.containsKey(callmd)) + revCallMap.put(callmd, new HashSet()); + revCallMap.get(callmd).add(md); callMap.get(md).add(callmd); + canCall.get(callmd).add(callmd); return; } @@ -102,28 +208,35 @@ public class JavaBuilder { if (!invocationMap.containsKey(cn)) invocationMap.put(cn, new HashSet>()); invocationMap.get(cn).add(new Pair(md, callmd)); + + if (impSet!=null) { + for(ClassDescriptor cdactual:impSet) { + searchimp: + while(cdactual!=null) { + Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol()); + + for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { + MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); + if (callmd.matches(matchmd)) { + //Found the method that will be called + if (!discovered.contains(matchmd)) { + discovered.add(matchmd); + toprocess.push(matchmd); + } + + if (!revCallMap.containsKey(matchmd)) + revCallMap.put(matchmd, new HashSet()); + revCallMap.get(matchmd).add(md); - for(ClassDescriptor cdactual:impSet) { - searchimp: - while(cdactual!=null) { - Set possiblematches=cdactual.getMethodTable().getSetFromSameScope(callmd.getSymbol()); - - for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) { - MethodDescriptor matchmd=(MethodDescriptor)matchit.next(); - if (callmd.matches(matchmd)) { - //Found the method that will be called - if (!discovered.contains(matchmd)) { - discovered.add(matchmd); - toprocess.push(matchmd); + callMap.get(md).add(matchmd); + canCall.get(callmd).add(matchmd); + break searchimp; } - callMap.get(md).add(matchmd); - - break searchimp; } + + //Didn't find method...look in super class + cdactual=cdactual.getSuperDesc(); } - - //Didn't find method...look in super class - cdactual=cdactual.getSuperDesc(); } } } @@ -133,6 +246,16 @@ public class JavaBuilder { if (!tdnew.isClass()) return; ClassDescriptor cdnew=tdnew.getClassDesc(); + //Make sure class is fully initialized + sc.checkClass(cdnew, SemanticCheck.INIT); + instantiateClass(cdnew); + } + + void instantiateClass(ClassDescriptor cdnew) { + if (classStatus.containsKey(cdnew)&&classStatus.get(cdnew)==CDINSTANTIATED) + return; + initClassDesc(cdnew, CDINSTANTIATED); + Stack tovisit=new Stack(); tovisit.add(cdnew); @@ -159,7 +282,11 @@ public class JavaBuilder { discovered.add(matchmd); toprocess.push(matchmd); } + if (!revCallMap.containsKey(matchmd)) + revCallMap.put(matchmd, new HashSet()); + revCallMap.get(matchmd).add(md); callMap.get(md).add(matchmd); + canCall.get(callmd).add(matchmd); break searchimp; } } @@ -199,46 +326,4 @@ public class JavaBuilder { } } } - - public static ParseNode readSourceFile(State state, String sourcefile) { - try { - Reader fr= new BufferedReader(new FileReader(sourcefile)); - Lex.Lexer l = new Lex.Lexer(fr); - java_cup.runtime.lr_parser g; - g = new Parse.Parser(l); - ParseNode p=null; - try { - p=(ParseNode) g./*debug_*/parse().value; - } catch (Exception e) { - System.err.println("Error parsing file:"+sourcefile); - e.printStackTrace(); - System.exit(-1); - } - state.addParseNode(p); - if (l.numErrors()!=0) { - System.out.println("Error parsing "+sourcefile); - System.exit(l.numErrors()); - } - state.lines+=l.line_num; - return p; - - } catch (Exception e) { - throw new Error(e); - } - } - - public void loadClass(BuildIR bir, String sourcefile) { - try { - ParseNode pn=readSourceFile(state, sourcefile); - bir.buildtree(pn, null,sourcefile); - } catch (Exception e) { - System.out.println("Error in sourcefile:"+sourcefile); - e.printStackTrace(); - System.exit(-1); - } catch (Error e) { - System.out.println("Error in sourcefile:"+sourcefile); - e.printStackTrace(); - System.exit(-1); - } - } } \ No newline at end of file diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 1c934579..d123a172 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -17,6 +17,10 @@ public class SemanticCheck { boolean checkAll; + public boolean hasLayout(ClassDescriptor cd) { + return completed.get(cd)!=null&&completed.get(cd)==INIT; + } + public SemanticCheck(State state, TypeUtil tu) { this(state, tu, true); } @@ -44,16 +48,16 @@ public class SemanticCheck { return cd; } - private void checkClass(ClassDescriptor cd) { + public void checkClass(ClassDescriptor cd) { checkClass(cd, INIT); } - private void checkClass(ClassDescriptor cd, int fullcheck) { + public void checkClass(ClassDescriptor cd, int fullcheck) { if (!completed.containsKey(cd)||completed.get(cd)=REFERENCE&&oldstatus=REFERENCE&&oldstatus=INIT) { @@ -1077,6 +1085,7 @@ public class SemanticCheck { if (!typetolookin.isArray()) { // Array's don't need constructor calls ClassDescriptor classtolookin = typetolookin.getClassDesc(); + checkClass(classtolookin, INIT); Set methoddescriptorset = classtolookin.getMethodTable().getSet(typetolookin.getSymbol()); MethodDescriptor bestmd = null; @@ -1231,6 +1240,7 @@ public class SemanticCheck { if (!typetolookin.isClass()) throw new Error("Error with method call to "+min.getMethodName()); ClassDescriptor classtolookin=typetolookin.getClassDesc(); + checkClass(classtolookin, INIT); //System.out.println("Method name="+min.getMethodName()); Set methoddescriptorset=classtolookin.getMethodTable().getSet(min.getMethodName()); diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index 2b8f6968..37a243c9 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -416,6 +416,7 @@ public class Main { TypeUtil tu; BuildFlat bf; + JavaBuilder jb=null; if (true) { BuildIR bir=new BuildIR(state); @@ -441,7 +442,7 @@ public class Main { bf.buildFlat(); State.logEvent("Done Building Flat"); } else { - JavaBuilder jb=new JavaBuilder(state); + jb=new JavaBuilder(state); jb.build(); tu=jb.getTypeUtil(); bf=jb.getBuildFlat(); @@ -464,7 +465,7 @@ public class Main { } } - CallGraph callgraph=state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu); + CallGraph callgraph=jb!=null?jb:(state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu)); // SSJava if(state.SSJAVA){ @@ -489,6 +490,8 @@ public class Main { /* Classify parameters */ MethodDescriptor md=(MethodDescriptor)methodit.next(); FlatMethod fm=state.getMethodFlat(md); + if (fm==null) + continue; cp.optimize(fm); dc.optimize(fm); if (!state.NOLOOP) @@ -651,7 +654,7 @@ public class Main { if( state.OOOJAVA ) { bc=new BuildOoOJavaCode(state, bf.getMap(), tu, sa, oooa, callgraph); } else { - bc=new BuildCode(state, bf.getMap(), tu, sa, callgraph); + bc=new BuildCode(state, bf.getMap(), tu, sa, callgraph, jb); } }