?? erl_memory_trace_block_table.c
字號:
static INLINE intgrow_table(emtbt_table *table){ if (table->current_size_index < sizeof(table_sizes)/sizeof(int)) { int new_size; table->current_size_index++; new_size = table_sizes[table->current_size_index]; ASSERT(new_size > 0); return resize_table(table, new_size); } return 1;}static INLINE voidshrink_table(emtbt_table *table){ if (table->current_size_index > 0) { int new_size; table->current_size_index--; new_size = table_sizes[table->current_size_index]; ASSERT(new_size > 0); (void) resize_table(table, new_size); }}static INLINE emtbt_block *peek_block(emtbt_table *table, usgnd_int_max ptr){ emtbt_block **bucket; emtbt_block *block; usgnd_int_32 hash; MK_HASH(hash, ptr, table->is_64_bit); bucket = &table->buckets[hash % table->no_of_buckets]; block = *bucket; if (!block) return NULL; while (block->bucket == bucket) { ASSERT(block); if (block->pointer == ptr) return block; if (!block->next) break; block = block->next; } return NULL;}static INLINE intinsert_block(emtbt_table *table, emtbt_block *block){ emtbt_block **bucket; emtbt_block *tmp_block; usgnd_int_32 hash; usgnd_int_max p;#if HARD_DEBUG check_table(table);#endif if (table->used_buckets >= table->max_used_buckets) { if(!grow_table(table)) return -1; } p = block->pointer; MK_HASH(hash, p, table->is_64_bit); block->hash = hash; bucket = &table->buckets[hash % table->no_of_buckets]; tmp_block = *bucket; if (tmp_block) { while (tmp_block->bucket == bucket) { if (tmp_block->pointer == p) return 0; if (!tmp_block->next) break; tmp_block = tmp_block->next; } } link_block(table, bucket, block); ASSERT(block == peek_block(table, p)); return 1;}static INLINE voiddelete_block(emtbt_table *table, emtbt_block *block){ emtbt_block **bucket; if (!block) return;#if HARD_DEBUG check_table(table);#endif bucket = block->bucket; ASSERT(bucket); if (block->prev) block->prev->next = block->next; else table->blocks = block->next; if (block->next) block->next->prev = block->prev; if (block == *bucket) { ASSERT(!block->prev || block->prev->bucket != bucket); if (block->next && block->next->bucket == bucket) *bucket = block->next; else { ASSERT(table->used_buckets > 0); *bucket = NULL; table->used_buckets--; } }#ifdef DEBUG block->next = ((emtbt_block *) 0xfffffff0); block->prev = ((emtbt_block *) 0xfffffff0); block->bucket = ((emtbt_block **) 0xfffffff0);#endif ASSERT(table->no_blocks > 0); table->no_blocks--; if (table->used_buckets < table->min_used_buckets) shrink_table(table);#if HARD_DEBUG check_table(table);#endif}static INLINE emtbt_block *fetch_block(emtbt_table *table, usgnd_int_max ptr){ emtbt_block *block; block = peek_block(table, ptr); delete_block(table, block); return block;}const char *emtbt_error_string(int error){ switch (error) { case EMTBT_ALLOC_XBLK_ERROR: return "Allocation to an already existing block"; case EMTBT_REALLOC_NOBLK_ERROR: return "Reallocation of non-existing block"; case EMTBT_REALLOC_XBLK_ERROR: return "Reallocation to an already existing block"; case EMTBT_REALLOC_BLK_TYPE_MISMATCH: return "Block types mismatch when reallocating"; case EMTBT_FREE_NOBLK_ERROR: return "Deallocation of non-existing block"; case EMTBT_FREE_BLK_TYPE_MISMATCH: return "Block types mismatch when deallocating"; case EMTBT_INTERNAL_ERROR: return "Block table internal error"; default: return NULL; }}emtbt_table *emtbt_new_table(int is_64_bit, void * (*alloc)(size_t), void * (*realloc)(void *, size_t), void (*free)(void *)){ emtbt_table *tab = (*alloc)(sizeof(emtbt_table)); if (tab) { tab->alloc = alloc; tab->realloc = realloc; tab->free = free; tab->is_64_bit = is_64_bit; tab->no_blocks = 0; tab->no_of_buckets = 0; tab->max_used_buckets = 0; tab->min_used_buckets = 0; tab->used_buckets = 0; tab->current_size_index = 0; tab->blocks = NULL; tab->buckets = NULL; tab->block_pools = NULL; tab->free_blocks = NULL; tab->blocks_per_pool = EMTBT_BLOCKS_PER_POOL; } return tab;}voidemtbt_destroy_table(emtbt_table *tab){ void (*freep)(void *); emtbt_block_pool *poolp1, *poolp2; freep = tab->free; /* Free block pools */ poolp1 = tab->block_pools; while (poolp1) { poolp2 = poolp1; poolp1 = poolp1->next; (*freep)((void *) poolp2); } if (tab->buckets) (*freep)((void *) tab->buckets); (*freep)((void *) tab);}#define CP_BLK(TO, FROM) \do { \ (TO)->time.secs = (FROM)->time.secs; \ (TO)->time.usecs = (FROM)->time.usecs; \ (TO)->type = (FROM)->type; \ (TO)->pointer = (FROM)->pointer; \ (TO)->size = (FROM)->size; \} while (0)intemtbt_alloc_op(emtbt_table *tab, emtp_operation *op){ int res; emtbt_block *blk; blk = block_alloc(tab); if (!blk) return ENOMEM; blk->time.secs = op->time.secs; blk->time.usecs = op->time.usecs; blk->type = op->u.block.type; blk->pointer = op->u.block.new_ptr; blk->size = op->u.block.new_size; res = insert_block(tab, blk); if (res < 0) return ENOMEM; else if (res == 0) return EMTBT_ALLOC_XBLK_ERROR; return 0;}intemtbt_realloc_op(emtbt_table *tab, emtp_operation *op, emtbt_block *old_blk){ int res; emtbt_block *blk; if (!op->u.block.new_size) { /* freed block */ blk = fetch_block(tab, op->u.block.prev_ptr); if (!blk) return EMTBT_REALLOC_NOBLK_ERROR; CP_BLK(old_blk, blk); block_free(tab, blk); } else { if (!op->u.block.new_ptr) { /* failed operation */ if (!op->u.block.prev_ptr) CP_BLK(old_blk, &null_blk); else { blk = peek_block(tab, op->u.block.prev_ptr); if (!blk) return EMTBT_REALLOC_NOBLK_ERROR; CP_BLK(old_blk, blk);#if 0 if (blk->type != op->u.block.type) return EMTBT_REALLOC_BLK_TYPE_MISMATCH;#endif } } else if (!op->u.block.prev_ptr) { /* new block */ CP_BLK(old_blk, &null_blk); blk = block_alloc(tab); if (!blk) return ENOMEM; blk->type = op->u.block.type; blk->pointer = op->u.block.new_ptr; blk->time.secs = op->time.secs; blk->time.usecs = op->time.usecs; blk->size = op->u.block.new_size; res = insert_block(tab, blk); if (res < 0) return ENOMEM; else if (res == 0) return EMTBT_REALLOC_XBLK_ERROR; } else if (op->u.block.new_ptr == op->u.block.prev_ptr) { /* resized block */ blk = peek_block(tab, op->u.block.prev_ptr); if (!blk) return EMTBT_REALLOC_NOBLK_ERROR; CP_BLK(old_blk, blk); blk->time.secs = op->time.secs; blk->time.usecs = op->time.usecs; blk->size = op->u.block.new_size;#if 0 if (blk->type != op->u.block.type) return EMTBT_REALLOC_BLK_TYPE_MISMATCH;#endif } else { /* moved block */ blk = fetch_block(tab, op->u.block.prev_ptr); if (!blk) return EMTBT_REALLOC_NOBLK_ERROR; CP_BLK(old_blk, blk); blk->time.secs = op->time.secs; blk->time.usecs = op->time.usecs; blk->pointer = op->u.block.new_ptr; blk->size = op->u.block.new_size; res = insert_block(tab, blk); if (res < 0) return ENOMEM; else if (res == 0) return EMTBT_REALLOC_XBLK_ERROR;#if 0 if (blk->type != op->u.block.type) return EMTBT_REALLOC_BLK_TYPE_MISMATCH;#endif } } return 0;}intemtbt_free_op(emtbt_table *tab, emtp_operation *op, emtbt_block *old_blk){ emtbt_block *blk; if (!op->u.block.prev_ptr) CP_BLK(old_blk, &null_blk); else { blk = fetch_block(tab, op->u.block.prev_ptr); if (!blk) return EMTBT_FREE_NOBLK_ERROR; CP_BLK(old_blk, blk); block_free(tab, blk);#if 0 if (blk->type != op->u.block.type) return EMTBT_FREE_BLK_TYPE_MISMATCH;#endif } return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -