pike.git / src / block_allocator.c

version» Context lines:

pike.git/src/block_allocator.c:9:      #define BA_BLOCKN(l, p, n) ((struct ba_block_header *)((char*)(p) + (l).doffset + (n)*((l).block_size)))   #define BA_LASTBLOCK(l, p) ((struct ba_block_header*)((char*)(p) + (l).doffset + (l).offset))   #define BA_CHECK_PTR(l, p, ptr) ((size_t)((char*)(ptr) - (char*)(p)) <= (l).offset + (l).doffset)      #define BA_ONE ((struct ba_block_header *)1)   #define BA_FLAG_SORTED 1u      static void print_allocator(const struct block_allocator * a);    + #ifdef PIKE_DEBUG + static void ba_check_ptr(struct block_allocator * a, int page, void * ptr, struct ba_block_header *loc, +  int ln); + #endif +    static INLINE unsigned INT32 ba_block_number(const struct ba_layout * l, const struct ba_page * p,    const void * ptr) {    return ((char*)ptr - (char*)BA_BLOCKN(*l, p, 0)) / l->block_size;   }      static INLINE void ba_dec_layout(struct ba_layout * l, int i) {    l->blocks >>= i;    l->offset += l->block_size;    l->offset >>= i;    l->offset -= l->block_size;
pike.git/src/block_allocator.c:225:    p = a->pages[a->alloc];    }       ptr = p->h.first;    PIKE_MEMPOOL_ALLOC(a, ptr, a->l.block_size);    PIKE_MEM_RW_RANGE(ptr, sizeof(struct ba_block_header));       p->h.used++;      #ifdef PIKE_DEBUG -  { -  struct ba_layout l = ba_get_layout(a, a->alloc); -  if (!BA_CHECK_PTR(l, p, ptr)) { -  print_allocator(a); -  Pike_fatal("about to return pointer from hell: %p\n", ptr); -  } -  } +  ba_check_ptr(a, a->alloc, ptr, NULL, __LINE__);   #endif       if (ptr->next == BA_ONE) {    struct ba_layout l = ba_get_layout(a, a->alloc);    p->h.first = (struct ba_block_header*)((char*)ptr + a->l.block_size);    PIKE_MEMPOOL_ALLOC(a, p->h.first, a->l.block_size);    p->h.first->next = (struct ba_block_header*)(ptrdiff_t)!(p->h.first == BA_LASTBLOCK(l, p));    PIKE_MEMPOOL_FREE(a, p->h.first, a->l.block_size);    } else { -  + #ifdef PIKE_DEBUG +  if (ptr->next) +  ba_check_ptr(a, a->alloc, ptr->next, ptr, __LINE__); + #endif    p->h.first = ptr->next;    }    PIKE_MEM_WO_RANGE(ptr, sizeof(struct ba_block_header));      #if PIKE_DEBUG    if (a->l.alignment && (size_t)ptr & (a->l.alignment - 1)) {    print_allocator(a);    Pike_fatal("Returning unaligned pointer.\n");    }   #endif
pike.git/src/block_allocator.c:287:    break;    }    }   found:      #ifdef PIKE_DEBUG    if (p) {   #endif    {    struct ba_block_header * b = (struct ba_block_header*)ptr; -  b->next = p->h.first; -  p->h.first = b; -  p->h.flags = 0; +    #ifdef PIKE_DEBUG    if (!p->h.used) {    print_allocator(a);    Pike_fatal("freeing from empty page %p\n", p);    } -  +  ba_check_ptr(a, a->last_free, ptr, NULL, __LINE__);   #endif -  +  b->next = p->h.first; +  p->h.first = b; +  p->h.flags = 0;    if (!(--p->h.used)) {    if (i+1 == a->size) {    ba_free_empty_pages(a);    } else {    ba_clear_page(a, p, &l);    }    }    }   #ifdef PIKE_DEBUG    } else {
pike.git/src/block_allocator.c:325:    struct ba_layout l;       for (i = a->size-1, l = ba_get_layout(a, i); i >= 0; ba_half_layout(&l), i--) {    struct ba_page * p = a->pages[i];    fprintf(stderr, "page: %p used: %u/%u last: %p p+offset: %p\n", a->pages[i],    p->h.used, l.blocks,    BA_BLOCKN(l, p, l.blocks-1), BA_LASTBLOCK(l, p));    }   }    + #ifdef PIKE_DEBUG +  + #define Pike_nfatal(n) \ +  (fprintf(stderr,msg_fatal_error,__FILE__,(long)(n)),debug_fatal) +  + static void ba_check_ptr(struct block_allocator * a, int page, void * ptr, struct ba_block_header * loc, +  int ln) { +  struct ba_layout l = ba_get_layout(a, page); +  struct ba_page * p = a->pages[page]; +  +  if (BA_BLOCKN(l, p, ba_block_number(&l, p, ptr)) != ptr) { +  char * block = (char*)BA_BLOCKN(l, p, ba_block_number(&l, p, ptr)); +  print_allocator(a); +  if (loc) fprintf(stderr, "In block %p:\n", loc); +  Pike_nfatal(ln)("Free-List corruption. List pointer %p is inside block [%p , %p)\n", +  ptr, block, block + l.block_size); +  } +  +  if (!BA_CHECK_PTR(l, p, ptr)) { +  print_allocator(a); +  if (loc) fprintf(stderr, "In block %p:\n", loc); +  Pike_nfatal(ln)("Free-List corruption. Block %p does not belong to page %p\n", ptr, p); +  } + } + #endif +    #if SIZEOF_LONG == 8 || SIZEOF_LONG_LONG == 8   #define BV_LENGTH 64   #define BV_ONE ((unsigned INT64)1)   #define BV_NIL ((unsigned INT64)0)   #define BV_CLZ clz64   #define BV_CTZ ctz64   typedef unsigned INT64 bv_int_t;   #else   #define BV_LENGTH 32   #define BV_ONE ((unsigned INT32)1)