From 6430a104b32da244d90e35344b12b225042169a9 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Mon, 13 Oct 2014 18:59:07 +0400 Subject: [PATCH] ecma_ref_ecma_string -> ecma_copy_or_ref_ecma_string: copying ecma-string when the string's reference counter reaches maximum value. --- .../ecma-builtin-string-prototype-object.c | 2 +- src/libecmaobjects/ecma-helpers-string.c | 36 +++++++++++++++---- src/libecmaobjects/ecma-helpers-value.c | 8 +++-- src/libecmaobjects/ecma-helpers.c | 4 +-- src/libecmaobjects/ecma-helpers.h | 2 +- src/libecmaoperations/ecma-conversion.c | 2 +- src/libecmaoperations/ecma-reference.c | 2 +- src/libecmaoperations/ecma-string-object.c | 3 +- 8 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/libecmabuiltins/ecma-builtin-string-prototype-object.c b/src/libecmabuiltins/ecma-builtin-string-prototype-object.c index db9eabfea..9316755e5 100644 --- a/src/libecmabuiltins/ecma-builtin-string-prototype-object.c +++ b/src/libecmabuiltins/ecma-builtin-string-prototype-object.c @@ -174,7 +174,7 @@ ecma_builtin_string_prototype_object_to_string (ecma_value_t this) /**< this arg ecma_string_t *prim_value_str_p = ECMA_GET_POINTER (prim_value_prop_p->u.internal_property.value); - ecma_ref_ecma_string (prim_value_str_p); + prim_value_str_p = ecma_copy_or_ref_ecma_string (prim_value_str_p); return ecma_make_normal_completion_value (ecma_make_string_value (prim_value_str_p)); } diff --git a/src/libecmaobjects/ecma-helpers-string.c b/src/libecmaobjects/ecma-helpers-string.c index 5b62e57da..8be1c2270 100644 --- a/src/libecmaobjects/ecma-helpers-string.c +++ b/src/libecmaobjects/ecma-helpers-string.c @@ -265,8 +265,8 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ string_desc_p->length = (ecma_length_t) length; } - ecma_ref_ecma_string (string1_p); - ecma_ref_ecma_string (string2_p); + string1_p = ecma_copy_or_ref_ecma_string (string1_p); + string2_p = ecma_copy_or_ref_ecma_string (string2_p); ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string1_cp, string1_p); ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string2_cp, string2_p); @@ -278,18 +278,40 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */ * Increase reference counter of ecma-string. * * @return pointer to same ecma-string descriptor with increased reference counter + * or the ecma-string's copy with reference counter set to 1 */ -void -ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */ +ecma_string_t* +ecma_copy_or_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */ { JERRY_ASSERT (string_desc_p != NULL); JERRY_ASSERT (string_desc_p->refs > 0); string_desc_p->refs++; - /* Check for overflow */ - JERRY_ASSERT (string_desc_p->refs > 0); -} /* ecma_ref_ecma_string */ + if (unlikely (string_desc_p->refs == 0)) + { + string_desc_p->refs--; + + if (string_desc_p->container == ECMA_STRING_CONTAINER_CHARS_IN_DESC + || string_desc_p->container == ECMA_STRING_CONTAINER_LIT_TABLE + || string_desc_p->container == ECMA_STRING_CONTAINER_UINT32_IN_DESC) + { + ecma_string_t *new_str_p = ecma_alloc_string (); + + *new_str_p = *string_desc_p; + + new_str_p->refs = 1; + + return new_str_p; + } + else + { + JERRY_UNIMPLEMENTED (); + } + } + + return string_desc_p; +} /* ecma_copy_or_ref_ecma_string */ /** * Decrease reference counter and deallocate ecma-string if diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index f121622f5..7c74e720e 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -212,9 +212,13 @@ ecma_copy_value (const ecma_value_t value, /**< ecma-value */ ecma_string_t *string_p = ECMA_GET_POINTER(value.value); JERRY_ASSERT(string_p != NULL); - ecma_ref_ecma_string (string_p); + string_p = ecma_copy_or_ref_ecma_string (string_p); - value_copy = value; + value_copy = (ecma_value_t) + { + .value_type = ECMA_TYPE_STRING + }; + ECMA_SET_NON_NULL_POINTER(value_copy.value, string_p); break; } diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index 2d6fe683b..5d78393ff 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -454,7 +454,7 @@ ecma_create_named_data_property (ecma_object_t *obj_p, /**< object */ prop_p->type = ECMA_PROPERTY_NAMEDDATA; - ecma_ref_ecma_string (name_p); + name_p = ecma_copy_or_ref_ecma_string (name_p); ECMA_SET_NON_NULL_POINTER(prop_p->u.named_data_property.name_p, name_p); prop_p->u.named_data_property.writable = writable; @@ -490,7 +490,7 @@ ecma_create_named_accessor_property (ecma_object_t *obj_p, /**< object */ prop_p->type = ECMA_PROPERTY_NAMEDACCESSOR; - ecma_ref_ecma_string (name_p); + name_p = ecma_copy_or_ref_ecma_string (name_p); ECMA_SET_NON_NULL_POINTER(prop_p->u.named_accessor_property.name_p, name_p); ECMA_SET_POINTER(prop_p->u.named_accessor_property.get_p, get_p); diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 495f53ff4..e39d2230f 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -102,7 +102,7 @@ extern ecma_string_t* ecma_new_ecma_string_from_number (ecma_number_t number); extern ecma_string_t* ecma_new_ecma_string_from_lit_index (literal_index_t lit_index); extern ecma_string_t* ecma_new_ecma_string_from_magic_string_id (ecma_magic_string_id_t id); extern ecma_string_t* ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t *string2_p); -extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p); +extern ecma_string_t* ecma_copy_or_ref_ecma_string (ecma_string_t *string_desc_p); extern void ecma_deref_ecma_string (ecma_string_t *string_p); extern ecma_number_t ecma_string_to_number (const ecma_string_t *str_p); extern ssize_t ecma_string_to_zt_string (const ecma_string_t *string_desc_p, diff --git a/src/libecmaoperations/ecma-conversion.c b/src/libecmaoperations/ecma-conversion.c index ac413368d..8e29c16b2 100644 --- a/src/libecmaoperations/ecma-conversion.c +++ b/src/libecmaoperations/ecma-conversion.c @@ -421,7 +421,7 @@ ecma_op_to_string (ecma_value_t value) /**< ecma-value */ case ECMA_TYPE_STRING: { res_p = ECMA_GET_POINTER (value.value); - ecma_ref_ecma_string (res_p); + res_p = ecma_copy_or_ref_ecma_string (res_p); break; } diff --git a/src/libecmaoperations/ecma-reference.c b/src/libecmaoperations/ecma-reference.c index 5a28af5c3..0aad474fd 100644 --- a/src/libecmaoperations/ecma-reference.c +++ b/src/libecmaoperations/ecma-reference.c @@ -79,7 +79,7 @@ ecma_make_reference (ecma_value_t base, /**< base value */ ecma_string_t *name_p, /**< referenced name */ bool is_strict) /**< strict reference flag */ { - ecma_ref_ecma_string (name_p); + name_p = ecma_copy_or_ref_ecma_string (name_p); ecma_reference_t ref = (ecma_reference_t) { diff --git a/src/libecmaoperations/ecma-string-object.c b/src/libecmaoperations/ecma-string-object.c index e466179c1..80b0f0c7e 100644 --- a/src/libecmaoperations/ecma-string-object.c +++ b/src/libecmaoperations/ecma-string-object.c @@ -118,8 +118,7 @@ ecma_op_string_object_get_own_property (ecma_object_t *obj_p, /**< the array obj { uint32_index = property_name_p->u.uint32_number; - ecma_ref_ecma_string (property_name_p); - new_prop_name_p = property_name_p; + new_prop_name_p = ecma_copy_or_ref_ecma_string (property_name_p); } else {