Changeset 13136 for trunk/abcl/src/org


Ignore:
Timestamp:
01/12/11 22:29:15 (11 years ago)
Author:
ehuelsmann
Message:

When a special bindings index has been assigned past the end
of the special bindings array, grow the array until it fits.

File:
1 edited

Legend:

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

    r13134 r13136  
    343343     * indicates an "UNBOUND VARIABLE" situation.
    344344     */
    345     final SpecialBinding[] specials
     345    SpecialBinding[] specials
    346346        = new SpecialBinding[Integer.valueOf(System.getProperty("abcl.specials.initialSize","4096"))+1];
     347
     348    /** The number of slots to grow the specials table in
     349     * case of insufficient storage.
     350     */
     351    final int specialsDelta
     352        = Integer.valueOf(System.getProperty("abcl.specials.grow.delta","1024"));
    347353
    348354    /** This variable points to the head of a linked list of saved
     
    383389     * if it doesn't already have one.
    384390     */
    385     private static final void assignSpecialIndex(Symbol sym)
     391    private void assignSpecialIndex(Symbol sym)
    386392    {
    387393        if (sym.specialIndex != 0)
     
    392398            if (sym.specialIndex == 0) {
    393399                Integer next = freeSpecialIndices.poll();
     400                if (next == null
     401                        && specials.length < lastSpecial.get()
     402                        && null == System.getProperty("abcl.specials.grow.slowly")) {
     403                    // free slots are exhausted; in the middle and at the end.
     404                    System.gc();
     405                    next = freeSpecialIndices.poll();
     406                }
    394407                if (next == null)
    395408                    sym.specialIndex = lastSpecial.incrementAndGet();
     
    430443    }
    431444
     445    private void growSpecials() {
     446        SpecialBinding[] newSpecials
     447                = new SpecialBinding[specials.length + specialsDelta];
     448        System.arraycopy(specials, 0, newSpecials, 0, specials.length);
     449        specials = newSpecials;
     450    }
     451
     452    private SpecialBinding ensureSpecialBinding(int idx) {
     453        SpecialBinding binding;
     454        boolean assigned;
     455        do {
     456            try {
     457                binding = specials[idx];
     458                assigned = true;
     459            }
     460            catch (ArrayIndexOutOfBoundsException e) {
     461                assigned = false;
     462                binding = null;  // suppresses 'unassigned' error
     463                growSpecials();
     464            }
     465        } while (! assigned);
     466        return binding;
     467    }
     468
    432469    public final SpecialBinding bindSpecial(Symbol name, LispObject value)
    433470    {
     
    435472
    436473        assignSpecialIndex(name);
    437         SpecialBinding binding = specials[idx = name.specialIndex];
     474        SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex);
    438475        savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials);
    439476        return specials[idx] = new SpecialBinding(idx, value);
     
    445482
    446483        assignSpecialIndex(name);
    447         SpecialBinding binding = specials[idx = name.specialIndex];
     484        SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex);
    448485        savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials);
    449486        return specials[idx]
     
    466503    public final LispObject lookupSpecial(Symbol name)
    467504    {
    468         SpecialBinding binding = specials[name.specialIndex];
     505        SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
    469506        return (binding == null) ? null : binding.value;
    470507    }
     
    472509    public final SpecialBinding getSpecialBinding(Symbol name)
    473510    {
    474         return specials[name.specialIndex];
     511        return ensureSpecialBinding(name.specialIndex);
    475512    }
    476513
    477514    public final LispObject setSpecialVariable(Symbol name, LispObject value)
    478515    {
    479         SpecialBinding binding = specials[name.specialIndex];
     516        SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
    480517        if (binding != null)
    481518            return binding.value = value;
     
    488525
    489526    {
    490         SpecialBinding binding = specials[name.specialIndex];
     527        SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
    491528        if (binding != null)
    492529            return binding.value = new Cons(thing, binding.value);
     
    504541    public final LispObject safeSymbolValue(Symbol name)
    505542    {
    506         SpecialBinding binding = specials[name.specialIndex];
     543        SpecialBinding binding = ensureSpecialBinding(name.specialIndex);
    507544        if (binding != null)
    508545            return binding.value;
Note: See TracChangeset for help on using the changeset viewer.