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.122 2001/05/14 03:28:36 hubbe Exp $"); + RCSID("$Id: mapping.c,v 1.123 2001/05/27 16:58:57 grubba 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:32:   struct mapping *gc_internal_mapping = 0;   static struct mapping *gc_mark_mapping_pos = 0;      #define unlink_mapping_data(M) do{ \    struct mapping_data *md_=(M); \    if(md_->hardlinks) { md_->hardlinks--; md_->valrefs--; } \    free_mapping_data(M); \   }while(0)       - #define MD_KEYPAIRS(MD, HSIZE) \ -  ( (struct keypair *)DO_ALIGN( (ptrdiff_t) (((struct mapping_data *)(MD))->hash + HSIZE), ALIGNOF(struct keypair)) ) -  +    #define MAPPING_DATA_SIZE(HSIZE, KEYPAIRS) \    (ptrdiff_t)( MD_KEYPAIRS(0, HSIZE) + KEYPAIRS )            #undef EXIT_BLOCK   #define EXIT_BLOCK(m) do{ \    INT32 e; \   DO_IF_DEBUG( \    if(m->refs) \
pike.git/src/mapping.c:71:    struct mapping *m; \    for(m=first_mapping;m;m=m->next) \    { \    num++; \    size+=MAPPING_DATA_SIZE(m->data->hashsize, m->data->num_keypairs); \    } \   }while(0)      BLOCK_ALLOC(mapping, 511)    + #ifndef PIKE_MAPPING_KEYPAIR_LOOP + #define FREE_KEYPAIR(md, k) do { \ +  k->next = md->free_list; \ +  md->free_list = k; \ +  } while(0) + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ + #define FREE_KEYPAIR(md, k) do { \ +  md->free_list--; \ +  if (k != md->free_list) { \ +  struct keypair **prev_; \ +  unsigned INT32 h_; \ +  /* Move the last keypair to the new hole. */ \ +  *k = *(md->free_list); \ +  h_ = k->hval % md->hashsize; \ +  prev_ = md->hash + h_; \ +  DO_IF_DEBUG( \ +  if (!*prev_) { \ +  fatal("Node to move not found!\n"); \ +  } \ +  ); \ +  while (*prev_ != md->free_list) { \ +  prev_ = &((*prev_)->next); \ +  DO_IF_DEBUG( \ +  if (!*prev_) { \ +  fatal("Node to move not found!\n"); \ +  } \ +  ); \ +  } \ +  *prev_ = k; \ +  } \ +  } while(0) + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */      #ifdef PIKE_DEBUG   /* This function checks that the type field isn't lacking any bits.    * It is used for debugging purposes only.    */   static void check_mapping_type_fields(struct mapping *m)   {    INT32 e;    struct keypair *k=0,**prev;    TYPE_FIELD ind_types, val_types;
pike.git/src/mapping.c:137:    e=MAPPING_DATA_SIZE(hashsize, size);       md=(struct mapping_data *)xalloc(e);       m->data=md;    md->hashsize=hashsize;       MEMSET((char *)md->hash, 0, sizeof(struct keypair *) * md->hashsize);       md->free_list=MD_KEYPAIRS(md, hashsize); + #ifndef PIKE_MAPPING_KEYPAIR_LOOP    for(e=1;e<size;e++)    {    md->free_list[e-1].next = md->free_list + e;    md->free_list[e-1].ind.type=T_INT;    md->free_list[e-1].val.type=T_INT;    }    md->free_list[e-1].next=0;    md->free_list[e-1].ind.type=T_INT;    md->free_list[e-1].val.type=T_INT; -  + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */    md->ind_types = 0;    md->val_types = 0;    md->flags = flags;    md->size = 0;    md->refs=0;    md->valrefs=0;    md->hardlinks=0;    md->num_keypairs=size;    }else{    if(flags & MAPPING_FLAG_WEAK)
pike.git/src/mapping.c:235:   {    unsigned INT32 h;    struct keypair *tmp;    struct keypair *k;       if(!from) return;    mapping_rehash_backwards_evil(md,from->next);       /* unlink */    k=md->free_list; + #ifndef PIKE_MAPPING_KEYPAIR_LOOP   #ifdef PIKE_DEBUG    if(!k) fatal("Error in rehash: not enough keypairs.\n");   #endif    md->free_list=k->next; -  + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  md->free_list++; + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */       /* initialize */    *k=*from;       /* link */    h=k->hval;    h%=md->hashsize;    k->next=md->hash[h];    md->hash[h]=k;   
pike.git/src/mapping.c:267:   {    unsigned INT32 h;    struct keypair *tmp;    struct keypair *k;       if(!from) return;    mapping_rehash_backwards_good(md,from->next);       /* unlink */    k=md->free_list; + #ifndef PIKE_MAPPING_KEYPAIR_LOOP   #ifdef PIKE_DEBUG    if(!k) fatal("Error in rehash: not enough keypairs.\n");   #endif    md->free_list=k->next; -  + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  md->free_list++; + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */       /* initialize */    k->hval=from->hval;    assign_svalue_no_free(&k->ind, &from->ind);    assign_svalue_no_free(&k->val, &from->val);       /* link */    h=k->hval;    h%=md->hashsize;    k->next=md->hash[h];
pike.git/src/mapping.c:377:    size=MAPPING_DATA_SIZE(md->hashsize, md->num_keypairs);       nmd=(struct mapping_data *)xalloc(size);    MEMCPY(nmd, md, size);    off=((char *)nmd) - ((char *)md);       RELOC(nmd->free_list);    for(e=0;e<nmd->hashsize;e++) RELOC(nmd->hash[e]);       keypairs=MD_KEYPAIRS(nmd, nmd->hashsize); + #ifndef PIKE_MAPPING_KEYPAIR_LOOP    for(e=0;e<nmd->num_keypairs;e++)    {    RELOC(keypairs[e].next);    add_ref_svalue(& keypairs[e].ind);    add_ref_svalue(& keypairs[e].val);    } -  + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  for(e=0;e<nmd->size;e++) +  { +  RELOC(keypairs[e].next); +  add_ref_svalue(& keypairs[e].ind); +  add_ref_svalue(& keypairs[e].val); +  } + #endif /* PIKE_MAPPING_KEYPAIR_LOOP */       nmd->refs=1;    nmd->valrefs=0;    nmd->hardlinks=0;       if(md->hardlinks)    {   #ifdef PIKE_DEBUG    if(md->refs <= 0 || md->valrefs<=0)    fatal("Hardlink without refs/valrefs!\n");
pike.git/src/mapping.c:645:    return;       mi_insert:   #ifdef PIKE_DEBUG    if(m->data != md)    fatal("Wrong dataset in mapping_insert!\n");    if(d_flag>1) check_mapping(m);   #endif    free_mapping_data(md);    /* We do a re-hash here instead of copying the mapping. */ -  if((!(k=md->free_list)) || md->refs>1) +  if( + #ifndef PIKE_MAPPING_KEYPAIR_LOOP +  (!md->free_list) || + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  (md->size >= md->num_keypairs) || + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */ +  md->refs>1)    {    debug_malloc_touch(m);    rehash(m, md->size * 2 + 2);    md=m->data; -  k=md->free_list; +     }    h=h2 % md->hashsize;       /* no need to lock here since we are not calling is_eq - Hubbe */       k=md->free_list; -  + #ifndef PIKE_MAPPING_KEYPAIR_LOOP    md->free_list=k->next; -  + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  md->free_list++; + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */    k->next=md->hash[h];    md->hash[h]=k;    md->ind_types |= 1 << key->type;    md->val_types |= 1 << val->type;    assign_svalue_no_free(& k->ind, key);    assign_svalue_no_free(& k->val, val);    k->hval = h2;    md->size++;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)
pike.git/src/mapping.c:757: Inside #if defined(PIKE_DEBUG)
   if(m->data != md)    fatal("Wrong dataset in mapping_get_item_ptr!\n");    if(d_flag)    check_mapping(m);   #endif    free_mapping_data(md);       if(t != T_INT) return 0;       /* no need to call PREPARE_* because we re-hash instead */ -  if(!(k=md->free_list) || md->refs>1) +  if( + #ifndef PIKE_MAPPING_KEYPAIR_LOOP +  !(md->free_list) || + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  (md->size >= md->num_keypairs) || + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */ +  md->refs>1)    {    debug_malloc_touch(m);    rehash(m, md->size * 2 + 2);    md=m->data; -  k=md->free_list; +     }    h=h2 % md->hashsize;    -  +  k=md->free_list; + #ifndef PIKE_MAPPING_KEYPAIR_LOOP    md->free_list=k->next; -  + #else /* PIKE_MAPPING_KEYPAIR_LOOP */ +  md->free_list++; + #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */    k->next=md->hash[h];    md->hash[h]=k;    assign_svalue_no_free(& k->ind, key);    k->val.type=T_INT;    k->val.subtype=NUMBER_NUMBER;    k->val.u.integer=0;    k->hval = h2;    md->ind_types |= 1 << key->type;    md->val_types |= BIT_INT;    md->size++;
pike.git/src/mapping.c:847:    free_mapping_data(md);    PREPARE_FOR_INDEX_CHANGE2();    /* No need to propagate */    *prev=k->next;    free_svalue(& k->ind);    if(to)    to[0]=k->val;    else    free_svalue(& k->val);    -  k->ind.type=T_INT; -  k->val.type=T_INT; +  FREE_KEYPAIR(md, k);    -  k->next=md->free_list; -  md->free_list=k; +  md->free_list->ind.type=T_INT; +  md->free_list->val.type=T_INT; +     md->size--;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    m->debug_size--;   #endif       if(md->size < (md->hashsize + 1) * MIN_LINK_LENGTH)    {    debug_malloc_touch(m);    rehash(m, MAP_SLOTS(m->data->size));
pike.git/src/mapping.c:909:       if((k->ind.type == T_OBJECT || k->ind.type == T_FUNCTION) &&    !k->ind.u.object->prog)    {    debug_malloc_touch(m);    debug_malloc_touch(md);    PREPARE_FOR_INDEX_CHANGE2();    *prev=k->next;    free_svalue(& k->ind);    free_svalue(& k->val); -  k->next=md->free_list; -  md->free_list=k; +  FREE_KEYPAIR(md, k); +  md->free_list->ind.type = T_INT; +  md->free_list->val.type = T_INT;    md->size--;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    {    m->debug_size++;    debug_malloc_touch(m);    }   #endif    debug_malloc_touch(md);    }else{
pike.git/src/mapping.c:1968:    { \    for(prev= md->hash + e;(k=*prev);) \    { \    int i = recurse_fn(&k->ind, 1); \    int v = recurse_fn(&k->val, 1); \    if(i || v) \    { \    *prev=k->next; \    if (!i) gc_free_svalue(&k->ind); \    if (!v) gc_free_svalue(&k->val); \ -  k->next=md->free_list; \ -  md->free_list=k; \ +  FREE_KEYPAIR(md, k); \ +  md->free_list->ind.type = T_INT; \ +  md->free_list->val.type = T_INT; \    md->size--; \    DO_IF_MAPPING_SIZE_DEBUG( \    if(m->data ==md) \    m->debug_size--; \    ) \    }else{ \    val_types |= 1 << k->val.type; \    ind_types |= 1 << k->ind.type; \    prev=&k->next; \    } \
pike.git/src/mapping.c:1996:    struct keypair *k,**prev; \    /* no locking required (no is_eq) */ \    for(e=0;e<md->hashsize;e++) \    { \    for(prev= md->hash + e;(k=*prev);) \    { \    if (recurse_fn(&k->ind, 1)) \    { \    *prev=k->next; \    gc_free_svalue(&k->val); \ -  k->next=md->free_list; \ -  md->free_list=k; \ +  FREE_KEYPAIR(md, k); \ +  md->free_list->ind.type = T_INT; \ +  md->free_list->val.type = T_INT; \    md->size--; \    DO_IF_MAPPING_SIZE_DEBUG( \    if(m->data ==md) \    m->debug_size--; \    ) \    }else{ \    recurse_fn(&k->val, 1); \    val_types |= 1 << k->val.type; \    ind_types |= 1 << k->ind.type; \    prev=&k->next; \
pike.git/src/mapping.c:2271: Inside #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)
   if(verbose_debug_exit)    debug_dump_mapping(m);   #endif       md=m->data;    for(e=0;e<md->hashsize;e++)    {    while((k=md->hash[e]))    {    md->hash[e]=k->next; -  k->next=md->free_list; -  md->free_list=k; +     free_svalue(&k->ind);    free_svalue(&k->val); -  +  FREE_KEYPAIR(md, k); +  md->free_list->ind.type = T_INT; +  md->free_list->val.type = T_INT;    }    }    md->size=0;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    m->debug_size=0;   #endif       SET_NEXT_AND_FREE(m, free_mapping);    }   }