-
Notifications
You must be signed in to change notification settings - Fork 0
/
LockNode.java
executable file
·105 lines (96 loc) · 3.69 KB
/
LockNode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**************************************************************************
* @author Mahdi Eslamimehr
* @version 0.1
***************************************************************************/
package ContractGen;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import soot.Type;
import soot.VoidType;
/******************************************************
* This class models a single node in the lock graph.
* A node in the lock graph has two main fields:
* - the 'l' field (Type: Aggregate),
* - the 's' field (Type: Boolean).
* The 'l' field is a collection of all synonymized
* lock values for a given synchronizing, locking or
* unlocking instance in the program.
* The 's' field distinguishes monitors (wt/ntfy)
* from locks (synch(x))
****************************************************/
public class LockNode {
private boolean s; // True for wait/notify
private Aggregate l; // The actual lock value
// For simple cycle check
public int visited = 0;
// For Tarjan decomposition
public int index;
public int lowlink;
/*****************************
* Construct a new Locknode.
***************************/
public LockNode(Aggregate l, boolean s) {
this.l = l;
this.s = s;
}
// Deep copy
public LockNode(LockNode o) {
s = o.s;
l = new Aggregate(o.l);
}
/**************************************************
* Returns the 'l' field of a lock node.
************************************************/
public Aggregate v() { return l; }
/**************************************************
* Returns the 's' field of a lock node.
************************************************/
public boolean isSynch() { return s; }
public String toString() { return (s?"M":"L")+","+l; }
/**************************************************
* Replace the value _old in the Locknode with
* value _new.
************************************************/
public void replace(Synonym _old, Aggregate _new) {
l.replace(_old, _new);
}
public int hashCode() { return ((s?101:353)+l.hashCode()); }
public boolean equals(Object o) {
LockNode ln = (LockNode) o;
// System.out.println("\nComparing >>"+L+"<< with >>"+toString()+"<<");
// System.out.println("\t His hashCode = "+L.hashCode()+", my hashCode = "+hashCode()+".");
// System.out.println("\t His LV's hashCode = "+L.l.hashCode()+", my LV's hashCode = "+l.hashCode()+".\n");
return ((ln.s==s) && (ln.l.equals(l)));
}
private static HashMap lockNodes = null;
public Type getType() {
if (!l.iterator().hasNext()) {
E.error("Empty lock node was found.");
return VoidType.v();
}
return ((Synonym) l.iterator().next()).getType();
}
public String getFullType() {
if (l.isEmpty() || !l.iterator().hasNext()) return VoidType.v().toString();
return ((Synonym) l.iterator().next()).fullType();
}
public boolean isFinal() {
if (l.isEmpty() || !l.iterator().hasNext()) return true;
return ((Synonym) l.iterator().next()).isFinal();
}
public boolean isStatic() {
if (l.isEmpty() || !l.iterator().hasNext()) return true;
return ((Synonym) l.iterator().next()).isStatic();
}
public boolean isPrivateOf(HashSet c) {
if (l.isEmpty() || !l.iterator().hasNext()) return false;
Synonym syn = (Synonym) l.iterator().next();
if (syn.isIfr()) {
InstField I = (InstField) syn.v();
String bType = I.base().fullType();
if (c.contains(bType)) return true;
}
return false;
}
}