Changeset 8369


Ignore:
Timestamp:
Jan 29, 2008, 5:50:19 PM (17 years ago)
Author:
Gary Byers
Message:

Implement an alternate approach to weak-hash-table processing
(the alternate approach is faster but doesn't handle circularity.)
Toggle between the traditional and new approaches (mostly as a
way of stress-testing.)

Location:
trunk/source/lisp-kernel
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/gc-common.c

    r8245 r8369  
    8989natural GCndnodes_in_area = 0, GCndynamic_dnodes_in_area = 0;
    9090LispObj GCweakvll = (LispObj)NULL;
     91LispObj GCdwsweakvll = (LispObj)NULL;
    9192LispObj GCephemeral_low = 0;
    9293natural GCn_ephemeral_dnodes = 0;
     
    210211    dnode,
    211212    npairs = (header_element_count(hashp->header) -
    212               ((sizeof(hash_table_vector_header)/sizeof(LispObj)) -1)) >> 1;
     213              (hash_table_vector_header_count -1)) >> 1;
    213214  LispObj *pairp = (LispObj*) (hashp+1), weakelement;
    214215  Boolean
     
    235236    pairp += 2;
    236237  }
    237 }   
    238    
     238}
     239
     240void
     241traditional_dws_mark_htabv(LispObj htabv)
     242{
     243  /* Do nothing, just add htabv to GCweakvll */
     244  LispObj *base = (LispObj *) ptr_from_lispobj(untag(htabv));
     245 
     246  deref(base,1) = GCweakvll;
     247  GCweakvll = htabv;
     248}
     249
     250void
     251ncircle_dws_mark_htabv(LispObj htabv)
     252{
     253  /* Do nothing, just add htabv to GCdwsweakvll */
     254  LispObj *base = (LispObj *) ptr_from_lispobj(untag(htabv));
     255 
     256  deref(base,1) = GCdwsweakvll;
     257  GCdwsweakvll = htabv;
     258}
     259
     260void
     261traditional_mark_weak_htabv(LispObj htabv)
     262{
     263  int i, skip = hash_table_vector_header_count;;
     264
     265  for (i = 2; i <= skip; i++) {
     266    rmark(deref(htabv,i));
     267  }
     268
     269  deref(htabv,1) = GCweakvll;
     270  GCweakvll = htabv;
     271}
     272
     273void
     274ncircle_mark_weak_htabv(LispObj htabv)
     275{
     276  int i, skip = hash_table_vector_header_count;;
     277  hash_table_vector_header *hashp = (hash_table_vector_header *)(untag(htabv));
     278  natural
     279    dnode,
     280    npairs = (header_element_count(hashp->header) -
     281              (hash_table_vector_header_count - 1)) >> 1;
     282  LispObj *pairp = (LispObj*) (hashp+1), weakelement;
     283  Boolean
     284    weak_on_value = ((hashp->flags & nhash_weak_value_mask) != 0);
     285  bitvector markbits = GCmarkbits;
     286  int tag;
     287
     288  for (i = 2; i <= skip; i++) {
     289    rmark(deref(htabv,i));
     290  }
     291 
     292  if (!weak_on_value) {
     293    pairp++;
     294  }
     295  /* unconditionally mark the non-weak element of each pair */
     296  while (npairs--) {
     297    rmark(*pairp);
     298    pairp += 2;
     299  }
     300
     301  deref(htabv,1) = GCweakvll;
     302  GCweakvll = htabv;
     303}
    239304
    240305
     
    249314    weak_value = ((flags & nhash_weak_value_mask) != 0);
    250315  int
    251     skip = (sizeof(hash_table_vector_header)/sizeof(LispObj))-1,
     316    skip = hash_table_vector_header_count-1,
    252317    key_tag,
    253318    val_tag,
     
    351416 
    352417void
    353 markhtabvs()
     418traditional_markhtabvs()
    354419{
    355420  LispObj this, header, pending;
     
    389454            marked_new = true;
    390455          }
    391         } else {
    392           deref(this,1) = (LispObj)NULL;
    393           for (i = 2; i <= elements; i++) {
    394             mark_root(deref(this,i));
    395           }
    396456        }
    397457      } else {
     
    440500
    441501void
     502ncircle_markhtabvs()
     503{
     504  LispObj this, header, pending = 0;
     505  int subtag;
     506  bitvector markbits = GCmarkbits;
     507  hash_table_vector_header *hashp;
     508  Boolean marked_new;
     509
     510  /* First, process any weak hash tables that may have
     511     been encountered by the link-inverting marker; we
     512     should have more stack space now. */
     513
     514  while (GCdwsweakvll) {
     515    this = GCdwsweakvll;
     516    GCdwsweakvll = deref(this,1);
     517    ncircle_mark_weak_htabv(this);
     518  }
     519
     520  while (GCweakvll) {
     521    this = GCweakvll;
     522    GCweakvll = deref(this,1);
     523     
     524    header = header_of(this);
     525    subtag = header_subtag(header);
     526     
     527    if (subtag == subtag_weak) {
     528      natural weak_type = deref(this,2);
     529      deref(this,1) = pending;
     530      pending = this;
     531      if ((weak_type & population_type_mask) == population_weak_alist) {
     532        if (mark_weak_alist(this, weak_type)) {
     533          marked_new = true;
     534          }
     535      }
     536    } else if (subtag == subtag_hash_vector) {
     537      reaphashv(this);
     538    }
     539  }
     540
     541  /* Now, everything's marked that's going to be,  and "pending" is a list
     542     of populations.  CDR down that list and free
     543     anything that isn't marked.
     544     */
     545
     546  while (pending) {
     547    this = pending;
     548    pending = deref(this,1);
     549    deref(this,1) = (LispObj)NULL;
     550
     551    subtag = header_subtag(header_of(this));
     552    if (subtag == subtag_weak) {
     553      reapweakv(this);
     554    } else {
     555      Bug(NULL, "Bad object on pending list: %s\n", this);
     556    }
     557  }
     558
     559  /* Finally, mark the termination lists in all terminatable weak vectors
     560     They are now linked together on GCweakvll.
     561     This is where to store  lisp_global(TERMINATION_LIST) if we decide to do that,
     562     but it will force terminatable popualations to hold on to each other
     563     (set TERMINATION_LIST before clearing GCweakvll, and don't clear deref(this,1)).
     564     */
     565  pending = GCweakvll;
     566  GCweakvll = (LispObj)NULL;
     567  while (pending) {
     568    this = pending;
     569    pending = deref(this,1);
     570    deref(this,1) = (LispObj)NULL;
     571    mark_root(deref(this,1+3));
     572  }
     573}
     574
     575void
    442576mark_tcr_tlb(TCR *tcr)
    443577{
     
    568702  }
    569703  return c;
     704}
     705
     706weak_mark_fun dws_mark_weak_htabv = traditional_dws_mark_htabv;
     707weak_mark_fun mark_weak_htabv = traditional_mark_weak_htabv;
     708weak_process_fun markhtabvs = traditional_markhtabvs;
     709
     710void
     711install_weak_mark_functions(int set) {
     712  switch(set) {
     713  case 0:
     714  default:
     715    dws_mark_weak_htabv = traditional_dws_mark_htabv;
     716    mark_weak_htabv = traditional_mark_weak_htabv;
     717    markhtabvs = traditional_markhtabvs;
     718    break;
     719  case 1:
     720    dws_mark_weak_htabv = ncircle_dws_mark_htabv;
     721    mark_weak_htabv = ncircle_mark_weak_htabv;
     722    markhtabvs = ncircle_markhtabvs;
     723    break;
     724  }
    570725}
    571726
     
    834989#endif
    835990
     991int weak_hash_toggle = 0;
     992
    836993void
    837994gc(TCR *tcr, signed_natural param)
     
    8491006  TCR *other_tcr;
    8501007  natural static_dnodes;
     1008
     1009  install_weak_mark_functions(weak_hash_toggle);
     1010  weak_hash_toggle = 1 - weak_hash_toggle;
    8511011
    8521012#ifndef FORCE_DWS_MARK
  • trunk/source/lisp-kernel/gc.h

    r8245 r8369  
    147147LispObj GCarealow, GCareadynamiclow;
    148148natural GCndnodes_in_area, GCndynamic_dnodes_in_area;
    149 LispObj GCweakvll;
     149LispObj GCweakvll,GCdwsweakvll;
    150150LispObj GCephemeral_low;
    151151natural GCn_ephemeral_dnodes;
     
    165165Boolean mark_weak_hash_vector(hash_table_vector_header *hashp, natural elements);
    166166Boolean mark_weak_alist(LispObj weak_alist, int weak_type);
    167 void markhtabvs(void);
    168167void mark_tcr_tlb(TCR *);
    169168void mark_tcr_xframes(TCR *);
     
    185184/* backend-interface */
    186185
     186typedef void (*weak_mark_fun) (LispObj);
     187weak_mark_fun mark_weak_htabv, dws_mark_weak_htabv;
     188
     189typedef void (*weak_process_fun)(void);
     190
     191weak_process_fun markhtabvs;
     192
     193
     194#define hash_table_vector_header_count (sizeof(hash_table_vector_header)/sizeof(LispObj))
     195
    187196void mark_root(LispObj);
     197void rmark(LispObj);
    188198void mark_xp(ExceptionInformation *);
    189199LispObj dnode_forwarding_address(natural, int);
  • trunk/source/lisp-kernel/x86-gc.c

    r8248 r8369  
    325325          ((hash_table_vector_header *) base)->cache_key = undefined;
    326326          ((hash_table_vector_header *) base)->cache_value = lisp_nil;
    327           deref(ptr_to_lispobj(base),1) = GCweakvll;
    328           GCweakvll = n;
     327          mark_weak_htabv(n);
    329328          return;
    330329        }
     
    494493          ((hash_table_vector_header *) base)->cache_key = undefined;
    495494          ((hash_table_vector_header *) base)->cache_value = lisp_nil;
    496           deref(ptr_to_lispobj(base),1) = GCweakvll;
    497           GCweakvll = n;
     495          mark_weak_htabv(n);
    498496          return;
    499497        }
     
    734732        ((hash_table_vector_header *) base)->cache_key = undefined;
    735733        ((hash_table_vector_header *) base)->cache_value = lisp_nil;
    736         deref(ptr_to_lispobj(base),1) = GCweakvll;
    737         GCweakvll = this;
    738         goto Climb;
     734        dws_mark_weak_htabv(this);
     735        element_count = hash_table_vector_header_count;
    739736      }
    740737    }
     
    998995          ((hash_table_vector_header *) start)->cache_key = undefined;
    999996          ((hash_table_vector_header *) start)->cache_value = lisp_nil;
    1000           start[1] = GCweakvll;
    1001           GCweakvll = (LispObj) (((natural) start) + fulltag_misc);
     997          mark_weak_htabv((LispObj)start);
    1002998          element_count = 0;
    1003999        }
     
    12951291      if ((header_subtag(node) == subtag_hash_vector) &&
    12961292          ((((hash_table_vector_header *)p)->flags) & nhash_track_keys_mask)) {
    1297         natural skip = (sizeof(hash_table_vector_header)/sizeof(LispObj))-1;
     1293        natural skip = hash_table_vector_header_count-1;
    12981294        hashp = (hash_table_vector_header *) p;
    12991295        p++;
Note: See TracChangeset for help on using the changeset viewer.