From 6f1ce8d6bbd9c0aae15f547da1be34359904e5b2 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 13 Jul 2016 04:50:47 -0700 Subject: [PATCH] Improve the construction of "length" built-in strings. The "length" property name is the most frequently used built-in string and also frequently created by various hot-paths. New functions are added to improve the speed of the "length" string creation. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers-string.c | 55 +++++++++++++++++++ jerry-core/ecma/base/ecma-helpers.h | 3 + .../ecma-builtin-array-prototype.c | 40 +++++++------- .../ecma-builtin-function-prototype.c | 4 +- .../builtin-objects/ecma-builtin-helpers.c | 2 +- .../ecma/builtin-objects/ecma-builtin-json.c | 4 +- .../ecma-builtin-string-prototype.c | 4 +- .../ecma/builtin-objects/ecma-builtins.c | 26 ++++++--- .../ecma/operations/ecma-array-object.c | 12 ++-- .../ecma/operations/ecma-function-object.c | 10 +--- .../ecma/operations/ecma-objects-arguments.c | 2 +- .../ecma/operations/ecma-objects-general.c | 30 ++-------- .../ecma/operations/ecma-regexp-object.c | 2 +- .../ecma/operations/ecma-string-object.c | 2 +- jerry-core/jerry.c | 6 +- jerry-core/lit/lit-globals.h | 5 ++ jerry-core/vm/vm.c | 8 +-- 17 files changed, 131 insertions(+), 84 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 9caf622637..5ea2a5fc09 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -183,6 +183,21 @@ ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, /**< ecma-strin string_desc_p->u.uint32_number = uint32_number; } /* ecma_init_ecma_string_from_uint32 */ +/** + * Initialize a length ecma-string + */ +inline void __attr_always_inline___ +ecma_init_ecma_length_string (ecma_string_t *string_desc_p) /**< ecma-string */ +{ + JERRY_ASSERT (lit_utf8_string_calc_hash ((const lit_utf8_byte_t *) "length", 6) == LIT_STRING_LENGTH_HASH); + + string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING | ECMA_STRING_REF_ONE; + string_desc_p->hash = LIT_STRING_LENGTH_HASH; + + string_desc_p->u.common_field = 0; + string_desc_p->u.magic_string_id = LIT_MAGIC_STRING_LENGTH; +} /* ecma_init_ecma_length_string */ + /** * Allocate new ecma-string and fill it with ecma-number * @@ -280,6 +295,20 @@ ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id) /**< return string_desc_p; } /* ecma_new_ecma_string_from_magic_string_ex_id */ +/** + * Allocate new ecma-string and fill it with reference to length magic string + * + * @return pointer to ecma-string descriptor + */ +ecma_string_t * +ecma_new_ecma_length_string (void) +{ + ecma_string_t *string_desc_p = ecma_alloc_string (); + ecma_init_ecma_length_string (string_desc_p); + + return string_desc_p; +} /* ecma_new_ecma_length_string */ + /** * Concatenate ecma-strings * @@ -761,6 +790,32 @@ ecma_string_is_empty (const ecma_string_t *str_p) /**< ecma-string */ && str_p->u.magic_string_id == LIT_MAGIC_STRING__EMPTY); } /* ecma_string_is_empty */ +/** + * Checks whether the string equals to "length". + * + * @return true if the string equals to "length" + * false otherwise + */ +inline bool __attr_always_inline___ +ecma_string_is_length (const ecma_string_t *string_p) /**< property name */ +{ + ecma_string_container_t container = ECMA_STRING_GET_CONTAINER (string_p); + + if (container == ECMA_STRING_CONTAINER_MAGIC_STRING) + { + return string_p->u.magic_string_id == LIT_MAGIC_STRING_LENGTH; + } + + if (container != ECMA_STRING_CONTAINER_HEAP_UTF8_STRING + || string_p->u.utf8_string.size != 6 + || string_p->hash != LIT_STRING_LENGTH_HASH) + { + return false; + } + + return !strncmp ((char *) (string_p + 1), "length", 6); +} /* ecma_string_is_length */ + /** * Long path part of ecma-string to ecma-string comparison routine * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index bd1623c889..66a730e8a7 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -168,6 +168,7 @@ extern ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t); extern ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t); extern ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t); extern ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t); +extern ecma_string_t *ecma_new_ecma_length_string (); extern ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *, ecma_string_t *); extern void ecma_ref_ecma_string (ecma_string_t *); extern void ecma_deref_ecma_string (ecma_string_t *); @@ -179,7 +180,9 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *, lit_utf8_byte_t *, lit_u extern void ecma_string_to_utf8_bytes (const ecma_string_t *, lit_utf8_byte_t *, lit_utf8_size_t); extern const lit_utf8_byte_t *ecma_string_raw_chars (const ecma_string_t *, lit_utf8_size_t *, bool *); extern void ecma_init_ecma_string_from_uint32 (ecma_string_t *, uint32_t); +extern void ecma_init_ecma_length_string (ecma_string_t *); extern bool ecma_string_is_empty (const ecma_string_t *); +extern bool ecma_string_is_length (const ecma_string_t *); extern bool ecma_compare_ecma_strings_equal_hashes (const ecma_string_t *, const ecma_string_t *); extern bool ecma_compare_ecma_strings (const ecma_string_t *, const ecma_string_t *); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 1ac76d8667..12ff96e0eb 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -60,7 +60,7 @@ ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< obje ecma_number_t length) /**< new length */ { ecma_value_t ret_value; - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ecma_value_t length_value = ecma_make_number_value (length); ret_value = ecma_op_object_put (object, @@ -145,7 +145,7 @@ ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_ar ecma_object_t *obj_p = ecma_get_object_from_value (obj_value); - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (length_value, @@ -369,7 +369,7 @@ ecma_builtin_array_prototype_join (const ecma_value_t this_arg, /**< this argume ecma_object_t *obj_p = ecma_get_object_from_value (obj_value); - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (length_value, @@ -474,7 +474,7 @@ ecma_builtin_array_prototype_object_pop (ecma_value_t this_arg) /**< this argume ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -555,7 +555,7 @@ ecma_builtin_array_prototype_object_push (ecma_value_t this_arg, /**< this argum ecma_object_t *obj_p = ecma_get_object_from_value (obj_this_value); /* 2. */ - ecma_string_t *length_str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_str_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (length_value, ecma_op_object_get (obj_p, length_str_p), ret_value); @@ -624,7 +624,7 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg) /**< this ar ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -720,7 +720,7 @@ ecma_builtin_array_prototype_object_shift (ecma_value_t this_arg) /**< this argu ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -835,7 +835,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (len_value, ecma_op_object_get (obj_p, length_magic_string_p), @@ -1205,7 +1205,7 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (len_value, ecma_op_object_get (obj_p, magic_string_length_p), @@ -1359,7 +1359,7 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); /* 3. */ - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (len_value, ecma_op_object_get (obj_p, length_magic_string_p), @@ -1646,7 +1646,7 @@ ecma_builtin_array_prototype_object_unshift (ecma_value_t this_arg, /**< this ar ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -1742,7 +1742,7 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -1838,7 +1838,7 @@ ecma_builtin_array_prototype_object_last_index_of (ecma_value_t this_arg, /**< t ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -1983,7 +1983,7 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2081,7 +2081,7 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2178,7 +2178,7 @@ ecma_builtin_array_prototype_object_for_each (ecma_value_t this_arg, /**< this a ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2270,7 +2270,7 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2380,7 +2380,7 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2501,7 +2501,7 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, @@ -2643,7 +2643,7 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th ret_value); ecma_object_t *obj_p = ecma_get_object_from_value (obj_this); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 2. */ ECMA_TRY_CATCH (len_value, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c index e34e17b645..56536e8cc9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c @@ -110,7 +110,7 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a else { ecma_object_t *obj_p = ecma_get_object_from_value (arg2); - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); /* 4. */ ECMA_TRY_CATCH (length_value, @@ -286,7 +286,7 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar /* 16. */ ecma_number_t length = ECMA_NUMBER_ZERO; - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 15. */ if (ecma_object_get_class_name (this_arg_obj_p) == LIT_MAGIC_STRING_FUNCTION_UL) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index 9128bacfcd..3f43fdabc3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -335,7 +335,7 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */ if (ecma_is_value_object (value) && (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL)) { - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 5.b.ii */ ECMA_TRY_CATCH (arg_len_value, ecma_op_object_get (ecma_get_object_from_value (value), diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index 7bc811fd91..107217f242 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -825,7 +825,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ /* 4.b */ else if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL) { - ecma_string_t *length_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_str_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (array_length, ecma_op_object_get (obj_p, length_str_p), @@ -1624,7 +1624,7 @@ ecma_builtin_json_array (ecma_object_t *obj_p, /**< the array object*/ /* 5. */ ecma_collection_header_t *partial_p = ecma_new_values_collection (NULL, 0, true); - ecma_string_t *length_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_str_p = ecma_new_ecma_length_string (); /* 6. */ ECMA_TRY_CATCH (array_length, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index bebffbec95..3c2db2f99f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -774,7 +774,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se ecma_value_t match_value) /**< returned match value */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); - ecma_string_t *length_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_string_p = ecma_new_ecma_length_string (); ecma_object_t *match_object_p = ecma_get_object_from_value (match_value); ECMA_TRY_CATCH (match_length_value, @@ -1818,7 +1818,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg /* 13.c.iii.5 */ start_pos = end_pos + match_str_length; - ecma_string_t *magic_length_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_length_str_p = ecma_new_ecma_length_string (); ECMA_TRY_CATCH (array_length_val, ecma_op_object_get (match_array_obj_p, magic_length_str_p), diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 38a5a0b2b9..7f3b6fb8cc 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -135,6 +135,22 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ /** Initializing [[PrimitiveValue]] properties of built-in prototype objects */ switch (obj_builtin_id) { +#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN + case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE: + { + ecma_string_t *length_str_p = ecma_new_ecma_length_string (); + + ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p, + length_str_p, + ECMA_PROPERTY_FLAG_WRITABLE); + + ecma_set_named_data_property_value (length_prop_p, ecma_make_integer_value (0)); + + ecma_deref_ecma_string (length_str_p); + break; + } +#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ARRAY_BUILTIN */ + #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN case ECMA_BUILTIN_ID_STRING_PROTOTYPE: { @@ -352,13 +368,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); - - bool is_length_property = ecma_compare_ecma_strings (string_p, magic_string_length_p); - - ecma_deref_ecma_string (magic_string_length_p); - - if (is_length_property) + if (ecma_string_is_length (string_p)) { /* * Lazy instantiation of 'length' property @@ -589,7 +599,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 15) */ - ecma_string_t *name_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *name_p = ecma_new_ecma_length_string (); ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true); ecma_deref_ecma_string (name_p); } diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 926d27f0b8..3e97828ad3 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -103,7 +103,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of * See also: ecma_object_get_class_name */ - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p, length_magic_string_p, @@ -157,7 +157,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY); // 1. - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); @@ -214,7 +214,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o if (new_len_uint32 >= old_len_uint32) { // i. - magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + magic_string_length_p = ecma_new_ecma_length_string (); ret_value = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, @@ -248,7 +248,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o } // j. - magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + magic_string_length_p = ecma_new_ecma_length_string (); ecma_value_t succeeded = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, @@ -329,7 +329,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o } // 3. - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); ecma_value_t completion = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, @@ -363,7 +363,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o prop_desc_not_writable.is_writable = false; ecma_value_t completion_set_not_writable; - magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + magic_string_length_p = ecma_new_ecma_length_string (); completion_set_not_writable = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &prop_desc_not_writable, diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 696dfd5dca..72213a7281 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -255,7 +255,7 @@ ecma_op_function_list_lazy_property_names (bool separate_enumerable, /**< true - ecma_string_t *name_p; /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - name_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + name_p = ecma_new_ecma_length_string (); ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true); ecma_deref_ecma_string (name_p); @@ -282,13 +282,7 @@ ecma_op_function_try_lazy_instantiate_property (ecma_object_t *obj_p, /**< the f { JERRY_ASSERT (!ecma_get_object_is_builtin (obj_p)); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); - - bool is_length_property = ecma_compare_ecma_strings (magic_string_length_p, property_name_p); - - ecma_deref_ecma_string (magic_string_length_p); - - if (is_length_property) + if (ecma_string_is_length (property_name_p)) { /* ECMA-262 v5, 13.2, 14-15 */ ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p; diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index 2786b06fab..d738768682 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -85,7 +85,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ARGUMENTS_UL; // 7. - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p, length_magic_string_p, ecma_make_uint32_value (arguments_number), diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index fbdb4c20e4..c7375eaf6a 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -245,25 +245,6 @@ ecma_op_general_object_get_property (ecma_object_t *obj_p, /**< the object */ } } /* ecma_op_general_object_get_property */ -/** - * Checks whether the property name is "length". - * - * @return true if the property name is length - * false otherwise - */ -static inline bool __attr_always_inline___ -ecma_op_general_object_property_name_is_length (ecma_string_t *property_name_p) /**< property name */ -{ - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); - - bool property_name_is_length = ecma_compare_ecma_strings (property_name_p, - magic_string_length_p); - - ecma_deref_ecma_string (magic_string_length_p); - - return property_name_is_length; -} /* ecma_op_general_object_property_name_is_length */ - /** * [[Put]] ecma general object's operation * @@ -305,7 +286,7 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ const ecma_object_type_t type = ecma_get_object_type (obj_p); if (type == ECMA_OBJECT_TYPE_ARGUMENTS - || (type == ECMA_OBJECT_TYPE_ARRAY && ecma_op_general_object_property_name_is_length (property_name_p))) + || (type == ECMA_OBJECT_TYPE_ARRAY && ecma_string_is_length (property_name_p))) { /* These cases cannot be optimized. */ ecma_property_descriptor_t value_desc = ecma_make_empty_property_descriptor (); @@ -379,11 +360,12 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ /* Since the length of an array is a non-configurable named data * property, the prop_p must be a non-NULL pointer for all arrays. */ - JERRY_ASSERT (!ecma_op_general_object_property_name_is_length (property_name_p)); + JERRY_ASSERT (!ecma_string_is_length (property_name_p)); + + ecma_string_t magic_string_length; + ecma_init_ecma_length_string (&magic_string_length); - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); - ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); - ecma_deref_ecma_string (magic_string_length_p); + ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, &magic_string_length); JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index ef87176da1..e3f495c7a3 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -1199,7 +1199,7 @@ re_set_result_array_properties (ecma_object_t *array_obj_p, /**< result array */ ecma_deref_ecma_string (result_prop_str_p); /* Set length property of the result array */ - result_prop_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + result_prop_str_p = ecma_new_ecma_length_string (); { ecma_property_descriptor_t array_item_prop_desc = ecma_make_empty_property_descriptor (); array_item_prop_desc.is_value_defined = true; diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index 25b6bfd4a8..acc92ab092 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -99,7 +99,7 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of ecma_set_internal_property_value (prim_value_prop_p, ecma_make_string_value (prim_prop_str_value_p)); // 15.5.5.1 - ecma_string_t *length_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p, length_magic_string_p, ECMA_PROPERTY_FIXED); diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index 65cdaf0dfc..49479f5091 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -942,11 +942,11 @@ jerry_get_array_length (const jerry_value_t value) } jerry_length_t length = 0; - ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); + ecma_string_t magic_string_length; + ecma_init_ecma_length_string (&magic_string_length); ecma_value_t len_value = ecma_op_object_get (ecma_get_object_from_value (value), - magic_string_length_p); - ecma_deref_ecma_string (magic_string_length_p); + &magic_string_length); length = ecma_number_to_uint32 (ecma_get_number_from_value (len_value)); ecma_free_value (len_value); diff --git a/jerry-core/lit/lit-globals.h b/jerry-core/lit/lit-globals.h index 8081571595..b5b6071399 100644 --- a/jerry-core/lit/lit-globals.h +++ b/jerry-core/lit/lit-globals.h @@ -139,4 +139,9 @@ typedef uint16_t lit_string_hash_t; */ #define LIT_STRING_HASH_LIMIT 0x10000u +/** + * Hash of the frequently used "length" string. + */ +#define LIT_STRING_LENGTH_HASH 0x3615u + #endif /* !LIT_GLOBALS_H */ diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 0ef671932f..94adde6bde 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1002,7 +1002,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ case VM_OC_APPEND_ARRAY: { ecma_object_t *array_obj_p; - ecma_string_t *length_str_p; + ecma_string_t length_str; ecma_property_t *length_prop_p; uint32_t length_num; uint32_t values_length = *byte_code_p++; @@ -1010,16 +1010,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ stack_top_p -= values_length; array_obj_p = ecma_get_object_from_value (stack_top_p[-1]); - length_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); - length_prop_p = ecma_get_named_property (array_obj_p, length_str_p); + ecma_init_ecma_length_string (&length_str); + length_prop_p = ecma_get_named_property (array_obj_p, &length_str); JERRY_ASSERT (length_prop_p != NULL); left_value = ecma_get_named_data_property_value (length_prop_p); length_num = ecma_get_uint32_from_value (left_value); - ecma_deref_ecma_string (length_str_p); - for (uint32_t i = 0; i < values_length; i++) { if (!ecma_is_value_array_hole (stack_top_p[i]))