1 package Analysis.Disjoint;
9 ////////////////////////////////////////////////
11 // important note! The static operations in this class that take
12 // canonicals and produce a canonical result sometimes need a
13 // "working copy" that IS NOT CANONICAL. So, even though it isn't
14 // perfectly clean, Canonical constructors have been changed from
15 // private to protected and they may be used in this file--however,
16 // only use a constructor for an object that will mutate during the
17 // calculation--use the factory method to obtain everything else!
20 // What this boils down to is that the only normally constructed
21 // object in a canonical operation should be the result out.
23 ////////////////////////////////////////////////
26 abstract public class Canonical {
28 // for generating unique canonical values
29 private static int canonicalCount = 1;
31 // the canon of objects
32 private static Hashtable<Canonical, Canonical>
33 canon = new Hashtable<Canonical, Canonical>();
37 public static Canonical makeCanonical( Canonical c ) {
39 if( canon.containsKey( c ) ) {
40 return canon.get( c );
43 c.canonicalValue = canonicalCount;
50 // any Canonical with value still 0 is NOT CANONICAL!
51 private int canonicalValue = 0;
53 public boolean isCanonical() {
54 return canonicalValue != 0;
57 public int getCanonicalValue() {
59 return canonicalValue;
63 // canonical objects should never be modified
64 // and therefore have changing hash codes, so
65 // use a standard canonical hash code method to
66 // enforce this, and define a specific hash code
67 // method each specific subclass should implement
68 abstract public int hashCodeSpecific();
70 private boolean hasHash = false;
72 final public int hashCode() {
73 int hash = hashCodeSpecific();
76 if( oldHash != hash ) {
77 throw new Error( "A CANONICAL HASH CHANGED" );
90 // mapping of a non-trivial operation to its result
91 private static Hashtable<CanonicalOp, Canonical>
92 op2result = new Hashtable<CanonicalOp, Canonical>();
96 ///////////////////////////////////////////////////////////
98 // Everything below are static methods that implement
99 // "mutating" operations on Canonical objects by returning
100 // the canonical result. If the op is non-trivial the
101 // canonical result is hashed by its defining CononicalOp
103 ///////////////////////////////////////////////////////////
106 // not weighty, don't bother with caching
107 public static ReachTuple unionUpArity( ReachTuple rt1,
111 assert rt1.isCanonical();
112 assert rt2.isCanonical();
113 assert rt1.hrnID == rt2.hrnID;
114 assert rt1.isMultiObject == rt2.isMultiObject;
115 assert rt1.isOutOfContext == rt2.isOutOfContext;
119 if( rt1.isMultiObject ) {
120 // on two non-ZERO arity multi regions, union arity is always
122 out = ReachTuple.factory( rt1.hrnID,
124 ReachTuple.ARITY_ZEROORMORE,
125 rt1.isOutOfContext );
128 // a single object region can only be ARITY_ONE (or zero by
130 assert rt1.arity == ReachTuple.ARITY_ONE;
134 assert out.isCanonical();
138 // not weighty, no caching
139 public static ReachTuple changeHrnIDTo( ReachTuple rt,
140 Integer hrnIDToChangeTo ) {
142 assert hrnIDToChangeTo != null;
144 ReachTuple out = ReachTuple.factory( hrnIDToChangeTo,
149 assert out.isCanonical();
154 public static ReachState attach( ReachState rs,
155 ExistPredSet preds ) {
157 assert preds != null;
158 assert rs.isCanonical();
159 assert preds.isCanonical();
162 new CanonicalOp( CanonicalOp.REACHSTATE_ATTACH_EXISTPREDSET,
166 Canonical result = op2result.get( op );
167 if( result != null ) {
168 return (ReachState) result;
171 // otherwise, no cached result...
172 ReachState out = new ReachState();
173 out.reachTuples.addAll( rs.reachTuples );
174 out.preds = Canonical.join( rs.preds,
177 out = (ReachState) makeCanonical( out );
178 op2result.put( op, out );
183 public static ReachState add( ReachState rs,
188 // this is only safe if we are certain the new tuple's
189 // ID doesn't already appear in the reach state
190 assert rs.containsHrnID( rt.getHrnID(),
191 rt.isOutOfContext() ) == null;
194 new CanonicalOp( CanonicalOp.REACHSTATE_ADD_REACHTUPLE,
198 Canonical result = op2result.get( op );
199 if( result != null ) {
200 return (ReachState) result;
203 // otherwise, no cached result...
204 ReachState out = new ReachState();
205 out.reachTuples.addAll( rs.reachTuples );
206 out.reachTuples.add( rt );
207 out.preds = rs.preds;
209 out = (ReachState) makeCanonical( out );
210 op2result.put( op, out );
215 public static ReachState unionUpArity( ReachState rs1,
219 assert rs1.isCanonical();
220 assert rs2.isCanonical();
223 new CanonicalOp( CanonicalOp.REACHSTATE_UNIONUPARITY_REACHSTATE,
227 Canonical result = op2result.get( op );
228 if( result != null ) {
229 return (ReachState) result;
232 // otherwise, no cached result...
233 ReachState out = new ReachState();
235 // first add everything from 1, and if it is
236 // also in 2 take the union of the tuple arities
237 Iterator<ReachTuple> rtItr = rs1.iterator();
238 while( rtItr.hasNext() ) {
239 ReachTuple rt1 = rtItr.next();
240 ReachTuple rt2 = rs2.containsHrnID( rt1.getHrnID(),
244 out.reachTuples.add( unionUpArity( rt1, rt2 ) );
246 out.reachTuples.add( rt1 );
250 // then add everything in 2 that wasn't in 1
251 rtItr = rs2.iterator();
252 while( rtItr.hasNext() ) {
253 ReachTuple rt2 = rtItr.next();
254 ReachTuple rt1 = rs1.containsHrnID( rt2.getHrnID(),
258 out.reachTuples.add( rt2 );
262 out.preds = Canonical.join( rs1.getPreds(),
266 out = (ReachState) makeCanonical( out );
267 op2result.put( op, out );
272 public static ReachState remove( ReachState rs, ReachTuple rt ) {
277 new CanonicalOp( CanonicalOp.REACHSTATE_REMOVE_REACHTUPLE,
281 Canonical result = op2result.get( op );
282 if( result != null ) {
283 return (ReachState) result;
286 // otherwise, no cached result...
287 ReachState out = new ReachState();
288 out.reachTuples.addAll( rs.reachTuples );
289 out.reachTuples.remove( rt );
290 out.preds = rs.preds;
292 out = (ReachState) makeCanonical( out );
293 op2result.put( op, out );
298 public static ReachState ageTuplesFrom( ReachState rs,
302 assert rs.isCanonical();
303 assert as.isCanonical();
306 new CanonicalOp( CanonicalOp.REACHSTATE_AGETUPLESFROM_ALLOCSITE,
310 Canonical result = op2result.get( op );
311 if( result != null ) {
312 return (ReachState) result;
315 // otherwise, no cached result...
316 ReachState out = new ReachState();
318 ReachTuple rtSummary = null;
319 ReachTuple rtOldest = null;
321 Iterator<ReachTuple> rtItr = rs.iterator();
322 while( rtItr.hasNext() ) {
323 ReachTuple rt = rtItr.next();
324 Integer hrnID = rt.getHrnID();
325 int age = as.getAgeCategory( hrnID );
327 // hrnIDs not associated with
328 // the site should be left alone, and
329 // those from this site but out-of-context
330 if( age == AllocSite.AGE_notInThisSite ||
333 out.reachTuples.add( rt );
335 } else if( age == AllocSite.AGE_summary ) {
336 // remember the summary tuple, but don't add it
337 // we may combine it with the oldest tuple
340 } else if( age == AllocSite.AGE_oldest ) {
341 // found an oldest hrnID, again just remember
346 assert age == AllocSite.AGE_in_I;
348 Integer I = as.getAge( hrnID );
351 // otherwise, we change this hrnID to the
353 Integer hrnIDToChangeTo = as.getIthOldest( I + 1 );
355 Canonical.changeHrnIDTo( rt, hrnIDToChangeTo );
356 out.reachTuples.add( rtAged );
360 // there are four cases to consider here
361 // 1. we found a summary tuple and no oldest tuple
362 // Here we just pass the summary unchanged
363 // 2. we found an oldest tuple, no summary
364 // Make a new, arity-one summary tuple
365 // 3. we found both a summary and an oldest
366 // Merge them by arity
367 // 4. (not handled) we found neither, do nothing
368 if( rtSummary != null && rtOldest == null ) {
369 out.reachTuples.add( rtSummary );
371 } else if( rtSummary == null && rtOldest != null ) {
372 out.reachTuples.add( ReachTuple.factory( as.getSummary(),
375 false // out-of-context
379 } else if( rtSummary != null && rtOldest != null ) {
380 out.reachTuples.add( Canonical.unionUpArity( rtSummary,
381 ReachTuple.factory( as.getSummary(),
384 false // out-of-context
390 out.preds = rs.preds;
392 out = (ReachState) makeCanonical( out );
393 op2result.put( op, out );
399 public static ReachSet unionORpreds( ReachSet rs1,
403 assert rs1.isCanonical();
404 assert rs2.isCanonical();
407 new CanonicalOp( CanonicalOp.REACHSET_UNIONORPREDS_REACHSET,
411 Canonical result = op2result.get( op );
412 if( result != null ) {
413 return (ReachSet) result;
416 // otherwise, no cached result...
417 ReachSet out = new ReachSet();
419 // first add everything from 1, and if it was also in 2
420 // take the OR of the predicates
421 Iterator<ReachState> stateItr = rs1.iterator();
422 while( stateItr.hasNext() ) {
423 ReachState state1 = stateItr.next();
424 ReachState state2 = rs2.containsIgnorePreds( state1 );
426 if( state2 != null ) {
427 out.reachStates.add( ReachState.factory( state1.reachTuples,
428 Canonical.join( state1.preds,
433 out.reachStates.add( state1 );
437 // then add everything in 2 that wasn't in 1
438 stateItr = rs2.iterator();
439 while( stateItr.hasNext() ) {
440 ReachState state2 = stateItr.next();
441 ReachState state1 = rs1.containsIgnorePreds( state2 );
443 if( state1 == null ) {
444 out.reachStates.add( state2 );
448 out = (ReachSet) makeCanonical( out );
449 op2result.put( op, out );
454 public static ReachSet intersection( ReachSet rs1,
458 assert rs1.isCanonical();
459 assert rs2.isCanonical();
462 new CanonicalOp( CanonicalOp.REACHSET_INTERSECTION_REACHSET,
466 Canonical result = op2result.get( op );
467 if( result != null ) {
468 return (ReachSet) result;
471 // otherwise, no cached result...
472 ReachSet out = new ReachSet();
473 Iterator<ReachState> itr = rs1.iterator();
474 while( itr.hasNext() ) {
475 ReachState state = (ReachState) itr.next();
476 if( rs2.reachStates.contains( state ) ) {
477 out.reachStates.add( state );
481 out = (ReachSet) makeCanonical( out );
482 op2result.put( op, out );
487 public static ReachSet add( ReachSet rs,
489 return unionORpreds( rs,
490 ReachSet.factory( state )
494 public static ReachSet remove( ReachSet rs,
497 assert state != null;
498 assert rs.isCanonical();
499 assert state.isCanonical();
502 new CanonicalOp( CanonicalOp.REACHSET_REMOVE_REACHSTATE,
506 Canonical result = op2result.get( op );
507 if( result != null ) {
508 return (ReachSet) result;
511 // otherwise, no cached result...
512 ReachSet out = new ReachSet();
513 out.reachStates.addAll( rs.reachStates );
514 out.reachStates.remove( state );
516 out = (ReachSet) makeCanonical( out );
517 op2result.put( op, out );
522 public static ReachSet applyChangeSet( ReachSet rs,
524 boolean keepSourceState ) {
527 assert rs.isCanonical();
528 assert cs.isCanonical();
530 // this primitive operand stuff is just a way to
531 // ensure distinct inputs to a CanonicalOp
533 if( keepSourceState ) {
540 new CanonicalOp( CanonicalOp.REACHSET_APPLY_CHANGESET,
545 Canonical result = op2result.get( op );
546 if( result != null ) {
547 return (ReachSet) result;
550 // otherwise, no cached result...
551 ReachSet out = new ReachSet();
553 Iterator<ReachState> stateItr = rs.iterator();
554 while( stateItr.hasNext() ) {
555 ReachState state = stateItr.next();
557 boolean changeFound = false;
559 Iterator<ChangeTuple> ctItr = cs.iterator();
560 while( ctItr.hasNext() ) {
561 ChangeTuple ct = ctItr.next();
563 if( state.equals( ct.getSetToMatch() ) ) {
564 out.reachStates.add( ct.getSetToAdd() );
569 if( keepSourceState || !changeFound ) {
570 out.reachStates.add( state );
574 out = (ReachSet) makeCanonical( out );
575 op2result.put( op, out );
580 public static ChangeSet unionUpArityToChangeSet( ReachSet rsO,
584 assert rsO.isCanonical();
585 assert rsR.isCanonical();
588 new CanonicalOp( CanonicalOp.REACHSET_UNIONTOCHANGESET_REACHSET,
592 Canonical result = op2result.get( op );
593 if( result != null ) {
594 return (ChangeSet) result;
597 // otherwise, no cached result...
598 ChangeSet out = ChangeSet.factory();
600 Iterator<ReachState> itrO = rsO.iterator();
601 while( itrO.hasNext() ) {
602 ReachState o = itrO.next();
604 Iterator<ReachState> itrR = rsR.iterator();
605 while( itrR.hasNext() ) {
606 ReachState r = itrR.next();
608 ReachState theUnion = ReachState.factory();
610 Iterator<ReachTuple> itrRelement = r.iterator();
611 while( itrRelement.hasNext() ) {
612 ReachTuple rtR = itrRelement.next();
613 ReachTuple rtO = o.containsHrnID( rtR.getHrnID(),
617 theUnion = Canonical.add( theUnion,
618 Canonical.unionUpArity( rtR,
623 theUnion = Canonical.add( theUnion,
629 Iterator<ReachTuple> itrOelement = o.iterator();
630 while( itrOelement.hasNext() ) {
631 ReachTuple rtO = itrOelement.next();
632 ReachTuple rtR = theUnion.containsHrnID( rtO.getHrnID(),
636 theUnion = Canonical.add( theUnion,
642 if( !theUnion.isEmpty() ) {
644 Canonical.union( out,
646 ChangeTuple.factory( o, theUnion )
653 assert out.isCanonical();
654 op2result.put( op, out );
659 public static ReachSet ageTuplesFrom( ReachSet rs,
663 assert rs.isCanonical();
664 assert as.isCanonical();
667 new CanonicalOp( CanonicalOp.REACHSET_AGETUPLESFROM_ALLOCSITE,
671 Canonical result = op2result.get( op );
672 if( result != null ) {
673 return (ReachSet) result;
676 // otherwise, no cached result...
677 ReachSet out = new ReachSet();
679 Iterator<ReachState> itrS = rs.iterator();
680 while( itrS.hasNext() ) {
681 ReachState state = itrS.next();
682 out.reachStates.add( Canonical.ageTuplesFrom( state, as ) );
685 out = (ReachSet) makeCanonical( out );
686 op2result.put( op, out );
691 public static ReachSet pruneBy( ReachSet rsO,
695 assert rsO.isCanonical();
696 assert rsP.isCanonical();
699 new CanonicalOp( CanonicalOp.REACHSET_PRUNEBY_REACHSET,
703 Canonical result = op2result.get( op );
704 if( result != null ) {
705 return (ReachSet) result;
708 // otherwise, no cached result...
709 ReachSet out = new ReachSet();
711 Iterator<ReachState> itrO = rsO.iterator();
712 while( itrO.hasNext() ) {
713 ReachState stateO = itrO.next();
715 boolean subsetExists = false;
717 Iterator<ReachState> itrP = rsP.iterator();
718 while( itrP.hasNext() && !subsetExists ) {
719 ReachState stateP = itrP.next();
721 if( stateP.isSubset( stateO ) ) {
727 out.reachStates.add( stateO );
731 out = (ReachSet) makeCanonical( out );
732 op2result.put( op, out );
737 public static ChangeSet union( ChangeSet cs1,
741 assert cs1.isCanonical();
742 assert cs2.isCanonical();
745 new CanonicalOp( CanonicalOp.CHANGESET_UNION_CHANGESET,
749 Canonical result = op2result.get( op );
750 if( result != null ) {
751 return (ChangeSet) result;
754 // otherwise, no cached result...
755 ChangeSet out = new ChangeSet();
756 out.changeTuples.addAll( cs1.changeTuples );
757 out.changeTuples.addAll( cs2.changeTuples );
759 out = (ChangeSet) makeCanonical( out );
760 op2result.put( op, out );
764 public static ChangeSet union( ChangeSet cs,
768 assert cs.isCanonical();
769 assert ct.isCanonical();
772 new CanonicalOp( CanonicalOp.CHANGESET_UNION_CHANGETUPLE,
776 Canonical result = op2result.get( op );
777 if( result != null ) {
778 return (ChangeSet) result;
781 // otherwise, no cached result...
782 ChangeSet out = new ChangeSet();
783 out.changeTuples.addAll( cs.changeTuples );
784 out.changeTuples.add( ct );
786 out = (ChangeSet) makeCanonical( out );
787 op2result.put( op, out );
793 public static ExistPredSet join( ExistPredSet eps1,
794 ExistPredSet eps2 ) {
798 assert eps1.isCanonical();
799 assert eps2.isCanonical();
802 new CanonicalOp( CanonicalOp.EXISTPREDSET_JOIN_EXISTPREDSET,
806 Canonical result = op2result.get( op );
807 if( result != null ) {
808 return (ExistPredSet) result;
811 // otherwise, no cached result...
812 ExistPredSet out = new ExistPredSet();
813 out.preds.addAll( eps1.preds );
814 out.preds.addAll( eps2.preds );
816 out = (ExistPredSet) makeCanonical( out );
817 op2result.put( op, out );
821 public static ExistPredSet add( ExistPredSet eps,
827 assert eps.isCanonical();
828 assert ep.isCanonical();
831 new CanonicalOp( CanonicalOp.EXISTPREDSET_ADD_EXISTPRED,
835 Canonical result = op2result.get( op );
836 if( result != null ) {
837 return (ExistPredSet) result;
840 // otherwise, no cached result...
841 ExistPredSet out = new ExistPredSet();
842 out.preds.addAll( eps.preds );
845 out = (ExistPredSet) makeCanonical( out );
846 op2result.put( op, out );
852 public static ReachSet toCalleeContext( ReachSet rs,
856 assert rs.isCanonical();
857 assert as.isCanonical();
860 new CanonicalOp( CanonicalOp.REACHSET_TOCALLEECONTEXT_ALLOCSITE,
864 Canonical result = op2result.get( op );
865 if( result != null ) {
866 return (ReachSet) result;
869 // otherwise, no cached result...
870 ReachSet out = ReachSet.factory();
871 Iterator<ReachState> itr = rs.iterator();
872 while( itr.hasNext() ) {
873 ReachState state = itr.next();
874 out = Canonical.add( out,
875 Canonical.toCalleeContext( state, as )
879 assert out.isCanonical();
880 op2result.put( op, out );
886 public static ReachState toCalleeContext( ReachState state,
888 assert state != null;
890 assert state.isCanonical();
891 assert as.isCanonical();
894 new CanonicalOp( CanonicalOp.REACHSTATE_TOCALLEECONTEXT_ALLOCSITE,
898 Canonical result = op2result.get( op );
899 if( result != null ) {
900 return (ReachState) result;
903 // otherwise, no cached result...
904 ReachState out = ReachState.factory();
905 Iterator<ReachTuple> itr = state.iterator();
906 while( itr.hasNext() ) {
907 ReachTuple rt = itr.next();
909 int age = as.getAgeCategory( rt.getHrnID() );
911 // this is the current mapping, where 0, 1, 2S were allocated
912 // in the current context, 0?, 1? and 2S? were allocated in a
913 // previous context, and we're translating to a future context
925 if( age == AllocSite.AGE_notInThisSite ) {
926 // things not from the site just go back in
927 out = Canonical.union( out, rt );
929 } else if( age == AllocSite.AGE_summary ||
932 // the in-context summary and all existing out-of-context
934 out = Canonical.union( out,
935 ReachTuple.factory( as.getSummary(),
938 true // out-of-context
942 // otherwise everything else just goes to an out-of-context
943 // version, everything else the same
944 Integer I = as.getAge( rt.getHrnID() );
947 assert !rt.isMultiObject();
949 out = Canonical.union( out,
950 ReachTuple.factory( rt.getHrnID(),
953 true // out-of-context
959 out = Canonical.attach( out,
963 assert out.isCanonical();
964 op2result.put( op, out );
970 public static ReachSet toCallerContext( ReachSet rs,
974 assert rs.isCanonical();
975 assert as.isCanonical();
978 new CanonicalOp( CanonicalOp.REACHSET_TOCALLERCONTEXT_ALLOCSITE,
982 Canonical result = op2result.get( op );
983 if( result != null ) {
984 return (ReachSet) result;
987 // otherwise, no cached result...
988 ReachSet out = ReachSet.factory();
989 Iterator<ReachState> itr = rs.iterator();
990 while( itr.hasNext() ) {
991 ReachState state = itr.next();
992 out = Canonical.unionORpreds( out,
993 Canonical.toCallerContext( state, as )
997 assert out.isCanonical();
998 op2result.put( op, out );
1003 public static ReachSet toCallerContext( ReachState state,
1005 assert state != null;
1007 assert state.isCanonical();
1008 assert as.isCanonical();
1011 new CanonicalOp( CanonicalOp.REACHSTATE_TOCALLERCONTEXT_ALLOCSITE,
1015 Canonical result = op2result.get( op );
1016 if( result != null ) {
1017 return (ReachSet) result;
1020 // otherwise, no cached result...
1021 ReachSet out = ReachSet.factory();
1023 // this method returns a ReachSet instead of a ReachState
1024 // because the companion method, toCallee, translates
1025 // symbols many-to-one, so state->state
1026 // but this method does an ~inverse mapping, one-to-many
1027 // so one state can split into a set of branched states
1040 // 2S?* -> {2S*, 2S?*}
1042 boolean found2Sooc = false;
1044 ReachState baseState = ReachState.factory();
1046 Iterator<ReachTuple> itr = state.iterator();
1047 while( itr.hasNext() ) {
1048 ReachTuple rt = itr.next();
1050 int age = as.getAgeCategory( rt.getHrnID() );
1052 if( age == AllocSite.AGE_notInThisSite ) {
1053 // things not from the site just go back in
1054 baseState = Canonical.add( baseState, rt );
1056 } else if( age == AllocSite.AGE_summary ) {
1058 if( rt.isOutOfContext() ) {
1059 // if its out-of-context, we only deal here with the ZERO-OR-MORE
1060 // arity, if ARITY-ONE we'll branch the base state after the loop
1061 if( rt.getArity() == ReachTuple.ARITY_ZEROORMORE ) {
1062 // add two overly conservative symbols to reach state (PUNTING)
1063 baseState = Canonical.add( baseState,
1064 ReachTuple.factory( as.getSummary(),
1066 ReachTuple.ARITY_ZEROORMORE,
1067 false // out-of-context
1070 baseState = Canonical.add( baseState,
1071 ReachTuple.factory( as.getSummary(),
1073 ReachTuple.ARITY_ZEROORMORE,
1074 true // out-of-context
1078 assert rt.getArity() == ReachTuple.ARITY_ONE;
1083 // the in-context just becomes shadow
1084 baseState = Canonical.add( baseState,
1085 ReachTuple.factory( as.getSummaryShadow(),
1088 false // out-of-context
1095 // otherwise age is in range [0, k]
1096 Integer I = as.getAge( rt.getHrnID() );
1098 assert !rt.isMultiObject();
1099 assert rt.getArity() == ReachTuple.ARITY_ONE;
1101 if( rt.isOutOfContext() ) {
1102 // becomes the in-context version
1103 baseState = Canonical.add( baseState,
1104 ReachTuple.factory( rt.getHrnID(),
1106 ReachTuple.ARITY_ONE,
1107 false // out-of-context
1112 // otherwise the ith symbol becomes shadowed
1113 baseState = Canonical.add( baseState,
1114 ReachTuple.factory( -rt.getHrnID(),
1116 ReachTuple.ARITY_ONE,
1117 false // out-of-context
1124 // now either make branches if we have 2S?, or
1125 // the current baseState is the only state we need
1127 // make a branch with every possibility of the one-to-many
1128 // mapping for 2S? appended to the baseState
1129 out = Canonical.add( out,
1130 Canonical.add( baseState,
1131 ReachTuple.factory( as.getSummary(),
1133 ReachTuple.ARITY_ONE,
1134 false // out-of-context
1139 out = Canonical.add( out,
1140 Canonical.add( baseState,
1141 ReachTuple.factory( as.getSummary(),
1143 ReachTuple.ARITY_ONE,
1144 true // out-of-context
1149 for( int i = 0; i < as.getAllocationDepth(); ++i ) {
1150 out = Canonical.add( out,
1151 Canonical.add( baseState,
1152 ReachTuple.factory( as.getIthOldest( i ),
1154 ReachTuple.ARITY_ONE,
1155 true // out-of-context
1162 // just use current baseState
1163 out = Canonical.add( out,
1168 assert out.isCanonical();
1169 op2result.put( op, out );
1181 public static ReachSet unshadow( ReachSet rs,
1185 assert rs.isCanonical();
1186 assert as.isCanonical();
1189 new CanonicalOp( CanonicalOp.REACHSET_UNSHADOW_ALLOCSITE,
1193 Canonical result = op2result.get( op );
1194 if( result != null ) {
1195 return (ReachSet) result;
1198 // otherwise, no cached result...
1199 ReachSet out = ReachSet.factory();
1200 Iterator<ReachState> itr = rs.iterator();
1201 while( itr.hasNext() ) {
1202 ReachState state = itr.next();
1203 out = Canonical.add( out,
1204 Canonical.unshadow( state, as )
1208 assert out.isCanonical();
1209 op2result.put( op, out );
1213 public static ReachState unshadow( ReachState state,
1215 assert state != null;
1217 assert state.isCanonical();
1218 assert as.isCanonical();
1221 new CanonicalOp( CanonicalOp.REACHSTATE_UNSHADOW_ALLOCSITE,
1225 Canonical result = op2result.get( op );
1226 if( result != null ) {
1227 return (ReachState) result;
1230 // this is the current mapping, where 0, 1, 2S were allocated
1231 // in the current context, 0?, 1? and 2S? were allocated in a
1232 // previous context, and we're translating to a future context
1238 // otherwise, no cached result...
1239 ReachState out = ReachState.factory();
1240 Iterator<ReachTuple> itr = state.iterator();
1241 while( itr.hasNext() ) {
1242 ReachTuple rt = itr.next();
1244 int age = as.getShadowAgeCategory( rt.getHrnID() );
1246 if( age == AllocSite.SHADOWAGE_notInThisSite ) {
1247 // things not from the site just go back in
1248 out = Canonical.add( out, rt );
1251 assert !rt.isOutOfContext();
1253 // otherwise unshadow it
1254 out = Canonical.add( out,
1255 ReachTuple.factory( -rt.getHrnID(),
1264 out = Canonical.attach( out,
1268 assert out.isCanonical();
1269 op2result.put( op, out );