Changeset 9958


Ignore:
Timestamp:
Jul 10, 2008, 9:14:42 AM (11 years ago)
Author:
gb
Message:

Import code from trunk (most changes have to do with weak htab
marking strategies.)

Remove some unused variables, to limit warnings when compiled with -Wall.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/working-0711/ccl/lisp-kernel/gc-common.c

    r7626 r9958  
    2424#include <stdlib.h>
    2525#include <string.h>
     26
     27#ifndef WINDOWS
    2628#include <sys/time.h>
    27 
     29#endif
     30
     31#ifndef timeradd
     32# define timeradd(a, b, result)                                               \
     33  do {                                                                        \
     34    (result)->tv_sec = (a)->tv_sec + (b)->tv_sec;                             \
     35    (result)->tv_usec = (a)->tv_usec + (b)->tv_usec;                          \
     36    if ((result)->tv_usec >= 1000000)                                         \
     37      {                                                                       \
     38        ++(result)->tv_sec;                                                   \
     39        (result)->tv_usec -= 1000000;                                         \
     40      }                                                                       \
     41  } while (0)
     42#endif
     43#ifndef timersub
     44# define timersub(a, b, result)                                               \
     45  do {                                                                        \
     46    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                             \
     47    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                          \
     48    if ((result)->tv_usec < 0) {                                              \
     49      --(result)->tv_sec;                                                     \
     50      (result)->tv_usec += 1000000;                                           \
     51    }                                                                         \
     52  } while (0)
     53#endif
     54
     55void
     56comma_output_decimal(char *buf, int len, natural n)
     57{
     58  int nout = 0;
     59
     60  buf[--len] = 0;
     61  do {
     62    buf[--len] = n%10+'0';
     63    n = n/10;
     64    if (n == 0) {
     65      while (len) {
     66        buf[--len] = ' ';
     67      }
     68      return;
     69    }
     70    if (len == 0) return;
     71    nout ++;
     72    if (nout == 3) {
     73      buf[--len] = ',';
     74      nout = 0;
     75    }
     76  } while (len >= 0);
     77}
    2878
    2979
     
    4292natural GCndnodes_in_area = 0, GCndynamic_dnodes_in_area = 0;
    4393LispObj GCweakvll = (LispObj)NULL;
     94LispObj GCdwsweakvll = (LispObj)NULL;
    4495LispObj GCephemeral_low = 0;
    4596natural GCn_ephemeral_dnodes = 0;
     
    163214    dnode,
    164215    npairs = (header_element_count(hashp->header) -
    165               ((sizeof(hash_table_vector_header)/sizeof(LispObj)) -1)) >> 1;
     216              (hash_table_vector_header_count -1)) >> 1;
    166217  LispObj *pairp = (LispObj*) (hashp+1), weakelement;
    167218  Boolean
     
    188239    pairp += 2;
    189240  }
    190 }   
    191    
     241}
     242
     243void
     244traditional_dws_mark_htabv(LispObj htabv)
     245{
     246  /* Do nothing, just add htabv to GCweakvll */
     247  LispObj *base = (LispObj *) ptr_from_lispobj(untag(htabv));
     248 
     249  deref(base,1) = GCweakvll;
     250  GCweakvll = htabv;
     251}
     252
     253void
     254ncircle_dws_mark_htabv(LispObj htabv)
     255{
     256  /* Do nothing, just add htabv to GCdwsweakvll */
     257  LispObj *base = (LispObj *) ptr_from_lispobj(untag(htabv));
     258 
     259  deref(base,1) = GCdwsweakvll;
     260  GCdwsweakvll = htabv;
     261}
     262
     263void
     264traditional_mark_weak_htabv(LispObj htabv)
     265{
     266  int i, skip = hash_table_vector_header_count;;
     267
     268  for (i = 2; i <= skip; i++) {
     269    rmark(deref(htabv,i));
     270  }
     271
     272  deref(htabv,1) = GCweakvll;
     273  GCweakvll = htabv;
     274}
     275
     276void
     277ncircle_mark_weak_htabv(LispObj htabv)
     278{
     279  int i, skip = hash_table_vector_header_count;
     280  hash_table_vector_header *hashp = (hash_table_vector_header *)(untag(htabv));
     281  natural
     282    npairs = (header_element_count(hashp->header) -
     283              (hash_table_vector_header_count - 1)) >> 1;
     284  LispObj *pairp = (LispObj*) (hashp+1);
     285  Boolean
     286    weak_on_value = ((hashp->flags & nhash_weak_value_mask) != 0);
     287
     288
     289  for (i = 2; i <= skip; i++) {
     290    rmark(deref(htabv,i));
     291  }
     292 
     293  if (!weak_on_value) {
     294    pairp++;
     295  }
     296  /* unconditionally mark the non-weak element of each pair */
     297  while (npairs--) {
     298    rmark(*pairp);
     299    pairp += 2;
     300  }
     301
     302  deref(htabv,1) = GCweakvll;
     303  GCweakvll = htabv;
     304}
    192305
    193306
     
    202315    weak_value = ((flags & nhash_weak_value_mask) != 0);
    203316  int
    204     skip = (sizeof(hash_table_vector_header)/sizeof(LispObj))-1,
     317    skip = hash_table_vector_header_count-1,
    205318    key_tag,
    206319    val_tag,
     
    304417 
    305418void
    306 markhtabvs()
     419traditional_markhtabvs()
    307420{
    308421  LispObj this, header, pending;
    309422  int subtag;
    310   bitvector markbits = GCmarkbits;
    311423  hash_table_vector_header *hashp;
    312424  Boolean marked_new;
     
    333445        }
    334446      } else if (subtag == subtag_hash_vector) {
    335         natural elements = header_element_count(header), i;
     447        natural elements = header_element_count(header);
    336448
    337449        hashp = (hash_table_vector_header *) ptr_from_lispobj(untag(this));
     
    342454            marked_new = true;
    343455          }
    344         } else {
    345           deref(this,1) = (LispObj)NULL;
    346           for (i = 2; i <= elements; i++) {
    347             mark_root(deref(this,i));
    348           }
    349456        }
    350457      } else {
     
    373480    } else {
    374481      reaphashv(this);
     482    }
     483  }
     484
     485  /* Finally, mark the termination lists in all terminatable weak vectors
     486     They are now linked together on GCweakvll.
     487     This is where to store  lisp_global(TERMINATION_LIST) if we decide to do that,
     488     but it will force terminatable popualations to hold on to each other
     489     (set TERMINATION_LIST before clearing GCweakvll, and don't clear deref(this,1)).
     490     */
     491  pending = GCweakvll;
     492  GCweakvll = (LispObj)NULL;
     493  while (pending) {
     494    this = pending;
     495    pending = deref(this,1);
     496    deref(this,1) = (LispObj)NULL;
     497    mark_root(deref(this,1+3));
     498  }
     499}
     500
     501void
     502ncircle_markhtabvs()
     503{
     504  LispObj this, header, pending = 0;
     505  int subtag;
     506  Boolean marked_new;
     507
     508  /* First, process any weak hash tables that may have
     509     been encountered by the link-inverting marker; we
     510     should have more stack space now. */
     511
     512  while (GCdwsweakvll) {
     513    this = GCdwsweakvll;
     514    GCdwsweakvll = deref(this,1);
     515    ncircle_mark_weak_htabv(this);
     516  }
     517
     518  while (GCweakvll) {
     519    this = GCweakvll;
     520    GCweakvll = deref(this,1);
     521     
     522    header = header_of(this);
     523    subtag = header_subtag(header);
     524     
     525    if (subtag == subtag_weak) {
     526      natural weak_type = deref(this,2);
     527      deref(this,1) = pending;
     528      pending = this;
     529      if ((weak_type & population_type_mask) == population_weak_alist) {
     530        if (mark_weak_alist(this, weak_type)) {
     531          marked_new = true;
     532          }
     533      }
     534    } else if (subtag == subtag_hash_vector) {
     535      reaphashv(this);
     536    }
     537  }
     538
     539  /* Now, everything's marked that's going to be,  and "pending" is a list
     540     of populations.  CDR down that list and free
     541     anything that isn't marked.
     542     */
     543
     544  while (pending) {
     545    this = pending;
     546    pending = deref(this,1);
     547    deref(this,1) = (LispObj)NULL;
     548
     549    subtag = header_subtag(header_of(this));
     550    if (subtag == subtag_weak) {
     551      reapweakv(this);
     552    } else {
     553      Bug(NULL, "Bad object on pending list: %s\n", this);
    375554    }
    376555  }
     
    564743#endif
    565744
     745
     746weak_mark_fun dws_mark_weak_htabv = traditional_dws_mark_htabv;
     747weak_mark_fun mark_weak_htabv = traditional_mark_weak_htabv;
     748weak_process_fun markhtabvs = traditional_markhtabvs;
     749
     750void
     751install_weak_mark_functions(natural set) {
     752  switch(set) {
     753  case 0:
     754  default:
     755    dws_mark_weak_htabv = traditional_dws_mark_htabv;
     756    mark_weak_htabv = traditional_mark_weak_htabv;
     757    markhtabvs = traditional_markhtabvs;
     758    break;
     759  case 1:
     760    dws_mark_weak_htabv = ncircle_dws_mark_htabv;
     761    mark_weak_htabv = ncircle_mark_weak_htabv;
     762    markhtabvs = ncircle_markhtabvs;
     763    break;
     764  }
     765}
     766
    566767LispObj
    567768node_forwarding_address(LispObj node)
     
    612813forward_gcable_ptrs()
    613814{
    614   LispObj *prev = &(lisp_global(GCABLE_POINTERS)), next;
     815  LispObj *prev = &(lisp_global(GCABLE_POINTERS)), next, new;
    615816
    616817  while ((next = *prev) != (LispObj)NULL) {
    617     *prev = node_forwarding_address(next);
     818    new = node_forwarding_address(next);
     819    if (new != next) {
     820      *prev = new;
     821    }
    618822    prev = &(((xmacptr *)ptr_from_lispobj(untag(next)))->link);
    619823  }
     
    716920reclaim_static_dnodes()
    717921{
    718   natural nstatic = tenured_area->static_dnodes, i, bits, mask, bitnum;
     922  natural nstatic = tenured_area->static_dnodes, i, bits, bitnum;
    719923  cons *c = (cons *)tenured_area->low, *d;
    720924  bitvector bitsp = GCmarkbits;
     
    778982*/
    779983
    780 
     984#ifdef WINDOWS
     985#define get_time(when) /* FIXME */
     986#else
    781987#define get_time(when) gettimeofday(&when, NULL)
    782 
     988#endif
    783989
    784990
     
    787993#endif
    788994
     995
    789996void
    790997gc(TCR *tcr, signed_natural param)
    791998{
    792   xframe_list *xframes = (tcr->xframe);
    793999  struct timeval start, stop;
    7941000  area *a = active_dynamic_area, *to = NULL, *from = NULL, *note = NULL;
    7951001  unsigned timeidx = 1;
    796   xframe_list *x;
     1002  paging_info paging_info_start;
    7971003  LispObj
    798     pkg,
     1004    pkg = 0,
    7991005    itabvec = 0;
    8001006  BytePtr oldfree = a->active;
    8011007  TCR *other_tcr;
    8021008  natural static_dnodes;
     1009
     1010  install_weak_mark_functions(lisp_global(WEAK_GC_METHOD) >> fixnumshift);
     1011
     1012
    8031013
    8041014#ifndef FORCE_DWS_MARK
     
    8461056
    8471057  if (GCverbose) {
     1058    char buf[16];
     1059
     1060    sample_paging_info(&paging_info_start);
     1061    comma_output_decimal(buf,16,area_dnode(oldfree,a->low) << dnode_shift);
    8481062    if (GCephemeral_low) {
    8491063      fprintf(stderr,
     
    8531067      fprintf(stderr,"\n\n;;; Starting full GC");
    8541068    }
    855     fprintf(stderr, ",  %ld bytes allocated.\n", area_dnode(oldfree,a->low) << dnode_shift);
     1069    fprintf(stderr, ", %s bytes allocated.\n", buf);
    8561070  }
    8571071
     
    9081122      }
    9091123    }
     1124
     1125    mark_root(lisp_global(STATIC_CONSES));
    9101126
    9111127    {
     
    10111227        sym = *raw;
    10121228        if (is_symbol_fulltag(sym)) {
    1013           lispsymbol *rawsym = (lispsymbol *)ptr_from_lispobj(untag(sym));
    10141229          natural dnode = gc_area_dnode(sym);
    10151230
     
    11291344    lispsymbol * total_bytes_freed = (lispsymbol *) &(nrs_TOTAL_BYTES_FREED);
    11301345    LispObj val;
    1131     struct timeval *timeinfo, elapsed;
     1346    struct timeval *timeinfo, elapsed = {0, 0};
    11321347
    11331348    val = total_gc_microseconds->vcell;
     
    11461361      *( (long long *) ptr_from_lispobj(((macptr *) ptr_from_lispobj(untag(val)))->address)) += justfreed;
    11471362      if (GCverbose) {
     1363        char buf[16];
     1364        paging_info paging_info_stop;
     1365
     1366        sample_paging_info(&paging_info_stop);
    11481367        if (justfreed <= heap_segment_size) {
    11491368          justfreed = 0;
    11501369        }
     1370        comma_output_decimal(buf,16,justfreed);
    11511371        if (note == tenured_area) {
    1152           fprintf(stderr,";;; Finished full GC.  Freed %lld bytes in %d.%06d s\n\n", justfreed, elapsed.tv_sec, elapsed.tv_usec);
     1372          fprintf(stderr,";;; Finished full GC. %s bytes freed in %d.%06d s\n\n", buf, elapsed.tv_sec, elapsed.tv_usec);
    11531373        } else {
    1154           fprintf(stderr,";;; Finished Ephemeral GC of generation %d.  Freed %lld bytes in %d.%06d s\n\n",
     1374          fprintf(stderr,";;; Finished EGC of generation %d. %s bytes freed in %d.%06d s\n\n",
    11551375                  (from == g2_area) ? 2 : (from == g1_area) ? 1 : 0,
    1156                   justfreed,
     1376                  buf,
    11571377                  elapsed.tv_sec, elapsed.tv_usec);
    11581378        }
    1159       }
    1160     }
    1161   }
    1162 }
     1379        report_paging_info_delta(stderr, &paging_info_start, &paging_info_stop);
     1380      }
     1381    }
     1382  }
     1383}
Note: See TracChangeset for help on using the changeset viewer.