6996626: Scope fix issues for ImportScope

Mon, 01 Nov 2010 19:28:40 -0700

author
jjg
date
Mon, 01 Nov 2010 19:28:40 -0700
changeset 729
6ce6ee1b831a
parent 728
895bea45a3e8
child 730
20659c8c917d

6996626: Scope fix issues for ImportScope
Reviewed-by: darcy

src/share/classes/com/sun/tools/javac/code/Scope.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Scope.java	Fri Oct 29 13:12:38 2010 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Scope.java	Mon Nov 01 19:28:40 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -31,8 +31,7 @@
    1.11  /** A scope represents an area of visibility in a Java program. The
    1.12   *  Scope class is a container for symbols which provides
    1.13   *  efficient access to symbols given their names. Scopes are implemented
    1.14 - *  as hash tables with "open addressing" and "double hashing".
    1.15 - *  Scopes can be nested; the next field of a scope points
    1.16 + *  as hash tables. Scopes can be nested; the next field of a scope points
    1.17   *  to its next outer scope. Nested scopes can share their hash tables.
    1.18   *
    1.19   *  <p><b>This is NOT part of any supported API.
    1.20 @@ -68,7 +67,6 @@
    1.21      public Entry elems;
    1.22  
    1.23      /** The number of elements in this scope.
    1.24 -     * This includes deleted elements, whose value is the sentinel.
    1.25       */
    1.26      public int nelems = 0;
    1.27  
    1.28 @@ -111,8 +109,7 @@
    1.29          }
    1.30      }
    1.31  
    1.32 -    /** Use as a "not-found" result for lookup.
    1.33 -     * Also used to mark deleted entries in the table.
    1.34 +    /** Every hash bucket is a list of Entry's which ends in sentinel.
    1.35       */
    1.36      private static final Entry sentinel = new Entry(null, null, null, null);
    1.37  
    1.38 @@ -133,15 +130,12 @@
    1.39          this.owner = owner;
    1.40          this.table = table;
    1.41          this.hashMask = table.length - 1;
    1.42 +        this.elems = null;
    1.43 +        this.nelems = 0;
    1.44 +        this.shared = 0;
    1.45          this.scopeCounter = scopeCounter;
    1.46      }
    1.47  
    1.48 -    /** Convenience constructor used for dup and dupUnshared. */
    1.49 -    private Scope(Scope next, Symbol owner, Entry[] table) {
    1.50 -        this(next, owner, table, next.scopeCounter);
    1.51 -        this.nelems = next.nelems;
    1.52 -    }
    1.53 -
    1.54      /** Construct a new scope, within scope next, with given owner,
    1.55       *  using a fresh table of length INITIAL_SIZE.
    1.56       */
    1.57 @@ -151,6 +145,7 @@
    1.58  
    1.59      protected Scope(Symbol owner, ScopeCounter scopeCounter) {
    1.60          this(null, owner, new Entry[INITIAL_SIZE], scopeCounter);
    1.61 +        for (int i = 0; i < INITIAL_SIZE; i++) table[i] = sentinel;
    1.62      }
    1.63  
    1.64      /** Construct a fresh scope within this scope, with same owner,
    1.65 @@ -159,7 +154,11 @@
    1.66       *  of fresh tables.
    1.67       */
    1.68      public Scope dup() {
    1.69 -        return dup(this.owner);
    1.70 +        Scope result = new Scope(this, this.owner, this.table, scopeCounter);
    1.71 +        shared++;
    1.72 +        // System.out.println("====> duping scope " + this.hashCode() + " owned by " + this.owner + " to " + result.hashCode());
    1.73 +        // new Error().printStackTrace(System.out);
    1.74 +        return result;
    1.75      }
    1.76  
    1.77      /** Construct a fresh scope within this scope, with new owner,
    1.78 @@ -168,7 +167,7 @@
    1.79       *  of fresh tables.
    1.80       */
    1.81      public Scope dup(Symbol newOwner) {
    1.82 -        Scope result = new Scope(this, newOwner, this.table);
    1.83 +        Scope result = new Scope(this, newOwner, this.table, scopeCounter);
    1.84          shared++;
    1.85          // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
    1.86          // new Error().printStackTrace(System.out);
    1.87 @@ -180,7 +179,7 @@
    1.88       *  the table of its outer scope.
    1.89       */
    1.90      public Scope dupUnshared() {
    1.91 -        return new Scope(this, this.owner, this.table.clone());
    1.92 +        return new Scope(this, this.owner, this.table.clone(), scopeCounter);
    1.93      }
    1.94  
    1.95      /** Remove all entries of this scope from its table, if shared
    1.96 @@ -190,7 +189,7 @@
    1.97          assert shared == 0;
    1.98          if (table != next.table) return next;
    1.99          while (elems != null) {
   1.100 -            int hash = getIndex(elems.sym.name);
   1.101 +            int hash = elems.sym.name.hashCode() & hashMask;
   1.102              Entry e = table[hash];
   1.103              assert e == elems : elems.sym;
   1.104              table[hash] = elems.shadowed;
   1.105 @@ -198,7 +197,6 @@
   1.106          }
   1.107          assert next.shared > 0;
   1.108          next.shared--;
   1.109 -        next.nelems = nelems;
   1.110          // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
   1.111          // new Error().printStackTrace(System.out);
   1.112          return next;
   1.113 @@ -217,17 +215,19 @@
   1.114                  s.hashMask = newtable.length - 1;
   1.115              }
   1.116          }
   1.117 -        int n = 0;
   1.118 -        for (int i = oldtable.length; --i >= 0; ) {
   1.119 -            Entry e = oldtable[i];
   1.120 -            if (e != null && e != sentinel) {
   1.121 -                table[getIndex(e.sym.name)] = e;
   1.122 -                n++;
   1.123 -            }
   1.124 +        for (int i = 0; i < newtable.length; i++) newtable[i] = sentinel;
   1.125 +        for (int i = 0; i < oldtable.length; i++) copy(oldtable[i]);
   1.126 +    }
   1.127 +
   1.128 +    /** Copy the given entry and all entries shadowed by it to table
   1.129 +     */
   1.130 +    private void copy(Entry e) {
   1.131 +        if (e.sym != null) {
   1.132 +            copy(e.shadowed);
   1.133 +            int hash = e.sym.name.hashCode() & hashMask;
   1.134 +            e.shadowed = table[hash];
   1.135 +            table[hash] = e;
   1.136          }
   1.137 -        // We don't need to update nelems for shared inherited scopes,
   1.138 -        // since that gets handled by leave().
   1.139 -        nelems = n;
   1.140      }
   1.141  
   1.142      /** Enter symbol sym in this scope.
   1.143 @@ -248,17 +248,13 @@
   1.144       */
   1.145      public void enter(Symbol sym, Scope s, Scope origin) {
   1.146          assert shared == 0;
   1.147 -        if (nelems * 3 >= hashMask * 2)
   1.148 -            dble();
   1.149 -        int hash = getIndex(sym.name);
   1.150 -        Entry old = table[hash];
   1.151 -        if (old == null) {
   1.152 -            old = sentinel;
   1.153 -            nelems++;
   1.154 -        }
   1.155 -        Entry e = makeEntry(sym, old, elems, s, origin);
   1.156 +        // Temporarily disabled (bug 6460352):
   1.157 +        // if (nelems * 3 >= hashMask * 2) dble();
   1.158 +        int hash = sym.name.hashCode() & hashMask;
   1.159 +        Entry e = makeEntry(sym, table[hash], elems, s, origin);
   1.160          table[hash] = e;
   1.161          elems = e;
   1.162 +        nelems++;
   1.163          scopeCounter.inc();
   1.164      }
   1.165  
   1.166 @@ -272,15 +268,15 @@
   1.167      public void remove(Symbol sym) {
   1.168          assert shared == 0;
   1.169          Entry e = lookup(sym.name);
   1.170 +        while (e.scope == this && e.sym != sym) e = e.next();
   1.171          if (e.scope == null) return;
   1.172  
   1.173          scopeCounter.inc();
   1.174  
   1.175          // remove e from table and shadowed list;
   1.176 -        int i = getIndex(sym.name);
   1.177 -        Entry te = table[i];
   1.178 +        Entry te = table[sym.name.hashCode() & hashMask];
   1.179          if (te == e)
   1.180 -            table[i] = e.shadowed;
   1.181 +            table[sym.name.hashCode() & hashMask] = e.shadowed;
   1.182          else while (true) {
   1.183              if (te.shadowed == e) {
   1.184                  te.shadowed = e.shadowed;
   1.185 @@ -339,50 +335,12 @@
   1.186          return lookup(name, noFilter);
   1.187      }
   1.188      public Entry lookup(Name name, Filter<Symbol> sf) {
   1.189 -        Entry e = table[getIndex(name)];
   1.190 -        if (e == null || e == sentinel)
   1.191 -            return sentinel;
   1.192 +        Entry e = table[name.hashCode() & hashMask];
   1.193          while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
   1.194              e = e.shadowed;
   1.195          return e;
   1.196      }
   1.197  
   1.198 -    /*void dump (java.io.PrintStream out) {
   1.199 -        out.println(this);
   1.200 -        for (int l=0; l < table.length; l++) {
   1.201 -            Entry le = table[l];
   1.202 -            out.print("#"+l+": ");
   1.203 -            if (le==sentinel) out.println("sentinel");
   1.204 -            else if(le == null) out.println("null");
   1.205 -            else out.println(""+le+" s:"+le.sym);
   1.206 -        }
   1.207 -    }*/
   1.208 -
   1.209 -    /** Look for slot in the table.
   1.210 -     *  We use open addressing with double hashing.
   1.211 -     */
   1.212 -    int getIndex (Name name) {
   1.213 -        int h = name.hashCode();
   1.214 -        int i = h & hashMask;
   1.215 -        // The expression below is always odd, so it is guaranteed
   1.216 -        // be be mutually prime with table.length, a power of 2.
   1.217 -        int x = hashMask - ((h + (h >> 16)) << 1);
   1.218 -        int d = -1; // Index of a deleted item.
   1.219 -        for (;;) {
   1.220 -            Entry e = table[i];
   1.221 -            if (e == null)
   1.222 -                return d >= 0 ? d : i;
   1.223 -            if (e == sentinel) {
   1.224 -                // We have to keep searching even if we see a deleted item.
   1.225 -                // However, remember the index in case we fail to find the name.
   1.226 -                if (d < 0)
   1.227 -                    d = i;
   1.228 -            } else if (e.sym.name == name)
   1.229 -                return i;
   1.230 -            i = (i + x) & hashMask;
   1.231 -        }
   1.232 -    }
   1.233 -
   1.234      public Iterable<Symbol> getElements() {
   1.235          return getElements(noFilter);
   1.236      }
   1.237 @@ -512,11 +470,10 @@
   1.238          }
   1.239  
   1.240          public Entry lookup(Name name) {
   1.241 -            Entry e = table[getIndex(name)];
   1.242 -            if (e == null)
   1.243 -                return sentinel;
   1.244 +            Entry e = table[name.hashCode() & hashMask];
   1.245              while (e.scope != null &&
   1.246 -                   (/* Since an inner class will show up in package and
   1.247 +                   (e.sym.name != name ||
   1.248 +                    /* Since an inner class will show up in package and
   1.249                       * import scopes until its inner class attribute has
   1.250                       * been processed, we have to weed it out here.  This
   1.251                       * is done by comparing the owners of the entry's

mercurial