diff --git a/jerry-core/api/jerry_literal_cache.h b/jerry-core/api/jerry_literal_cache.h new file mode 100755 index 0000000000000000000000000000000000000000..580216a23f8c7be2bb93bf845c4baa3fb8185116 --- /dev/null +++ b/jerry-core/api/jerry_literal_cache.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: jerry literal cache definition + * Author: Harmony OS Software group + * Create: 2020-11-19 + */ +#ifndef JERRY_LITERAL_CACHE_H +#define JERRY_LITERAL_CACHE_H + +#include + +void InitJerryLiteralCache(void); + +void ClearJerryLiteralCache(void); + +void AddJerryLiteralCache(int32_t hash, void *p); + +void DelJerryLiteralCache(int32_t hash); + +void *GetJerryLiteralCache(int32_t hash); +#endif \ No newline at end of file diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c old mode 100644 new mode 100755 index 244caa821c1f97e63122fb422111d49717028e57..a28006621214fe3050499fa4dd5855f60c1dc508 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -1342,6 +1342,18 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ ecma_dealloc_extended_object (object_p, ext_object_size); } /* ecma_gc_free_object */ +bool g_isGCEnabled = true; +void EnableGC() +{ + g_isGCEnabled = true; + ecma_gc_run(); +} + +void DisableGC() +{ + g_isGCEnabled = false; +} + /** * Run garbage collection, freeing objects that are no longer referenced. */ @@ -1354,6 +1366,10 @@ ecma_gc_run (void) JERRY_CONTEXT (ecma_gc_new_objects) = 0; + if (!g_isGCEnabled) { + return; + } + ecma_object_t black_list_head; black_list_head.gc_next_cp = JMEM_CP_NULL; ecma_object_t *black_end_p = &black_list_head; diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c old mode 100644 new mode 100755 index 4c94038d20babe6eef4926e4eb72a82383430973..21bfadc0df77c2f83bacaafdef5b4c7bc0984127 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -293,7 +293,7 @@ ecma_new_ecma_string_from_utf8_buffer (lit_utf8_size_t length, /**< length of th * @return pointer to ecma string with the special representation * NULL, if there is no special representation for the string */ -static ecma_string_t * +ecma_string_t * ecma_find_special_string (const lit_utf8_byte_t *string_p, /**< utf8 string */ lit_utf8_size_t string_size) /**< string size */ { @@ -360,6 +360,46 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri return string_desc_p; } /* ecma_new_ecma_string_from_utf8 */ +static ecma_long_utf8_string_t g_literalStringCache; + +ecma_string_t * ecma_new_nonref_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t size) +{ + ecma_length_t length = lit_utf8_string_length (string_p, size); + + if (JERRY_LIKELY (size <= UINT16_MAX)) + { + if (JERRY_LIKELY (length != size)) + { + JERRY_ASSERT (length < size); + ecma_utf8_string_t *string_desc_p; + string_desc_p = (ecma_utf8_string_t *)&g_literalStringCache; + string_desc_p->header.refs_and_container = ECMA_STRING_CONTAINER_HEAP_UTF8_STRING | ECMA_STRING_REF_ONE; + string_desc_p->header.u.hash = lit_utf8_string_calc_hash (string_p, size); + string_desc_p->size = (uint16_t) size; + string_desc_p->length = (uint16_t) length; + + return (ecma_string_t *) string_desc_p; + } + + ecma_ascii_string_t *string_desc_p; + string_desc_p = (ecma_ascii_string_t *)&g_literalStringCache; + string_desc_p->header.refs_and_container = ECMA_STRING_CONTAINER_HEAP_ASCII_STRING | ECMA_STRING_REF_ONE; + string_desc_p->header.u.hash = lit_utf8_string_calc_hash (string_p, size); + string_desc_p->size = (uint16_t) size; + + return (ecma_string_t *) string_desc_p; + } + + ecma_long_utf8_string_t *string_desc_p; + string_desc_p = (ecma_long_utf8_string_t *)&g_literalStringCache; + string_desc_p->header.refs_and_container = ECMA_STRING_CONTAINER_HEAP_LONG_UTF8_STRING | ECMA_STRING_REF_ONE; + string_desc_p->header.u.hash = lit_utf8_string_calc_hash (string_p, size); + string_desc_p->size = size; + string_desc_p->length = length; + + return (ecma_string_t *) string_desc_p; +} + /** * Allocate a new ecma-string and initialize it from the utf8 string argument. * All 4-bytes long unicode sequences are converted into two 3-bytes long sequences. @@ -1662,19 +1702,20 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /**< ecma-st const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p; lit_utf8_size_t utf8_string1_size, utf8_string2_size; - if (JERRY_LIKELY (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_ASCII_STRING)) - { - utf8_string1_p = ECMA_ASCII_STRING_GET_BUFFER (string1_p); - utf8_string1_size = ((ecma_ascii_string_t *) string1_p)->size; - utf8_string2_p = ECMA_ASCII_STRING_GET_BUFFER (string2_p); - utf8_string2_size = ((ecma_ascii_string_t *) string2_p)->size; - } - else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING) + if (JERRY_LIKELY (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING)) { utf8_string1_p = ECMA_UTF8_STRING_GET_BUFFER (string1_p); utf8_string1_size = ((ecma_utf8_string_t *) string1_p)->size; utf8_string2_p = ECMA_UTF8_STRING_GET_BUFFER (string2_p); utf8_string2_size = ((ecma_utf8_string_t *) string2_p)->size; + + } + else if (ECMA_STRING_GET_CONTAINER(string1_p) == ECMA_STRING_CONTAINER_HEAP_ASCII_STRING) + { + utf8_string1_p = ECMA_ASCII_STRING_GET_BUFFER (string1_p); + utf8_string1_size = ((ecma_ascii_string_t *) string1_p)->size; + utf8_string2_p = ECMA_ASCII_STRING_GET_BUFFER (string2_p); + utf8_string2_size = ((ecma_ascii_string_t *) string2_p)->size; } else { @@ -1745,6 +1786,92 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /**< ecma-string */ return ecma_compare_ecma_strings_longpath (string1_p, string2_p); } /* ecma_compare_ecma_strings */ +static bool JERRY_ATTR_NOINLINE +ecma_compare_ecma_strings_longpath_with_literal (const ecma_string_t *string1_p, /**< ecma_string */ + const ecma_string_t *string2_p, + const lit_utf8_byte_t *chars_p) /**< ecma_string */ +{ + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_GET_CONTAINER (string2_p)); + + const lit_utf8_byte_t *utf8_string2_p; + lit_utf8_size_t utf8_string1_size,utf8_string2_size; + + if(JERRY_LIKELY (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_UTF8_STRING)) + { + utf8_string1_size = ((ecma_utf8_string_t *) string1_p)->size; + utf8_string2_p = ECMA_UTF8_STRING_GET_BUFFER (string2_p); + utf8_string2_size = ((ecma_utf8_string_t *) string2_p)->size; + + } + else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_ASCII_STRING) + { + utf8_string1_size = ((ecma_ascii_string_t *) string1_p)->size; + utf8_string2_p = ECMA_ASCII_STRING_GET_BUFFER (string2_p); + utf8_string2_size = ((ecma_ascii_string_t *) string2_p)->size; + } + else + { + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_HEAP_ASCII_STRING); + + utf8_string1_size = ((ecma_long_utf8_string_t *) string1_p)->size; + utf8_string2_p = ECMA_LONG_UTF8_STRING_GET_BUFFER (string2_p); + utf8_string2_size = ((ecma_long_utf8_string_t *) string2_p)->size; + } + + if (utf8_string1_size != utf8_string2_size) + { + return false; + } + + return !memcmp ((char *) chars_p, (char *) utf8_string2_p, utf8_string1_size); +} /* ecma_compare_ecma_strings_longpath */ + +extern inline bool JERRY_ATTR_ALWAYS_INLINE +ecma_compare_ecma_strings_with_literal (const ecma_string_t *string1_p, /**< ecma-string */ + const ecma_string_t *string2_p,\ + const lit_utf8_byte_t *chars_p) /**< ecma-string */ +{ + JERRY_ASSERT (string1_p != NULL && string2_p != NULL); + + /* Fast paths first. */ + if (string1_p == string2_p) + { + return true; + } + + /* Either string is direct, return with false. */ + if (ECMA_IS_DIRECT_STRING (((uintptr_t) string1_p) | ((uintptr_t) string2_p))) + { + return false; + } + + if (string1_p->u.hash != string2_p->u.hash) + { + return false; + } + + ecma_string_container_t string1_container = ECMA_STRING_GET_CONTAINER (string1_p); + + if (string1_container != ECMA_STRING_GET_CONTAINER (string2_p)) + { + return false; + } + + if (string1_container == ECMA_STRING_CONTAINER_UINT32_IN_DESC) + { + return true; + } + +#if ENABLED (JERRY_ES2015) + if (string1_container == ECMA_STRING_CONTAINER_SYMBOL) + { + return false; + } +#endif /* ENABLED (JERRY_ES2015) */ + + return ecma_compare_ecma_strings_longpath_with_literal (string1_p, string2_p, chars_p); +} /* ecma_compare_ecma_strings */ + /** * Compare two non-direct ecma-strings * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h old mode 100644 new mode 100755 index 83acd6fbc6132296c46fdea87bda16ed0c6ad495..f1c1dc54f36596abff13ed2abd2bb5e6503aa6a9 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -292,6 +292,9 @@ ecma_string_t *ecma_new_map_key_string (ecma_value_t value); bool ecma_prop_name_is_map_key (ecma_string_t *string_p); #endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) || ENABLED (JERRY_ES2015_BUILTIN_SET) */ ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); +ecma_string_t *ecma_new_nonref_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); +ecma_string_t *ecma_find_special_string (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); +bool ecma_compare_ecma_strings_with_literal (const ecma_string_t *string1_p, const ecma_string_t *string2_p, const lit_utf8_byte_t *chars_p); ecma_string_t *ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size); ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit); diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c old mode 100644 new mode 100755 index e4dc58ce3d4e6a6e34e1b350f0ddecadf3f9bbc2..499ce16b20b9b0a4d62b4b2bcdef3568e988b491 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -17,6 +17,20 @@ #include "ecma-literal-storage.h" #include "ecma-helpers.h" #include "jcontext.h" +#include "jerry_literal_cache.h" + +void InitJerryLiteralCache(void) {} + +void ClearJerryLiteralCache(void) {} + +void AddJerryLiteralCache(int32_t hash, void *p) {} + +void DelJerryLiteralCache(int32_t hash) {} + +void *GetJerryLiteralCache(int32_t hash) +{ + return (void*)UINT32_MAX; +} /** \addtogroup ecma ECMA * @{ @@ -73,6 +87,7 @@ ecma_free_string_list (jmem_cpointer_t string_list_cp) /**< string list */ string_list_p->values[i]); JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p)); + DelJerryLiteralCache(string_p->u.hash); ecma_destroy_ecma_string (string_p); } } @@ -131,13 +146,22 @@ ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */ lit_utf8_size_t size) /**< size of the string */ { - ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size); - - if (ECMA_IS_DIRECT_STRING (string_p)) + ecma_string_t *string_desc_p = ecma_find_special_string (chars_p,size); + if ((string_desc_p != NULL) && ECMA_IS_DIRECT_STRING (string_desc_p)) { - return ecma_make_string_value (string_p); + return ecma_make_string_value (string_desc_p); } + ecma_string_t *nonref_string_p = ecma_new_nonref_ecma_string_from_utf8(chars_p, size); + ecma_string_t *cached_literal = (ecma_string_t *)GetJerryLiteralCache(nonref_string_p->u.hash); + if ((cached_literal != NULL) && (cached_literal != (void*)UINT32_MAX)) { + if (ecma_compare_ecma_strings_with_literal (nonref_string_p, cached_literal,chars_p)) { + return ecma_make_string_value (cached_literal); + } + } + + ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size); + jmem_cpointer_t string_list_cp = JERRY_CONTEXT (string_list_first_cp); jmem_cpointer_t *empty_cpointer_p = NULL; @@ -153,8 +177,12 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string { empty_cpointer_p = string_list_p->values + i; } + + if ((cached_literal == NULL) && empty_cpointer_p != NULL) { + break; + } } - else + else if (cached_literal != NULL) { ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, string_list_p->values[i]); @@ -168,6 +196,9 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string } } + if ((cached_literal == NULL) && (empty_cpointer_p != NULL)) { + break; + } string_list_cp = string_list_p->next_cp; } @@ -178,6 +209,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string if (empty_cpointer_p != NULL) { *empty_cpointer_p = result; + AddJerryLiteralCache(string_p->u.hash, string_p); return ecma_make_string_value (string_p); } @@ -193,6 +225,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string new_item_p->next_cp = JERRY_CONTEXT (string_list_first_cp); JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (string_list_first_cp), new_item_p); + AddJerryLiteralCache(string_p->u.hash, string_p); return ecma_make_string_value (string_p); } /* ecma_find_or_create_literal_string */ diff --git a/jerry-core/jmem/jmem-heap.c b/jerry-core/jmem/jmem-heap.c old mode 100644 new mode 100755 index 7a5cb5eaaaace5a42257c5d41785617f7adab372..d0fe71e1a76083e34a565daeb58f80d3a59a6e95 --- a/jerry-core/jmem/jmem-heap.c +++ b/jerry-core/jmem/jmem-heap.c @@ -23,6 +23,17 @@ #include "jrt-bit-fields.h" #include "jrt-libc-includes.h" +void *JerryHeapMalloc(uint32_t size) +{ + return NULL; +} +bool JerryHeapFree(void *addr) +{ + return false; +} + +void JerryHeapInit() {} + #define JMEM_ALLOCATOR_INTERNAL #include "jmem-allocator-internal.h" @@ -135,6 +146,18 @@ jmem_heap_finalize (void) static void * JERRY_ATTR_HOT jmem_heap_alloc (const size_t size) /**< size of requested block */ { + if (size > 8 && size <= 24) { + void *data_space_p = JerryHeapMalloc (size); + if (data_space_p != NULL) + { + JERRY_CONTEXT (jmem_heap_allocated_size) += size; + while(JERRY_CONTEXT(jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit)) + { + JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT; + } + return data_space_p; + } + } #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) /* Align size. */ const size_t required_size = ((size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT) * JMEM_ALIGNMENT; @@ -470,6 +493,18 @@ jmem_heap_free_block_internal (void *ptr, /**< pointer to beginning of data spac JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_limit) >= JERRY_CONTEXT (jmem_heap_allocated_size)); JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) > 0); + if (JerryHeapFree(ptr)) { + JERRY_CONTEXT (jmem_heap_allocated_size) -= size; + + while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT(jmem_heap_limit)) + { + JERRY_CONTEXT(jmem_heap_limit) -= CONFIG_GC_LIMIT; + } + + JERRY_ASSERT (JERRY_CONTEXT(jmem_heap_limit) >= JERRY_CONTEXT(jmem_heap_allocated_size)); + return; + } + #if !ENABLED (JERRY_SYSTEM_ALLOCATOR) /* checking that ptr points to the heap */ JERRY_ASSERT (jmem_is_heap_pointer (ptr)); @@ -506,186 +541,22 @@ jmem_heap_realloc_block (void *ptr, /**< memory region to reallocate */ const size_t old_size, /**< current size of the region */ const size_t new_size) /**< desired new size */ { -#if !ENABLED (JERRY_SYSTEM_ALLOCATOR) - JERRY_ASSERT (jmem_is_heap_pointer (ptr)); - JERRY_ASSERT ((uintptr_t) ptr % JMEM_ALIGNMENT == 0); - JERRY_ASSERT (old_size != 0); - JERRY_ASSERT (new_size != 0); - - jmem_heap_free_t * const block_p = (jmem_heap_free_t *) ptr; - const size_t aligned_new_size = (new_size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT; - const size_t aligned_old_size = (old_size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT; - - if (aligned_old_size == aligned_new_size) - { - JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size); - JMEM_HEAP_STAT_FREE (old_size); - JMEM_HEAP_STAT_ALLOC (new_size); - return block_p; - } - - if (aligned_new_size < aligned_old_size) - { - JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size); - JMEM_HEAP_STAT_FREE (old_size); - JMEM_HEAP_STAT_ALLOC (new_size); - jmem_heap_insert_block ((jmem_heap_free_t *) ((uint8_t *) block_p + aligned_new_size), - jmem_heap_find_prev (block_p), - aligned_old_size - aligned_new_size); - - JERRY_CONTEXT (jmem_heap_allocated_size) -= (aligned_old_size - aligned_new_size); - while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT (jmem_heap_limit)) - { - JERRY_CONTEXT (jmem_heap_limit) -= CONFIG_GC_LIMIT; - } - - return block_p; - } - - void *ret_block_p = NULL; - const size_t required_size = aligned_new_size - aligned_old_size; - -#if !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) - if (JERRY_CONTEXT (jmem_heap_allocated_size) + required_size >= JERRY_CONTEXT (jmem_heap_limit)) -#endif /* !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */ - { - ecma_free_unused_memory (JMEM_PRESSURE_LOW); - } - - jmem_heap_free_t *prev_p = jmem_heap_find_prev (block_p); - JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t)); - jmem_heap_free_t * const next_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (prev_p->next_offset); - - /* Check if block can be extended at the end */ - if (((jmem_heap_free_t *) ((uint8_t *) block_p + aligned_old_size)) == next_p) - { - JMEM_VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t)); - - if (required_size <= next_p->size) - { - /* Block can be extended, update the list. */ - if (required_size == next_p->size) - { - prev_p->next_offset = next_p->next_offset; - } - else - { - jmem_heap_free_t *const new_next_p = (jmem_heap_free_t *) ((uint8_t *) next_p + required_size); - JMEM_VALGRIND_DEFINED_SPACE (new_next_p, sizeof (jmem_heap_free_t)); - new_next_p->next_offset = next_p->next_offset; - new_next_p->size = (uint32_t) (next_p->size - required_size); - JMEM_VALGRIND_NOACCESS_SPACE (new_next_p, sizeof (jmem_heap_free_t)); - prev_p->next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (new_next_p); - } - - /* next_p will be marked as undefined space. */ - JMEM_VALGRIND_RESIZE_SPACE (block_p, old_size, new_size); - ret_block_p = block_p; - } - else - { - JMEM_VALGRIND_NOACCESS_SPACE (next_p, sizeof (jmem_heap_free_t)); - } - - JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t)); - } - /* - * Check if block can be extended at the front. - * This is less optimal because we need to copy the data, but still better than allocting a new block. - */ - else if (jmem_heap_get_region_end (prev_p) == block_p) - { - if (required_size <= prev_p->size) - { - if (required_size == prev_p->size) - { - JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t)); - prev_p = jmem_heap_find_prev (prev_p); - JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t)); - prev_p->next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (next_p); - } - else - { - prev_p->size = (uint32_t) (prev_p->size - required_size); - } - - JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t)); - - ret_block_p = (uint8_t *) block_p - required_size; - - /* Mark the the new block as undefined so that we are able to write to it. */ - JMEM_VALGRIND_UNDEFINED_SPACE (ret_block_p, old_size); - /* The blocks are likely to overlap, so mark the old block as defined memory again. */ - JMEM_VALGRIND_DEFINED_SPACE (block_p, old_size); - memmove (ret_block_p, block_p, old_size); - - JMEM_VALGRIND_FREELIKE_SPACE (block_p); - JMEM_VALGRIND_MALLOCLIKE_SPACE (ret_block_p, new_size); - JMEM_VALGRIND_DEFINED_SPACE (ret_block_p, old_size); - } - else - { - JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t)); - } - } - - if (ret_block_p != NULL) - { - /* Managed to extend the block. Update memory usage and the skip pointer. */ - JERRY_CONTEXT (jmem_heap_list_skip_p) = prev_p; - JERRY_CONTEXT (jmem_heap_allocated_size) += required_size; - - while (JERRY_CONTEXT (jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit)) - { - JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT; - } - } - else - { - /* Could not extend block. Allocate new region and copy the data. */ - /* jmem_heap_alloc_block_internal will adjust the allocated_size, but insert_block will not, - so we reduce it here first, so that the limit calculation remains consistent. */ - JERRY_CONTEXT (jmem_heap_allocated_size) -= aligned_old_size; - ret_block_p = jmem_heap_alloc_block_internal (new_size); - - /* jmem_heap_alloc_block_internal may trigger garbage collection, which can create new free blocks - * in the heap structure, so we need to look up the previous block again. */ - prev_p = jmem_heap_find_prev (block_p); - - memcpy (ret_block_p, block_p, old_size); - jmem_heap_insert_block (block_p, prev_p, aligned_old_size); - /* jmem_heap_alloc_block_internal will call JMEM_VALGRIND_MALLOCLIKE_SPACE */ - JMEM_VALGRIND_FREELIKE_SPACE (block_p); - } - - JMEM_HEAP_STAT_FREE (old_size); - JMEM_HEAP_STAT_ALLOC (new_size); - return ret_block_p; -#else /* ENABLED (JERRY_SYSTEM_ALLOCATOR) */ const size_t required_size = new_size - old_size; -#if !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) if (JERRY_CONTEXT (jmem_heap_allocated_size) + required_size >= JERRY_CONTEXT (jmem_heap_limit)) -#endif /* !ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */ { ecma_free_unused_memory (JMEM_PRESSURE_LOW); } - JERRY_CONTEXT (jmem_heap_allocated_size) += required_size; - - while (JERRY_CONTEXT (jmem_heap_allocated_size) >= JERRY_CONTEXT (jmem_heap_limit)) - { - JERRY_CONTEXT (jmem_heap_limit) += CONFIG_GC_LIMIT; - } - - while (JERRY_CONTEXT (jmem_heap_allocated_size) + CONFIG_GC_LIMIT <= JERRY_CONTEXT (jmem_heap_limit)) - { - JERRY_CONTEXT (jmem_heap_limit) -= CONFIG_GC_LIMIT; + void *newBuffer = jmem_heap_alloc_block(new_size); + size_t copySize = (old_size > new_size) ? new_size : old_size; + if (newBuffer) { + memcpy(newBuffer, ptr, copySize); + jmem_heap_free_block(ptr, old_size); + return newBuffer; + }else { + jmem_heap_free_block(ptr, old_size); + return NULL; } - - JMEM_HEAP_STAT_FREE (old_size); - JMEM_HEAP_STAT_ALLOC (new_size); - return realloc (ptr, new_size); -#endif /* !ENABLED (JERRY_SYSTEM_ALLOCATOR) */ } /* jmem_heap_realloc_block */ /**