From 9c3aa4a003e7dca97b54560ef1efc3dcb80454f4 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Fri, 30 Oct 2015 18:44:49 +0300 Subject: [PATCH] Improve performance of item 3.l of arrays' [[DefineOwnProperty]] (ecma_op_array_object_define_own_property). JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com --- .../ecma/operations/ecma-array-object.cpp | 61 +++++++++++++++---- jerry-core/ecma/operations/ecma-objects.cpp | 2 +- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/jerry-core/ecma/operations/ecma-array-object.cpp b/jerry-core/ecma/operations/ecma-array-object.cpp index 354f59efc..135a7564c 100644 --- a/jerry-core/ecma/operations/ecma-array-object.cpp +++ b/jerry-core/ecma/operations/ecma-array-object.cpp @@ -291,29 +291,60 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o // l JERRY_ASSERT (new_len_uint32 < old_len_uint32); - bool reduce_succeeded = true; + /* + * Item i. is replaced with faster iteration: only indices that actually exist in the array, are iterated + */ + bool is_reduce_succeeded = true; - while (new_len_uint32 < old_len_uint32) + ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, + true, + false, + false); + + ecma_length_t array_index_props_num = array_index_props_p->unit_number; + + MEM_DEFINE_LOCAL_ARRAY (array_index_values_p, array_index_props_num, uint32_t); + + ecma_collection_iterator_t iter; + ecma_collection_iterator_init (&iter, array_index_props_p); + + uint32_t array_index_values_pos = 0; + + while (ecma_collection_iterator_next (&iter)) { - // i - old_len_uint32--; + ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p); - // ii - ecma_string_t *old_length_string_p = ecma_new_ecma_string_from_uint32 (old_len_uint32); + uint32_t index; + bool is_index = ecma_string_get_array_index (property_name_p, &index); + JERRY_ASSERT (is_index); + JERRY_ASSERT (index < old_len_uint32); + + array_index_values_p[array_index_values_pos++] = index; + } + + JERRY_ASSERT (array_index_values_pos == array_index_props_num); + + while (array_index_values_pos != 0 + && array_index_values_p[--array_index_values_pos] >= new_len_uint32) + { + uint32_t index = array_index_values_p[array_index_values_pos]; + + // ii. + ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); ecma_completion_value_t delete_succeeded = ecma_op_object_delete (obj_p, - old_length_string_p, + index_string_p, false); - ecma_deref_ecma_string (old_length_string_p); + ecma_deref_ecma_string (index_string_p); - // iii if (ecma_is_completion_value_normal_false (delete_succeeded)) { - JERRY_ASSERT (ecma_is_value_number (new_len_property_desc.value)); + // iii. + new_len_uint32 = (index + 1u); ecma_number_t *new_len_num_p = ecma_get_number_from_value (new_len_property_desc.value); // 1. - *new_len_num_p = ecma_uint32_to_number (old_len_uint32 + 1); + *new_len_num_p = ecma_uint32_to_number (index + 1u); // 2. if (!new_writable) @@ -333,13 +364,17 @@ ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array o JERRY_ASSERT (ecma_is_completion_value_normal_true (completion) || ecma_is_completion_value_normal_false (completion)); - reduce_succeeded = false; + is_reduce_succeeded = false; break; } } - if (!reduce_succeeded) + MEM_FINALIZE_LOCAL_ARRAY (array_index_values_p); + + ecma_free_values_collection (array_index_props_p, true); + + if (!is_reduce_succeeded) { ret_value = ecma_reject (is_throw); } diff --git a/jerry-core/ecma/operations/ecma-objects.cpp b/jerry-core/ecma/operations/ecma-objects.cpp index 11e759f67..2c5c159b4 100644 --- a/jerry-core/ecma/operations/ecma-objects.cpp +++ b/jerry-core/ecma/operations/ecma-objects.cpp @@ -656,7 +656,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ else { JERRY_ASSERT (insertion_pos < array_index_name_pos); - JERRY_ASSERT (index < array_index_names_p[insertion_pos]); + JERRY_ASSERT (index >= array_index_names_p[insertion_pos]); uint32_t move_pos = ++array_index_name_pos;