From d5a016cf0878e31af6b71b4c1ee613b24e02c7f2 Mon Sep 17 00:00:00 2001 From: jjenista Date: Mon, 11 Oct 2010 19:11:16 +0000 Subject: [PATCH] two methods for generating a reach graph at any desired program point, one is a dummy System method, the other is a dummy FlatNode, turns out dummy FlatNode works fine except that joptimize will optimize it out, could fix that later but its still useful for debugging --- .../Analysis/Disjoint/DisjointAnalysis.java | 48 +++++++++++++++++-- .../src/Analysis/Disjoint/PointerMethod.java | 1 + Robust/src/ClassLibrary/System.java | 3 ++ Robust/src/IR/Flat/BuildCode.java | 13 +++-- Robust/src/IR/Flat/BuildFlat.java | 8 ++++ Robust/src/IR/Flat/FKind.java | 1 + Robust/src/IR/Flat/FlatGenReachNode.java | 31 ++++++++++++ Robust/src/IR/Tree/BuildIR.java | 8 +++- Robust/src/IR/Tree/GenReachNode.java | 22 +++++++++ Robust/src/IR/Tree/Kind.java | 1 + Robust/src/IR/Tree/SemanticCheck.java | 1 + Robust/src/Lex/Keyword.java | 1 + Robust/src/Lex/Lexer.java | 2 +- Robust/src/Parse/java14.cup | 13 +++++ 14 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 Robust/src/IR/Flat/FlatGenReachNode.java create mode 100644 Robust/src/IR/Tree/GenReachNode.java diff --git a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java index a07a2a6e..faae0e9e 100644 --- a/Robust/src/Analysis/Disjoint/DisjointAnalysis.java +++ b/Robust/src/Analysis/Disjoint/DisjointAnalysis.java @@ -1110,6 +1110,19 @@ public class DisjointAnalysis { // to apply to the reachability graph switch( fn.kind() ) { + case FKind.FlatGenReachNode: { + System.out.println( "Generating a reach graph!" ); + rg.writeGraph( "genReach"+d, + true, // write labels (variables) + true, // selectively hide intermediate temp vars + true, // prune unreachable heap regions + false, // hide reachability altogether + true, // hide subset reachability states + true, // hide predicates + true ); // hide edge taints + } break; + + case FKind.FlatMethod: { // construct this method's initial heap model (IHM) // since we're working on the FlatMethod, we know @@ -1415,6 +1428,21 @@ public class DisjointAnalysis { FlatCall fc = (FlatCall) fn; MethodDescriptor mdCallee = fc.getMethod(); FlatMethod fmCallee = state.getMethodFlat( mdCallee ); + + + if( mdCallee.getSymbol().equals( "genReach" ) ) { + rg.writeGraph( "genReach"+d, + true, // write labels (variables) + true, // selectively hide intermediate temp vars + true, // prune unreachable heap regions + false, // hide reachability altogether + true, // hide subset reachability states + true, // hide predicates + true ); // hide edge taints + break; + } + + boolean debugCallSite = mdCaller.getSymbol().equals( state.DISJOINTDEBUGCALLER ) && @@ -1654,7 +1682,14 @@ public class DisjointAnalysis { Descriptor d = (Descriptor) me.getKey(); ReachGraph rg = (ReachGraph) me.getValue(); - rg.writeGraph( "COMPLETE"+d, + String graphName; + if( d instanceof TaskDescriptor ) { + graphName = "COMPLETEtask"+d; + } else { + graphName = "COMPLETE"+d; + } + + rg.writeGraph( graphName, true, // write labels (variables) true, // selectively hide intermediate temp vars true, // prune unreachable heap regions @@ -1728,7 +1763,14 @@ public class DisjointAnalysis { } Integer n = mapDescriptorToNumUpdates.get( d ); - rg.writeGraph( d+"COMPLETE"+String.format( "%05d", n ), + String graphName; + if( d instanceof TaskDescriptor ) { + graphName = d+"COMPLETEtask"+String.format( "%05d", n ); + } else { + graphName = d+"COMPLETE"+String.format( "%05d", n ); + } + + rg.writeGraph( graphName, true, // write labels (variables) true, // selectively hide intermediate temp vars true, // prune unreachable heap regions @@ -2540,7 +2582,7 @@ getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) { true, // selectively hide intermediate temp vars true, // prune unreachable heap regions false, // hide reachability - true, // hide subset reachability states + false, // hide subset reachability states true, // hide predicates false );// hide edge taints } diff --git a/Robust/src/Analysis/Disjoint/PointerMethod.java b/Robust/src/Analysis/Disjoint/PointerMethod.java index 396474d3..c3625e94 100644 --- a/Robust/src/Analysis/Disjoint/PointerMethod.java +++ b/Robust/src/Analysis/Disjoint/PointerMethod.java @@ -97,6 +97,7 @@ public class PointerMethod { case FKind.FlatBackEdge: case FKind.FlatSESEEnterNode: case FKind.FlatSESEExitNode: + case FKind.FlatGenReachNode: return true; case FKind.FlatCastNode: FlatCastNode fcn=(FlatCastNode)fn; diff --git a/Robust/src/ClassLibrary/System.java b/Robust/src/ClassLibrary/System.java index 249a09e4..05443dac 100644 --- a/Robust/src/ClassLibrary/System.java +++ b/Robust/src/ClassLibrary/System.java @@ -79,4 +79,7 @@ public class System { /* Only used for microbenchmark testing of SingleTM version */ public static native void arraycopy(Object src, int srcPos, Object dst, int destPos, int length); + + // for disjoint reachability analysis + public static void genReach(); } diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 4adce576..bdf2b645 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -1897,7 +1897,7 @@ public class BuildCode { while( dynSrcItr.hasNext() ) { TempDescriptor dynSrcVar = dynSrcItr.next(); output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); - output.println(" INTPTR "+dynSrcVar+"_srcOffset;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); } } } @@ -2245,7 +2245,7 @@ public class BuildCode { while( dynSrcItr.hasNext() ) { TempDescriptor dynSrcVar = dynSrcItr.next(); output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); - output.println(" INTPTR "+dynSrcVar+"_srcOffset;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); } // declare local temps for in-set primitives, and if it is @@ -2389,7 +2389,7 @@ public class BuildCode { } output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ - " = *(("+typeStr+"*) ("+ + " = *(("+typeStr+"*) ((void*)"+ paramsprefix+"->"+temp+"_srcSESE + "+ paramsprefix+"->"+temp+"_srcOffset));"); @@ -2965,7 +2965,7 @@ public class BuildCode { } output.println(" "+generateTemp( fmContext, dynVar, null )+ - " = *(("+typeStr+"*) ("+ + " = *(("+typeStr+"*) ((void*)"+ dynVar+"_srcSESE + "+dynVar+"_srcOffset));"); if( state.COREPROF ) { output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); @@ -3215,6 +3215,11 @@ public class BuildCode { output.println("/* nop */"); break; + case FKind.FlatGenReachNode: + // this node is just for generating a reach graph + // in disjointness analysis at a particular program point + break; + case FKind.FlatExit: output.println("/* exit */"); break; diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index 584e8767..5c70bf8b 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -1227,6 +1227,11 @@ public class BuildFlat { 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); @@ -1365,6 +1370,9 @@ public class BuildFlat { case Kind.SESENode: return flattenSESENode((SESENode)bsn); + case Kind.GenReachNode: + return flattenGenReachNode((GenReachNode)bsn); + case Kind.ContinueBreakNode: return flattenContinueBreakNode((ContinueBreakNode)bsn); } diff --git a/Robust/src/IR/Flat/FKind.java b/Robust/src/IR/Flat/FKind.java index 2ba61b50..89cbf474 100644 --- a/Robust/src/IR/Flat/FKind.java +++ b/Robust/src/IR/Flat/FKind.java @@ -28,4 +28,5 @@ public class FKind { public static final int FlatWriteDynamicVarNode=25; public static final int FlatInstanceOfNode=26; public static final int FlatExit=27; + public static final int FlatGenReachNode=28; } diff --git a/Robust/src/IR/Flat/FlatGenReachNode.java b/Robust/src/IR/Flat/FlatGenReachNode.java new file mode 100644 index 00000000..d72c2e3a --- /dev/null +++ b/Robust/src/IR/Flat/FlatGenReachNode.java @@ -0,0 +1,31 @@ +package IR.Flat; +import IR.TypeDescriptor; + +public class FlatGenReachNode extends FlatNode { + String graphName; + + public FlatGenReachNode( String graphName ) { + this.graphName = graphName; + } + + public String getGraphName() { + return graphName; + } + + public FlatNode clone(TempMap t){ return new FlatGenReachNode( graphName ); } + public void rewriteUse(TempMap t){} + public void rewriteDst(TempMap t) {} + + + public String toString() { + return "FlatGenReachNode_"+graphName; + } + + public int kind() { + return FKind.FlatGenReachNode; + } + + public TempDescriptor [] writesTemps() { + return new TempDescriptor[0]; + } +} diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index b4d6b3bd..a2bd61e7 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -779,9 +779,13 @@ public class BuildIR { blockstatements.addAll(parseSESEBlock(blockstatements,pn.getChild("body").getFirstChild())); blockstatements.add(end); } else if (isNode(pn,"continue")) { - blockstatements.add(new ContinueBreakNode(false)); + blockstatements.add(new ContinueBreakNode(false)); } else if (isNode(pn,"break")) { - blockstatements.add(new ContinueBreakNode(true)); + blockstatements.add(new ContinueBreakNode(true)); + + } else if (isNode(pn,"genreach")) { + String graphName = pn.getChild("graphName").getTerminal(); + blockstatements.add( new GenReachNode( graphName ) ); } else { System.out.println("---------------"); diff --git a/Robust/src/IR/Tree/GenReachNode.java b/Robust/src/IR/Tree/GenReachNode.java new file mode 100644 index 00000000..1335c514 --- /dev/null +++ b/Robust/src/IR/Tree/GenReachNode.java @@ -0,0 +1,22 @@ +package IR.Tree; + +public class GenReachNode extends BlockStatementNode { + String graphName; + + public GenReachNode( String graphName ) { + assert graphName != null; + this.graphName = graphName; + } + + public String printNode(int indent) { + return "genReach "+graphName; + } + + public String getGraphName() { + return graphName; + } + + public int kind() { + return Kind.GenReachNode; + } +} diff --git a/Robust/src/IR/Tree/Kind.java b/Robust/src/IR/Tree/Kind.java index 40375f46..4bbe21fa 100644 --- a/Robust/src/IR/Tree/Kind.java +++ b/Robust/src/IR/Tree/Kind.java @@ -29,4 +29,5 @@ public class Kind { public final static int InstanceOfNode=26; public final static int ArrayInitializerNode=27; public final static int SynchronizedNode=28; + public final static int GenReachNode=29; } diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 2e9a5e9e..e8ddffce 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -305,6 +305,7 @@ public class SemanticCheck { return; case Kind.SESENode: + case Kind.GenReachNode: // do nothing, no semantic check for SESEs return; } diff --git a/Robust/src/Lex/Keyword.java b/Robust/src/Lex/Keyword.java index 763086ed..3b830c8d 100644 --- a/Robust/src/Lex/Keyword.java +++ b/Robust/src/Lex/Keyword.java @@ -41,6 +41,7 @@ class Keyword extends Token { key_table.put("finally", new Integer(Sym.FINALLY)); key_table.put("float", new Integer(Sym.FLOAT)); key_table.put("for", new Integer(Sym.FOR)); + key_table.put("genreach", new Integer(Sym.GENREACH)); key_table.put("goto", new Integer(Sym.GOTO)); key_table.put("if", new Integer(Sym.IF)); key_table.put("import", new Integer(Sym.IMPORT)); diff --git a/Robust/src/Lex/Lexer.java b/Robust/src/Lex/Lexer.java index 2d16e68a..34f24fde 100644 --- a/Robust/src/Lex/Lexer.java +++ b/Robust/src/Lex/Lexer.java @@ -261,7 +261,7 @@ public class Lexer { "else", "enum", "extends", "external", "final", "finally", "flag", //keyword for failure aware computation - "float", "for","getoffset", "global", "goto", "if", + "float", "for", "genreach", "getoffset", "global", "goto", "if", //"implements", "import", "instanceof", "int", //"interface", diff --git a/Robust/src/Parse/java14.cup b/Robust/src/Parse/java14.cup index 4831dee3..3b03115c 100644 --- a/Robust/src/Parse/java14.cup +++ b/Robust/src/Parse/java14.cup @@ -103,6 +103,9 @@ terminal ASSERT; // assert_statement terminal ELLIPSIS; terminal ENUM; +// added for disjoint reachability analysis +terminal GENREACH; + // 19.2) The Syntactic Grammar non terminal ParseNode goal; @@ -194,6 +197,7 @@ non terminal ParseNode synchronized_statement; //non terminal ParseNode catches, catch_clause; //non terminal ParseNode finally; //non terminal ParseNode assert_statement; +non terminal ParseNode genreach_statement; // 19.12) Expressions non terminal ParseNode primary, primary_no_new_array; non terminal ParseNode class_instance_creation_expression; @@ -1195,6 +1199,7 @@ statement_without_trailing_substatement ::= | atomic_statement:st {: RESULT=st; :} | sese_statement:st {: RESULT=st; :} | synchronized_statement:st {: RESULT=st; :} + | genreach_statement:st {: RESULT=st; :} // | throw_statement // | try_statement // | assert_statement @@ -1990,3 +1995,11 @@ expression ::= assignment_expression:exp {: //constant_expression ::= // expression // ; + + +genreach_statement ::= + GENREACH IDENTIFIER:graphName SEMICOLON {: + ParseNode pn=new ParseNode("genreach"); + pn.addChild("graphName").addChild(graphName); + RESULT=pn; :} + ; -- 2.34.1