pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: mapping.c,v 1.126 2003/06/02 16:35:28 mast Exp $"); + RCSID("$Id: mapping.c,v 1.127 2003/09/08 15:27:58 mast Exp $");   #include "main.h"   #include "object.h"   #include "mapping.h"   #include "svalue.h"   #include "array.h"   #include "pike_macros.h"   #include "pike_error.h"   #include "pike_memory.h"   #include "dynamic_buffer.h"   #include "interpret.h"
pike.git/src/mapping.c:1942:   #define DO_IF_MAPPING_SIZE_DEBUG(x) x   #else   #define DO_IF_MAPPING_SIZE_DEBUG(x)   #endif      #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)) { \ +  if (!IS_DESTRUCTED(&k->ind) && \ +  recurse_fn(&k->ind, 1, T_MAPPING, m)) { \    DO_IF_DEBUG(fatal("Didn't expect an svalue zapping now.\n")); \    } \ -  recurse_fn(&k->val, 1); \ +  recurse_fn(&k->val, 1, T_MAPPING, m); \    val_types |= 1 << k->val.type; \    } \   } while (0)      #define GC_RECURSE(MD, REC_KEYPAIR, TYPE, IND_TYPES, VAL_TYPES) do { \    INT32 e; \    int remove; \    struct keypair *k,**prev; \    /* no locking required (no is_eq) */ \    for(e=0;e<MD->hashsize;e++) \
pike.git/src/mapping.c:1984:    }else{ \    VAL_TYPES |= 1 << k->val.type; \    IND_TYPES |= 1 << k->ind.type; \    prev=&k->next; \    } \    } \    } \   } while (0)      #define GC_REC_KP(REMOVE, N_REC, W_REC, N_TST, W_TST) do { \ -  if ((REMOVE = N_REC(&k->ind, 1))) \ +  if ((REMOVE = N_REC(&k->ind, 1, T_MAPPING, m))) \    gc_free_svalue(&k->val); \    else \ -  N_REC(&k->val, 1); \ +  N_REC(&k->val, 1, T_MAPPING, m); \   } while (0)      #define GC_REC_KP_IND(REMOVE, N_REC, W_REC, N_TST, W_TST) do { \ -  if ((REMOVE = W_REC(&k->ind, 1))) \ +  if ((REMOVE = W_REC(&k->ind, 1, T_MAPPING, m))) \    gc_free_svalue(&k->val); \    else \ -  N_REC(&k->val, 1); \ +  N_REC(&k->val, 1, T_MAPPING, m); \   } while (0)      #define GC_REC_KP_VAL(REMOVE, N_REC, W_REC, N_TST, W_TST) do { \    if ((REMOVE = N_TST(&k->ind))) /* Don't recurse now. */ \    gc_free_svalue(&k->val); \ -  else if ((REMOVE = W_REC(&k->val, 1))) \ +  else if ((REMOVE = W_REC(&k->val, 1, T_MAPPING, m))) \    gc_free_svalue(&k->ind); \    else \ -  N_REC(&k->ind, 1); /* Now we can recurse the index. */ \ +  N_REC(&k->ind, 1, T_MAPPING, m); /* Now we can recurse the index. */ \   } while (0)      #define GC_REC_KP_BOTH(REMOVE, N_REC, W_REC, N_TST, W_TST) do { \    if ((REMOVE = W_TST(&k->ind))) /* Don't recurse now. */ \    gc_free_svalue(&k->val); \ -  else if ((REMOVE = W_REC(&k->val, 1))) \ +  else if ((REMOVE = W_REC(&k->val, 1, T_MAPPING, m))) \    gc_free_svalue(&k->ind); \    else \ -  W_REC(&k->ind, 1); /* Now we can recurse the index. */ \ +  W_REC(&k->ind, 1, T_MAPPING, m); /* Now we can recurse the index. */ \   } while (0)      void gc_mark_mapping_as_referenced(struct mapping *m)   {   #ifdef PIKE_DEBUG    if(m->data->refs <=0)    fatal("Zero refs in mapping->data\n");   #endif       if(gc_mark(m)) {
pike.git/src/mapping.c:2038:    gc_internal_mapping = m->next;    else {    DOUBLEUNLINK(first_mapping, m);    DOUBLELINK(first_mapping, m); /* Linked in first. */    }       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. */ -  GC_RECURSE_MD_IN_USE(md, gc_mark_svalues, ind_types, val_types); +  GC_RECURSE_MD_IN_USE(md, debug_gc_mark_svalues, ind_types, val_types);    gc_assert_checked_as_nonweak(md);    }    else    switch (md->flags & MAPPING_WEAK) {    case 0: -  GC_RECURSE(md, GC_REC_KP, gc_mark, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP, debug_gc_mark, ind_types, val_types);    gc_assert_checked_as_nonweak(md);    break;    case MAPPING_WEAK_INDICES: -  GC_RECURSE(md, GC_REC_KP_IND, gc_mark, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_IND, debug_gc_mark, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    case MAPPING_WEAK_VALUES: -  GC_RECURSE(md, GC_REC_KP_VAL, gc_mark, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_VAL, debug_gc_mark, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    default: -  GC_RECURSE(md, GC_REC_KP_BOTH, gc_mark, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_BOTH, debug_gc_mark, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    }    md->val_types = val_types;    md->ind_types = ind_types;    }    }   }      void real_gc_cycle_check_mapping(struct mapping *m, int weak)
pike.git/src/mapping.c:2080: Inside #if defined(PIKE_DEBUG)
     #ifdef PIKE_DEBUG    if(md->refs <=0)    fatal("Zero refs in mapping->data\n");   #endif       if ((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. */ -  GC_RECURSE_MD_IN_USE(md, gc_cycle_check_svalues, ind_types, val_types); +  GC_RECURSE_MD_IN_USE(md, debug_gc_cycle_check_svalues, ind_types, val_types);    gc_assert_checked_as_nonweak(md);    }    else    switch (md->flags & MAPPING_WEAK) {    case 0: -  GC_RECURSE(md, GC_REC_KP, gc_cycle_check, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP, debug_gc_cycle_check, ind_types, val_types);    gc_assert_checked_as_nonweak(md);    break;    case MAPPING_WEAK_INDICES: -  GC_RECURSE(md, GC_REC_KP_IND, gc_cycle_check, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_IND, debug_gc_cycle_check, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    case MAPPING_WEAK_VALUES: -  GC_RECURSE(md, GC_REC_KP_VAL, gc_cycle_check, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_VAL, debug_gc_cycle_check, ind_types, val_types);    gc_assert_checked_as_weak(md);    break;    default: -  GC_RECURSE(md, GC_REC_KP_BOTH, gc_cycle_check, ind_types, val_types); +  GC_RECURSE(md, GC_REC_KP_BOTH, debug_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_mapping(struct mapping *m)
pike.git/src/mapping.c:2220:   }      void gc_zap_ext_weak_refs_in_mappings(void)   {    gc_mark_mapping_pos = first_mapping;    while (gc_mark_mapping_pos != gc_internal_mapping && gc_ext_weak_refs) {    struct mapping *m = gc_mark_mapping_pos;    gc_mark_mapping_pos = m->next;    gc_mark_mapping_as_referenced(m);    } -  discard_queue(&gc_mark_queue); +  gc_mark_discard_queue();   }      void gc_free_all_unreferenced_mappings(void)   {    struct mapping *m,*next;    struct mapping_data *md;       for(m=gc_internal_mapping;m;m=next)    {    if(gc_do_free(m))