src/share/classes/com/sun/tools/javac/code/Scope.java

changeset 858
96d4226bdd60
parent 816
7c537f4298fb
child 877
351027202f60
equal deleted inserted replaced
857:3aa269645199 858:96d4226bdd60
70 /** The number of elements in this scope. 70 /** The number of elements in this scope.
71 * This includes deleted elements, whose value is the sentinel. 71 * This includes deleted elements, whose value is the sentinel.
72 */ 72 */
73 int nelems = 0; 73 int nelems = 0;
74 74
75 /** A timestamp - useful to quickly check whether a scope has changed or not
76 */
77 public ScopeCounter scopeCounter;
78
79 static ScopeCounter dummyCounter = new ScopeCounter() {
80 @Override
81 public void inc() {
82 //do nothing
83 }
84 };
85
86 /** A list of scopes to be notified if items are to be removed from this scope. 75 /** A list of scopes to be notified if items are to be removed from this scope.
87 */ 76 */
88 List<Scope> listeners = List.nil(); 77 List<Scope> listeners = List.nil();
89
90 public static class ScopeCounter {
91 protected static final Context.Key<ScopeCounter> scopeCounterKey =
92 new Context.Key<ScopeCounter>();
93
94 public static ScopeCounter instance(Context context) {
95 ScopeCounter instance = context.get(scopeCounterKey);
96 if (instance == null)
97 instance = new ScopeCounter(context);
98 return instance;
99 }
100
101 protected ScopeCounter(Context context) {
102 context.put(scopeCounterKey, this);
103 }
104
105 private ScopeCounter() {};
106
107 private long val = 0;
108
109 public void inc() {
110 val++;
111 }
112
113 public long val() {
114 return val;
115 }
116 }
117 78
118 /** Use as a "not-found" result for lookup. 79 /** Use as a "not-found" result for lookup.
119 * Also used to mark deleted entries in the table. 80 * Also used to mark deleted entries in the table.
120 */ 81 */
121 private static final Entry sentinel = new Entry(null, null, null, null); 82 private static final Entry sentinel = new Entry(null, null, null, null);
124 */ 85 */
125 private static final int INITIAL_SIZE = 0x10; 86 private static final int INITIAL_SIZE = 0x10;
126 87
127 /** A value for the empty scope. 88 /** A value for the empty scope.
128 */ 89 */
129 public static final Scope emptyScope = new Scope(null, null, new Entry[]{}, dummyCounter); 90 public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
130 91
131 /** Construct a new scope, within scope next, with given owner, using 92 /** Construct a new scope, within scope next, with given owner, using
132 * given table. The table's length must be an exponent of 2. 93 * given table. The table's length must be an exponent of 2.
133 */ 94 */
134 private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { 95 private Scope(Scope next, Symbol owner, Entry[] table) {
135 this.next = next; 96 this.next = next;
136 Assert.check(emptyScope == null || owner != null); 97 Assert.check(emptyScope == null || owner != null);
137 this.owner = owner; 98 this.owner = owner;
138 this.table = table; 99 this.table = table;
139 this.hashMask = table.length - 1; 100 this.hashMask = table.length - 1;
140 this.scopeCounter = scopeCounter;
141 } 101 }
142 102
143 /** Convenience constructor used for dup and dupUnshared. */ 103 /** Convenience constructor used for dup and dupUnshared. */
144 private Scope(Scope next, Symbol owner, Entry[] table) { 104 private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
145 this(next, owner, table, next.scopeCounter); 105 this(next, owner, table);
146 this.nelems = next.nelems; 106 this.nelems = nelems;
147 } 107 }
148 108
149 /** Construct a new scope, within scope next, with given owner, 109 /** Construct a new scope, within scope next, with given owner,
150 * using a fresh table of length INITIAL_SIZE. 110 * using a fresh table of length INITIAL_SIZE.
151 */ 111 */
152 public Scope(Symbol owner) { 112 public Scope(Symbol owner) {
153 this(owner, dummyCounter); 113 this(null, owner, new Entry[INITIAL_SIZE]);
154 }
155
156 protected Scope(Symbol owner, ScopeCounter scopeCounter) {
157 this(null, owner, new Entry[INITIAL_SIZE], scopeCounter);
158 } 114 }
159 115
160 /** Construct a fresh scope within this scope, with same owner, 116 /** Construct a fresh scope within this scope, with same owner,
161 * which shares its table with the outer scope. Used in connection with 117 * which shares its table with the outer scope. Used in connection with
162 * method leave if scope access is stack-like in order to avoid allocation 118 * method leave if scope access is stack-like in order to avoid allocation
170 * which shares its table with the outer scope. Used in connection with 126 * which shares its table with the outer scope. Used in connection with
171 * method leave if scope access is stack-like in order to avoid allocation 127 * method leave if scope access is stack-like in order to avoid allocation
172 * of fresh tables. 128 * of fresh tables.
173 */ 129 */
174 public Scope dup(Symbol newOwner) { 130 public Scope dup(Symbol newOwner) {
175 Scope result = new Scope(this, newOwner, this.table); 131 Scope result = new Scope(this, newOwner, this.table, this.nelems);
176 shared++; 132 shared++;
177 // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode()); 133 // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
178 // new Error().printStackTrace(System.out); 134 // new Error().printStackTrace(System.out);
179 return result; 135 return result;
180 } 136 }
182 /** Construct a fresh scope within this scope, with same owner, 138 /** Construct a fresh scope within this scope, with same owner,
183 * with a new hash table, whose contents initially are those of 139 * with a new hash table, whose contents initially are those of
184 * the table of its outer scope. 140 * the table of its outer scope.
185 */ 141 */
186 public Scope dupUnshared() { 142 public Scope dupUnshared() {
187 return new Scope(this, this.owner, this.table.clone()); 143 return new Scope(this, this.owner, this.table.clone(), this.nelems);
188 } 144 }
189 145
190 /** Remove all entries of this scope from its table, if shared 146 /** Remove all entries of this scope from its table, if shared
191 * with next. 147 * with next.
192 */ 148 */
261 nelems++; 217 nelems++;
262 } 218 }
263 Entry e = makeEntry(sym, old, elems, s, origin); 219 Entry e = makeEntry(sym, old, elems, s, origin);
264 table[hash] = e; 220 table[hash] = e;
265 elems = e; 221 elems = e;
266 scopeCounter.inc();
267 } 222 }
268 223
269 Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) { 224 Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
270 return new Entry(sym, shadowed, sibling, scope); 225 return new Entry(sym, shadowed, sibling, scope);
271 } 226 }
275 */ 230 */
276 public void remove(Symbol sym) { 231 public void remove(Symbol sym) {
277 Assert.check(shared == 0); 232 Assert.check(shared == 0);
278 Entry e = lookup(sym.name); 233 Entry e = lookup(sym.name);
279 if (e.scope == null) return; 234 if (e.scope == null) return;
280
281 scopeCounter.inc();
282 235
283 // remove e from table and shadowed list; 236 // remove e from table and shadowed list;
284 int i = getIndex(sym.name); 237 int i = getIndex(sym.name);
285 Entry te = table[i]; 238 Entry te = table[i];
286 if (te == e) 239 if (te == e)
557 public static class DelegatedScope extends Scope { 510 public static class DelegatedScope extends Scope {
558 Scope delegatee; 511 Scope delegatee;
559 public static final Entry[] emptyTable = new Entry[0]; 512 public static final Entry[] emptyTable = new Entry[0];
560 513
561 public DelegatedScope(Scope outer) { 514 public DelegatedScope(Scope outer) {
562 super(outer, outer.owner, emptyTable, outer.scopeCounter); 515 super(outer, outer.owner, emptyTable);
563 delegatee = outer; 516 delegatee = outer;
564 } 517 }
565 public Scope dup() { 518 public Scope dup() {
566 return new DelegatedScope(next); 519 return new DelegatedScope(next);
567 } 520 }
580 public void remove(Symbol sym) { 533 public void remove(Symbol sym) {
581 throw new AssertionError(sym); 534 throw new AssertionError(sym);
582 } 535 }
583 public Entry lookup(Name name) { 536 public Entry lookup(Name name) {
584 return delegatee.lookup(name); 537 return delegatee.lookup(name);
585 }
586 }
587
588 /** A class scope, for which a scope counter should be provided */
589 public static class ClassScope extends Scope {
590
591 ClassScope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) {
592 super(next, owner, table, scopeCounter);
593 }
594
595 public ClassScope(Symbol owner, ScopeCounter scopeCounter) {
596 super(owner, scopeCounter);
597 } 538 }
598 } 539 }
599 540
600 /** An error scope, for which the owner should be an error symbol. */ 541 /** An error scope, for which the owner should be an error symbol. */
601 public static class ErrorScope extends Scope { 542 public static class ErrorScope extends Scope {
602 ErrorScope(Scope next, Symbol errSymbol, Entry[] table) { 543 ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
603 super(next, /*owner=*/errSymbol, table, dummyCounter); 544 super(next, /*owner=*/errSymbol, table);
604 } 545 }
605 public ErrorScope(Symbol errSymbol) { 546 public ErrorScope(Symbol errSymbol) {
606 super(errSymbol); 547 super(errSymbol);
607 } 548 }
608 public Scope dup() { 549 public Scope dup() {

mercurial