Changeset 13136
- Timestamp:
- 01/12/11 22:29:15 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/abcl/src/org/armedbear/lisp/LispThread.java
r13134 r13136 343 343 * indicates an "UNBOUND VARIABLE" situation. 344 344 */ 345 finalSpecialBinding[] specials345 SpecialBinding[] specials 346 346 = 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")); 347 353 348 354 /** This variable points to the head of a linked list of saved … … 383 389 * if it doesn't already have one. 384 390 */ 385 private static finalvoid assignSpecialIndex(Symbol sym)391 private void assignSpecialIndex(Symbol sym) 386 392 { 387 393 if (sym.specialIndex != 0) … … 392 398 if (sym.specialIndex == 0) { 393 399 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 } 394 407 if (next == null) 395 408 sym.specialIndex = lastSpecial.incrementAndGet(); … … 430 443 } 431 444 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 432 469 public final SpecialBinding bindSpecial(Symbol name, LispObject value) 433 470 { … … 435 472 436 473 assignSpecialIndex(name); 437 SpecialBinding binding = specials[idx = name.specialIndex];474 SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex); 438 475 savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials); 439 476 return specials[idx] = new SpecialBinding(idx, value); … … 445 482 446 483 assignSpecialIndex(name); 447 SpecialBinding binding = specials[idx = name.specialIndex];484 SpecialBinding binding = ensureSpecialBinding(idx = name.specialIndex); 448 485 savedSpecials = new SpecialBindingsMark(idx, binding, savedSpecials); 449 486 return specials[idx] … … 466 503 public final LispObject lookupSpecial(Symbol name) 467 504 { 468 SpecialBinding binding = specials[name.specialIndex];505 SpecialBinding binding = ensureSpecialBinding(name.specialIndex); 469 506 return (binding == null) ? null : binding.value; 470 507 } … … 472 509 public final SpecialBinding getSpecialBinding(Symbol name) 473 510 { 474 return specials[name.specialIndex];511 return ensureSpecialBinding(name.specialIndex); 475 512 } 476 513 477 514 public final LispObject setSpecialVariable(Symbol name, LispObject value) 478 515 { 479 SpecialBinding binding = specials[name.specialIndex];516 SpecialBinding binding = ensureSpecialBinding(name.specialIndex); 480 517 if (binding != null) 481 518 return binding.value = value; … … 488 525 489 526 { 490 SpecialBinding binding = specials[name.specialIndex];527 SpecialBinding binding = ensureSpecialBinding(name.specialIndex); 491 528 if (binding != null) 492 529 return binding.value = new Cons(thing, binding.value); … … 504 541 public final LispObject safeSymbolValue(Symbol name) 505 542 { 506 SpecialBinding binding = specials[name.specialIndex];543 SpecialBinding binding = ensureSpecialBinding(name.specialIndex); 507 544 if (binding != null) 508 545 return binding.value;
Note: See TracChangeset
for help on using the changeset viewer.