Fix tabbing.... Please fix your editors so they do tabbing correctly!!! (Spaces...
[IRC.git] / Robust / src / Analysis / Disjoint / ReachTuple.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8 ///////////////////////////////////////////
9 //  IMPORTANT
10 //  This class is an immutable Canonical, so
11 //
12 //  0) construct them with a factory pattern
13 //  to ensure only canonical versions escape
14 //
15 //  1) any operation that modifies a Canonical
16 //  is a static method in the Canonical class
17 //
18 //  2) operations that just read this object
19 //  should be defined here
20 //
21 //  3) every Canonical subclass hashCode should
22 //  throw an error if the hash ever changes
23 //
24 ///////////////////////////////////////////
25
26 // a reach touple is a pair that indicates a
27 // heap region node and an arity
28
29 public class ReachTuple extends Canonical {
30
31   // defined by the source heap region
32   protected Integer hrnID;
33   protected boolean isMultiObject;
34
35   // arity of reachability paths from the
36   // given heap region
37   public static final int ARITY_ZEROORMORE = 0;
38   public static final int ARITY_ONE        = 1;
39   public static final int ARITY_ONEORMORE  = 2;
40   protected int arity;
41
42   // whether this represents heap regions out
43   // of the current calling context or not
44   protected boolean isOutOfContext;
45
46
47   public static ReachTuple factory(Integer hrnID,
48                                    boolean isMultiObject,
49                                    int arity,
50                                    boolean ooc) {
51     ReachTuple out = new ReachTuple(hrnID,
52                                     isMultiObject,
53                                     arity,
54                                     ooc);
55     out = (ReachTuple) Canonical.makeCanonical(out);
56     return out;
57   }
58
59   public static ReachTuple factory(HeapRegionNode hrn) {
60     ReachTuple out = new ReachTuple(hrn.getID(),
61                                     !hrn.isSingleObject(),
62                                     ARITY_ONE,
63                                     false);
64     out = (ReachTuple) Canonical.makeCanonical(out);
65     return out;
66   }
67
68   protected ReachTuple(Integer hrnID,
69                        boolean isMultiObject,
70                        int arity,
71                        boolean ooc) {
72     assert hrnID != null;
73
74     this.hrnID          = hrnID;
75     this.isMultiObject  = isMultiObject;
76     this.arity          = arity;
77     this.isOutOfContext = ooc;
78
79     // just make sure this stuff is true now
80     // that analysis doesn't use ONEORMORE
81     assert arity != ARITY_ONEORMORE;
82     if( !isMultiObject ) {
83       assert arity == ARITY_ONE;
84     }
85   }
86
87
88   public Integer getHrnID() {
89     return hrnID;
90   }
91
92   public boolean isMultiObject() {
93     return isMultiObject;
94   }
95
96   public int getArity() {
97     return arity;
98   }
99
100   public boolean isOutOfContext() {
101     return isOutOfContext;
102   }
103
104
105   public boolean equalsSpecific(Object o) {
106     if( o == null ) {
107       return false;
108     }
109
110     if( !(o instanceof ReachTuple) ) {
111       return false;
112     }
113
114     ReachTuple rt = (ReachTuple) o;
115
116     return hrnID.equals(rt.hrnID)       &&
117            arity          == rt.arity          &&
118            isOutOfContext == rt.isOutOfContext;
119   }
120
121   public int hashCodeSpecific() {
122     int hash = (hrnID.intValue() << 2) ^ arity;
123     if( isOutOfContext ) {
124       hash = ~hash;
125     }
126     return hash;
127   }
128
129
130   public String toString() {
131     String s = hrnID.toString();
132
133     if( isMultiObject ) {
134       s += "M";
135     }
136
137     if( isOutOfContext ) {
138       s += "?";
139     }
140
141     if( arity == ARITY_ZEROORMORE ) {
142       s += "*";
143     } else if( arity == ARITY_ONEORMORE ) {
144       s += "+";
145     }
146
147     return s;
148   }
149 }