Changeset 13238


Ignore:
Timestamp:
Nov 30, 2009, 7:14:38 PM (10 years ago)
Author:
gb
Message:

STATIC-CONS stuff, finally.

Todo:

  • policy (should interact with GC threshold)
  • check lower_heap_start() interaction with ephemeral areas when EGC disabled.
  • only for x86-64; may not even compile yet on other platforms
  • image relocation with pure code ? Yikes.
Location:
branches/purify/source
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • branches/purify/source/compiler/X86/x86-arch.lisp

    r12127 r13238  
    3333    kernel-imports                      ; some things we need to have imported for us.
    3434    objc-2-personality
    35     emulator-registers                  ; Where the 68K registers are kept.
    36     appmain                             ; application's (c-runtime) main() function
     35    savetoc                  ; used to save TOC on some platforms
     36    saver13                             ; used to save r13 on some platforms
    3737    subprims-base                       ; start of dynamic subprims jump table
    3838    ret1valaddr                         ; magic multiple-values return address.
     
    6161    lexpr-return1v                      ; single-value lexpr return address
    6262    in-gc                               ; non-zero when GC-ish thing active
    63     metering-info                       ; kernel metering structure
     63    free-static-conses                  ; fixnum
    6464    objc-2-end-catch                    ; _objc_end_catch
    6565    short-float-zero                    ; low half of 1.0d0
    6666    double-float-one                    ; high half of 1.0d0
    67     ffi-exception                       ; ffi fpscr[fex] bit
     67    static-cons-area                    ;
    6868    exception-saved-registers           ; saved registers from exception frame
    6969    oldest-ephemeral                    ; doublenode address of oldest ephemeral object or 0
  • branches/purify/source/compiler/arch.lisp

    r12789 r13238  
    352352(defconstant gc-trap-function-set-lisp-heap-threshold 17)
    353353(defconstant gc-trap-function-use-lisp-heap-threshold 18)
     354(defconstant gc-trap-function-ensure-static-conses 19)
    354355(defconstant gc-trap-function-egc-control 32)
    355356(defconstant gc-trap-function-configure-egc 64)
    356 (defconstant gc-trap-function-set-hons-area-size 128)
    357357(defconstant gc-trap-function-freeze 129)
    358358(defconstant gc-trap-function-thaw 130)
  • branches/purify/source/level-0/X86/x86-misc.lisp

    r12361 r13238  
     1
     2
    13;;; -*- Mode: Lisp; Package: CCL -*-
    24;;;
     
    885887  (cmpxchgq (% temp0) (@ (+ (target-nil-value) (x8664::kernel-global static-conses))))
    886888  (jnz @again)
     889  (lock)
     890  (subq ($ x8664::fixnumone) (@ (+ (target-nil-value) (x8664::kernel-global free-static-conses))))
    887891  @lose
    888892  (movq (% rax) (% arg_z))
    889893  (single-value-return))
    890894
    891 (defx86lapfunction %augment-static-conses ((head arg_y) (tail arg_z))
    892   @again
    893   (movq (@ (+ (target-nil-value) (x8664::kernel-global static-conses))) (% rax))
    894   (movq (% rax) (@ target::cons.cdr (% tail)))
    895   (lock)
    896   (cmpxchgq (% head) (@ (+ (target-nil-value) (x8664::kernel-global static-conses))))
    897   (jnz @again)
    898   @lose
    899   (movl ($ (target-nil-value)) (% arg_z.l))
    900   (single-value-return))
     895
    901896 
    902897(defx86lapfunction %staticp ((x arg_z))
    903898  (check-nargs 1)
    904   (ref-global tenured-area temp0)
     899  (ref-global static-cons-area temp0)
    905900  (movq (% x) (% imm0))
     901  (movl ($ (target-nil-value)) (% arg_z.l))
    906902  (subq (@ target::area.low (% temp0)) (% imm0))
    907903  (shrq ($ target::dnode-shift) (% imm0))
    908   (cmpq (@ target::area.static-dnodes (% temp0)) (% imm0))
    909   (leaq (@ (% imm0) target::fixnumone) (% arg_z))
    910   (movl ($ (target-nil-value)) (%l imm0))
    911   (cmovaeq (% imm0) (% arg_z))
     904  (movq (@ target::area.ndwords (% temp0)) (% imm1))
     905  (subq (% imm0) (% imm1))
     906  (lea (@ 128 (% imm1)) (% imm1))
     907  (leaq (@ (% imm1) target::fixnumone) (% imm1))
     908  (cmovaq (% imm1) (% arg_z))
    912909  (single-value-return))
    913910
    914911(defx86lapfunction %static-inverse-cons ((n arg_z))
    915912  (check-nargs 1)
    916   (ref-global tenured-area temp0)
    917   (movq (@ target::area.low (% temp0)) (% imm0))
    918   (leaq (@ target::fulltag-cons (% imm0) (% n) 2) (% arg_z))
     913  (subq ($ '128) (% arg_z))
     914  (ref-global static-cons-area temp0)
     915  (movq (@ target::area.high (% temp0)) (% imm0))
     916  (subq (% arg_z) (% imm0))
     917  (subq (% arg_z) (% imm0))
     918  (lea (@ x8664::fulltag-cons (% imm0)) (% arg_z))
    919919  (single-value-return))
    920920
  • branches/purify/source/level-0/X86/x86-utils.lisp

    r12837 r13238  
    471471  (jmp-subprim .SPnvalret))
    472472
    473  
     473
     474(defx86lapfunction %ensure-static-conses ()
     475  (check-nargs 0)
     476  (movl ($ arch::gc-trap-function-ensure-static-conses) (% imm0.l))
     477  (uuo-gc-trap)
     478  (movl ($ (target-nil-value)) (% arg_z.l))
     479  (single-value-return))
     480
    474481
    475482
  • branches/purify/source/lib/misc.lisp

    r12838 r13238  
    976976          (format out "~&~a~34t~12d~46t~16d~16d" (aref *heap-utilization-vector-type-names* i)  count sizes psizes))))
    977977    (format out "~&   Total sizes: ~47t~16d~16d" (+ total-cons-size total-vector-size) (+ total-cons-size total-physical-vector-size))))
    978                            
     978
     979
     980(defglobal static-cons-lock (make-lock))
     981
    979982;; The number of words to allocate for static conses when the user requests
    980983;; one and we don't have any left over
    981984(defparameter *static-cons-chunk* 1048576)
    982985
    983 (defun initialize-static-cons ()
    984   "Activates collection of garbage conses in the static-conses
    985    list and allocates initial static conses."
    986   ; There might be a race here when multiple threads call this
    987   ; function.  However, the discarded static conses will become
    988   ; garbage and be added right back to the list.  No harm here
    989   ; except for additional garbage collections.
    990   (%set-kernel-global 'static-conses nil)
    991   (allocate-static-conses))
    992 
    993 (defun allocate-static-conses ()
    994   "Allocates some memory, freezes it and lets it become garbage.
    995    This will add the memory to the list of free static conses."
    996   (let* ((nfullgc (full-gccount)))
    997     (multiple-value-bind (head tail)
    998         (%allocate-list 0 *static-cons-chunk*)
    999       (if (eql (full-gccount) nfullgc)
    1000         (freeze)
    1001         (flash-freeze))
    1002       (%augment-static-conses head tail))))
     986
     987
     988
    1003989
    1004990(defun static-cons (car-value cdr-value)
     
    1006992   and thus doesn't trigger re-hashing when used as a key in a hash
    1007993   table.  Usage is equivalent to regular CONS."
    1008   (when (eq (%get-kernel-global 'static-conses) 0)
    1009     (initialize-static-cons))
    1010   (let ((cell (%atomic-pop-static-cons)))
    1011     (if cell
    1012       (progn
    1013         (setf (car cell) car-value)
    1014         (setf (cdr cell) cdr-value)
    1015         cell)
    1016       (progn
    1017         (allocate-static-conses)
    1018         (static-cons car-value cdr-value)))))
     994  (loop
     995    (let ((cell (%atomic-pop-static-cons)))
     996      (if cell
     997        (progn
     998          (setf (car cell) car-value)
     999          (setf (cdr cell) cdr-value)
     1000          (return cell))
     1001        (progn
     1002          (%ensure-static-conses))))))
     1003
     1004(defun free-static-conses ()
     1005  (%get-kernel-global free-static-conses))
     1006
     1007(defun reserved-static-conses ()
     1008  (%fixnum-ref-natural (%get-kernel-global static-cons-area) target::area.ndwords))
    10191009       
    10201010
  • branches/purify/source/lisp-kernel/gc-common.c

    r13042 r13238  
    10171017reclaim_static_dnodes()
    10181018{
    1019   natural nstatic = tenured_area->static_dnodes, i, bits, bitnum;
     1019  natural nstatic = tenured_area->static_dnodes,
     1020    i,
     1021    bits,
     1022    bitnum,
     1023    nfree = 0,
     1024    nstatic_conses = area_dnode(static_cons_area->high, static_cons_area->low);
    10201025  cons *c = (cons *)tenured_area->low, *d;
    10211026  bitvector bitsp = GCmarkbits;
    10221027  LispObj head = lisp_global(STATIC_CONSES);
    10231028
    1024   if (nstatic) {
    1025     if (head) {
    1026       for (i = 0; i < nstatic; i+= nbits_in_word, c+= nbits_in_word) {
    1027         bits = *bitsp++;
    1028         if (bits != ALL_ONES) {
    1029           for (bitnum = 0; bitnum < nbits_in_word; bitnum++) {
    1030             if (! (bits & (BIT0_MASK>>bitnum))) {
    1031               d = c + bitnum;
    1032               d->car = 0;
    1033               d->cdr = head;
    1034               head = ((LispObj)d)+fulltag_cons;
    1035             }
    1036           }
    1037         }
    1038       }
    1039       lisp_global(STATIC_CONSES) = head;
    1040     } else {
    1041       for (i = 0; i < nstatic; i+= nbits_in_word, c+= nbits_in_word) {
    1042         bits = *bitsp++;
    1043         if (bits != ALL_ONES) {
    1044           for (bitnum = 0; bitnum < nbits_in_word; bitnum++) {
    1045             if (! (bits & (BIT0_MASK>>bitnum))) {
    1046               d = c + bitnum;
    1047               d->car = 0;
    1048               d->cdr = 0;
    1049             }
    1050           }
    1051         }
    1052       }
    1053     }
    1054   }
     1029  for (i = 0; i < nstatic; i+= nbits_in_word, c+= nbits_in_word) {
     1030    bits = *bitsp++;
     1031    if (bits != ALL_ONES) {
     1032      for (bitnum = 0; bitnum < nbits_in_word; bitnum++) {
     1033        if (! (bits & (BIT0_MASK>>bitnum))) {
     1034          d = c + bitnum;
     1035          d->car = 0;
     1036          if (i < nstatic_conses) {               
     1037            d->cdr = head;
     1038            head = ((LispObj)d)+fulltag_cons;
     1039            nfree++;
     1040          } else {
     1041            d->cdr = 0;
     1042          }
     1043        }
     1044      }
     1045    }
     1046  }
     1047  lisp_global(STATIC_CONSES) = head;
     1048  lisp_global(FREE_STATIC_CONSES)+=(nfree<<fixnumshift);
    10551049}
    10561050
  • branches/purify/source/lisp-kernel/gc.h

    r13042 r13238  
    142142#define GC_TRAP_FUNCTION_SET_LISP_HEAP_THRESHOLD 17
    143143#define GC_TRAP_FUNCTION_USE_LISP_HEAP_THRESHOLD 18
     144#define GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES 19
    144145#define GC_TRAP_FUNCTION_EGC_CONTROL 32
    145146#define GC_TRAP_FUNCTION_CONFIGURE_EGC 64
    146 #define GC_TRAP_FUNCTION_SET_HONS_AREA_SIZE 128 /* deprecated */
    147147#define GC_TRAP_FUNCTION_FREEZE 129
    148148#define GC_TRAP_FUNCTION_THAW 130
  • branches/purify/source/lisp-kernel/image.c

    r13042 r13238  
    358358        break;
    359359      case AREA_STATIC_CONS:
    360         if (bias) {
    361           relocate_area_contents(a, bias);
    362         }
    363         add_area_holding_area_lock(a);
    364360        break;
    365361      case AREA_DYNAMIC:
     362        lower_heap_start(static_cons_area->low,a);
    366363        if (bias) {
    367364          relocate_area_contents(a, bias);
     
    466463  signed_natural section_data_delta;
    467464#endif
     465
     466  /*
     467    Coerce macptrs to dead_macptrs.
     468  */
     469 
     470  prepare_to_write_dynamic_space(active_dynamic_area);
     471
     472  /*
     473     If we ever support continuing after saving an image,
     474     undo this .. */
     475
     476  if (static_cons_area->high > static_cons_area->low) {
     477    active_dynamic_area->low = static_cons_area->high;
     478    tenured_area->static_dnodes -= area_dnode(static_cons_area->high, static_cons_area->low);
     479  }
    468480
    469481  areas[0] = nilreg_area;
     
    510522#endif
    511523
    512   /*
    513     Coerce macptrs to dead_macptrs.
    514   */
    515  
    516   prepare_to_write_dynamic_space(active_dynamic_area);
    517524
    518525  {
     
    533540  for (i = MIN_KERNEL_GLOBAL; i < 0; i++) {
    534541    switch (i) {
     542    case FREE_STATIC_CONSES:
    535543    case FWDNUM:
    536544    case GC_NUM:
  • branches/purify/source/lisp-kernel/lisp_globals.h

    r13042 r13238  
    5353#define LEXPR_RETURN1V (-31)    /* single-value &lexpr cleanup code */
    5454#define IN_GC (-32)             /* non-zero when lisp addresses may be invalid */
    55 #define METERING_INFO (-33)     /* address of lisp_metering global */
     55#define FREE_STATIC_CONSES (-33)     /* length of freelist */
    5656#define OBJC_2_END_CACTCH (-34)          /* address of ObjC 2.0 objc_end_catch() */
    5757#define SHORT_FLOAT_ZERO (-35)  /* low half of 1.0d0 */
    5858#define DOUBLE_FLOAT_ONE (-36)  /* high half of 1.0d0 */
    59 #define LISP_RETURN_HOOK (-37)  /* install lisp exception handling */
     59#define STATIC_CONS_AREA (-37)  /* static_cons_area */
    6060#define LISP_EXIT_HOOK (-38)    /* install foreign exception handling */
    6161#define OLDEST_EPHEMERAL (-39)  /* doubleword address of oldest ephemeral object or 0 */
  • branches/purify/source/lisp-kernel/pmcl-kernel.c

    r13042 r13238  
    665665}
    666666   
     667void
     668lower_heap_start(BytePtr new_low, area *a)
     669{
     670  natural new_dnodes = area_dnode(low_markable_address,new_low);
     671
     672  if (new_dnodes) {
     673    natural n = (new_dnodes+7)>>3;
     674
     675    BytePtr old_markbits = (BytePtr)dynamic_mark_ref_bits,
     676      new_markbits = old_markbits-n;
     677    CommitMemory(new_markbits,n);
     678    dynamic_mark_ref_bits = (bitvector)new_markbits;
     679    if (a->refbits) {
     680      a->refbits= dynamic_mark_ref_bits;
     681    }
     682    a->static_dnodes += new_dnodes;
     683    a->ndnodes += new_dnodes;
     684    a->low = new_low;
     685    low_markable_address = new_low;
     686    lisp_global(HEAP_START) = (LispObj)new_low;
     687    static_cons_area->ndnodes = area_dnode(static_cons_area->high,new_low);
     688  }
     689}
    667690
    668691void
     
    19331956    a->static_used = 0;
    19341957    lisp_global(TENURED_AREA) = ptr_to_lispobj(tenured_area);
     1958    lisp_global(STATIC_CONS_AREA) = ptr_to_lispobj(static_cons_area);
    19351959    lisp_global(REFBITS) = ptr_to_lispobj(global_mark_ref_bits);
    19361960    g2_area->threshold = default_g2_threshold;
     
    19431967  init_threads((void *)(stack_base), tcr);
    19441968  thread_init_tcr(tcr, current_sp, current_sp-stack_base);
     1969
     1970  if (lisp_global(STATIC_CONSES) == 0) {
     1971    lisp_global(STATIC_CONSES) = lisp_nil;
     1972  }
    19451973
    19461974  lisp_global(EXCEPTION_LOCK) = ptr_to_lispobj(new_recursive_lock());
  • branches/purify/source/lisp-kernel/ppc-exceptions.c

    r13129 r13238  
    30733073    terminate_lisp();
    30743074  }
    3075   lisp_global(LISP_EXIT_HOOK) = (LispObj) restore_foreign_exception_ports;
    3076   lisp_global(LISP_RETURN_HOOK) = (LispObj) tcr_establish_lisp_exception_port;
    30773075}
    30783076
  • branches/purify/source/lisp-kernel/thread_manager.c

    r12798 r13238  
    13281328  tcr->single_float_convert.tag = subtag_single_float;
    13291329#endif
    1330   lisp_global(TCR_COUNT) += (1<<fixnumshift);
    13311330  tcr->suspend = new_semaphore(0);
    13321331  tcr->resume = new_semaphore(0);
  • branches/purify/source/lisp-kernel/x86-exceptions.c

    r13082 r13238  
    164164}
    165165
     166void
     167allocate_static_conses(natural n)
     168{
     169  BytePtr old_low = static_cons_area->low,
     170    new_low = old_low - (n<<dnode_shift);
     171  cons *c;
     172  natural i;
     173  LispObj prev;
     174
     175  CommitMemory(new_low,old_low-new_low);
     176
     177  static_cons_area->low = new_low;
     178  lower_heap_start(new_low, tenured_area);
     179  if (active_dynamic_area->low == old_low) {
     180    active_dynamic_area->low = new_low;
     181  }
     182  for (i=0, prev=lisp_global(STATIC_CONSES), c=(cons *)new_low;
     183       i < n;
     184       i++, c++) {
     185    c->cdr = prev;
     186    prev = ((LispObj)c)+fulltag_cons;
     187  }
     188  lisp_global(STATIC_CONSES)=prev;
     189  lisp_global(FREE_STATIC_CONSES)+=(n<<fixnumshift);
     190}
    166191
    167192Boolean
     
    219244    }
    220245    xpGPR(xp, Iimm0) = lisp_heap_gc_threshold;
     246    break;
     247
     248  case GC_TRAP_FUNCTION_ENSURE_STATIC_CONSES:
     249    allocate_static_conses(32768);
    221250    break;
    222251
     
    288317      }
    289318      switch (selector) {
    290       case GC_TRAP_FUNCTION_SET_HONS_AREA_SIZE:
    291         xpGPR(xp, Iimm0) = 0;
    292         break;
    293319      case GC_TRAP_FUNCTION_FREEZE:
    294320        a->active = (BytePtr) align_to_power_of_2(a->active, log2_page_size);
     
    34943520    terminate_lisp();
    34953521  }
    3496   lisp_global(LISP_EXIT_HOOK) = (LispObj) restore_foreign_exception_ports;
    3497   lisp_global(LISP_RETURN_HOOK) = (LispObj) tcr_establish_lisp_exception_port;
    34983522}
    34993523
Note: See TracChangeset for help on using the changeset viewer.