Rework memory statistics to provide useful user information. (#1812)

Obsolote statistics is also removed.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2017-05-16 02:52:12 +02:00
committed by yichoi
parent f5b385ca6c
commit f4fbf0b0b5
18 changed files with 347 additions and 246 deletions
@@ -41,8 +41,6 @@ void jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t s
* @{
*/
#ifdef JMEM_STATS
void jmem_pools_get_stats (jmem_pools_stats_t *);
void jmem_pools_stats_reset_peak (void);
void jmem_pools_stats_print (void);
#endif /* JMEM_STATS */
+117 -11
View File
@@ -152,16 +152,6 @@ jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t severi
} /* jmem_run_free_unused_memory_callbacks */
#ifdef JMEM_STATS
/**
* Reset peak values in memory usage statistics
*/
void
jmem_stats_reset_peak (void)
{
jmem_heap_stats_reset_peak ();
jmem_pools_stats_reset_peak ();
} /* jmem_stats_reset_peak */
/**
* Print memory usage statistics
*/
@@ -169,6 +159,122 @@ void
jmem_stats_print (void)
{
jmem_heap_stats_print ();
jmem_pools_stats_print ();
} /* jmem_stats_print */
/**
* Register byte code allocation.
*/
void
jmem_stats_allocate_byte_code_bytes (size_t byte_code_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
heap_stats->byte_code_bytes += byte_code_size;
if (heap_stats->byte_code_bytes >= heap_stats->peak_byte_code_bytes)
{
heap_stats->peak_byte_code_bytes = heap_stats->byte_code_bytes;
}
} /* jmem_stats_allocate_byte_code_bytes */
/**
* Register byte code free.
*/
void
jmem_stats_free_byte_code_bytes (size_t byte_code_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
JERRY_ASSERT (heap_stats->byte_code_bytes >= byte_code_size);
heap_stats->byte_code_bytes -= byte_code_size;
} /* jmem_stats_free_byte_code_bytes */
/**
* Register string allocation.
*/
void
jmem_stats_allocate_string_bytes (size_t string_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
heap_stats->string_bytes += string_size;
if (heap_stats->string_bytes >= heap_stats->peak_string_bytes)
{
heap_stats->peak_string_bytes = heap_stats->string_bytes;
}
} /* jmem_stats_allocate_string_bytes */
/**
* Register string free.
*/
void
jmem_stats_free_string_bytes (size_t string_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
JERRY_ASSERT (heap_stats->string_bytes >= string_size);
heap_stats->string_bytes -= string_size;
} /* jmem_stats_free_string_bytes */
/**
* Register object allocation.
*/
void
jmem_stats_allocate_object_bytes (size_t object_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
heap_stats->object_bytes += object_size;
if (heap_stats->object_bytes >= heap_stats->peak_object_bytes)
{
heap_stats->peak_object_bytes = heap_stats->object_bytes;
}
} /* jmem_stats_allocate_object_bytes */
/**
* Register object free.
*/
void
jmem_stats_free_object_bytes (size_t object_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
JERRY_ASSERT (heap_stats->object_bytes >= object_size);
heap_stats->object_bytes -= object_size;
} /* jmem_stats_free_object_bytes */
/**
* Register property allocation.
*/
void
jmem_stats_allocate_property_bytes (size_t property_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
heap_stats->property_bytes += property_size;
if (heap_stats->property_bytes >= heap_stats->peak_property_bytes)
{
heap_stats->peak_property_bytes = heap_stats->property_bytes;
}
} /* jmem_stats_allocate_property_bytes */
/**
* Register property free.
*/
void
jmem_stats_free_property_bytes (size_t property_size)
{
jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
JERRY_ASSERT (heap_stats->property_bytes >= property_size);
heap_stats->property_bytes -= property_size;
} /* jmem_stats_free_property_bytes */
#endif /* JMEM_STATS */
+18 -20
View File
@@ -574,16 +574,6 @@ jmem_heap_get_stats (jmem_heap_stats_t *out_heap_stats_p) /**< [out] heap stats
*out_heap_stats_p = JERRY_CONTEXT (jmem_heap_stats);
} /* jmem_heap_get_stats */
/**
* Reset peak values in memory usage statistics
*/
void
jmem_heap_stats_reset_peak (void)
{
JERRY_CONTEXT (jmem_heap_stats).peak_allocated_bytes = JERRY_CONTEXT (jmem_heap_stats).allocated_bytes;
JERRY_CONTEXT (jmem_heap_stats).peak_waste_bytes = JERRY_CONTEXT (jmem_heap_stats).waste_bytes;
} /* jmem_heap_stats_reset_peak */
/**
* Print heap memory usage statistics
*/
@@ -595,18 +585,34 @@ jmem_heap_stats_print (void)
JERRY_DEBUG_MSG ("Heap stats:\n"
" Heap size = %zu bytes\n"
" Allocated = %zu bytes\n"
" Waste = %zu bytes\n"
" Peak allocated = %zu bytes\n"
" Waste = %zu bytes\n"
" Peak waste = %zu bytes\n"
" Allocated byte code data = %zu bytes\n"
" Peak allocated byte code data = %zu bytes\n"
" Allocated string data = %zu bytes\n"
" Peak allocated string data = %zu bytes\n"
" Allocated object data = %zu bytes\n"
" Peak allocated object data = %zu bytes\n"
" Allocated property data = %zu bytes\n"
" Peak allocated property data = %zu bytes\n"
" Skip-ahead ratio = %zu.%04zu\n"
" Average alloc iteration = %zu.%04zu\n"
" Average free iteration = %zu.%04zu\n"
"\n",
heap_stats->size,
heap_stats->allocated_bytes,
heap_stats->waste_bytes,
heap_stats->peak_allocated_bytes,
heap_stats->waste_bytes,
heap_stats->peak_waste_bytes,
heap_stats->byte_code_bytes,
heap_stats->peak_byte_code_bytes,
heap_stats->string_bytes,
heap_stats->peak_string_bytes,
heap_stats->object_bytes,
heap_stats->peak_object_bytes,
heap_stats->property_bytes,
heap_stats->peak_property_bytes,
heap_stats->skip_count / heap_stats->nonskip_count,
heap_stats->skip_count % heap_stats->nonskip_count * 10000 / heap_stats->nonskip_count,
heap_stats->alloc_iter_count / heap_stats->alloc_count,
@@ -643,19 +649,11 @@ jmem_heap_stat_alloc (size_t size) /**< Size of allocated block */
{
heap_stats->peak_allocated_bytes = heap_stats->allocated_bytes;
}
if (heap_stats->allocated_bytes > heap_stats->global_peak_allocated_bytes)
{
heap_stats->global_peak_allocated_bytes = heap_stats->allocated_bytes;
}
if (heap_stats->waste_bytes > heap_stats->peak_waste_bytes)
{
heap_stats->peak_waste_bytes = heap_stats->waste_bytes;
}
if (heap_stats->waste_bytes > heap_stats->global_peak_waste_bytes)
{
heap_stats->global_peak_waste_bytes = heap_stats->waste_bytes;
}
} /* jmem_heap_stat_alloc */
/**
-138
View File
@@ -31,24 +31,6 @@
* @{
*/
#ifdef JMEM_STATS
static void jmem_pools_stat_free_pool (void);
static void jmem_pools_stat_new_alloc (void);
static void jmem_pools_stat_reuse (void);
static void jmem_pools_stat_dealloc (void);
# define JMEM_POOLS_STAT_FREE_POOL() jmem_pools_stat_free_pool ()
# define JMEM_POOLS_STAT_NEW_ALLOC() jmem_pools_stat_new_alloc ()
# define JMEM_POOLS_STAT_REUSE() jmem_pools_stat_reuse ()
# define JMEM_POOLS_STAT_DEALLOC() jmem_pools_stat_dealloc ()
#else /* !JMEM_STATS */
# define JMEM_POOLS_STAT_FREE_POOL()
# define JMEM_POOLS_STAT_NEW_ALLOC()
# define JMEM_POOLS_STAT_REUSE()
# define JMEM_POOLS_STAT_DEALLOC()
#endif /* JMEM_STATS */
/*
* Valgrind-related options and headers
*/
@@ -107,8 +89,6 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
{
const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
JMEM_POOLS_STAT_REUSE ();
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_p->next_p;
@@ -119,7 +99,6 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
}
else
{
JMEM_POOLS_STAT_NEW_ALLOC ();
return (void *) jmem_heap_alloc_block (8);
}
}
@@ -131,8 +110,6 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
{
const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
JMEM_POOLS_STAT_REUSE ();
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_p->next_p;
@@ -143,7 +120,6 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
}
else
{
JMEM_POOLS_STAT_NEW_ALLOC ();
return (void *) jmem_heap_alloc_block (16);
}
#else /* !JERRY_CPOINTER_32_BIT */
@@ -183,8 +159,6 @@ jmem_pools_free (void *chunk_p, /**< pointer to the chunk */
}
VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size);
JMEM_POOLS_STAT_FREE_POOL ();
} /* jmem_pools_free */
/**
@@ -203,7 +177,6 @@ jmem_pools_collect_empty (void)
VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_heap_free_block (chunk_p, 8);
JMEM_POOLS_STAT_DEALLOC ();
chunk_p = next_p;
}
@@ -218,122 +191,11 @@ jmem_pools_collect_empty (void)
VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_heap_free_block (chunk_p, 16);
JMEM_POOLS_STAT_DEALLOC ();
chunk_p = next_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
} /* jmem_pools_collect_empty */
#ifdef JMEM_STATS
/**
* Get pools memory usage statistics
*/
void
jmem_pools_get_stats (jmem_pools_stats_t *out_pools_stats_p) /**< [out] pools' stats */
{
JERRY_ASSERT (out_pools_stats_p != NULL);
*out_pools_stats_p = JERRY_CONTEXT (jmem_pools_stats);
} /* jmem_pools_get_stats */
/**
* Reset peak values in memory usage statistics
*/
void
jmem_pools_stats_reset_peak (void)
{
JERRY_CONTEXT (jmem_pools_stats).peak_pools_count = JERRY_CONTEXT (jmem_pools_stats.pools_count);
} /* jmem_pools_stats_reset_peak */
/**
* Print pools memory usage statistics
*/
void
jmem_pools_stats_print (void)
{
jmem_pools_stats_t *pools_stats = &JERRY_CONTEXT (jmem_pools_stats);
JERRY_DEBUG_MSG ("Pools stats:\n"
" Pool chunks: %zu\n"
" Peak pool chunks: %zu\n"
" Free chunks: %zu\n"
" Pool reuse ratio: %zu.%04zu\n",
pools_stats->pools_count,
pools_stats->peak_pools_count,
pools_stats->free_chunks,
pools_stats->reused_count / pools_stats->new_alloc_count,
pools_stats->reused_count % pools_stats->new_alloc_count * 10000 / pools_stats->new_alloc_count);
} /* jmem_pools_stats_print */
/**
* Account for allocation of new pool chunk
*/
static void
jmem_pools_stat_new_alloc (void)
{
jmem_pools_stats_t *pools_stats = &JERRY_CONTEXT (jmem_pools_stats);
pools_stats->pools_count++;
pools_stats->new_alloc_count++;
if (pools_stats->pools_count > pools_stats->peak_pools_count)
{
pools_stats->peak_pools_count = pools_stats->pools_count;
}
if (pools_stats->pools_count > pools_stats->global_peak_pools_count)
{
pools_stats->global_peak_pools_count = pools_stats->pools_count;
}
} /* jmem_pools_stat_new_alloc */
/**
* Account for reuse of pool chunk
*/
static void
jmem_pools_stat_reuse (void)
{
jmem_pools_stats_t *pools_stats = &JERRY_CONTEXT (jmem_pools_stats);
pools_stats->pools_count++;
pools_stats->free_chunks--;
pools_stats->reused_count++;
if (pools_stats->pools_count > pools_stats->peak_pools_count)
{
pools_stats->peak_pools_count = pools_stats->pools_count;
}
if (pools_stats->pools_count > pools_stats->global_peak_pools_count)
{
pools_stats->global_peak_pools_count = pools_stats->pools_count;
}
} /* jmem_pools_stat_reuse */
/**
* Account for freeing a chunk
*/
static void
jmem_pools_stat_free_pool (void)
{
jmem_pools_stats_t *pools_stats = &JERRY_CONTEXT (jmem_pools_stats);
JERRY_ASSERT (pools_stats->pools_count > 0);
pools_stats->pools_count--;
pools_stats->free_chunks++;
} /* jmem_pools_stat_free_pool */
/**
* Account for freeing a chunk
*/
static void
jmem_pools_stat_dealloc (void)
{
JERRY_CONTEXT (jmem_pools_stats).free_chunks--;
} /* jmem_pools_stat_dealloc */
#endif /* JMEM_STATS */
#undef VALGRIND_NOACCESS_SPACE
#undef VALGRIND_UNDEFINED_SPACE
#undef VALGRIND_DEFINED_SPACE
+26 -24
View File
@@ -119,30 +119,46 @@ void jmem_heap_free_block (void *ptr, const size_t size);
*/
typedef struct
{
size_t size; /**< size */
size_t size; /**< heap total size */
size_t allocated_bytes; /**< currently allocated bytes */
size_t peak_allocated_bytes; /**< peak allocated bytes */
size_t global_peak_allocated_bytes; /**< non-resettable peak allocated bytes */
size_t waste_bytes; /**< bytes waste due to blocks filled partially
* and due to block headers */
size_t peak_waste_bytes; /**< peak bytes waste */
size_t global_peak_waste_bytes; /**< non-resettable peak bytes waste */
size_t waste_bytes; /**< bytes waste due to blocks filled partially */
size_t peak_waste_bytes; /**< peak wasted bytes */
size_t byte_code_bytes; /**< allocated memory for byte code */
size_t peak_byte_code_bytes; /**< peak allocated memory for byte code */
size_t string_bytes; /**< allocated memory for strings */
size_t peak_string_bytes; /**< peak allocated memory for strings */
size_t object_bytes; /**< allocated memory for objects */
size_t peak_object_bytes; /**< peak allocated memory for objects */
size_t property_bytes; /**< allocated memory for properties */
size_t peak_property_bytes; /**< peak allocated memory for properties */
size_t skip_count; /**< Number of skip-aheads during insertion of free block */
size_t nonskip_count; /**< Number of times we could not skip ahead during
* free block insertion */
size_t alloc_count; /**< Number of allocation of new pool chunk */
size_t alloc_count; /**< number of memory allocations */
size_t free_count; /**< number of memory frees */
size_t alloc_iter_count; /**< Number of iterations required for allocations */
size_t free_count; /**< Number of freeing of pool chunk */
size_t free_iter_count; /**< Number of iterations required for inserting free blocks */
} jmem_heap_stats_t;
void jmem_stats_reset_peak (void);
void jmem_stats_print (void);
void jmem_stats_allocate_byte_code_bytes (size_t property_size);
void jmem_stats_free_byte_code_bytes (size_t property_size);
void jmem_stats_allocate_string_bytes (size_t string_size);
void jmem_stats_free_string_bytes (size_t string_size);
void jmem_stats_allocate_object_bytes (size_t object_size);
void jmem_stats_free_object_bytes (size_t string_size);
void jmem_stats_allocate_property_bytes (size_t property_size);
void jmem_stats_free_property_bytes (size_t property_size);
#endif /* JMEM_STATS */
jmem_cpointer_t jmem_compress_pointer (const void *pointer_p) __attr_pure___;
@@ -231,20 +247,6 @@ void jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t s
* \addtogroup poolman Memory pool manager
* @{
*/
#ifdef JMEM_STATS
/**
* Pools' memory usage statistics
*/
typedef struct
{
size_t pools_count; /**< pools' count */
size_t peak_pools_count; /**< peak pools' count */
size_t global_peak_pools_count; /**< non-resettable peak pools' count */
size_t free_chunks; /**< free chunks count */
size_t new_alloc_count; /**< Number of newly allocated pool chunks */
size_t reused_count; /**< Number of reused pool chunks */
} jmem_pools_stats_t;
#endif /* JMEM_STATS */
void *jmem_pools_alloc (size_t size);
void jmem_pools_free (void *chunk_p, size_t size);