Branch: Tag:

2008-05-02

2008-05-02 04:15:18 by Martin Stjernholm <mast@lysator.liu.se>

Added Pike.count_memory to be able to see the memory consumed by arbitrary
pike structures.

The Gmp classes have been fixed to accurately report sizes, but there's
probably more to do in other modules.

Rev: lib/modules/Pike.pmod/module.pmod:1.17
Rev: src/array.c:1.205
Rev: src/builtin_functions.c:1.659
Rev: src/gc.c:1.305
Rev: src/gc.h:1.131
Rev: src/mapping.c:1.199
Rev: src/modules/Gmp/acconfig.h:1.8
Rev: src/modules/Gmp/configure.in:1.48
Rev: src/modules/Gmp/mpf.cmod:1.35
Rev: src/modules/Gmp/mpq.cmod:1.27
Rev: src/modules/Gmp/mpz_glue.c:1.178
Rev: src/multiset.c:1.107
Rev: src/object.c:1.288
Rev: src/pike_types.c:1.323
Rev: src/program.c:1.681
Rev: src/stralloc.c:1.216
Rev: src/stralloc.h:1.102

2:   || 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.198 2008/01/28 19:46:13 mast Exp $ + || $Id: mapping.c,v 1.199 2008/05/02 04:15:11 mast Exp $   */      #include "global.h"
2322:   #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; \
2463:    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)
2472:    DOUBLELINK(first_mapping, m); /* Linked in first. */    }    -  if(gc_mark(md) && ((md->ind_types | md->val_types) & BIT_COMPLEX)) { +  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) {    TYPE_FIELD ind_types = 0, val_types = 0;    if (MAPPING_DATA_IN_USE(md)) {    /* Must leave the mapping data untouched if it's busy. */
2504:    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;   }   
2568:    } GC_CYCLE_LEAVE;   }    - static void gc_check_mapping(struct mapping *m) + static void gc_check_md (struct mapping_data *md)   { -  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. */
2613:    gc_checked_as_weak(md);    }    } -  } GC_LEAVE; - } +       unsigned gc_touch_all_mappings(void)   {
2637:       for(m=first_mapping;m;m=m->next)    { +  struct mapping_data *md = m->data; +    #ifdef DEBUG_MALLOC -  if (((int)m->data) == 0x55555555) { +  if (((int) PTR_TO_INT (md)) == 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 */    -  gc_check_mapping(m); +  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; +    #ifdef PIKE_DEBUG    if(d_flag > 1) check_mapping_type_fields(m);   #endif