From 79bc5d02208935bad827e5c2a42a0fd2d2ef6e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20K=C3=A1d=C3=A1r?= Date: Wed, 27 Jul 2016 16:35:25 +0200 Subject: [PATCH] Bugfixes related to low memory conditions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Bugfix for removing property hashmap in ecma_gc_run. - Fixed bug in ecma_create_property() caused by the new property pair allocation. JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu --- jerry-core/ecma/base/ecma-gc.c | 13 ++++++---- jerry-core/ecma/base/ecma-helpers.c | 40 +++++++++++++++++++---------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 8731b02a6..707a4ed47 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -549,12 +549,15 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ { JERRY_ASSERT (ecma_gc_is_object_visited (obj_iter_p)); - ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p); - - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) + if (!ecma_is_lexical_environment (obj_iter_p) + || ecma_get_lex_env_type (obj_iter_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { - ecma_property_hashmap_free (obj_iter_p); + ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p); + if (prop_iter_p != NULL + && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) + { + ecma_property_hashmap_free (obj_iter_p); + } } obj_iter_p = ecma_gc_get_object_next (obj_iter_p); diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index f38072c3e..948d6aaf7 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -401,26 +401,21 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); jmem_cpointer_t *property_list_head_p = &object_p->property_list_or_bound_object_cp; - bool has_hashmap = false; - - if (*property_list_head_p != ECMA_NULL_POINTER) - { - /* If the first entry is a hashmap, it is skipped. */ - ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, - *property_list_head_p); - - if (ECMA_PROPERTY_GET_TYPE (first_property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) - { - property_list_head_p = &first_property_p->next_property_cp; - has_hashmap = true; - } - } if (*property_list_head_p != ECMA_NULL_POINTER) { /* If the first entry is free (deleted), it is reused. */ ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, *property_list_head_p); + bool has_hashmap = false; + + if (ECMA_PROPERTY_GET_TYPE (first_property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) + { + property_list_head_p = &first_property_p->next_property_cp; + first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + *property_list_head_p); + has_hashmap = true; + } JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p)); @@ -457,6 +452,23 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ /* Otherwise we create a new property pair and use its second value. */ ecma_property_pair_t *first_property_pair_p = ecma_alloc_property_pair (); + /* Need to query property_list_head_p again and recheck the existennce + * of property hasmap, because ecma_alloc_property_pair may delete them. */ + property_list_head_p = &object_p->property_list_or_bound_object_cp; + bool has_hashmap = false; + + if (*property_list_head_p != ECMA_NULL_POINTER) + { + ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, + *property_list_head_p); + + if (ECMA_PROPERTY_GET_TYPE (first_property_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) + { + property_list_head_p = &first_property_p->next_property_cp; + has_hashmap = true; + } + } + /* Just copy the previous value (no need to decompress, compress). */ first_property_pair_p->header.next_property_cp = *property_list_head_p; first_property_pair_p->header.types[0].type_and_flags = ECMA_PROPERTY_TYPE_DELETED;