From f4fbf0b0b56ae238b91788487d5bccc04adce511 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Tue, 16 May 2017 02:52:12 +0200 Subject: [PATCH] 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 --- jerry-core/api/jerry-snapshot.c | 8 ++ jerry-core/api/jerry.c | 14 -- jerry-core/debugger/jerry-debugger.c | 4 + jerry-core/ecma/base/ecma-alloc.c | 133 ++++++++++++++++++- jerry-core/ecma/base/ecma-alloc.h | 36 +++-- jerry-core/ecma/base/ecma-globals.h | 1 - jerry-core/ecma/base/ecma-helpers-string.c | 18 +-- jerry-core/ecma/base/ecma-helpers.c | 4 + jerry-core/ecma/base/ecma-literal-storage.c | 3 +- jerry-core/include/jerryscript-core.h | 2 +- jerry-core/jcontext/jcontext.h | 1 - jerry-core/jmem/jmem-allocator-internal.h | 2 - jerry-core/jmem/jmem-allocator.c | 128 ++++++++++++++++-- jerry-core/jmem/jmem-heap.c | 38 +++--- jerry-core/jmem/jmem-poolman.c | 138 -------------------- jerry-core/jmem/jmem.h | 50 +++---- jerry-core/parser/js/js-parser.c | 4 + jerry-main/main-unix.c | 9 -- 18 files changed, 347 insertions(+), 246 deletions(-) diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index 9a6dccdc2..fd1d3bdad 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -373,6 +373,10 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data { bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (code_size); +#ifdef JMEM_STATS + jmem_stats_allocate_byte_code_bytes (code_size); +#endif /* JMEM_STATS */ + memcpy (bytecode_p, snapshot_data_p + offset, code_size); } else @@ -384,6 +388,10 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (total_size); +#ifdef JMEM_STATS + jmem_stats_allocate_byte_code_bytes (total_size); +#endif /* JMEM_STATS */ + memcpy (bytecode_p, snapshot_data_p + offset, code_size); bytecode_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG); diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 6a48c6d18..1e42452a4 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -52,7 +52,6 @@ JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY && (int) ECMA_INIT_SHOW_OPCODES == (int) JERRY_INIT_SHOW_OPCODES && (int) ECMA_INIT_SHOW_REGEXP_OPCODES == (int) JERRY_INIT_SHOW_REGEXP_OPCODES && (int) ECMA_INIT_MEM_STATS == (int) JERRY_INIT_MEM_STATS - && (int) ECMA_INIT_MEM_STATS_SEPARATE == (int) JERRY_INIT_MEM_STATS_SEPARATE && (int) ECMA_INIT_DEBUGGER == (int) JERRY_INIT_DEBUGGER, ecma_init_flag_t_must_be_equal_to_jerry_init_flag_t); @@ -152,11 +151,6 @@ jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */ /* Zero out all members. */ memset (&JERRY_CONTEXT (JERRY_CONTEXT_FIRST_MEMBER), 0, sizeof (jerry_context_t)); - if (flags & JERRY_INIT_MEM_STATS_SEPARATE) - { - flags |= JERRY_INIT_MEM_STATS; - } - JERRY_CONTEXT (jerry_init_flags) = flags; jerry_make_api_available (); @@ -327,14 +321,6 @@ jerry_parse (const jerry_char_t *source_p, /**< script source */ ecma_free_value (parse_status); -#ifdef JMEM_STATS - if (JERRY_CONTEXT (jerry_init_flags) & JERRY_INIT_MEM_STATS_SEPARATE) - { - jmem_stats_print (); - jmem_stats_reset_peak (); - } -#endif /* JMEM_STATS */ - is_strict = ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0); ecma_object_t *lex_env_p = ecma_get_global_environment (); ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p, diff --git a/jerry-core/debugger/jerry-debugger.c b/jerry-core/debugger/jerry-debugger.c index 36c10759c..8628aa97c 100644 --- a/jerry-core/debugger/jerry-debugger.c +++ b/jerry-core/debugger/jerry-debugger.c @@ -318,6 +318,10 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer the the rec JERRY_CONTEXT (debugger_byte_code_free_tail) = ECMA_NULL_POINTER; } +#ifdef JMEM_STATS + jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); +#endif /* JMEM_STATS */ + jmem_heap_free_block (byte_code_free_p, ((size_t) byte_code_free_p->size) << JMEM_ALIGNMENT_LOG); return true; diff --git a/jerry-core/ecma/base/ecma-alloc.c b/jerry-core/ecma/base/ecma-alloc.c index 3bbcdf275..cdff7c6d3 100644 --- a/jerry-core/ecma/base/ecma-alloc.c +++ b/jerry-core/ecma/base/ecma-alloc.c @@ -80,12 +80,37 @@ JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <= ALLOC (ecma_type) \ DEALLOC (ecma_type) -DECLARE_ROUTINES_FOR (object) DECLARE_ROUTINES_FOR (number) DECLARE_ROUTINES_FOR (collection_header) DECLARE_ROUTINES_FOR (collection_chunk) -DECLARE_ROUTINES_FOR (string) -DECLARE_ROUTINES_FOR (getter_setter_pointers) + +/** + * Allocate memory for ecma-object + * + * @return pointer to allocated memory + */ +inline ecma_object_t * __attr_always_inline___ +ecma_alloc_object (void) +{ +#ifdef JMEM_STATS + jmem_stats_allocate_object_bytes (sizeof (ecma_object_t)); +#endif /* JMEM_STATS */ + + return (ecma_object_t *) jmem_pools_alloc (sizeof (ecma_object_t)); +} /* ecma_alloc_object */ + +/** + * Dealloc memory from an ecma-object + */ +inline void __attr_always_inline___ +ecma_dealloc_object (ecma_object_t *object_p) /**< object to be freed */ +{ +#ifdef JMEM_STATS + jmem_stats_free_object_bytes (sizeof (ecma_object_t)); +#endif /* JMEM_STATS */ + + jmem_pools_free (object_p, sizeof (ecma_object_t)); +} /* ecma_dealloc_object */ /** * Allocate memory for extended object @@ -95,6 +120,10 @@ DECLARE_ROUTINES_FOR (getter_setter_pointers) inline ecma_extended_object_t * __attr_always_inline___ ecma_alloc_extended_object (size_t size) /**< size of object */ { +#ifdef JMEM_STATS + jmem_stats_allocate_object_bytes (size); +#endif /* JMEM_STATS */ + return jmem_heap_alloc_block (size); } /* ecma_alloc_extended_object */ @@ -105,9 +134,99 @@ inline void __attr_always_inline___ ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< property pair to be freed */ size_t size) /**< size of object */ { +#ifdef JMEM_STATS + jmem_stats_free_object_bytes (size); +#endif /* JMEM_STATS */ + jmem_heap_free_block (ext_object_p, size); } /* ecma_dealloc_extended_object */ +/** + * Allocate memory for ecma-string descriptor + * + * @return pointer to allocated memory + */ +inline ecma_string_t * __attr_always_inline___ +ecma_alloc_string (void) +{ +#ifdef JMEM_STATS + jmem_stats_allocate_string_bytes (sizeof (ecma_string_t)); +#endif /* JMEM_STATS */ + + return (ecma_string_t *) jmem_pools_alloc (sizeof (ecma_string_t)); +} /* ecma_alloc_string */ + +/** + * Dealloc memory from ecma-string descriptor + */ +inline void __attr_always_inline___ +ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */ +{ +#ifdef JMEM_STATS + jmem_stats_free_string_bytes (sizeof (ecma_string_t)); +#endif /* JMEM_STATS */ + + jmem_pools_free (string_p, sizeof (ecma_string_t)); +} /* ecma_dealloc_string */ + +/** + * Allocate memory for string with character data + * + * @return pointer to allocated memory + */ +inline ecma_string_t * __attr_always_inline___ +ecma_alloc_string_buffer (size_t size) /**< size of string */ +{ +#ifdef JMEM_STATS + jmem_stats_allocate_string_bytes (size); +#endif /* JMEM_STATS */ + + return jmem_heap_alloc_block (size); +} /* ecma_alloc_string_buffer */ + +/** + * Dealloc memory of a string with character data + */ +inline void __attr_always_inline___ +ecma_dealloc_string_buffer (ecma_string_t *string_p, /**< string with data */ + size_t size) /**< size of string */ +{ +#ifdef JMEM_STATS + jmem_stats_free_string_bytes (size); +#endif /* JMEM_STATS */ + + jmem_heap_free_block (string_p, size); +} /* ecma_dealloc_string_buffer */ + +/** + * Allocate memory for getter-setter pointer pair + * + * @return pointer to allocated memory + */ +inline ecma_getter_setter_pointers_t * __attr_always_inline___ +ecma_alloc_getter_setter_pointers (void) +{ +#ifdef JMEM_STATS + jmem_stats_allocate_property_bytes (sizeof (ecma_property_pair_t)); +#endif /* JMEM_STATS */ + + return (ecma_getter_setter_pointers_t *) jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t)); +} /* ecma_alloc_getter_setter_pointers */ + +/** + * Dealloc memory from getter-setter pointer pair + */ +inline void __attr_always_inline___ +ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *getter_setter_pointers_p) /**< pointer pair + * to be freed */ +{ +#ifdef JMEM_STATS + jmem_stats_free_property_bytes (sizeof (ecma_property_pair_t)); +#endif /* JMEM_STATS */ + + jmem_pools_free (getter_setter_pointers_p, sizeof (ecma_getter_setter_pointers_t)); +} /* ecma_dealloc_getter_setter_pointers */ + /** * Allocate memory for ecma-property pair * @@ -116,6 +235,10 @@ ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< propert inline ecma_property_pair_t * __attr_always_inline___ ecma_alloc_property_pair (void) { +#ifdef JMEM_STATS + jmem_stats_allocate_property_bytes (sizeof (ecma_property_pair_t)); +#endif /* JMEM_STATS */ + return jmem_heap_alloc_block (sizeof (ecma_property_pair_t)); } /* ecma_alloc_property_pair */ @@ -125,6 +248,10 @@ ecma_alloc_property_pair (void) inline void __attr_always_inline___ ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */ { +#ifdef JMEM_STATS + jmem_stats_free_property_bytes (sizeof (ecma_property_pair_t)); +#endif /* JMEM_STATS */ + jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t)); } /* ecma_dealloc_property_pair */ diff --git a/jerry-core/ecma/base/ecma-alloc.h b/jerry-core/ecma/base/ecma-alloc.h index 435ed54c2..16ebf8316 100644 --- a/jerry-core/ecma/base/ecma-alloc.h +++ b/jerry-core/ecma/base/ecma-alloc.h @@ -37,6 +37,18 @@ ecma_object_t *ecma_alloc_object (void); */ void ecma_dealloc_object (ecma_object_t *object_p); +/** + * Allocate memory for extended object + * + * @return pointer to allocated memory + */ +ecma_extended_object_t *ecma_alloc_extended_object (size_t size); + +/** + * Dealloc memory of an extended object + */ +void ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, size_t size); + /** * Allocate memory for ecma-number * @@ -85,6 +97,18 @@ ecma_string_t *ecma_alloc_string (void); */ void ecma_dealloc_string (ecma_string_t *string_p); +/** + * Allocate memory for string with character data + * + * @return pointer to allocated memory + */ +ecma_string_t *ecma_alloc_string_buffer (size_t size); + +/** + * Dealloc memory of a string with character data + */ +void ecma_dealloc_string_buffer (ecma_string_t *string_p, size_t size); + /** * Allocate memory for getter-setter pointer pair * @@ -97,18 +121,6 @@ ecma_getter_setter_pointers_t *ecma_alloc_getter_setter_pointers (void); */ void ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *getter_setter_pointers_p); -/* - * Allocate memory for extended object - * - * @return pointer to allocated memory - */ -ecma_extended_object_t *ecma_alloc_extended_object (size_t size); - -/** - * Dealloc memory of an extended object - */ -void ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, size_t size); - /** * Allocate memory for ecma-property pair * diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index e2f0b8757..65bb0c29b 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -62,7 +62,6 @@ typedef enum ECMA_INIT_SHOW_OPCODES = (1u << 0), /**< dump byte-code to log after parse */ ECMA_INIT_SHOW_REGEXP_OPCODES = (1u << 1), /**< dump regexp byte-code to log after compilation */ ECMA_INIT_MEM_STATS = (1u << 2), /**< dump memory statistics */ - ECMA_INIT_MEM_STATS_SEPARATE = (1u << 3), /**< dump memory statistics and reset peak values after parse */ ECMA_INIT_DEBUGGER = (1u << 4), /**< enable all features required by debugging */ } ecma_init_flag_t; diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 582c534d2..196fd9bbe 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -187,7 +187,7 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri if (likely (string_size <= UINT16_MAX)) { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + string_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + string_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -198,7 +198,7 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri } else { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + string_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_long_string_t) + string_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -275,7 +275,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string if (likely (string_size <= UINT16_MAX)) { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + converted_string_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + converted_string_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -286,7 +286,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string } else { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + converted_string_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_long_string_t) + converted_string_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -428,7 +428,7 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */ && lit_is_ex_utf8_string_magic (str_buf, str_size) == lit_get_magic_string_ex_count ()); #endif /* !JERRY_NDEBUG */ - ecma_string_t *string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + str_size); + ecma_string_t *string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + str_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->hash = lit_utf8_string_calc_hash (str_buf, str_size); @@ -671,7 +671,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ if (likely (new_size <= UINT16_MAX)) { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_string_t) + new_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + new_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -682,7 +682,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ } else { - string_desc_p = jmem_heap_alloc_block (sizeof (ecma_long_string_t) + new_size); + string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_long_string_t) + new_size); string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE; string_desc_p->u.common_uint32_field = 0; @@ -763,14 +763,14 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ } #endif /* !JERRY_NDEBUG */ - jmem_heap_free_block (string_p, string_p->u.utf8_string.size + sizeof (ecma_string_t)); + ecma_dealloc_string_buffer (string_p, string_p->u.utf8_string.size + sizeof (ecma_string_t)); return; } case ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING: { JERRY_ASSERT (string_p->u.long_utf8_string_size > UINT16_MAX); - jmem_heap_free_block (string_p, string_p->u.long_utf8_string_size + sizeof (ecma_long_string_t)); + ecma_dealloc_string_buffer (string_p, string_p->u.long_utf8_string_size + sizeof (ecma_long_string_t)); return; } case ECMA_STRING_CONTAINER_UINT32_IN_DESC: diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index e49043986..f2e3382b8 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -1424,6 +1424,10 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ return; } #endif /* JERRY_DEBUGGER */ + +#ifdef JMEM_STATS + jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); +#endif /* JMEM_STATS */ } else { diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c index 54d423487..c0d40e205 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ecma-alloc.h" #include "ecma-literal-storage.h" #include "ecma-helpers.h" #include "jcontext.h" @@ -179,7 +180,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp); } - ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc (sizeof (ecma_string_t)); + ecma_string_t *string_p = ecma_alloc_string (); string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER; string_p->u.lit_number = num; diff --git a/jerry-core/include/jerryscript-core.h b/jerry-core/include/jerryscript-core.h index 0c9a3001b..f50f042d7 100644 --- a/jerry-core/include/jerryscript-core.h +++ b/jerry-core/include/jerryscript-core.h @@ -55,7 +55,7 @@ typedef enum JERRY_INIT_SHOW_OPCODES = (1u << 0), /**< dump byte-code to log after parse */ JERRY_INIT_SHOW_REGEXP_OPCODES = (1u << 1), /**< dump regexp byte-code to log after compilation */ JERRY_INIT_MEM_STATS = (1u << 2), /**< dump memory statistics */ - JERRY_INIT_MEM_STATS_SEPARATE = (1u << 3), /**< dump memory statistics and reset peak values after parse */ + JERRY_INIT_MEM_STATS_SEPARATE = (1u << 3), /**< deprecated, an unused placeholder now */ JERRY_INIT_DEBUGGER = (1u << 4), /**< enable all features required by debugging */ } jerry_init_flag_t; diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 16342ce47..df24c9bd3 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -106,7 +106,6 @@ typedef struct #ifdef JMEM_STATS jmem_heap_stats_t jmem_heap_stats; /**< heap's memory usage statistics */ - jmem_pools_stats_t jmem_pools_stats; /**< pools' memory usage statistics */ #endif /* JMEM_STATS */ #ifdef JERRY_VALGRIND_FREYA diff --git a/jerry-core/jmem/jmem-allocator-internal.h b/jerry-core/jmem/jmem-allocator-internal.h index a76b1672b..c2e6d737d 100644 --- a/jerry-core/jmem/jmem-allocator-internal.h +++ b/jerry-core/jmem/jmem-allocator-internal.h @@ -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 */ diff --git a/jerry-core/jmem/jmem-allocator.c b/jerry-core/jmem/jmem-allocator.c index a3400b924..db3bb8fbe 100644 --- a/jerry-core/jmem/jmem-allocator.c +++ b/jerry-core/jmem/jmem-allocator.c @@ -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 */ diff --git a/jerry-core/jmem/jmem-heap.c b/jerry-core/jmem/jmem-heap.c index fd804a730..45b62cb36 100644 --- a/jerry-core/jmem/jmem-heap.c +++ b/jerry-core/jmem/jmem-heap.c @@ -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 */ /** diff --git a/jerry-core/jmem/jmem-poolman.c b/jerry-core/jmem/jmem-poolman.c index 1710696d2..e9092b247 100644 --- a/jerry-core/jmem/jmem-poolman.c +++ b/jerry-core/jmem/jmem-poolman.c @@ -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 diff --git a/jerry-core/jmem/jmem.h b/jerry-core/jmem/jmem.h index 5168adf2b..111c09c2f 100644 --- a/jerry-core/jmem/jmem.h +++ b/jerry-core/jmem/jmem.h @@ -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); diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 09c7a7261..b38ad15eb 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1600,6 +1600,10 @@ parser_post_processing (parser_context_t *context_p) /**< context */ compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size); +#ifdef JMEM_STATS + jmem_stats_allocate_byte_code_bytes (total_size); +#endif /* JMEM_STATS */ + byte_code_p = (uint8_t *) compiled_code_p; compiled_code_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG); compiled_code_p->refs = 1; diff --git a/jerry-main/main-unix.c b/jerry-main/main-unix.c index e8dcd8731..e391e8ec7 100644 --- a/jerry-main/main-unix.c +++ b/jerry-main/main-unix.c @@ -97,7 +97,6 @@ print_help (const char *name) " -h, --help\n" " -v, --version\n" " --mem-stats\n" - " --mem-stats-separate\n" " --parse-only\n" " --show-opcodes\n" " --show-regexp-opcodes\n" @@ -411,14 +410,6 @@ main (int argc, flags |= JERRY_INIT_MEM_STATS; } } - else if (!strcmp ("--mem-stats-separate", argv[i])) - { - if (check_feature (JERRY_FEATURE_MEM_STATS, argv[i])) - { - jerry_port_default_set_log_level (JERRY_LOG_LEVEL_DEBUG); - flags |= JERRY_INIT_MEM_STATS_SEPARATE; - } - } else if (!strcmp ("--parse-only", argv[i])) { is_parse_only = true;