Changeset 13792


Ignore:
Timestamp:
Jun 9, 2010, 3:28:22 AM (10 years ago)
Author:
gb
Message:

New pre-GC notification mechanism.

Location:
trunk/source
Files:
8 edited

Legend:

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

    r13280 r13792  
    354354(defconstant gc-trap-function-use-lisp-heap-threshold 18)
    355355(defconstant gc-trap-function-ensure-static-conses 19)
     356(defconstant gc-trap-function-get-gc-notification-threshold 20)
     357(defconstant gc-trap-function-set-gc-notification-threshold 21)
     358
    356359(defconstant gc-trap-function-egc-control 32)
    357360(defconstant gc-trap-function-configure-egc 64)
  • trunk/source/level-0/X86/X8632/x8632-utils.lisp

    r13279 r13792  
    435435  (single-value-return))
    436436
     437(defx8632lapfunction set-gc-notification-threshold ((threshold arg_z))
     438  "Set the value of the kernel variable that can be used to trigger
     439GC notifications."
     440  (check-nargs 1)
     441  (save-simple-frame)
     442  (call-subprim .SPgetu32)
     443  (movd (% imm0) (% mm0))
     444  (movl ($ arch::gc-trap-function-set-gc-notification-threshold) (% imm0))
     445  (uuo-gc-trap)
     446  (restore-simple-frame)
     447  (jmp-subprim .SPmakeu32))
     448 
     449(defx8632lapfunction get-gc-notification-threshold ()
     450  "Get the value of the kernel variable that can be used to trigger
     451GC notifications."
     452  (check-nargs 0)
     453  (movl ($ arch::gc-trap-function-get-gc-notification-threshold) (% imm0))
     454  (uuo-gc-trap)
     455  (jmp-subprim .SPmakeu32))
     456
    437457;;; offset is a fixnum, one of the x8632::kernel-import-xxx constants.
    438458;;; Returns that kernel import, a fixnum.
  • trunk/source/level-0/X86/x86-utils.lisp

    r13279 r13792  
    476476  (single-value-return))
    477477
     478(defx86lapfunction set-gc-notification-threshold ((threshold arg_z))
     479  "Set the value of the kernel variable that can be used to trigger
     480GC notifications."
     481  (check-nargs 1)
     482  (save-simple-frame)
     483  (call-subprim .SPgetu64)
     484  (movq (% imm0) (% imm1))
     485  (movq ($ arch::gc-trap-function-set-gc-notification-threshold) (% imm0))
     486  (uuo-gc-trap)
     487  (restore-simple-frame)
     488  (jmp-subprim .SPmakeu64))
     489
     490(defx86lapfunction get-gc-notification-threshold ((threshold arg_z))
     491  "Get the value of the kernel variable that can be used to trigger
     492GC notifications."
     493  (check-nargs 1)
     494  (movq ($ arch::gc-trap-function-set-gc-notification-threshold) (% imm0))
     495  (uuo-gc-trap)
     496  (jmp-subprim .SPmakeu64))
     497 
    478498
    479499
  • trunk/source/lisp-kernel/gc.h

    r13296 r13792  
    6666
    6767extern natural lisp_heap_gc_threshold;
     68extern natural lisp_heap_notify_threshold;
    6869void mark_root(LispObj);
    6970void mark_pc_root(LispObj);
     
    144145#define GC_TRAP_FUNCTION_USE_LISP_HEAP_THRESHOLD 18
    145146#define GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES 19
     147#define GC_TRAP_FUNCTION_GET_GC_NOTIFICATION_THRESHOLD 20
     148#define GC_TRAP_FUNCTION_SET_GC_NOTIFICATION_THRESHOLD 21
    146149#define GC_TRAP_FUNCTION_EGC_CONTROL 32
    147150#define GC_TRAP_FUNCTION_CONFIGURE_EGC 64
  • trunk/source/lisp-kernel/image.c

    r13511 r13792  
    564564    lisp_global(G2_THRESHOLD) = g2_area->threshold;
    565565    lisp_global(EGC_ENABLED) = (LispObj)egc_was_enabled;
     566    lisp_global(GC_NOTIFY_THRESHOLD) = lisp_heap_notify_threshold;
    566567  }
    567568  /*
     
    569570    as is DELETED_STATIC_PAIRS.
    570571    Nothing else is even meaningful at this point.
     572    Except for those things that've become meaningful since that
     573    comment was written.
    571574  */
    572575  for (i = MIN_KERNEL_GLOBAL; i < 0; i++) {
     
    582585    case G1_THRESHOLD:
    583586    case G2_THRESHOLD:
     587    case GC_NOTIFY_THRESHOLD:
    584588      break;
    585589    case WEAKVLL:
  • trunk/source/lisp-kernel/lisp_globals.h

    r13330 r13792  
    8282#define G1_THRESHOLD (-508)
    8383#define G2_THRESHOLD (-507)
     84#define GC_NOTIFY_THRESHOLD (-506)
    8485#else
    8586#define LISP_HEAP_THRESHOLD (-1023)
     
    8889#define G1_THRESHOLD (-1020)
    8990#define G2_THRESHOLD (-1019)
     91#define GC_NOTIFY_THRESHOLD (-1018)
    9092#endif
    9193
  • trunk/source/lisp-kernel/pmcl-kernel.c

    r13627 r13792  
    402402natural
    403403lisp_heap_gc_threshold = DEFAULT_LISP_HEAP_GC_THRESHOLD;
     404
     405natural
     406lisp_heap_notify_threshold = 0;
    404407
    405408natural
     
    17921795
    17931796  set_nil(load_image(image_name));
     1797  lisp_heap_notify_threshold = GC_NOTIFY_THRESHOLD;
    17941798  lisp_heap_threshold_from_image = lisp_global(LISP_HEAP_THRESHOLD);
     1799 
    17951800  if (lisp_heap_threshold_from_image) {
    17961801    if ((!lisp_heap_threshold_set_from_command_line) &&
  • trunk/source/lisp-kernel/x86-exceptions.c

    r13767 r13792  
    5555log2_page_size = 12;
    5656
     57Boolean
     58did_gc_notification_since_last_full_gc = false;
     59
    5760
    5861void
     
    7780
    7881Boolean
    79 new_heap_segment(ExceptionInformation *xp, natural need, Boolean extend, TCR *tcr)
     82new_heap_segment(ExceptionInformation *xp, natural need, Boolean extend, TCR *tcr, Boolean *crossed_threshold)
    8083{
    8184  area *a;
    8285  natural newlimit, oldlimit;
    8386  natural log2_allocation_quantum = tcr->log2_allocation_quantum;
     87
     88  if (crossed_threshold) {
     89    *crossed_threshold = false;
     90  }
    8491
    8592  a  = active_dynamic_area;
     
    110117  tcr->save_allocbase = (void *) oldlimit;
    111118
     119  if (crossed_threshold && (!extend)) {
     120    if (((a->high - (BytePtr)newlimit) < lisp_heap_notify_threshold)&&
     121        ((a->high - (BytePtr)oldlimit) >= lisp_heap_notify_threshold)) {
     122      *crossed_threshold = true;
     123    }
     124  }
     125   
     126
    112127  return true;
    113128}
     
    117132                natural bytes_needed,
    118133                signed_natural disp_from_allocptr,
    119                 TCR *tcr)
     134                TCR *tcr,
     135                Boolean *crossed_threshold)
    120136{
    121137  area *a = active_dynamic_area;
     
    131147     without extending the heap.
    132148  */
    133   if (new_heap_segment(xp, bytes_needed, false, tcr)) {
     149  if (new_heap_segment(xp, bytes_needed, false, tcr, crossed_threshold)) {
    134150    xpGPR(xp, Iallocptr) -= disp_from_allocptr;
    135151    tcr->save_allocptr = (void *) (xpGPR(xp, Iallocptr));
     
    144160    untenure_from_area(tenured_area); /* force a full GC */
    145161    gc_from_xp(xp, 0L);
     162    did_gc_notification_since_last_full_gc = false;
    146163  }
    147164 
    148165  /* Try again, growing the heap if necessary */
    149   if (new_heap_segment(xp, bytes_needed, true, tcr)) {
     166  if (new_heap_segment(xp, bytes_needed, true, tcr, NULL)) {
    150167    xpGPR(xp, Iallocptr) -= disp_from_allocptr;
    151168    tcr->save_allocptr = (void *) (xpGPR(xp, Iallocptr));
     
    221238    break;
    222239
     240  case GC_TRAP_FUNCTION_SET_GC_NOTIFICATION_THRESHOLD:
     241    if ((signed_natural)arg >= 0) {
     242      lisp_heap_notify_threshold = arg;
     243    }
     244    /* fall through */
     245
     246  case GC_TRAP_FUNCTION_GET_GC_NOTIFICATION_THRESHOLD:
     247    xpGPR(xp, Iimm0) = lisp_heap_notify_threshold;
     248    break;
     249
    223250  case GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES:
    224251    ensure_static_conses(xp, tcr, 32768);
     
    242269      if (!full_gc_deferred) {
    243270        gc_from_xp(xp, 0L);
     271        did_gc_notification_since_last_full_gc = false;
    244272        break;
    245273      }
     
    253281    }
    254282    gc_from_xp(xp, 0L);
     283    did_gc_notification_since_last_full_gc = false;
    255284    if (gc_deferred > gc_previously_deferred) {
    256285      full_gc_deferred = 1;
     
    476505}
    477506
     507void
     508callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr)
     509{
     510  LispObj cmain = nrs_CMAIN.vcell;
     511  if ((fulltag_of(cmain) == fulltag_misc) &&
     512      (header_subtag(header_of(cmain)) == subtag_macptr)) {
     513    LispObj *save_vsp = (LispObj *)xpGPR(xp,Isp),
     514      word_beyond_vsp = save_vsp[-1],
     515      save_fp = xpGPR(xp,Ifp),
     516      xcf = create_exception_callback_frame(xp, tcr);
     517
     518    callback_to_lisp(tcr, cmain, xp, xcf, SIGTRAP, 0, 0, 0);
     519    did_gc_notification_since_last_full_gc = true;
     520    xpGPR(xp,Ifp) = save_fp;
     521    xpGPR(xp,Isp) = (LispObj)save_vsp;
     522    save_vsp[-1] = word_beyond_vsp;
     523  }
     524}
     525
     526
    478527/*
    479528  Allocate a large list, where "large" means "large enough to
     
    494543    current,
    495544    initial = xpGPR(xp,Iarg_y);
     545  Boolean notify_pending_gc = false;
    496546
    497547  if (nconses == 0) {
     
    502552  }
    503553  update_bytes_allocated(tcr, (void *)tcr->save_allocptr);
    504   if (allocate_object(xp,bytes_needed,bytes_needed-fulltag_cons,tcr)) {
     554  if (allocate_object(xp,bytes_needed,bytes_needed-fulltag_cons,tcr, &notify_pending_gc)) {
    505555    tcr->save_allocptr -= fulltag_cons;
    506556    for (current = xpGPR(xp,Iallocptr);
     
    511561    }
    512562    xpGPR(xp,Iarg_z) = prev;
     563    if (notify_pending_gc && !did_gc_notification_since_last_full_gc) {
     564      callback_for_gc_notification(xp,tcr);
     565    }
    513566  } else {
    514567    lisp_allocation_failure(xp,tcr,bytes_needed);
     
    518571
    519572Boolean
    520 handle_alloc_trap(ExceptionInformation *xp, TCR *tcr)
     573handle_alloc_trap(ExceptionInformation *xp, TCR *tcr, Boolean *notify)
    521574{
    522575  natural cur_allocptr, bytes_needed;
    523576  unsigned allocptr_tag;
    524577  signed_natural disp;
     578  Boolean notify_pending_gc = false;
    525579 
    526580  cur_allocptr = xpGPR(xp,Iallocptr);
     
    538592
    539593  update_bytes_allocated(tcr,((BytePtr)(cur_allocptr+disp)));
    540   if (allocate_object(xp, bytes_needed, disp, tcr)) {
     594  if (allocate_object(xp, bytes_needed, disp, tcr, notify)) {
     595    if (notify && *notify) {
     596      xpPC(xp)+=2;
     597      /* Finish the allocation: add a header if necessary,
     598         clear the tag bits in tcr.save_allocptr. */
     599      pc_luser_xp(xp,tcr,NULL);
     600      callback_for_gc_notification(xp,tcr);
     601    }
    541602    return true;
    542603  }
     
    10121073  pc program_counter = (pc)xpPC(context);
    10131074
     1075  if (old_valence != TCR_STATE_LISP) {
     1076    return false;
     1077  }
     1078
    10141079  switch (signum) {
    10151080  case SIGNUM_FOR_INTN_TRAP:
     
    10251090        switch (*program_counter) {
    10261091        case UUO_ALLOC_TRAP:
    1027           if (handle_alloc_trap(context, tcr)) {
    1028             xpPC(context) += 2; /* we might have GCed. */
    1029             return true;
     1092          {
     1093            Boolean did_notify = false,
     1094              *notify_ptr = &did_notify;
     1095            if (did_gc_notification_since_last_full_gc) {
     1096              notify_ptr = NULL;
     1097            }
     1098            if (handle_alloc_trap(context, tcr, notify_ptr)) {
     1099              if (! did_notify) {
     1100                xpPC(context) += 2;     /* we might have GCed. */
     1101              }
     1102              return true;
     1103            }
    10301104          }
    10311105          break;
     
    15831657{
    15841658  TCR* tcr = get_tcr(true);
    1585 #if 1
     1659#if 0
    15861660  if (tcr->valence != TCR_STATE_LISP) {
    15871661    lisp_Debugger(context, info, signum, true, "exception in foreign context");
Note: See TracChangeset for help on using the changeset viewer.