[armedbear-cvs] r13136 - trunk/abcl/src/org/armedbear/lisp
Erik Huelsmann
ehuelsmann at common-lisp.net
Wed Jan 12 22:29:16 UTC 2011
Author: ehuelsmann
Date: Wed Jan 12 17:29:15 2011
New Revision: 13136
Log:
When a special bindings index has been assigned past the end
of the special bindings array, grow the array until it fits.
Modified:
trunk/abcl/src/org/armedbear/lisp/LispThread.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 17:29:15 2011
@@ -342,9 +342,15 @@
* SpecialBinding object, but the value field of it is null, that
* indicates an "UNBOUND VARIABLE" situation.
*/
- final SpecialBinding[] specials
+ SpecialBinding[] specials
= new SpecialBinding[Integer.valueOf(System.getProperty("abcl.specials.initialSize","4096"))+1];
+ /** The number of slots to grow the specials table in
+ * case of insufficient storage.
+ */
+ final int specialsDelta
+ = Integer.valueOf(System.getProperty("abcl.specials.grow.delta","1024"));
+
/** This variable points to the head of a linked list of saved
* special bindings. Its main purpose is to allow a mark/reset
* interface to special binding and unbinding.
@@ -382,7 +388,7 @@
/** Assigns a specials array index number to the symbol,
* if it doesn't already have one.
*/
- private static final void assignSpecialIndex(Symbol sym)
+ private void assignSpecialIndex(Symbol sym)
{
if (sym.specialIndex != 0)
return;
@@ -391,6 +397,13 @@
// Don't use an atomic access: we'll be swapping values only once.
if (sym.specialIndex == 0) {
Integer next = freeSpecialIndices.poll();
+ if (next == null
+ && specials.length < lastSpecial.get()
+ && null == System.getProperty("abcl.specials.grow.slowly")) {
+ // free slots are exhausted; in the middle and at the end.
+ System.gc();
+ next = freeSpecialIndices.poll();
+ }
if (next == null)
sym.specialIndex = lastSpecial.incrementAndGet();
else
@@ -429,12 +442,36 @@
}
}
+ private void growSpecials() {
+ SpecialBinding[] newSpecials
+ = new SpecialBinding[specials.length + specialsDelta];
+ System.arraycopy(specials, 0, newSpecials, 0, specials.length);
+ specials = newSpecials;
+ }
+
+ private SpecialBinding ensureSpecialBinding(int idx) {
+ SpecialBinding binding;
+ boolean assigned;
+ do {
+ try {
+ binding = specials[idx];
+ assigned = true;
+ }
+ catch (ArrayIndexOutOfBoundsException e) {
+ assigned = false;
+ binding = null; // suppresses 'unassigned' error
+ growSpecials();
+ }
+ } while (! assigned);
+ return binding;
+ }
+
public final SpecialBinding bindSpecial(Symbol name, LispObject value)
{
int idx;
assignSpecialIndex(name);
- SpecialBinding binding = specials[idx = name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex);
savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials);
return specials[idx] = new SpecialBinding(idx, value);
}
@@ -444,7 +481,7 @@
int idx;
assignSpecialIndex(name);
- SpecialBinding binding = specials[idx = name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex);
savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials);
return specials[idx]
= new SpecialBinding(idx,
@@ -465,18 +502,18 @@
*/
public final LispObject lookupSpecial(Symbol name)
{
- SpecialBinding binding = specials[name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
return (binding == null) ? null : binding.value;
}
public final SpecialBinding getSpecialBinding(Symbol name)
{
- return specials[name.specialIndex];
+ return ensureSpecialBinding(name.specialIndex);
}
public final LispObject setSpecialVariable(Symbol name, LispObject value)
{
- SpecialBinding binding = specials[name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
if (binding != null)
return binding.value = value;
@@ -487,7 +524,7 @@
public final LispObject pushSpecial(Symbol name, LispObject thing)
{
- SpecialBinding binding = specials[name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
if (binding != null)
return binding.value = new Cons(thing, binding.value);
@@ -503,7 +540,7 @@
// Returns symbol value or NIL if unbound.
public final LispObject safeSymbolValue(Symbol name)
{
- SpecialBinding binding = specials[name.specialIndex];
+ SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
if (binding != null)
return binding.value;
More information about the armedbear-cvs
mailing list