Changeset 11520


Ignore:
Timestamp:
Dec 15, 2008, 7:41:06 AM (11 years ago)
Author:
gb
Message:

PPC support for %ALLOCATE-LIST, which is intended to be used to
implement MAKE-LIST when N is large enough that allocating N
individual CONSes might trigger the EGC/GC unproductively.

Location:
trunk/source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/arch.lisp

    r11150 r11520  
    6666(defconstant error-kill 16)
    6767(defconstant error-cant-call 17)        ; Attempt to funcall something that is not a symbol or function.
     68(defconstant error-allocate-list 18)
     69
    6870(eval-when (:compile-toplevel :load-toplevel :execute)
    6971  (defconstant error-type-error 128)
  • trunk/source/level-0/PPC/ppc-utils.lisp

    r10959 r11520  
    585585  #+32-bit-target
    586586  (ba .SPmakeu32))
     587
     588;;; Make a list.  This can be faster than doing so by doing CONS
     589;;; repeatedly, since the latter strategy might triger the GC several
     590;;; times if N is large.
     591(defppclapfunction %allocate-list ((initial-element arg_y) (nconses arg_z))
     592  (check-nargs 2)
     593  (save-lisp-context)
     594  (uuo_interr arch::error-allocate-list rzero)
     595  (vpush arg_z)
     596  (vpush arg_y)
     597  (set-nargs 2)
     598  (ba .SPnvalret))
    587599 
    588600
  • trunk/source/lisp-kernel/lisp-errors.h

    r11143 r11520  
    3535#define error_kill 16
    3636#define error_cant_call 17
     37#define error_allocate_list 18
    3738
    3839#define error_type_error 128
  • trunk/source/lisp-kernel/ppc-exceptions.c

    r11501 r11520  
    296296}
    297297
     298void
     299lisp_allocation_failure(ExceptionInformation *xp, TCR *tcr, natural bytes_needed)
     300{
     301  /* Couldn't allocate the object.  If it's smaller than some arbitrary
     302     size (say 128K bytes), signal a "chronically out-of-memory" condition;
     303     else signal a "allocation request failed" condition.
     304  */
     305  xpGPR(xp,allocptr) = xpGPR(xp,allocbase) = VOID_ALLOCPTR;
     306  handle_error(xp, bytes_needed < (128<<10) ? XNOMEM : error_alloc_failed, 0, 0,  xpPC(xp));
     307}
     308
     309/*
     310  Allocate a large list, where "large" means "large enough to
     311  possibly trigger the EGC several times if this was done
     312  by individually allocating each CONS."  The number of
     313  ocnses in question is in arg_z; on successful return,
     314  the list will be in arg_z
     315*/
     316
     317Boolean
     318allocate_list(ExceptionInformation *xp, TCR *tcr)
     319{
     320  natural
     321    nconses = (unbox_fixnum(xpGPR(xp,arg_z))),
     322    bytes_needed = (nconses << dnode_shift);
     323  LispObj
     324    prev = lisp_nil,
     325    current,
     326    initial = xpGPR(xp,arg_y);
     327
     328  if (nconses == 0) {
     329    /* Silly case */
     330    xpGPR(xp,arg_z) = lisp_nil;
     331    xpGPR(xp,allocptr) = lisp_nil;
     332    return true;
     333  }
     334  update_bytes_allocated(tcr, (void *)(void *) tcr->save_allocptr);
     335  if (allocate_object(xp,bytes_needed,(-bytes_needed)+fulltag_cons,tcr)) {
     336    for (current = xpGPR(xp,allocptr);
     337         nconses;
     338         prev = current, current+= dnode_size, nconses--) {
     339      deref(current,0) = prev;
     340      deref(current,1) = initial;
     341    }
     342    xpGPR(xp,arg_z) = prev;
     343    xpGPR(xp,arg_y) = xpGPR(xp,allocptr);
     344    xpGPR(xp,allocptr)-=fulltag_cons;
     345  } else {
     346    lisp_allocation_failure(xp,tcr,bytes_needed);
     347  }
     348  return true;
     349}
     350
    298351OSStatus
    299352handle_alloc_trap(ExceptionInformation *xp, TCR *tcr)
     
    353406      return 0;
    354407    }
    355     /* Couldn't allocate the object.  If it's smaller than some arbitrary
    356        size (say 128K bytes), signal a "chronically out-of-memory" condition;
    357        else signal a "allocation request failed" condition.
    358     */
    359     xpGPR(xp,allocptr) = xpGPR(xp,allocbase) = VOID_ALLOCPTR;
    360     handle_error(xp, bytes_needed < (128<<10) ? XNOMEM : error_alloc_failed, 0, 0,  xpPC(xp));
     408    lisp_allocation_failure(xp,tcr,bytes_needed);
    361409    return -1;
    362410  }
     
    13561404        xpGPR(xp,imm0) = (LispObj)kill_tcr(target);
    13571405        break;
     1406      case error_allocate_list:
     1407        allocate_list(xp,get_tcr(true));
     1408        break;
    13581409      default:
    13591410        status = handle_error(xp, errnum, rb, 0,  where);
Note: See TracChangeset for help on using the changeset viewer.