introduce WAMR memory profiling tool (experimental) (#390)
This commit is contained in:
@ -385,10 +385,6 @@ gc_alloc_vo_internal(void *vheap, gc_size_t size,
|
||||
/* clear buffer appended by GC_ALIGN_8() */
|
||||
memset((uint8*)ret + size, 0, tot_size - tot_size_unaligned);
|
||||
|
||||
#if BH_ENABLE_MEMORY_PROFILING != 0
|
||||
os_printf("HEAP.ALLOC: heap: %p, size: %u\n", heap, size);
|
||||
#endif
|
||||
|
||||
finish:
|
||||
os_mutex_unlock(&heap->lock);
|
||||
return ret;
|
||||
@ -469,10 +465,6 @@ gc_realloc_vo_internal(void *vheap, void *ptr, gc_size_t size,
|
||||
|
||||
ret = hmu_to_obj(hmu);
|
||||
|
||||
#if BH_ENABLE_MEMORY_PROFILING != 0
|
||||
os_printf("HEAP.ALLOC: heap: %p, size: %u\n", heap, size);
|
||||
#endif
|
||||
|
||||
finish:
|
||||
os_mutex_unlock(&heap->lock);
|
||||
|
||||
@ -548,9 +540,6 @@ gc_free_vo_internal(void *vheap, gc_object_t obj,
|
||||
g_total_free += size;
|
||||
|
||||
heap->total_free_size += size;
|
||||
#if BH_ENABLE_MEMORY_PROFILING != 0
|
||||
os_printf("HEAP.FREE, heap: %p, size: %u\n", heap, size);
|
||||
#endif
|
||||
|
||||
if (!hmu_get_pinuse(hmu)) {
|
||||
prev = (hmu_t*) ((char*) hmu - *((int*) hmu - 1));
|
||||
@ -600,6 +589,12 @@ gc_dump_heap_stats(gc_heap_t *heap)
|
||||
g_total_malloc, g_total_free, g_total_malloc - g_total_free);
|
||||
}
|
||||
|
||||
uint32
|
||||
gc_get_heap_highmark_size(gc_heap_t *heap)
|
||||
{
|
||||
return heap->highmark_size;
|
||||
}
|
||||
|
||||
void
|
||||
gci_dump(gc_heap_t *heap)
|
||||
{
|
||||
|
||||
@ -145,7 +145,9 @@ hmu_verify(hmu_t *hmu);
|
||||
* HMU free chunk management
|
||||
*/
|
||||
|
||||
#ifndef HMU_NORMAL_NODE_CNT
|
||||
#define HMU_NORMAL_NODE_CNT 32
|
||||
#endif
|
||||
#define HMU_FC_NORMAL_MAX_SIZE ((HMU_NORMAL_NODE_CNT - 1) << 3)
|
||||
#define HMU_IS_FC_NORMAL(size) ((size) < HMU_FC_NORMAL_MAX_SIZE)
|
||||
#if HMU_FC_NORMAL_MAX_SIZE >= GC_MAX_HEAP_SIZE
|
||||
|
||||
@ -9,16 +9,17 @@ gc_handle_t
|
||||
gc_init_with_pool(char *buf, gc_size_t buf_size)
|
||||
{
|
||||
char *buf_end = buf + buf_size;
|
||||
char *buf_aligned = (char*) (((uintptr_t) buf + 7) & (uintptr_t)~7);
|
||||
char *buf_aligned = (char*)(((uintptr_t) buf + 7) & (uintptr_t)~7);
|
||||
char *base_addr = buf_aligned + sizeof(gc_heap_t);
|
||||
gc_heap_t *heap = (gc_heap_t*) buf_aligned;
|
||||
gc_heap_t *heap = (gc_heap_t*)buf_aligned;
|
||||
gc_size_t heap_max_size;
|
||||
hmu_normal_node_t *p = NULL;
|
||||
hmu_tree_node_t *root = NULL, *q = NULL;
|
||||
int i = 0, ret;
|
||||
|
||||
if (buf_size < 1024) {
|
||||
os_printf("[GC_ERROR]heap_init_size(%d) < 1024\n", buf_size);
|
||||
if (buf_size < APP_HEAP_SIZE_MIN) {
|
||||
os_printf("[GC_ERROR]heap init buf size (%u) < %u\n",
|
||||
buf_size, APP_HEAP_SIZE_MIN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -66,12 +67,14 @@ gc_init_with_pool(char *buf, gc_size_t buf_size)
|
||||
q->parent = root;
|
||||
q->size = heap->current_size;
|
||||
|
||||
bh_assert(root->size <= HMU_FC_NORMAL_MAX_SIZE
|
||||
&& HMU_FC_NORMAL_MAX_SIZE < q->size);
|
||||
bh_assert(root->size <= HMU_FC_NORMAL_MAX_SIZE);
|
||||
|
||||
#if BH_ENABLE_MEMORY_PROFILING != 0
|
||||
os_printf("heap is successfully initialized with max_size=%u.\n",
|
||||
heap_max_size);
|
||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||
os_printf("Heap created, total size: %u\n", buf_size);
|
||||
os_printf(" heap struct size: %u\n", sizeof(gc_heap_t));
|
||||
os_printf(" actual heap size: %u\n", heap_max_size);
|
||||
os_printf(" padding bytes: %u\n",
|
||||
buf_size - sizeof(gc_heap_t) - heap_max_size);
|
||||
#endif
|
||||
return heap;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ bh_hash_map_create(uint32 size, bool use_lock,
|
||||
}
|
||||
|
||||
total_size = offsetof(HashMap, elements) +
|
||||
sizeof(HashMapElem) * (uint64)size +
|
||||
sizeof(HashMapElem *) * (uint64)size +
|
||||
(use_lock ? sizeof(korp_mutex) : 0);
|
||||
|
||||
if (total_size >= UINT32_MAX
|
||||
@ -61,7 +61,7 @@ bh_hash_map_create(uint32 size, bool use_lock,
|
||||
if (use_lock) {
|
||||
map->lock = (korp_mutex*)
|
||||
((uint8*)map + offsetof(HashMap, elements)
|
||||
+ sizeof(HashMapElem) * size);
|
||||
+ sizeof(HashMapElem *) * size);
|
||||
if (os_mutex_init(map->lock)) {
|
||||
LOG_ERROR("HashMap create failed: init map lock failed.\n");
|
||||
BH_FREE(map);
|
||||
@ -188,8 +188,8 @@ bh_hash_map_update(HashMap *map, void *key, void *value,
|
||||
os_mutex_unlock(map->lock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
elem = elem->next;
|
||||
}
|
||||
|
||||
if (map->lock) {
|
||||
@ -286,3 +286,53 @@ bh_hash_map_destroy(HashMap *map)
|
||||
BH_FREE(map);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32
|
||||
bh_hash_map_get_struct_size(HashMap *hashmap)
|
||||
{
|
||||
uint32 size = offsetof(HashMap, elements)
|
||||
+ sizeof(HashMapElem *) * hashmap->size;
|
||||
|
||||
if (hashmap->lock) {
|
||||
size += sizeof(korp_mutex);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32
|
||||
bh_hash_map_get_elem_struct_size()
|
||||
{
|
||||
return sizeof(HashMapElem);
|
||||
}
|
||||
|
||||
bool
|
||||
bh_hash_map_traverse(HashMap *map, TraverseCallbackFunc callback)
|
||||
{
|
||||
uint32 index;
|
||||
HashMapElem *elem, *next;
|
||||
|
||||
if (!map || !callback) {
|
||||
LOG_ERROR("HashMap traverse failed: map or callback is NULL.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (map->lock) {
|
||||
os_mutex_lock(map->lock);
|
||||
}
|
||||
|
||||
for (index = 0; index < map->size; index++) {
|
||||
elem = map->elements[index];
|
||||
while (elem) {
|
||||
next = elem->next;
|
||||
callback(elem->key, elem->value);
|
||||
elem = next;
|
||||
}
|
||||
}
|
||||
|
||||
if (map->lock) {
|
||||
os_mutex_unlock(map->lock);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -32,6 +32,10 @@ typedef void (*KeyDestroyFunc)(void *key);
|
||||
when an hash element is removed. */
|
||||
typedef void (*ValueDestroyFunc)(void *key);
|
||||
|
||||
/* traverse callback function:
|
||||
auto called when traverse every hash element */
|
||||
typedef void (*TraverseCallbackFunc)(void *key, void *value);
|
||||
|
||||
/**
|
||||
* Create a hash map.
|
||||
*
|
||||
@ -124,6 +128,37 @@ bh_hash_map_remove(HashMap *map, void *key,
|
||||
bool
|
||||
bh_hash_map_destroy(HashMap *map);
|
||||
|
||||
/**
|
||||
* Get the structure size of HashMap
|
||||
*
|
||||
* @param map the hash map to calculate
|
||||
*
|
||||
* @return the memory space occupied by HashMap structure
|
||||
*/
|
||||
uint32
|
||||
bh_hash_map_get_struct_size(HashMap *hashmap);
|
||||
|
||||
/**
|
||||
* Get the structure size of HashMap Element
|
||||
*
|
||||
* @return the memory space occupied by HashMapElem structure
|
||||
*/
|
||||
uint32
|
||||
bh_hash_map_get_elem_struct_size();
|
||||
|
||||
/**
|
||||
* Traverse the hash map and call the callback function
|
||||
*
|
||||
* @param map the hash map to traverse
|
||||
* @callback the function to be called for every element
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
* Note: if the hash map has lock, the map will be locked during traverse,
|
||||
* keep the callback function as simple as possible.
|
||||
*/
|
||||
bool
|
||||
bh_hash_map_traverse(HashMap *map, TraverseCallbackFunc callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -41,6 +41,9 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
|
||||
_close(file);
|
||||
return NULL;
|
||||
}
|
||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||
printf("Read file, total size: %u\n", file_size);
|
||||
#endif
|
||||
|
||||
read_size = _read(file, buffer, file_size);
|
||||
_close(file);
|
||||
@ -88,6 +91,9 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
|
||||
close(file);
|
||||
return NULL;
|
||||
}
|
||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||
printf("Read file, total size: %u\n", file_size);
|
||||
#endif
|
||||
|
||||
read_size = (uint32)read(file, buffer, file_size);
|
||||
close(file);
|
||||
|
||||
Reference in New Issue
Block a user