[armedbear-cvs] r13134 - trunk/abcl/src/org/armedbear/lisp
Erik Huelsmann
ehuelsmann at common-lisp.net
Wed Jan 12 21:35:33 UTC 2011
Author: ehuelsmann
Date: Wed Jan 12 16:35:30 2011
New Revision: 13134
Log:
Make sure symbols which have been assigned a specialIndex
free their index when being garbage collected.
Modified:
trunk/abcl/src/org/armedbear/lisp/LispThread.java
trunk/abcl/src/org/armedbear/lisp/Symbol.java
Modified: trunk/abcl/src/org/armedbear/lisp/LispThread.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/LispThread.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/LispThread.java Wed Jan 12 16:35:30 2011
@@ -37,6 +37,7 @@
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
public final class LispThread extends LispObject
@@ -327,6 +328,12 @@
final static AtomicInteger lastSpecial
= new AtomicInteger(UNASSIGNED_SPECIAL_INDEX);
+ /** A list of indices which can be (re)used for symbols to
+ * be assigned a special slot index.
+ */
+ final static ConcurrentLinkedQueue<Integer> freeSpecialIndices
+ = new ConcurrentLinkedQueue<Integer>();
+
/** This array stores the current special binding for every symbol
* which has been globally or locally declared special.
*
@@ -335,12 +342,8 @@
* SpecialBinding object, but the value field of it is null, that
* indicates an "UNBOUND VARIABLE" situation.
*/
- final SpecialBinding[] specials = new SpecialBinding[4097];
-
- /** This array stores the symbols associated with the special
- * bindings slots.
- */
- final static Symbol[] specialNames = new Symbol[4097];
+ final SpecialBinding[] specials
+ = new SpecialBinding[Integer.valueOf(System.getProperty("abcl.specials.initialSize","4096"))+1];
/** This variable points to the head of a linked list of saved
* special bindings. Its main purpose is to allow a mark/reset
@@ -387,9 +390,42 @@
synchronized (sym) {
// Don't use an atomic access: we'll be swapping values only once.
if (sym.specialIndex == 0) {
- sym.specialIndex = lastSpecial.incrementAndGet();
- specialNames[sym.specialIndex] = sym;
+ Integer next = freeSpecialIndices.poll();
+ if (next == null)
+ sym.specialIndex = lastSpecial.incrementAndGet();
+ else
+ sym.specialIndex = next.intValue();
+ }
+ }
+ }
+
+ /** Frees up an index previously assigned to a symbol for re-assignment
+ * to another symbol. Returns without effect if the symbol has the
+ * default UNASSIGNED_SPECIAL_INDEX special index.
+ */
+ protected static void releaseSpecialIndex(Symbol sym)
+ {
+ int index = sym.specialIndex;
+ if (index != UNASSIGNED_SPECIAL_INDEX) {
+ // clear out the values in the
+ Iterator<LispThread> it = map.values().iterator();
+ while (it.hasNext()) {
+ LispThread thread = it.next();
+
+ // clear out the values in the saved specials list
+ SpecialBindingsMark savedSpecial = thread.savedSpecials;
+ while (savedSpecial != null) {
+ if (savedSpecial.idx == index) {
+ savedSpecial.idx = 0;
+ savedSpecial.binding = null;
+ }
+ savedSpecial = savedSpecial.next;
+ }
+
+ thread.specials[index] = null;
}
+
+ freeSpecialIndices.add(new Integer(index));
}
}
Modified: trunk/abcl/src/org/armedbear/lisp/Symbol.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Symbol.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/Symbol.java Wed Jan 12 16:35:30 2011
@@ -94,6 +94,17 @@
this.pkg = pkg;
}
+ @Override
+ @SuppressWarnings("FinalizeDeclaration")
+ protected void finalize() throws Throwable {
+ try {
+ if (specialIndex != LispThread.UNASSIGNED_SPECIAL_INDEX)
+ LispThread.releaseSpecialIndex(this);
+ } finally {
+ super.finalize();
+ }
+ }
+
@Override
public LispObject typeOf()
{
More information about the armedbear-cvs
mailing list