Changeset 16066


Ignore:
Timestamp:
Apr 22, 2014, 9:05:06 PM (6 years ago)
Author:
gb
Message:

pending GC notification mechanism for ARM (has been on x86 for a few
years.)

(setq ccl:*pending-gc-notification-hook* some-0-arg-function)

(set-gc-notification-threshold N)

arranges to call the value the function when free space before the
next full GC drops below N bytes.

Location:
trunk/source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-0/ARM/arm-utils.lisp

    r15870 r16066  
    449449  (bx lr))
    450450
     451(defarmlapfunction set-gc-notification-threshold ((threshold arg_z))
     452  "Set the value of the kernel variable that can be used to trigger
     453GC notifications."
     454  (check-nargs 1)
     455  (build-lisp-frame)
     456  (sploadlr .SPgetu32)
     457  (blx lr)
     458  (mov imm1 imm0)
     459  (mov imm0 (:$ arch::gc-trap-function-set-gc-notification-threshold))
     460  (uuo-gc-trap)
     461  (restore-lisp-frame imm1)
     462  (spjump .SPmakeu32))
     463
     464(defarmlapfunction get-gc-notification-threshold ()
     465  "Get the value of the kernel variable that can be used to trigger
     466GC notifications."
     467  (check-nargs 0)
     468  (mov imm0 (:$ arch::gc-trap-function-get-gc-notification-threshold))
     469  (uuo-gc-trap)
     470  (spjump .SPmakeu32))
     471
     472
    451473(defparameter *kernel-import-table* nil)
    452474
  • trunk/source/level-1/arm-trap-support.lisp

    r14767 r16066  
    175175        (t (funcall thunk (xp-gpr-lisp xp arm::sp)))))
    176176
     177(defparameter *pending-gc-notification-hook* nil)
     178
    177179(defcallback xcmain (:address xp
    178180                              :signed-fullword signal
     
    189191                   ()
    190192                   frame-ptr))
     193          ((eql signal #$SIGTRAP)
     194           (let* ((hook *pending-gc-notification-hook*))
     195               (declare (special *pending-gc-notification-hook*))
     196               (when hook (funcall hook))))
    191197          (t
    192198           (error "cmain callback: signal = ~d, arg = #x~x, fnreg = ~d, offset = ~d"
  • trunk/source/lisp-kernel/arm-exceptions.c

    r16064 r16066  
    7878Boolean allocation_enabled = true;
    7979
     80Boolean
     81did_gc_notification_since_last_full_gc = false;
     82
    8083
    8184
     
    209212                natural bytes_needed,
    210213                signed_natural disp_from_allocptr,
    211                 TCR *tcr)
     214                TCR *tcr,
     215                Boolean *crossed_threshold)
    212216{
    213217  area *a = active_dynamic_area;
     
    223227     without extending the heap.
    224228  */
    225   if (new_heap_segment(xp, bytes_needed, false, tcr, NULL)) {
     229  if (new_heap_segment(xp, bytes_needed, false, tcr, crossed_threshold)) {
    226230    xpGPR(xp, allocptr) += disp_from_allocptr;
    227231    return true;
     
    235239    untenure_from_area(tenured_area); /* force a full GC */
    236240    gc_from_xp(xp, 0L);
     241    did_gc_notification_since_last_full_gc = false;
    237242  }
    238243 
     
    271276  xpGPR(xp,allocptr) = xpGPR(xp,allocbase) = VOID_ALLOCPTR;
    272277  handle_error(xp, bytes_needed < (128<<10) ? XNOMEM : error_alloc_failed,0, NULL);
     278}
     279
     280void
     281callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr)
     282{
     283  LispObj cmain = nrs_CMAIN.vcell;
     284
     285  did_gc_notification_since_last_full_gc = true;
     286  if ((fulltag_of(cmain) == fulltag_misc) &&
     287      (header_subtag(header_of(cmain)) == subtag_macptr)) {
     288    callback_to_lisp(cmain,xp,SIGTRAP,0,NULL);
     289  }
    273290}
    274291
     
    291308    current,
    292309    initial = xpGPR(xp,arg_y);
     310  Boolean notify_pending_gc = false;
    293311
    294312  if (nconses == 0) {
    295313    /* Silly case */
    296314    xpGPR(xp,arg_z) = lisp_nil;
    297     xpGPR(xp,allocptr) = lisp_nil;
    298315    return true;
    299316  }
    300317  update_bytes_allocated(tcr, (void *)(void *) tcr->save_allocptr);
    301   if (allocate_object(xp,bytes_needed,(-bytes_needed)+fulltag_cons,tcr)) {
     318  if (allocate_object(xp,bytes_needed,(-bytes_needed)+fulltag_cons,tcr,&notify_pending_gc)) {
    302319    for (current = xpGPR(xp,allocptr);
    303320         nconses;
     
    309326    xpGPR(xp,arg_y) = xpGPR(xp,allocptr);
    310327    xpGPR(xp,allocptr)-=fulltag_cons;
     328    if (notify_pending_gc && !did_gc_notification_since_last_full_gc) {
     329      callback_for_gc_notification(xp,tcr);
     330    }
    311331  } else {
    312332    lisp_allocation_failure(xp,tcr,bytes_needed);
     
    316336
    317337Boolean
    318 handle_alloc_trap(ExceptionInformation *xp, TCR *tcr)
     338handle_alloc_trap(ExceptionInformation *xp, TCR *tcr, Boolean *notify)
    319339{
    320340  pc program_counter;
     
    356376
    357377  update_bytes_allocated(tcr,((BytePtr)(cur_allocptr-disp)));
    358   if (allocate_object(xp, bytes_needed, disp, tcr)) {
     378  if (allocate_object(xp, bytes_needed, disp, tcr, notify)) {
    359379    adjust_exception_pc(xp,4);
     380    if (notify && *notify) {
     381      pc_luser_xp(xp,tcr,NULL);
     382      callback_for_gc_notification(xp,tcr);
     383    }
    360384    return true;
    361385  }
     
    420444    xpGPR(xp, imm0) = lisp_heap_gc_threshold;
    421445    break;
     446
     447  case GC_TRAP_FUNCTION_SET_GC_NOTIFICATION_THRESHOLD:
     448    if ((signed_natural)arg >= 0) {
     449      lisp_heap_notify_threshold = arg;
     450      did_gc_notification_since_last_full_gc = false;
     451    }
     452    /* fall through */
     453
     454  case GC_TRAP_FUNCTION_GET_GC_NOTIFICATION_THRESHOLD:
     455    xpGPR(xp, imm0) = lisp_heap_notify_threshold;
     456    break;
     457
    422458
    423459  case GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES:
     
    10141050
    10151051  if (IS_ALLOC_TRAP(instruction)) {
    1016     return handle_alloc_trap(xp, tcr);
     1052    Boolean did_notify = false,
     1053      *notify_ptr = &did_notify;
     1054    if (did_gc_notification_since_last_full_gc) {
     1055      notify_ptr = NULL;
     1056    }
     1057    return handle_alloc_trap(xp, tcr, notify_ptr);
    10171058  } else if ((xnum == SIGSEGV) ||
    10181059             (xnum == SIGBUS)) {
     
    17521793           VOID_ALLOCPTR */
    17531794        xpGPR(xp,allocptr) = VOID_ALLOCPTR;
     1795        tcr->save_allocptr = tcr->save_allocbase = VOID_ALLOCPTR;
    17541796      }
    17551797      return;
  • trunk/source/lisp-kernel/pmcl-kernel.c

    r15995 r16066  
    19951995
    19961996  set_nil(load_image(image_name));
    1997   lisp_heap_notify_threshold = GC_NOTIFY_THRESHOLD;
     1997  lisp_heap_notify_threshold = lisp_global(GC_NOTIFY_THRESHOLD);
    19981998  lisp_heap_threshold_from_image = lisp_global(LISP_HEAP_THRESHOLD);
    19991999 
  • trunk/source/lisp-kernel/x86-exceptions.c

    r16065 r16066  
    604604    /* Silly case */
    605605    xpGPR(xp,Iarg_z) = lisp_nil;
    606     xpGPR(xp,Iallocptr) = lisp_nil;
    607606    return true;
    608607  }
Note: See TracChangeset for help on using the changeset viewer.