Changeset 13134


Ignore:
Timestamp:
01/12/11 21:35:30 (11 years ago)
Author:
ehuelsmann
Message:

Make sure symbols which have been assigned a specialIndex
free their index when being garbage collected.

Location:
trunk/abcl/src/org/armedbear/lisp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/LispThread.java

    r13109 r13134  
    3838import java.util.Iterator;
    3939import java.util.concurrent.ConcurrentHashMap;
     40import java.util.concurrent.ConcurrentLinkedQueue;
    4041import java.util.concurrent.atomic.AtomicInteger;
    4142
     
    328329        = new AtomicInteger(UNASSIGNED_SPECIAL_INDEX);
    329330
     331    /** A list of indices which can be (re)used for symbols to
     332     * be assigned a special slot index.
     333     */
     334    final static ConcurrentLinkedQueue<Integer> freeSpecialIndices
     335        = new ConcurrentLinkedQueue<Integer>();
     336   
    330337    /** This array stores the current special binding for every symbol
    331338     * which has been globally or locally declared special.
     
    336343     * indicates an "UNBOUND VARIABLE" situation.
    337344     */
    338     final SpecialBinding[] specials = new SpecialBinding[4097];
    339 
    340     /** This array stores the symbols associated with the special
    341      * bindings slots.
    342      */
    343     final static Symbol[] specialNames = new Symbol[4097];
     345    final SpecialBinding[] specials
     346        = new SpecialBinding[Integer.valueOf(System.getProperty("abcl.specials.initialSize","4096"))+1];
    344347
    345348    /** This variable points to the head of a linked list of saved
     
    388391            // Don't use an atomic access: we'll be swapping values only once.
    389392            if (sym.specialIndex == 0) {
    390                 sym.specialIndex = lastSpecial.incrementAndGet();
    391                 specialNames[sym.specialIndex] = sym;
    392             }
     393                Integer next = freeSpecialIndices.poll();
     394                if (next == null)
     395                    sym.specialIndex = lastSpecial.incrementAndGet();
     396                else
     397                    sym.specialIndex = next.intValue();
     398            }
     399        }
     400    }
     401
     402    /** Frees up an index previously assigned to a symbol for re-assignment
     403     * to another symbol. Returns without effect if the symbol has the
     404     * default UNASSIGNED_SPECIAL_INDEX special index.
     405     */
     406    protected static void releaseSpecialIndex(Symbol sym)
     407    {
     408        int index = sym.specialIndex;
     409        if (index != UNASSIGNED_SPECIAL_INDEX) {
     410            // clear out the values in the
     411            Iterator<LispThread> it = map.values().iterator();
     412            while (it.hasNext()) {
     413                LispThread thread = it.next();
     414
     415                // clear out the values in the saved specials list
     416                SpecialBindingsMark savedSpecial = thread.savedSpecials;
     417                while (savedSpecial != null) {
     418                    if (savedSpecial.idx == index) {
     419                        savedSpecial.idx = 0;
     420                        savedSpecial.binding = null;
     421                    }
     422                    savedSpecial = savedSpecial.next;
     423                }
     424
     425                thread.specials[index] = null;
     426            }
     427
     428            freeSpecialIndices.add(new Integer(index));
    393429        }
    394430    }
  • trunk/abcl/src/org/armedbear/lisp/Symbol.java

    r12978 r13134  
    9494    this.pkg = pkg;
    9595  }
     96
     97    @Override
     98    @SuppressWarnings("FinalizeDeclaration")
     99    protected void finalize() throws Throwable {
     100        try {
     101            if (specialIndex != LispThread.UNASSIGNED_SPECIAL_INDEX)
     102                LispThread.releaseSpecialIndex(this);
     103        } finally {
     104            super.finalize();
     105        }
     106    }
    96107
    97108  @Override
Note: See TracChangeset for help on using the changeset viewer.