1 /* |
1 /* |
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
131 /** Construct a new scope, within scope next, with given owner, using |
131 /** Construct a new scope, within scope next, with given owner, using |
132 * given table. The table's length must be an exponent of 2. |
132 * given table. The table's length must be an exponent of 2. |
133 */ |
133 */ |
134 private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { |
134 private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) { |
135 this.next = next; |
135 this.next = next; |
136 assert emptyScope == null || owner != null; |
136 Assert.check(emptyScope == null || owner != null); |
137 this.owner = owner; |
137 this.owner = owner; |
138 this.table = table; |
138 this.table = table; |
139 this.hashMask = table.length - 1; |
139 this.hashMask = table.length - 1; |
140 this.scopeCounter = scopeCounter; |
140 this.scopeCounter = scopeCounter; |
141 } |
141 } |
189 |
189 |
190 /** Remove all entries of this scope from its table, if shared |
190 /** Remove all entries of this scope from its table, if shared |
191 * with next. |
191 * with next. |
192 */ |
192 */ |
193 public Scope leave() { |
193 public Scope leave() { |
194 assert shared == 0; |
194 Assert.check(shared == 0); |
195 if (table != next.table) return next; |
195 if (table != next.table) return next; |
196 while (elems != null) { |
196 while (elems != null) { |
197 int hash = getIndex(elems.sym.name); |
197 int hash = getIndex(elems.sym.name); |
198 Entry e = table[hash]; |
198 Entry e = table[hash]; |
199 assert e == elems : elems.sym; |
199 Assert.check(e == elems, elems.sym); |
200 table[hash] = elems.shadowed; |
200 table[hash] = elems.shadowed; |
201 elems = elems.sibling; |
201 elems = elems.sibling; |
202 } |
202 } |
203 assert next.shared > 0; |
203 Assert.check(next.shared > 0); |
204 next.shared--; |
204 next.shared--; |
205 next.nelems = nelems; |
205 next.nelems = nelems; |
206 // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode()); |
206 // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode()); |
207 // new Error().printStackTrace(System.out); |
207 // new Error().printStackTrace(System.out); |
208 return next; |
208 return next; |
209 } |
209 } |
210 |
210 |
211 /** Double size of hash table. |
211 /** Double size of hash table. |
212 */ |
212 */ |
213 private void dble() { |
213 private void dble() { |
214 assert shared == 0; |
214 Assert.check(shared == 0); |
215 Entry[] oldtable = table; |
215 Entry[] oldtable = table; |
216 Entry[] newtable = new Entry[oldtable.length * 2]; |
216 Entry[] newtable = new Entry[oldtable.length * 2]; |
217 for (Scope s = this; s != null; s = s.next) { |
217 for (Scope s = this; s != null; s = s.next) { |
218 if (s.table == oldtable) { |
218 if (s.table == oldtable) { |
219 assert s == this || s.shared != 0; |
219 Assert.check(s == this || s.shared != 0); |
220 s.table = newtable; |
220 s.table = newtable; |
221 s.hashMask = newtable.length - 1; |
221 s.hashMask = newtable.length - 1; |
222 } |
222 } |
223 } |
223 } |
224 int n = 0; |
224 int n = 0; |
249 * Enter symbol sym in this scope, but mark that it comes from |
249 * Enter symbol sym in this scope, but mark that it comes from |
250 * given scope `s' accessed through `origin'. The last two |
250 * given scope `s' accessed through `origin'. The last two |
251 * arguments are only used in import scopes. |
251 * arguments are only used in import scopes. |
252 */ |
252 */ |
253 public void enter(Symbol sym, Scope s, Scope origin) { |
253 public void enter(Symbol sym, Scope s, Scope origin) { |
254 assert shared == 0; |
254 Assert.check(shared == 0); |
255 if (nelems * 3 >= hashMask * 2) |
255 if (nelems * 3 >= hashMask * 2) |
256 dble(); |
256 dble(); |
257 int hash = getIndex(sym.name); |
257 int hash = getIndex(sym.name); |
258 Entry old = table[hash]; |
258 Entry old = table[hash]; |
259 if (old == null) { |
259 if (old == null) { |
272 |
272 |
273 /** Remove symbol from this scope. Used when an inner class |
273 /** Remove symbol from this scope. Used when an inner class |
274 * attribute tells us that the class isn't a package member. |
274 * attribute tells us that the class isn't a package member. |
275 */ |
275 */ |
276 public void remove(Symbol sym) { |
276 public void remove(Symbol sym) { |
277 assert shared == 0; |
277 Assert.check(shared == 0); |
278 Entry e = lookup(sym.name); |
278 Entry e = lookup(sym.name); |
279 if (e.scope == null) return; |
279 if (e.scope == null) return; |
280 |
280 |
281 scopeCounter.inc(); |
281 scopeCounter.inc(); |
282 |
282 |
312 } |
312 } |
313 |
313 |
314 /** Enter symbol sym in this scope if not already there. |
314 /** Enter symbol sym in this scope if not already there. |
315 */ |
315 */ |
316 public void enterIfAbsent(Symbol sym) { |
316 public void enterIfAbsent(Symbol sym) { |
317 assert shared == 0; |
317 Assert.check(shared == 0); |
318 Entry e = lookup(sym.name); |
318 Entry e = lookup(sym.name); |
319 while (e.scope == this && e.sym.kind != sym.kind) e = e.next(); |
319 while (e.scope == this && e.sym.kind != sym.kind) e = e.next(); |
320 if (e.scope != this) enter(sym); |
320 if (e.scope != this) enter(sym); |
321 } |
321 } |
322 |
322 |