pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: mapping.c,v 1.199 2008/05/02 04:15:11 mast Exp $ + || $Id: mapping.c,v 1.200 2008/05/11 02:35:22 mast Exp $   */      #include "global.h"   #include "main.h"   #include "object.h"   #include "mapping.h"   #include "svalue.h"   #include "array.h"   #include "pike_macros.h"   #include "pike_error.h"
pike.git/src/mapping.c:270:    free((char *) md);    GC_FREE_BLOCK(md);   }      PMOD_EXPORT void do_free_mapping(struct mapping *m)   {    if (m)    inl_free_mapping(m);   }    - /* This function is used to rehash a mapping without loosing the internal + /* This function is used to rehash a mapping without losing the internal    * order in each hash chain. This is to prevent mappings from becoming    * inefficient just after being rehashed.    */   static void mapping_rehash_backwards_evil(struct mapping_data *md,    struct keypair *from)   {    unsigned INT32 h;    struct keypair *k, *prev = NULL, *next;       if(!(k = from)) return;
pike.git/src/mapping.c:2309: Inside #if defined(PIKE_DEBUG)
  }      void check_all_mappings(void)   {    struct mapping *m;    for(m=first_mapping;m;m=m->next)    check_mapping(m);   }   #endif    + static void visit_mapping_data (struct mapping_data *md, int action, +  struct mapping *m) + { +  switch (action) { + #ifdef PIKE_DEBUG +  default: +  Pike_fatal ("Unknown visit action %d.\n", action); +  case VISIT_NORMAL: +  case VISIT_COMPLEX_ONLY: +  break; + #endif +  case VISIT_COUNT_BYTES: +  mc_counted_bytes += MAPPING_DATA_SIZE (md->hashsize, md->num_keypairs); +  break; +  } +  +  if ((md->ind_types | md->val_types) & +  (action & VISIT_COMPLEX_ONLY ? BIT_COMPLEX : BIT_REF_TYPES)) { +  int ind_ref_type = +  md->flags & MAPPING_WEAK_INDICES ? REF_TYPE_WEAK : REF_TYPE_NORMAL; +  int val_ref_type = +  md->flags & MAPPING_WEAK_VALUES ? REF_TYPE_WEAK : REF_TYPE_NORMAL; +  INT32 e; +  struct keypair *k; +  NEW_MAPPING_LOOP (md) { +  visit_svalue (&k->ind, ind_ref_type); +  visit_svalue (&k->val, val_ref_type); +  } +  } + } +  + void visit_mapping (struct mapping *m, int action) + { +  switch (action) { + #ifdef PIKE_DEBUG +  default: +  Pike_fatal ("Unknown visit action %d.\n", action); +  case VISIT_NORMAL: +  case VISIT_COMPLEX_ONLY: +  break; + #endif +  case VISIT_COUNT_BYTES: +  mc_counted_bytes += sizeof (struct mapping); +  break; +  } +  +  visit_ref (m->data, REF_TYPE_INTERNAL, +  (visit_thing_fn *) &visit_mapping_data, m); + } +    #ifdef MAPPING_SIZE_DEBUG   #define DO_IF_MAPPING_SIZE_DEBUG(x) x   #else   #define DO_IF_MAPPING_SIZE_DEBUG(x)   #endif    - static void gc_check_md (struct mapping_data *md); -  +    #define GC_RECURSE_MD_IN_USE(MD, RECURSE_FN, IND_TYPES, VAL_TYPES) do { \    INT32 e; \    struct keypair *k; \    IND_TYPES = MD->ind_types; \    NEW_MAPPING_LOOP(MD) { \    if (!IS_DESTRUCTED(&k->ind) && RECURSE_FN(&k->ind, 1)) { \    DO_IF_DEBUG(Pike_fatal("Didn't expect an svalue zapping now.\n")); \    } \    RECURSE_FN(&k->val, 1); \    VAL_TYPES |= 1 << k->val.type; \    } \   } while (0)      #ifdef PIKE_MAPPING_KEYPAIR_LOOP - /* NOTE: Broken code below! */ + #error Broken code below!   #define GC_RECURSE(M, MD, REC_KEYPAIR, TYPE, IND_TYPES, VAL_TYPES) do { \    int remove; \    struct keypair *k,**prev_; \    /* no locking required (no is_eq) */ \    for(k = MD_KEYPAIRS(md, md->hashsize);k < MD->free_list;) \    { \    REC_KEYPAIR(remove, \    PIKE_CONCAT(TYPE, _svalues), \    PIKE_CONCAT(TYPE, _weak_svalues), \    PIKE_CONCAT(TYPE, _without_recurse), \
pike.git/src/mapping.c:2458: Inside #if defined(PIKE_DEBUG)
   if(m->data->refs <=0)    Pike_fatal("Zero refs in mapping->data\n");   #endif    debug_malloc_touch(m);    debug_malloc_touch(m->data);       if(gc_mark(m))    GC_ENTER (m, T_MAPPING) {    struct mapping_data *md = m->data;    -  if (Pike_in_gc == GC_PASS_COUNT_MEMORY) { -  gc_counted_bytes += sizeof (struct mapping); -  gc_check (md); -  } -  +     if (m == gc_mark_mapping_pos)    gc_mark_mapping_pos = m->next;    if (m == gc_internal_mapping)    gc_internal_mapping = m->next;    else {    DOUBLEUNLINK(first_mapping, m);    DOUBLELINK(first_mapping, m); /* Linked in first. */    }    -  if(gc_mark(md)) { -  if (Pike_in_gc == GC_PASS_COUNT_MEMORY) { -  gc_counted_bytes += -  MAPPING_DATA_SIZE (md->hashsize, md->num_keypairs); -  gc_check_md (md); -  } -  -  if ((md->ind_types | md->val_types) & BIT_COMPLEX) { +  if(gc_mark(md) && ((md->ind_types | md->val_types) & BIT_COMPLEX)) {    TYPE_FIELD ind_types = 0, val_types = 0;    if (MAPPING_DATA_IN_USE(md)) {    /* Must leave the mapping data untouched if it's busy. */    debug_malloc_touch(m);    debug_malloc_touch(md);    GC_RECURSE_MD_IN_USE(md, gc_mark_svalues, ind_types, val_types);    gc_assert_checked_as_nonweak(md);    }    else    switch (md->flags & MAPPING_WEAK) {
pike.git/src/mapping.c:2511:    break;    case MAPPING_WEAK_VALUES:    debug_malloc_touch(m);    debug_malloc_touch(md);    GC_RECURSE(m, md, GC_REC_KP_VAL, gc_mark, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    default:    debug_malloc_touch(m);    debug_malloc_touch(md); -  GC_RECURSE(m, md, GC_REC_KP_BOTH, gc_mark, ind_types,val_types); +  GC_RECURSE(m, md, GC_REC_KP_BOTH, gc_mark, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    }    md->val_types = val_types;    md->ind_types = ind_types;    } -  } +     } GC_LEAVE;   }      void real_gc_cycle_check_mapping(struct mapping *m, int weak)   {    GC_CYCLE_ENTER(m, T_MAPPING, weak) {    struct mapping_data *md = m->data;    debug_malloc_touch(m);    debug_malloc_touch(md);   
pike.git/src/mapping.c:2576:    GC_RECURSE(m, md, GC_REC_KP_BOTH, gc_cycle_check, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    }    md->val_types = val_types;    md->ind_types = ind_types;    }    } GC_CYCLE_LEAVE;   }    - static void gc_check_md (struct mapping_data *md) + static void gc_check_mapping(struct mapping *m)   { -  +  struct mapping_data *md = m->data; +  +  if((md->ind_types | md->val_types) & BIT_COMPLEX) +  GC_ENTER (m, T_MAPPING) {    INT32 e;    struct keypair *k;    -  +  if(!debug_gc_check (md, " as mapping data block of a mapping")) {    if (!(md->flags & MAPPING_WEAK) || MAPPING_DATA_IN_USE(md))    /* Disregard the weak flag if the mapping data is busy; we must    * leave it untouched in that case anyway. */    NEW_MAPPING_LOOP(md)    {    debug_gc_check_svalues(&k->ind, 1, " as mapping index");    debug_gc_check_svalues(&k->val, 1, " as mapping value");    }    else {    switch (md->flags & MAPPING_WEAK) {
pike.git/src/mapping.c:2616:    NEW_MAPPING_LOOP(md)    {    debug_gc_check_weak_svalues(&k->ind, 1, " as mapping index");    debug_gc_check_weak_svalues(&k->val, 1, " as mapping value");    }    break;    }    gc_checked_as_weak(md);    }   } +  } GC_LEAVE; + }      unsigned gc_touch_all_mappings(void)   {    unsigned n = 0;    struct mapping *m;    if (first_mapping && first_mapping->prev)    Pike_fatal("Error in mapping link list.\n");    for (m = first_mapping; m; m = m->next) {    debug_gc_touch(m);    n++;
pike.git/src/mapping.c:2638:    }    return n;   }      void gc_check_all_mappings(void)   {    struct mapping *m;       for(m=first_mapping;m;m=m->next)    { -  struct mapping_data *md = m->data; -  +    #ifdef DEBUG_MALLOC -  if (((int) PTR_TO_INT (md)) == 0x55555555) { +  if (((int) PTR_TO_INT (m->data)) == 0x55555555) {    fprintf(stderr, "** Zapped mapping in list of active mappings!\n");    describe_something(m, T_MAPPING, 0,2,0, NULL);    Pike_fatal("Zapped mapping in list of active mappings!\n");    }   #endif /* DEBUG_MALLOC */    -  if((md->ind_types | md->val_types) & BIT_COMPLEX) -  GC_ENTER (m, T_MAPPING) { -  if(!debug_gc_check (md, " as mapping data block of a mapping")) -  gc_check_md (md); -  } GC_LEAVE; -  +  gc_check_mapping(m);   #ifdef PIKE_DEBUG    if(d_flag > 1) check_mapping_type_fields(m);   #endif    }   }      void gc_mark_all_mappings(void)   {    gc_mark_mapping_pos = gc_internal_mapping;    while (gc_mark_mapping_pos) {