diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index e848710fe..1fe83335d 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -795,7 +795,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr if (!(generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC)) { - ecma_collection_header_t *lit_pool_p = ecma_new_values_collection (); + ecma_collection_t *lit_pool_p = ecma_new_collection (); ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p); @@ -1048,7 +1048,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */ static void scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */ const uint8_t *buffer_end_p, /**< snapshot buffer end */ - ecma_collection_header_t *lit_pool_p, /**< list of known values */ + ecma_collection_t *lit_pool_p, /**< list of known values */ const uint8_t *literal_base_p) /**< start of literal data */ { JERRY_ASSERT (buffer_end_p > buffer_p); @@ -1225,14 +1225,14 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t return 0; } - ecma_collection_header_t *lit_pool_p = ecma_new_values_collection (); + ecma_collection_t *lit_pool_p = ecma_new_collection (); for (uint32_t i = 0; i < number_of_snapshots; i++) { if (inp_buffer_sizes_p[i] < sizeof (jerry_snapshot_header_t)) { *error_p = "invalid snapshot file"; - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return 0; } @@ -1243,7 +1243,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t || !snapshot_check_global_flags (header_p->global_flags)) { *error_p = "invalid snapshot version or unsupported features present"; - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return 0; } @@ -1271,7 +1271,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t if (functions_size >= out_buffer_size) { *error_p = "output buffer is too small"; - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return 0; } @@ -1615,21 +1615,21 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0); const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset; - ecma_collection_header_t *lit_pool_p = ecma_new_values_collection (); + ecma_collection_t *lit_pool_p = ecma_new_collection (); scan_snapshot_functions (snapshot_data_p + header_p->func_offsets[0], literal_base_p, lit_pool_p, literal_base_p); lit_utf8_size_t literal_count = 0; - ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p); + ecma_value_t *buffer_p = lit_pool_p->buffer_p; /* Count the valid and non-magic identifiers in the list. */ - while (iterator_p != NULL) + for (uint32_t i = 0; i < lit_pool_p->item_count; i++) { - if (ecma_is_value_string (*iterator_p)) + if (ecma_is_value_string (buffer_p[i])) { - ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p); + ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]); /* NOTE: * We don't save a literal (in C format) which isn't a valid @@ -1643,13 +1643,11 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho literal_count++; } } - - iterator_p = ecma_collection_iterator_next (iterator_p); } if (literal_count == 0) { - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return 0; } @@ -1659,13 +1657,14 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *); lit_utf8_size_t literal_idx = 0; - iterator_p = ecma_collection_iterator_init (lit_pool_p); + buffer_p = lit_pool_p->buffer_p; - while (iterator_p != NULL) + /* Count the valid and non-magic identifiers in the list. */ + for (uint32_t i = 0; i < lit_pool_p->item_count; i++) { - if (ecma_is_value_string (*iterator_p)) + if (ecma_is_value_string (buffer_p[i])) { - ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p); + ecma_string_t *literal_p = ecma_get_string_from_value (buffer_p[i]); /* NOTE: * We don't save a literal (in C format) which isn't a valid @@ -1679,11 +1678,9 @@ jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapsho literal_array[literal_idx++] = literal_p; } } - - iterator_p = ecma_collection_iterator_next (iterator_p); } - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); /* Sort the strings by size at first, then lexicographically. */ jerry_save_literals_sort (literal_array, literal_count); diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 6170e88a1..6278df362 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -2765,16 +2765,16 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */ } ecma_object_t *object_p = ecma_get_object_from_value (obj_val); - ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (names_p); + ecma_collection_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE); + ecma_value_t *buffer_p = names_p->buffer_p; ecma_value_t property_value = ECMA_VALUE_EMPTY; bool continuous = true; - while (continuous && ecma_value_p != NULL) + for (uint32_t i = 0; continuous && (i < names_p->item_count); i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); property_value = ecma_op_object_get (object_p, property_name_p); @@ -2783,13 +2783,11 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */ break; } - continuous = foreach_p (*ecma_value_p, property_value, user_data_p); + continuous = foreach_p (buffer_p[i], property_value, user_data_p); ecma_free_value (property_value); - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } - ecma_free_values_collection (names_p, 0); + ecma_collection_free (names_p); if (!ECMA_IS_VALUE_ERROR (property_value)) { diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 28f07ed6d..05c6084a9 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -200,21 +200,29 @@ ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended } /* Mark all reactions. */ - ecma_value_t *ecma_value_p; - ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->fulfill_reactions); + ecma_promise_object_t *promise_object_p = (ecma_promise_object_t *) ext_object_p; + ecma_collection_t *collection_p = promise_object_p->fulfill_reactions; - while (ecma_value_p != NULL) + if (collection_p != NULL) { - ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p)); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t i = 0; i < collection_p->item_count; i++) + { + ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i])); + } } - ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->reject_reactions); + collection_p = promise_object_p->reject_reactions; - while (ecma_value_p != NULL) + if (collection_p != NULL) { - ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p)); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t i = 0; i < collection_p->item_count; i++) + { + ecma_gc_set_object_visited (ecma_get_object_from_value (buffer_p[i])); + } } } /* ecma_gc_mark_promise_object */ @@ -768,10 +776,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ case LIT_MAGIC_STRING_PROMISE_UL: { ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value); - ecma_free_values_collection (((ecma_promise_object_t *) object_p)->fulfill_reactions, - ECMA_COLLECTION_NO_REF_OBJECTS); - ecma_free_values_collection (((ecma_promise_object_t *) object_p)->reject_reactions, - ECMA_COLLECTION_NO_REF_OBJECTS); + ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->fulfill_reactions); + ecma_collection_free_if_not_object (((ecma_promise_object_t *) object_p)->reject_reactions); ecma_dealloc_extended_object (object_p, sizeof (ecma_promise_object_t)); return; } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 71dd883e3..50ccaabb6 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -76,7 +76,6 @@ typedef enum ECMA_TYPE_SYMBOL = 4, /**< pointer to description of a symbol */ ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */ ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference (only supported by C API) */ - ECMA_TYPE_POINTER = ECMA_TYPE_ERROR, /**< a generic aligned pointer */ ECMA_TYPE_SNAPSHOT_OFFSET = ECMA_TYPE_ERROR, /**< offset to a snapshot number/string */ ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */ } ecma_type_t; @@ -1216,57 +1215,36 @@ typedef double ecma_number_t; */ #define ECMA_STRING_NOT_ARRAY_INDEX UINT32_MAX -/* - * Ecma-collection: a growable list of ecma-values. Currently the list is - * a chain list, where appending new items at the end is cheap operation. - * - * Enumerating elements is also cheap, since each page is terminated by a - * special ecma-value: collection-type. This type has a pointer to the next - * chunk. The last chunk is terminated by a NULL pointer. There when the - * next value is requested from the iterator it simply checks the next - * memory location. If it is not a collection-type value, it returns with - * the value. Otherwise it gets the start address of the next chunk, and - * return the value there. - * - * The collection-type value is always the last item of a collection chunk, - * even if the chunk is not completely filled with values (this is only true - * for the last chunk). Each chunk must have at least one non collection-type - * value as well. - */ - /** - * Collection flags. - */ -typedef enum -{ - ECMA_COLLECTION_NO_REF_OBJECTS = (1u << 0), /**< do not increase the refcount of objects */ - ECMA_COLLECTION_NO_COPY = (1u << 1), /**< do not copy values */ -} ecma_collection_flag_t; - -/** - * Description of a collection's header. + * Ecma-collection: a growable list of ecma-values. */ typedef struct { - jmem_cpointer_t first_chunk_cp; /**< compressed pointer to first chunk with collection's data */ - jmem_cpointer_t last_chunk_cp; /**< compressed pointer to last chunk with collection's data */ - ecma_length_t item_count; /**< number of items in the collection */ -} ecma_collection_header_t; + uint32_t item_count; /**< number of items in the collection */ + uint32_t capacity; /**< number of items can be stored in the underlying buffer */ + ecma_value_t *buffer_p; /**< underlying data buffer */ +} ecma_collection_t; /** - * Maximum number of items stored by a collection chunk (excluding the last collection-type value). + * Initial capacity of an ecma-collection */ -#define ECMA_COLLECTION_CHUNK_ITEMS 5 +#define ECMA_COLLECTION_INITIAL_CAPACITY 4 /** - * Collection chunk item. + * Ecma-collenction grow factor when the collection underlying buffer need to be reallocated */ -typedef struct -{ - ecma_value_t items[ECMA_COLLECTION_CHUNK_ITEMS + 1]; /**< ecma-value list, where the last value is a special - * collection-type value which points to the next chunk, - * so the chunk area is enlarged by one for this value */ -} ecma_collection_chunk_t; +#define ECMA_COLLECTION_GROW_FACTOR (ECMA_COLLECTION_INITIAL_CAPACITY * 2) + +/** + * Compute the total allocated size of the collection based on it's capacity + */ +#define ECMA_COLLECTION_ALLOCATED_SIZE(capacity) \ + (uint32_t) (sizeof (ecma_collection_t) + (capacity * sizeof (ecma_value_t))) + +/** + * Initial allocated size of an ecma-collection + */ +#define ECMA_COLLECTION_INITIAL_SIZE ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY) /** * Direct string types (2 bit). diff --git a/jerry-core/ecma/base/ecma-helpers-collection.c b/jerry-core/ecma/base/ecma-helpers-collection.c new file mode 100644 index 000000000..56850cb27 --- /dev/null +++ b/jerry-core/ecma/base/ecma-helpers-collection.c @@ -0,0 +1,150 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-alloc.h" +#include "ecma-gc.h" +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "jrt.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmahelpers Helpers for operations with ECMA data types + * @{ + */ + +/** + * Allocate a collection of ecma values. + * + * @return pointer to the collection + */ +ecma_collection_t * +ecma_new_collection (void) +{ + ecma_collection_t *collection_p; + collection_p = (ecma_collection_t *) jmem_heap_alloc_block (sizeof (ecma_collection_t)); + + collection_p->item_count = 0; + collection_p->capacity = ECMA_COLLECTION_INITIAL_CAPACITY; + const uint32_t size = ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY); + collection_p->buffer_p = (ecma_value_t *) jmem_heap_alloc_block (size); + + return collection_p; +} /* ecma_new_collection */ + +/** + * Deallocate a collection of ecma values without freeing it's values + */ +inline void JERRY_ATTR_ALWAYS_INLINE +ecma_collection_destroy (ecma_collection_t *collection_p) /**< value collection */ +{ + JERRY_ASSERT (collection_p != NULL); + + jmem_heap_free_block (collection_p->buffer_p, ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity)); + jmem_heap_free_block (collection_p, sizeof (ecma_collection_t)); +} /* ecma_collection_destroy */ + +/** + * Free the object collection elements and deallocate the collection + */ +void +ecma_collection_free_objects (ecma_collection_t *collection_p) /**< value collection */ +{ + JERRY_ASSERT (collection_p != NULL); + + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t i = 0; i < collection_p->item_count; i++) + { + if (ecma_is_value_object (buffer_p[i])) + { + ecma_deref_object (ecma_get_object_from_value (buffer_p[i])); + } + } + + ecma_collection_destroy (collection_p); +} /* ecma_collection_free_objects */ + +/** + * Free the non-object collection elements and deallocate the collection + */ +void +ecma_collection_free_if_not_object (ecma_collection_t *collection_p) /**< value collection */ +{ + JERRY_ASSERT (collection_p != NULL); + + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t i = 0; i < collection_p->item_count; i++) + { + ecma_free_value_if_not_object (buffer_p[i]); + } + + ecma_collection_destroy (collection_p); +} /* ecma_collection_free_if_not_object */ + +/** + * Free the collection elements and deallocate the collection + */ +void +ecma_collection_free (ecma_collection_t *collection_p) /**< value collection */ +{ + JERRY_ASSERT (collection_p != NULL); + + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t i = 0; i < collection_p->item_count; i++) + { + ecma_free_value (buffer_p[i]); + } + + ecma_collection_destroy (collection_p); +} /* ecma_collection_free */ + +/** + * Append new value to ecma values collection + * + * Note: The reference count of the values are not increased + */ +void +ecma_collection_push_back (ecma_collection_t *collection_p, /**< value collection */ + ecma_value_t value) /**< ecma value to append */ +{ + JERRY_ASSERT (collection_p != NULL); + + ecma_value_t *buffer_p = collection_p->buffer_p; + + if (JERRY_LIKELY (collection_p->item_count < collection_p->capacity)) + { + buffer_p[collection_p->item_count++] = value; + return; + } + + const uint32_t new_capacity = collection_p->capacity + ECMA_COLLECTION_GROW_FACTOR; + const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity); + const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity); + + buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size); + buffer_p[collection_p->item_count++] = value; + collection_p->capacity = new_capacity; + + collection_p->buffer_p = buffer_p; +} /* ecma_collection_push_back */ + +/** + * @} + * @} + */ diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 679b55c37..12cc04df3 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -389,18 +389,6 @@ ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */ return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR); } /* ecma_is_value_error_reference */ -/** - * Check if the value is an aligned pointer. - * - * @return true - if the value contains an aligned pointer, - * false - otherwise - */ -inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE -ecma_is_value_pointer (ecma_value_t value) /**< ecma value */ -{ - return (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER); -} /* ecma_is_value_pointer */ - /** * Debug assertion that specified value's type is one of ECMA-defined * script-visible types, i.e.: undefined, null, boolean, number, string, object. @@ -658,29 +646,6 @@ ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**< return ecma_pointer_to_ecma_value (error_ref_p) | ECMA_TYPE_ERROR; } /* ecma_make_error_reference_value */ -/** - * Create an ecma value from an aligned pointer - * - * @return ecma-value representation of the aligned pointer - */ -inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE -ecma_make_pointer_value (const void *any_p) /**< any aligned pointer */ -{ -#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY - - uintptr_t uint_ptr = (uintptr_t) any_p; - JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0); - return ((ecma_value_t) uint_ptr) | ECMA_TYPE_POINTER; - -#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ - - jmem_cpointer_t ptr_cp; - ECMA_SET_POINTER (ptr_cp, any_p); - return (((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT) | ECMA_TYPE_POINTER; - -#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ -} /* ecma_make_pointer_value */ - /** * Get integer value from an integer ecma value * @@ -813,23 +778,6 @@ ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */ return (ecma_error_reference_t *) ecma_get_pointer_from_ecma_value (value); } /* ecma_get_error_reference_from_value */ -/** - * Get an aligned pointer from an ecma value - * - * @return pointer value - */ -inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE -ecma_get_pointer_from_value (ecma_value_t value) /**< ecma value */ -{ - JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER); - -#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY - return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK); -#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ - return ECMA_GET_POINTER (void, value >> ECMA_VALUE_SHIFT); -#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ -} /* ecma_get_pointer_from_value */ - /** * Invert a boolean value * diff --git a/jerry-core/ecma/base/ecma-helpers-values-collection.c b/jerry-core/ecma/base/ecma-helpers-values-collection.c deleted file mode 100644 index 14ba80119..000000000 --- a/jerry-core/ecma/base/ecma-helpers-values-collection.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright JS Foundation and other contributors, http://js.foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ecma-alloc.h" -#include "ecma-globals.h" -#include "ecma-helpers.h" -#include "jrt.h" - -/** \addtogroup ecma ECMA - * @{ - * - * \addtogroup ecmahelpers Helpers for operations with ECMA data types - * @{ - */ - -/** - * The type of ecma error and ecma collection chunk must be the same. - */ -JERRY_STATIC_ASSERT (ECMA_TYPE_ERROR == ECMA_TYPE_POINTER, - ecma_type_error_must_be_the_same_as_ecma_type_pointer); - -/** - * Allocate a collection of ecma values. - * - * @return pointer to the collection's header - */ -ecma_collection_header_t * -ecma_new_values_collection (void) -{ - ecma_collection_header_t *header_p; - header_p = (ecma_collection_header_t *) jmem_pools_alloc (sizeof (ecma_collection_header_t)); - - header_p->item_count = 0; - header_p->first_chunk_cp = ECMA_NULL_POINTER; - header_p->last_chunk_cp = ECMA_NULL_POINTER; - - return header_p; -} /* ecma_new_values_collection */ - -/** - * Free the collection of ecma values. - */ -void -ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection's header */ - uint32_t flags) /**< combination of ecma_collection_flag_t flags */ -{ - jmem_cpointer_t chunk_cp = header_p->first_chunk_cp; - - jmem_pools_free (header_p, sizeof (ecma_collection_header_t)); - - if (chunk_cp == JMEM_CP_NULL) - { - return; - } - - ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, chunk_cp); - - do - { - ecma_value_t *item_p = chunk_p->items; - - JERRY_ASSERT (!ecma_is_value_pointer (*item_p)); - - do - { - if (!(flags & ECMA_COLLECTION_NO_COPY) - && (!ecma_is_value_object (*item_p) - || !(flags & ECMA_COLLECTION_NO_REF_OBJECTS))) - { - ecma_free_value (*item_p); - } - - item_p++; - } - while (!ecma_is_value_pointer (*item_p)); - - ecma_collection_chunk_t *next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (*item_p); - - jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t)); - - chunk_p = next_chunk_p; - } - while (chunk_p != NULL); -} /* ecma_free_values_collection */ - -/** - * Append new value to ecma values collection - */ -void -ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< collection's header */ - ecma_value_t value, /**< ecma value to append */ - uint32_t flags) /**< combination of ecma_collection_flag_t flags */ -{ - ecma_length_t item_index; - ecma_collection_chunk_t *chunk_p; - - if (JERRY_UNLIKELY (header_p->item_count == 0)) - { - item_index = 0; - chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t)); - - ECMA_SET_NON_NULL_POINTER (header_p->first_chunk_cp, chunk_p); - header_p->last_chunk_cp = header_p->first_chunk_cp; - } - else - { - item_index = header_p->item_count % ECMA_COLLECTION_CHUNK_ITEMS; - - chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, - header_p->last_chunk_cp); - - if (JERRY_UNLIKELY (item_index == 0)) - { - JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) - && ecma_get_pointer_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL); - - ecma_collection_chunk_t *next_chunk_p; - next_chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t)); - - chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_pointer_value ((void *) next_chunk_p); - ECMA_SET_NON_NULL_POINTER (header_p->last_chunk_cp, next_chunk_p); - - chunk_p = next_chunk_p; - } - else - { - JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[item_index]) - && ecma_get_pointer_from_value (chunk_p->items[item_index]) == NULL); - } - } - - if (!(flags & ECMA_COLLECTION_NO_COPY) - && (!ecma_is_value_object (value) - || !(flags & ECMA_COLLECTION_NO_REF_OBJECTS))) - { - value = ecma_copy_value (value); - } - - chunk_p->items[item_index] = value; - chunk_p->items[item_index + 1] = ecma_make_pointer_value (NULL); - header_p->item_count++; -} /* ecma_append_to_values_collection */ - -/** - * Initialize new collection iterator for the collection - * - * @return pointer to the first item - */ -ecma_value_t * -ecma_collection_iterator_init (ecma_collection_header_t *header_p) /**< header of collection */ -{ - if (JERRY_UNLIKELY (!header_p || header_p->item_count == 0)) - { - return NULL; - } - - ecma_collection_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, - header_p->first_chunk_cp); - - return chunk_p->items; -} /* ecma_collection_iterator_init */ - -/** - * Move collection iterator to next element if there is any. - * - * @return pointer to the next item - */ -ecma_value_t * -ecma_collection_iterator_next (ecma_value_t *ecma_value_p) /**< current value */ -{ - JERRY_ASSERT (ecma_value_p != NULL); - - ecma_value_p++; - - if (JERRY_UNLIKELY (ecma_is_value_pointer (*ecma_value_p))) - { - ecma_value_p = ((ecma_collection_chunk_t *) ecma_get_pointer_from_value (*ecma_value_p))->items; - - JERRY_ASSERT (ecma_value_p == NULL || !ecma_is_value_pointer (*ecma_value_p)); - return ecma_value_p; - } - - return ecma_value_p; -} /* ecma_collection_iterator_next */ - -/** - * @} - * @} - */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 86b21ef5f..a4fbde471 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -184,7 +184,6 @@ bool JERRY_ATTR_CONST ecma_is_value_direct_string (ecma_value_t value); bool JERRY_ATTR_CONST ecma_is_value_non_direct_string (ecma_value_t value); bool JERRY_ATTR_CONST ecma_is_value_object (ecma_value_t value); bool JERRY_ATTR_CONST ecma_is_value_error_reference (ecma_value_t value); -bool JERRY_ATTR_CONST ecma_is_value_pointer (ecma_value_t value); void ecma_check_value_type_is_spec_defined (ecma_value_t value); @@ -203,7 +202,6 @@ ecma_value_t JERRY_ATTR_PURE ecma_make_prop_name_value (const ecma_string_t *ecm ecma_value_t JERRY_ATTR_PURE ecma_make_magic_string_value (lit_magic_string_id_t id); ecma_value_t JERRY_ATTR_PURE ecma_make_object_value (const ecma_object_t *object_p); ecma_value_t JERRY_ATTR_PURE ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p); -ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p); ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value); ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value); ecma_number_t * ecma_get_pointer_from_float_value (ecma_value_t value); @@ -215,7 +213,6 @@ ecma_string_t JERRY_ATTR_PURE *ecma_get_symbol_from_value (ecma_value_t value); ecma_string_t JERRY_ATTR_PURE *ecma_get_prop_name_from_value (ecma_value_t value); ecma_object_t JERRY_ATTR_PURE *ecma_get_object_from_value (ecma_value_t value); ecma_error_reference_t JERRY_ATTR_PURE *ecma_get_error_reference_from_value (ecma_value_t value); -void * JERRY_ATTR_PURE ecma_get_pointer_from_value (ecma_value_t value); ecma_value_t JERRY_ATTR_CONST ecma_invert_boolean_value (ecma_value_t value); ecma_value_t ecma_copy_value (ecma_value_t value); ecma_value_t ecma_fast_copy_value (ecma_value_t value); @@ -351,15 +348,13 @@ lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num, lit_utf8_byte_t *out_digits_p, int32_t *out_decimal_exp_p); -/* ecma-helpers-values-collection.c */ -ecma_collection_header_t *ecma_new_values_collection (void); -void ecma_free_values_collection (ecma_collection_header_t *header_p, uint32_t flags); -void ecma_append_to_values_collection (ecma_collection_header_t *header_p, ecma_value_t v, uint32_t flags); - -ecma_value_t * -ecma_collection_iterator_init (ecma_collection_header_t *header_p); -ecma_value_t * -ecma_collection_iterator_next (ecma_value_t *iterator_p); +/* ecma-helpers-collection.c */ +ecma_collection_t *ecma_new_collection (void); +void ecma_collection_push_back (ecma_collection_t *collection_p, ecma_value_t value); +void ecma_collection_destroy (ecma_collection_t *collection_p); +void ecma_collection_free (ecma_collection_t *collection_p); +void ecma_collection_free_if_not_object (ecma_collection_t *collection_p); +void ecma_collection_free_objects (ecma_collection_t *collection_p); /* ecma-helpers.c */ ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type); diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c index bb34b7816..83ac43b27 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -298,7 +298,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be * Append the value at the end of the appropriate list if it is not present there. */ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appended */ - ecma_collection_header_t *lit_pool_p) /**< list of known values */ + ecma_collection_t *lit_pool_p) /**< list of known values */ { /* Unlike direct numbers, direct strings are converted to character literals. */ if (!ecma_is_value_string (value) && !ecma_is_value_float_number (value)) @@ -306,21 +306,19 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen return; } - ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p); + ecma_value_t *buffer_p = lit_pool_p->buffer_p; - while (iterator_p != NULL) + for (uint32_t i = 0; i < lit_pool_p->item_count; i++) { /* Strings / numbers are direct strings or stored in the literal storage. * Therefore direct comparison is enough to find the same strings / numbers. */ - if (*iterator_p == value) + if (buffer_p[i] == value) { return; } - - iterator_p = ecma_collection_iterator_next (iterator_p); } - ecma_append_to_values_collection (lit_pool_p, value, ECMA_COLLECTION_NO_COPY); + ecma_collection_push_back (lit_pool_p, value); } /* ecma_save_literals_append_value */ /** @@ -328,7 +326,7 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen */ void ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, /**< byte-code data */ - ecma_collection_header_t *lit_pool_p) /**< list of known values */ + ecma_collection_t *lit_pool_p) /**< list of known values */ { ecma_value_t *literal_p; uint32_t argument_end = 0; @@ -414,7 +412,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_ * false - otherwise */ bool -ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list of known values */ +ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, /**< list of known values */ uint32_t *buffer_p, /**< [out] output snapshot buffer */ size_t buffer_size, /**< size of the buffer */ size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */ @@ -437,18 +435,18 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list max_lit_table_size = (UINT32_MAX >> JERRY_SNAPSHOT_LITERAL_SHIFT); } - ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p); + ecma_value_t *lit_buffer_p = lit_pool_p->buffer_p; /* Compute the size of the literal pool. */ - while (iterator_p != NULL) + for (uint32_t i = 0; i < lit_pool_p->item_count; i++) { - if (ecma_is_value_float_number (*iterator_p)) + if (ecma_is_value_float_number (lit_buffer_p[i])) { lit_table_size += (uint32_t) sizeof (ecma_number_t); } else { - ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p); + ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]); lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p), JERRY_SNAPSHOT_LITERAL_ALIGNMENT); @@ -457,11 +455,9 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list /* Check whether enough space is available and the maximum size is not reached. */ if (lit_table_size > max_lit_table_size) { - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return false; } - - iterator_p = ecma_collection_iterator_next (iterator_p); } lit_mem_to_snapshot_id_map_entry_t *map_p; @@ -479,28 +475,28 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list *out_map_p = map_p; *out_map_len_p = total_count; - iterator_p = ecma_collection_iterator_init (lit_pool_p); + lit_buffer_p = lit_pool_p->buffer_p; /* Generate literal pool data. */ - while (iterator_p != NULL) + for (uint32_t i = 0; i < lit_pool_p->item_count; i++) { - map_p->literal_id = *iterator_p; + map_p->literal_id = lit_buffer_p[i]; map_p->literal_offset = (literal_offset << JERRY_SNAPSHOT_LITERAL_SHIFT) | ECMA_TYPE_SNAPSHOT_OFFSET; ecma_length_t length; - if (ecma_is_value_float_number (*iterator_p)) + if (ecma_is_value_float_number (lit_buffer_p[i])) { map_p->literal_offset |= JERRY_SNAPSHOT_LITERAL_IS_NUMBER; - ecma_number_t num = ecma_get_float_from_value (*iterator_p); + ecma_number_t num = ecma_get_float_from_value (lit_buffer_p[i]); memcpy (destination_p, &num, sizeof (ecma_number_t)); length = JERRY_ALIGNUP (sizeof (ecma_number_t), JERRY_SNAPSHOT_LITERAL_ALIGNMENT); } else { - ecma_string_t *string_p = ecma_get_string_from_value (*iterator_p); + ecma_string_t *string_p = ecma_get_string_from_value (lit_buffer_p[i]); length = ecma_string_get_size (string_p); *(uint16_t *) destination_p = (uint16_t) length; @@ -514,11 +510,10 @@ ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, /**< list destination_p += length; literal_offset += length; - iterator_p = ecma_collection_iterator_next (iterator_p); map_p++; } - ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY); + ecma_collection_destroy (lit_pool_p); return true; } /* ecma_save_literals_for_snapshot */ diff --git a/jerry-core/ecma/base/ecma-literal-storage.h b/jerry-core/ecma/base/ecma-literal-storage.h index 6f296a7ce..debbcc50a 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.h +++ b/jerry-core/ecma/base/ecma-literal-storage.h @@ -44,10 +44,10 @@ ecma_value_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, ecma_value_t ecma_find_or_create_literal_number (ecma_number_t number_arg); #if ENABLED (JERRY_SNAPSHOT_SAVE) -void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_header_t *lit_pool_p); +void ecma_save_literals_append_value (ecma_value_t value, ecma_collection_t *lit_pool_p); void ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_p, - ecma_collection_header_t *lit_pool_p); -bool ecma_save_literals_for_snapshot (ecma_collection_header_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size, + ecma_collection_t *lit_pool_p); +bool ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, uint32_t *buffer_p, size_t buffer_size, size_t *in_out_buffer_offset_p, lit_mem_to_snapshot_id_map_entry_t **out_map_p, uint32_t *out_map_len_p); #endif /* ENABLED (JERRY_SNAPSHOT_SAVE) */ 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 970455b29..9e2a9f494 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -952,17 +952,16 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum return ecma_raise_type_error (ECMA_ERR_MSG ("Compare function is not callable.")); } - ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES); + ecma_collection_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES); uint32_t defined_prop_count = 0; - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (array_index_props_p); + ecma_value_t *buffer_p = array_index_props_p->buffer_p; /* Count properties with name that is array index less than len */ - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < array_index_props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); uint32_t index = ecma_string_get_array_index (property_name_p); JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX); @@ -977,13 +976,12 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum uint32_t copied_num = 0; JMEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t); - ecma_value_p = ecma_collection_iterator_init (array_index_props_p); + buffer_p = array_index_props_p->buffer_p; /* Copy unsorted array into a native c array. */ - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < array_index_props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); uint32_t index = ecma_string_get_array_index (property_name_p); JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX); @@ -1045,7 +1043,7 @@ clean_up: if (ECMA_IS_VALUE_ERROR (ret_value)) { - ecma_free_values_collection (array_index_props_p, 0); + ecma_collection_free (array_index_props_p); return ret_value; } @@ -1053,12 +1051,11 @@ clean_up: /* Undefined properties should be in the back of the array. */ - ecma_value_p = ecma_collection_iterator_init (array_index_props_p); + buffer_p = array_index_props_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < array_index_props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); uint32_t index = ecma_string_get_array_index (property_name_p); JERRY_ASSERT (index != ECMA_STRING_NOT_ARRAY_INDEX); @@ -1069,13 +1066,13 @@ clean_up: if (ECMA_IS_VALUE_ERROR (del_value)) { - ecma_free_values_collection (array_index_props_p, 0); + ecma_collection_free (array_index_props_p); return del_value; } } } - ecma_free_values_collection (array_index_props_p, 0); + ecma_collection_free (array_index_props_p); return ecma_copy_value (this_arg); } /* ecma_builtin_array_prototype_object_sort */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c index d3cdcb127..e89cfe9dc 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c @@ -63,21 +63,19 @@ ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, /**< s * @return true, if the string is already in the collection. */ bool -ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**< collection */ +ecma_has_string_value_in_collection (ecma_collection_t *collection_p, /**< collection */ ecma_string_t *string_p) /**< string */ { - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (collection_p); + ecma_value_t *buffer_p = collection_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < collection_p->item_count; i++) { - ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p); + ecma_string_t *current_p = ecma_get_string_from_value (buffer_p[i]); if (ecma_compare_ecma_strings (current_p, string_p)) { return true; } - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } return false; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index 06746cd90..6cf9262be 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -278,29 +278,22 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */ JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array)); ecma_object_t *new_array_p = ecma_get_object_from_value (new_array); - uint32_t index = 0; - - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, opts); + ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, opts); if (props_p->item_count == 0) { - ecma_free_values_collection (props_p, 0); + ecma_collection_destroy (props_p); return new_array; } JERRY_ASSERT (((ecma_extended_object_t *) new_array_p)->u.array.is_fast_mode); + ecma_value_t *buffer_p = props_p->buffer_p; ecma_value_t *values_p = ecma_fast_array_extend (new_array_p, props_p->item_count); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + memcpy (values_p, buffer_p, props_p->item_count * sizeof (ecma_value_t)); - while (ecma_value_p != NULL) - { - values_p[index++] = ecma_copy_value_if_not_object (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); - } - - ecma_free_values_collection (props_p, 0); + ecma_collection_free_objects (props_p); return new_array; } /* ecma_builtin_helper_object_get_properties */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 5d46171c2..319811a80 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -153,7 +153,7 @@ typedef struct struct_ecma_json_occurence_stack_item_t typedef struct { /** Collection for property keys. */ - ecma_collection_header_t *property_list_p; + ecma_collection_t *property_list_p; /** Collection for traversing objects. */ ecma_json_occurence_stack_item_t *occurence_stack_last_p; @@ -175,15 +175,11 @@ ecma_value_t ecma_builtin_json_parse_buffer (const lit_utf8_byte_t * str_start_p lit_utf8_size_t string_size); ecma_value_t ecma_builtin_json_string_from_object (const ecma_value_t arg1); bool ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, ecma_object_t *object_p); -bool ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, ecma_string_t *string_p); +bool ecma_has_string_value_in_collection (ecma_collection_t *collection_p, ecma_string_t *string_p); -ecma_value_t -ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket, - ecma_string_t *stepback_p, ecma_collection_header_t *partial_p, - ecma_json_stringify_context_t *context_p); ecma_value_t ecma_builtin_helper_json_create_non_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket, - ecma_collection_header_t *partial_p); + ecma_collection_t *partial_p); #endif /* ENABLED (JERRY_BUILTIN_JSON) */ /* ecma-builtin-helper-error.c */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index d84d68593..494a61612 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -636,15 +636,14 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f { ecma_object_t *object_p = ecma_get_object_from_value (value); - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE); + ecma_collection_t *props_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; /* 3.d.iii */ - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); /* 3.d.iii.1 */ ecma_value_t result = ecma_builtin_json_internalize_property (reviver_p, object_p, property_name_p); @@ -652,7 +651,7 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f /* 3.d.iii.2 */ if (ECMA_IS_VALUE_ERROR (result)) { - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); ecma_deref_object (object_p); return result; @@ -676,7 +675,7 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f } } - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); } ecma_value_t arguments_list[2]; @@ -898,7 +897,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /* const bool has_gap = !ecma_compare_ecma_string_to_magic_id (context_p->gap_str_p, LIT_MAGIC_STRING__EMPTY); const lit_utf8_size_t separator_size = ecma_stringbuilder_get_size (&context_p->indent_builder); - ecma_collection_header_t *property_keys_p; + ecma_collection_t *property_keys_p; /* 5. */ if (context_p->property_list_p->item_count > 0) { @@ -911,14 +910,14 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /* } /* 8. */ - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (property_keys_p); + ecma_value_t *buffer_p = property_keys_p->buffer_p; ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_LEFT_BRACE); const lit_utf8_size_t left_brace = ecma_stringbuilder_get_size (&context_p->result_builder); lit_utf8_size_t last_prop = left_brace; - ecma_value_t result = ECMA_VALUE_EMPTY; - while (ecma_value_p != NULL) + + for (uint32_t i = 0; i < property_keys_p->item_count; i++) { if (has_gap) { @@ -927,7 +926,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /* separator_size); } - ecma_string_t *key_p = ecma_get_string_from_value (*ecma_value_p); + ecma_string_t *key_p = ecma_get_string_from_value (buffer_p[i]); ecma_builtin_json_quote (&context_p->result_builder, key_p); ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_COLON); @@ -958,8 +957,6 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /* /* The property should not be appended, we must backtrack. */ ecma_stringbuilder_revert (&context_p->result_builder, last_prop); } - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } if (last_prop != left_brace) @@ -988,7 +985,7 @@ ecma_builtin_json_serialize_object (ecma_json_stringify_context_t *context_p, /* cleanup: if (context_p->property_list_p->item_count == 0) { - ecma_free_values_collection (property_keys_p, 0); + ecma_collection_free (property_keys_p); } return result; @@ -1334,7 +1331,7 @@ ecma_builtin_json_string_from_object (const ecma_value_t arg1) /**< object argum ecma_json_stringify_context_t context; context.occurence_stack_last_p = NULL; context.indent_builder = ecma_stringbuilder_create (); - context.property_list_p = ecma_new_values_collection (); + context.property_list_p = ecma_new_collection (); context.replacer_function_p = NULL; context.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); @@ -1342,7 +1339,7 @@ ecma_builtin_json_string_from_object (const ecma_value_t arg1) /**< object argum ecma_deref_ecma_string (context.gap_str_p); ecma_stringbuilder_destroy (&context.indent_builder); - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); return ret_value; } /*ecma_builtin_json_string_from_object*/ @@ -1365,7 +1362,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ ecma_json_stringify_context_t context; context.replacer_function_p = NULL; - context.property_list_p = ecma_new_values_collection (); + context.property_list_p = ecma_new_collection (); /* 4. */ if (ecma_is_value_object (arg2)) @@ -1393,7 +1390,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (ECMA_IS_VALUE_ERROR (value)) { - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); return value; } @@ -1422,7 +1419,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (ECMA_IS_VALUE_ERROR (str_val)) { - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); ecma_free_value (value); return str_val; } @@ -1440,7 +1437,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (!ecma_has_string_value_in_collection (context.property_list_p, string_p)) { - ecma_append_to_values_collection (context.property_list_p, item, ECMA_COLLECTION_NO_COPY); + ecma_collection_push_back (context.property_list_p, item); } else { @@ -1468,7 +1465,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (ECMA_IS_VALUE_ERROR (value)) { - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); return value; } @@ -1481,7 +1478,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (ECMA_IS_VALUE_ERROR (value)) { - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); return value; } @@ -1554,7 +1551,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ ecma_deref_ecma_string (context.gap_str_p); ecma_stringbuilder_destroy (&context.indent_builder); - ecma_free_values_collection (context.property_list_p, 0); + ecma_collection_free (context.property_list_p); return ret_value; } /* ecma_builtin_json_stringify */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index f6e0439df..e7e4dc33b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -321,14 +321,13 @@ ecma_builtin_object_object_get_own_property_symbols (ecma_object_t *obj_p) /**< static ecma_value_t ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument */ { - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS); + ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); /* 2.a */ ecma_property_descriptor_t prop_desc; @@ -351,14 +350,14 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument * if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) { - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return define_own_prop_ret; } ecma_free_value (define_own_prop_ret); } - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); /* 3. */ ecma_set_object_extensible (obj_p, false); @@ -380,14 +379,13 @@ ecma_builtin_object_object_seal (ecma_object_t *obj_p) /**< routine's argument * static ecma_value_t ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument */ { - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS); + ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); /* 2.a */ ecma_property_descriptor_t prop_desc; @@ -417,14 +415,14 @@ ecma_builtin_object_object_freeze (ecma_object_t *obj_p) /**< routine's argument if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) { - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return define_own_prop_ret; } ecma_free_value (define_own_prop_ret); } - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); /* 3. */ ecma_set_object_extensible (obj_p, false); @@ -478,14 +476,13 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine' ecma_value_t ret_value = ECMA_VALUE_TRUE; /* 2. */ - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS); + ecma_collection_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[i]); /* 2.a */ ecma_property_t property = ecma_op_object_get_own_property (obj_p, @@ -510,7 +507,7 @@ ecma_builtin_object_frozen_or_sealed_helper (ecma_object_t *obj_p, /**< routine' } } - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return ret_value; } /* ecma_builtin_object_frozen_or_sealed_helper */ @@ -597,21 +594,20 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine ecma_object_t *props_p = ecma_get_object_from_value (props); /* 3. */ - ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_CONVERT_FAST_ARRAYS - | ECMA_LIST_ENUMERABLE); - uint32_t property_number = prop_names_p->item_count; + ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_CONVERT_FAST_ARRAYS + | ECMA_LIST_ENUMERABLE); ecma_value_t ret_value = ECMA_VALUE_ERROR; - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p); + ecma_value_t *buffer_p = prop_names_p->buffer_p; /* 4. */ - JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, property_number, ecma_property_descriptor_t); + JMEM_DEFINE_LOCAL_ARRAY (property_descriptors, prop_names_p->item_count, ecma_property_descriptor_t); uint32_t property_descriptor_number = 0; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < prop_names_p->item_count; i++) { /* 5.a */ - ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (*ecma_value_p)); + ecma_value_t desc_obj = ecma_op_object_get (props_p, ecma_get_string_from_value (buffer_p[i])); if (ECMA_IS_VALUE_ERROR (desc_obj)) { @@ -634,26 +630,22 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine property_descriptor_number++; ecma_free_value (conv_result); - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } /* 6. */ - ecma_value_p = ecma_collection_iterator_init (prop_names_p); + buffer_p = prop_names_p->buffer_p; - for (uint32_t index = 0; index < property_number; index++) + for (uint32_t i = 0; i < prop_names_p->item_count; i++) { ecma_value_t define_own_prop_ret = ecma_op_object_define_own_property (obj_p, - ecma_get_string_from_value (*ecma_value_p), - &property_descriptors[index]); + ecma_get_string_from_value (buffer_p[i]), + &property_descriptors[i]); if (ECMA_IS_VALUE_ERROR (define_own_prop_ret)) { goto cleanup; } ecma_free_value (define_own_prop_ret); - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } ecma_ref_object (obj_p); @@ -670,7 +662,7 @@ cleanup: JMEM_FINALIZE_LOCAL_ARRAY (property_descriptors); - ecma_free_values_collection (prop_names_p, 0); + ecma_collection_free (prop_names_p); ecma_deref_object (props_p); @@ -821,14 +813,14 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a /* 5.b.iii */ /* TODO: extends this collection if symbols will be supported */ - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS - | ECMA_LIST_ENUMERABLE); + ecma_collection_t *props_p = ecma_op_object_get_property_names (from_obj_p, ECMA_LIST_CONVERT_FAST_ARRAYS + | ECMA_LIST_ENUMERABLE); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; - while (ecma_value_p != NULL && ecma_is_value_empty (ret_value)) + for (uint32_t j = 0; (j < props_p->item_count) && ecma_is_value_empty (ret_value); j++) { - ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p); + ecma_string_t *property_name_p = ecma_get_string_from_value (buffer_p[j]); /* 5.c.i-ii */ ecma_property_descriptor_t prop_desc; @@ -866,12 +858,10 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a ecma_free_value (prop_value); ecma_free_property_descriptor (&prop_desc); } - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } ecma_deref_object (from_obj_p); - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); } /* 6. */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 4db22e1c0..00927a53b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -898,24 +898,22 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in * properties, * false - list all properties into main collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable' - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped 'non-enumerable' + * collection */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { - ecma_collection_header_t *for_enumerable_p = main_collection_p; + ecma_collection_t *for_enumerable_p = main_collection_p; JERRY_UNUSED (for_enumerable_p); - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 15) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); } else { @@ -941,7 +939,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in ecma_length_t index = 0; uint32_t *bitset_p = built_in_props_p->instantiated_bitset; - ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p + ecma_collection_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p : main_collection_p); while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT) @@ -969,11 +967,9 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in { ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id); - ecma_append_to_values_collection (for_non_enumerable_p, name, 0); + ecma_collection_push_back (for_non_enumerable_p, name); } - ecma_deref_ecma_string (name_p); - curr_property_p++; index++; } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index 8b2fbaec1..15d21c42e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -92,8 +92,8 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t void ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); bool ecma_builtin_is (ecma_object_t *obj_p, ecma_builtin_id_t builtin_id); ecma_object_t * diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 087145f09..f144b8e6b 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -492,7 +492,7 @@ ecma_fast_array_set_length (ecma_object_t *object_p, /**< fast access mode array * * @return collection of strings - property names */ -ecma_collection_header_t * +ecma_collection_t * ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mode array object */ uint32_t opts) /**< any combination of ecma_list_properties_options_t values */ { @@ -501,7 +501,7 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; JERRY_ASSERT (ext_obj_p->u.array.is_fast_mode); - ecma_collection_header_t *ret_p = ecma_new_values_collection (); + ecma_collection_t *ret_p = ecma_new_collection (); #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) if (opts & ECMA_LIST_SYMBOLS) @@ -518,7 +518,7 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo { if (append_length) { - ecma_append_to_values_collection (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), 0); + ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); } return ret_p; @@ -535,12 +535,12 @@ ecma_fast_array_get_property_names (ecma_object_t *object_p, /**< fast access mo ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i); - ecma_append_to_values_collection (ret_p, ecma_make_string_value (index_str_p), ECMA_COLLECTION_NO_COPY); + ecma_collection_push_back (ret_p, ecma_make_string_value (index_str_p)); } if (append_length) { - ecma_append_to_values_collection (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), 0); + ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); } if (opts & ECMA_LIST_CONVERT_FAST_ARRAYS) @@ -1094,19 +1094,16 @@ ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obje * false - list all properties into main * collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' - * collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped - * 'non-enumerable' - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped + * 'non-enumerable' + * collection */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY); - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); } /* ecma_op_array_list_lazy_property_names */ /** diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index 876878be7..b5de122f9 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -62,7 +62,7 @@ void ecma_array_object_delete_property (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_property_value_t *prop_value_p); -ecma_collection_header_t * +ecma_collection_t * ecma_fast_array_get_property_names (ecma_object_t *object_p, uint32_t opts); void @@ -87,8 +87,8 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t void ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); /** * @} diff --git a/jerry-core/ecma/operations/ecma-container-object.c b/jerry-core/ecma/operations/ecma-container-object.c index 1bfe48f29..3d5aab9c4 100644 --- a/jerry-core/ecma/operations/ecma-container-object.c +++ b/jerry-core/ecma/operations/ecma-container-object.c @@ -457,23 +457,22 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value); - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS); + ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS); - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; ecma_value_t ret_value = ECMA_VALUE_UNDEFINED; ecma_ref_object (internal_obj_p); - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { - ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p); + ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]); ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p); JERRY_ASSERT (property_p != NULL); if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) { - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); continue; } @@ -497,7 +496,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ } else { - key_arg = *ecma_value_p; + key_arg = buffer_p[i]; } } @@ -514,12 +513,10 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */ } ecma_free_value (call_value); - - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); } ecma_deref_object (internal_obj_p); - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return ret_value; } /* ecma_op_container_foreach */ @@ -664,7 +661,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */ ecma_map_object_t *map_object_p = (ecma_map_object_t *) (ecma_get_object_from_value (iterated_value)); ecma_object_t *internal_obj_p = ecma_get_object_from_value (map_object_p->header.u.class_prop.u.value); - ecma_collection_header_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS); + ecma_collection_t *props_p = ecma_op_object_get_property_names (internal_obj_p, ECMA_LIST_NO_OPTS); uint32_t length = props_p->item_count; uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index; @@ -698,34 +695,31 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */ if (index >= length) { ext_obj_p->u.pseudo_array.u2.iterated_value = ECMA_VALUE_EMPTY; - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE); } uint8_t iterator_kind = ext_obj_p->u.pseudo_array.extra_info; - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p); + ecma_value_t *buffer_p = props_p->buffer_p; ecma_value_t ret_value = ECMA_VALUE_UNDEFINED; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < props_p->item_count; i++) { if (index > 0) { index--; - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); continue; } - ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (*ecma_value_p); + ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[i]); ecma_property_t *property_p = ecma_find_named_property (internal_obj_p, prop_name_p); JERRY_ASSERT (property_p != NULL); if (ecma_is_value_empty (ECMA_PROPERTY_VALUE_PTR (property_p)->value)) { - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); - - if (ecma_value_p == NULL) + if (i == props_p->item_count - 1) { ret_value = ecma_create_iter_result_object (ECMA_VALUE_UNDEFINED, ECMA_VALUE_TRUE); } @@ -752,7 +746,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */ } else { - key_arg = *ecma_value_p; + key_arg = buffer_p[i]; } } @@ -779,7 +773,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */ break; } - ecma_free_values_collection (props_p, 0); + ecma_collection_free (props_p); return ret_value; } /* ecma_op_container_iterator_next */ diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 35bd9db8b..d1296f352 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -1416,24 +1416,20 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio * false - list all properties into main * collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped - * 'non-enumerable' - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped + * 'non-enumerable' + * collection */ { JERRY_UNUSED (main_collection_p); - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE)); const ecma_compiled_code_t *bytecode_data_p; @@ -1453,14 +1449,10 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) { /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER)); /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS)); } } /* ecma_op_function_list_lazy_property_names */ @@ -1480,19 +1472,16 @@ ecma_op_external_function_list_lazy_property_names (bool separate_enumerable, /* * false - list all properties into * main collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' - * collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped + * collection */ { JERRY_UNUSED (main_collection_p); - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE)); } /* ecma_op_external_function_list_lazy_property_names */ /** @@ -1511,30 +1500,23 @@ ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable, /**< * false - list all properties into * main collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' - * collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped - * 'non-enumerable' - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped + * 'non-enumerable' + * collection */ { JERRY_UNUSED (main_collection_p); - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER)); /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */ - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS)); } /* ecma_op_bound_function_list_lazy_property_names */ /** diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index 91f7056b1..b5be3358f 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -97,18 +97,18 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p void ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); void ecma_op_external_function_list_lazy_property_names (bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); void ecma_op_bound_function_list_lazy_property_names (bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); /** * @} diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index d45ea66bc..4244aa82a 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1654,7 +1654,7 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */ * * @return collection of strings - property names */ -ecma_collection_header_t * +ecma_collection_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ uint32_t opts) /**< any combination of ecma_list_properties_options_t values */ { @@ -1671,8 +1671,8 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } } - ecma_collection_header_t *ret_p = ecma_new_values_collection (); - ecma_collection_header_t *skipped_non_enumerable_p = ecma_new_values_collection (); + ecma_collection_t *ret_p = ecma_new_collection (); + ecma_collection_t *skipped_non_enumerable_p = ecma_new_collection (); const ecma_object_type_t type = ecma_get_object_type (obj_p); const bool obj_is_builtin = ecma_get_object_is_builtin (obj_p); @@ -1696,7 +1696,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ ecma_length_t string_named_properties_count = 0; ecma_length_t array_index_named_properties_count = 0; - ecma_collection_header_t *prop_names_p = ecma_new_values_collection (); + ecma_collection_t *prop_names_p = ecma_new_collection (); #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) if (JERRY_LIKELY (!is_symbols_only)) @@ -1783,23 +1783,21 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p); + ecma_value_t *buffer_p = prop_names_p->buffer_p; const size_t own_names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size; JERRY_VLA (uint32_t, own_names_hashes_bitmap, own_names_hashes_bitmap_size); memset (own_names_hashes_bitmap, 0, own_names_hashes_bitmap_size * sizeof (own_names_hashes_bitmap[0])); - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < prop_names_p->item_count; i++) { - ecma_string_t *name_p = ecma_get_string_from_value (*ecma_value_p); + ecma_string_t *name_p = ecma_get_string_from_value (buffer_p[i]); #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) /* Symbols are never lazy listed */ JERRY_ASSERT (!ecma_prop_name_is_symbol (name_p)); #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); - uint8_t hash = (uint8_t) ecma_string_hash (name_p); uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); @@ -1839,12 +1837,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) { - ecma_value_p = ecma_collection_iterator_init (prop_names_p); + buffer_p = prop_names_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t j = 0; j < prop_names_p->item_count; j++) { - ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); if (ecma_compare_ecma_strings (index_str_p, current_name_p)) { @@ -1858,9 +1855,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ { own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); - ecma_append_to_values_collection (prop_names_p, - ecma_make_string_value (index_str_p), - ECMA_COLLECTION_NO_COPY); + ecma_collection_push_back (prop_names_p, ecma_make_string_value (index_str_p)); } } } @@ -1926,12 +1921,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) { - ecma_value_p = ecma_collection_iterator_init (prop_names_p); + buffer_p = prop_names_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t j = 0; j < prop_names_p->item_count; j++) { - ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); if (ecma_compare_ecma_strings (name_p, current_name_p)) { @@ -1945,21 +1939,19 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ { own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); - ecma_append_to_values_collection (prop_names_p, - ecma_make_prop_name_value (name_p), - 0); + ecma_collection_push_back (prop_names_p, ecma_make_prop_name_value (name_p)); + } + else + { + ecma_deref_ecma_string (name_p); } } else { JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (*property_p)); - ecma_append_to_values_collection (skipped_non_enumerable_p, - ecma_make_prop_name_value (name_p), - 0); + ecma_collection_push_back (skipped_non_enumerable_p, ecma_make_prop_name_value (name_p)); } - - ecma_deref_ecma_string (name_p); } } @@ -1967,12 +1959,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ } } - ecma_value_p = ecma_collection_iterator_init (prop_names_p); + buffer_p = prop_names_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < prop_names_p->item_count; i++) { - ecma_string_t *name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *name_p = ecma_get_prop_name_from_value (buffer_p[i]); uint32_t index = ecma_string_get_array_index (name_p); @@ -1996,12 +1987,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ uint32_t name_pos = array_index_named_properties_count + string_named_properties_count; uint32_t array_index_name_pos = 0; - ecma_value_p = ecma_collection_iterator_init (prop_names_p); + buffer_p = prop_names_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < prop_names_p->item_count; i++) { - ecma_string_t *name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *name_p = ecma_get_prop_name_from_value (buffer_p[i]); uint32_t index = ecma_string_get_array_index (name_p); @@ -2062,7 +2052,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ JMEM_FINALIZE_LOCAL_ARRAY (array_index_names_p); - ecma_free_values_collection (prop_names_p, 0); + ecma_collection_free (prop_names_p); /* Third pass: * embedding own property names of current object of prototype chain to aggregate property names collection */ @@ -2086,12 +2076,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ else { /* Name with same hash has already occured. */ - ecma_value_p = ecma_collection_iterator_init (ret_p); + buffer_p = ret_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t j = 0; j < ret_p->item_count; j++) { - ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); if (ecma_compare_ecma_strings (name_p, current_name_p)) { @@ -2103,12 +2092,11 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ if (is_append) { - ecma_value_p = ecma_collection_iterator_init (skipped_non_enumerable_p); + buffer_p = skipped_non_enumerable_p->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t j = 0; j < skipped_non_enumerable_p->item_count; j++) { - ecma_string_t *current_name_p = ecma_get_prop_name_from_value (*ecma_value_p); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); if (ecma_compare_ecma_strings (name_p, current_name_p)) { @@ -2122,10 +2110,13 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ { JERRY_ASSERT ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0); - ecma_append_to_values_collection (ret_p, ecma_make_prop_name_value (names_p[i]), 0); + ecma_collection_push_back (ret_p, ecma_make_prop_name_value (name_p)); + } + else + { + ecma_deref_ecma_string (name_p); } - ecma_deref_ecma_string (name_p); } JMEM_FINALIZE_LOCAL_ARRAY (names_p); @@ -2140,7 +2131,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ prototype_chain_iter_p->u2.prototype_cp); } - ecma_free_values_collection (skipped_non_enumerable_p, 0); + ecma_collection_free (skipped_non_enumerable_p); return ret_p; } /* ecma_op_object_get_property_names */ diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index 8802e4be1..c416ed2bd 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -57,7 +57,7 @@ bool ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_s ecma_property_descriptor_t *prop_desc_p); ecma_value_t ecma_op_object_has_instance (ecma_object_t *obj_p, ecma_value_t value); bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p); -ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts); +ecma_collection_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts); lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p); bool ecma_object_class_is (ecma_object_t *object_p, uint32_t class_id); diff --git a/jerry-core/ecma/operations/ecma-promise-object.c b/jerry-core/ecma/operations/ecma-promise-object.c index a785dd704..d60a94872 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.c +++ b/jerry-core/ecma/operations/ecma-promise-object.c @@ -145,15 +145,14 @@ ecma_set_already_resolved_value (ecma_value_t already_resolved, /**< the already * See also: ES2015 25.4.1.8 */ static void -ecma_promise_trigger_reactions (ecma_collection_header_t *reactions, /**< lists of reactions */ +ecma_promise_trigger_reactions (ecma_collection_t *reactions, /**< lists of reactions */ ecma_value_t value) /**< value for resolve or reject */ { - ecma_value_t *ecma_value_p = ecma_collection_iterator_init (reactions); + ecma_value_t *buffer_p = reactions->buffer_p; - while (ecma_value_p != NULL) + for (uint32_t i = 0; i < reactions->item_count; i++) { - ecma_enqueue_promise_reaction_job (*ecma_value_p, value); - ecma_value_p = ecma_collection_iterator_next (ecma_value_p); + ecma_enqueue_promise_reaction_job (buffer_p[i], value); } } /* ecma_promise_trigger_reactions */ @@ -174,19 +173,19 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */ ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (reason)); ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p; - /* GC can be triggered by ecma_new_values_collection so freeing the collection + /* GC can be triggered by ecma_new_collection so freeing the collection first and creating a new one might cause a heap after use event. */ - ecma_collection_header_t *reject_reactions = promise_p->reject_reactions; - ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions; + ecma_collection_t *reject_reactions = promise_p->reject_reactions; + ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions; /* Fulfill reactions will never be triggered. */ ecma_promise_trigger_reactions (reject_reactions, reason); - promise_p->reject_reactions = ecma_new_values_collection (); - promise_p->fulfill_reactions = ecma_new_values_collection (); + promise_p->reject_reactions = ecma_new_collection (); + promise_p->fulfill_reactions = ecma_new_collection (); - ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS); - ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS); + ecma_collection_free_if_not_object (reject_reactions); + ecma_collection_free_if_not_object (fulfill_reactions); } /* ecma_reject_promise */ /** @@ -206,19 +205,19 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */ ecma_promise_set_result (obj_p, ecma_copy_value_if_not_object (value)); ecma_promise_object_t *promise_p = (ecma_promise_object_t *) obj_p; - /* GC can be triggered by ecma_new_values_collection so freeing the collection + /* GC can be triggered by ecma_new_collection so freeing the collection first and creating a new one might cause a heap after use event. */ - ecma_collection_header_t *reject_reactions = promise_p->reject_reactions; - ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions; + ecma_collection_t *reject_reactions = promise_p->reject_reactions; + ecma_collection_t *fulfill_reactions = promise_p->fulfill_reactions; /* Reject reactions will never be triggered. */ ecma_promise_trigger_reactions (fulfill_reactions, value); - promise_p->reject_reactions = ecma_new_values_collection (); - promise_p->fulfill_reactions = ecma_new_values_collection (); + promise_p->reject_reactions = ecma_new_collection (); + promise_p->fulfill_reactions = ecma_new_collection (); - ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS); - ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS); + ecma_collection_free_if_not_object (reject_reactions); + ecma_collection_free_if_not_object (fulfill_reactions); } /* ecma_fulfill_promise */ /** @@ -502,8 +501,8 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function /* 5 */ ecma_promise_set_state (object_p, ECMA_PROMISE_STATE_PENDING); /* 6-7. */ - promise_object_p->fulfill_reactions = ecma_new_values_collection (); - promise_object_p->reject_reactions = ecma_new_values_collection (); + promise_object_p->fulfill_reactions = ecma_new_collection (); + promise_object_p->reject_reactions = ecma_new_collection (); /* 8. */ ecma_promise_resolving_functions_t *funcs = ecma_promise_create_resolving_functions (object_p); @@ -706,13 +705,8 @@ ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' * if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_PENDING) { /* 7. */ - ecma_append_to_values_collection (promise_p->fulfill_reactions, - ecma_make_object_value (fulfill_reaction_p), - ECMA_COLLECTION_NO_REF_OBJECTS); - - ecma_append_to_values_collection (promise_p->reject_reactions, - ecma_make_object_value (reject_reaction_p), - ECMA_COLLECTION_NO_REF_OBJECTS); + ecma_collection_push_back (promise_p->fulfill_reactions, ecma_make_object_value (fulfill_reaction_p)); + ecma_collection_push_back (promise_p->reject_reactions, ecma_make_object_value (reject_reaction_p)); } else if (ecma_promise_get_state (obj_p) == ECMA_PROMISE_STATE_FULFILLED) { diff --git a/jerry-core/ecma/operations/ecma-promise-object.h b/jerry-core/ecma/operations/ecma-promise-object.h index ad1e8777b..2e71b6225 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.h +++ b/jerry-core/ecma/operations/ecma-promise-object.h @@ -64,8 +64,8 @@ typedef struct { ecma_extended_object_t ecma_extended_object_t; /**< extended object part */ uint8_t state; /**< promise state, see ecma_promise_state_t */ - ecma_collection_header_t *fulfill_reactions; /**< list of PromiseFullfillReactions */ - ecma_collection_header_t *reject_reactions; /**< list of PromiseRejectReactions */ + ecma_collection_t *fulfill_reactions; /**< list of PromiseFullfillReactions */ + ecma_collection_t *reject_reactions; /**< list of PromiseRejectReactions */ } ecma_promise_object_t; bool ecma_is_promise (ecma_object_t *obj_p); diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index e3dc117c4..2f3a11ecd 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -91,17 +91,16 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj * false - list all properties into main * collection. */ - ecma_collection_header_t *main_collection_p, /**< 'main' - * collection */ - ecma_collection_header_t *non_enum_collection_p) /**< skipped - * 'non-enumerable' - * collection */ + ecma_collection_t *main_collection_p, /**< 'main' collection */ + ecma_collection_t *non_enum_collection_p) /**< skipped + * 'non-enumerable' + * collection */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS); - ecma_collection_header_t *for_enumerable_p = main_collection_p; + ecma_collection_t *for_enumerable_p = main_collection_p; - ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; + ecma_collection_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL); @@ -115,14 +114,10 @@ ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String obj ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i); /* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */ - ecma_append_to_values_collection (for_enumerable_p, ecma_make_string_value (name_p), 0); - - ecma_deref_ecma_string (name_p); + ecma_collection_push_back (for_enumerable_p, ecma_make_string_value (name_p)); } - ecma_append_to_values_collection (for_non_enumerable_p, - ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), - 0); + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); } /* ecma_op_string_list_lazy_property_names */ /** diff --git a/jerry-core/ecma/operations/ecma-string-object.h b/jerry-core/ecma/operations/ecma-string-object.h index 5c7d80508..b1c4b7ad9 100644 --- a/jerry-core/ecma/operations/ecma-string-object.h +++ b/jerry-core/ecma/operations/ecma-string-object.h @@ -31,8 +31,8 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, ecma_length_ void ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable, - ecma_collection_header_t *main_collection_p, - ecma_collection_header_t *non_enum_collection_p); + ecma_collection_t *main_collection_p, + ecma_collection_t *non_enum_collection_p); /** diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index e4b371c95..1ab64870d 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -765,8 +765,7 @@ ecma_is_typedarray (ecma_value_t value) /**< the target need to be checked */ */ void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */ - ecma_collection_header_t *main_collection_p) /**< 'main' - * collection */ + ecma_collection_t *main_collection_p) /**< 'main' collection */ { JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p))); @@ -776,9 +775,7 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA { ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i); - ecma_append_to_values_collection (main_collection_p, ecma_make_string_value (name_p), 0); - - ecma_deref_ecma_string (name_p); + ecma_collection_push_back (main_collection_p, ecma_make_string_value (name_p)); } } /* ecma_op_typedarray_list_lazy_property_names */ diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index 1b82af6fa..8c7612f04 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -50,7 +50,7 @@ void ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, ecma_number_t ecma_get_typedarray_element (lit_utf8_byte_t *src, lit_magic_string_id_t class_id); void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, - ecma_collection_header_t *main_collection_p); + ecma_collection_t *main_collection_p); ecma_value_t ecma_op_typedarray_get_index_prop (ecma_object_t *obj_p, uint32_t index); bool ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, uint32_t index, diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index d0e3dc7ab..485f102b4 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -226,17 +226,15 @@ vm_op_delete_var (ecma_value_t name_literal, /**< name literal */ * * @return chain list of property names */ -ecma_collection_chunk_t * +ecma_collection_t * opfunc_for_in (ecma_value_t left_value, /**< left value */ ecma_value_t *result_obj_p) /**< expression object */ { - ecma_collection_chunk_t *prop_names_p = NULL; - /* 3. */ if (ecma_is_value_undefined (left_value) || ecma_is_value_null (left_value)) { - return prop_names_p; + return NULL; } /* 4. */ @@ -244,24 +242,18 @@ opfunc_for_in (ecma_value_t left_value, /**< left value */ /* ecma_op_to_object will only raise error on null/undefined values but those are handled above. */ JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_expr_value)); ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value); - ecma_collection_header_t *prop_names_coll_p; - prop_names_coll_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE); + ecma_collection_t *prop_names_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE); - if (prop_names_coll_p->item_count != 0) + if (prop_names_p->item_count != 0) { - prop_names_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t, - prop_names_coll_p->first_chunk_cp); - - ecma_ref_object (obj_p); *result_obj_p = ecma_make_object_value (obj_p); + return prop_names_p; } - /* Note: We release the collection header here, and return the chunk list of the collection, which will - * be handled and released by the vm loop. */ - jmem_pools_free (prop_names_coll_p, sizeof (ecma_collection_header_t)); - ecma_free_value (obj_expr_value); + ecma_deref_object (obj_p); + ecma_collection_destroy (prop_names_p); - return prop_names_p; + return NULL; } /* opfunc_for_in */ /** diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index 0df56ae59..faafba7c7 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -90,7 +90,7 @@ vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict); ecma_value_t vm_op_delete_var (ecma_value_t name_literal, ecma_object_t *lex_env_p); -ecma_collection_chunk_t * +ecma_collection_t * opfunc_for_in (ecma_value_t left_value, ecma_value_t *result_obj_p); /** diff --git a/jerry-core/vm/vm-stack.c b/jerry-core/vm/vm-stack.c index a3b76a36c..a00b0c022 100644 --- a/jerry-core/vm/vm-stack.c +++ b/jerry-core/vm/vm-stack.c @@ -94,31 +94,19 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ { JERRY_ASSERT (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]) == VM_CONTEXT_FOR_IN); - ecma_collection_chunk_t *chunk_p; - chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, vm_stack_top_p[-2]); - uint32_t index = vm_stack_top_p[-3]; + ecma_collection_t *collection_p; + collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, vm_stack_top_p[-2]); - while (chunk_p != NULL) + ecma_value_t *buffer_p = collection_p->buffer_p; + + for (uint32_t index = vm_stack_top_p[-3]; index < collection_p->item_count; index++) { - ecma_value_t value = chunk_p->items[index]; - - if (JERRY_UNLIKELY (ecma_is_value_pointer (value))) - { - ecma_collection_chunk_t *next_chunk_p; - next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value); - jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t)); - - chunk_p = next_chunk_p; - index = 0; - } - else - { - ecma_free_value (value); - index++; - } + ecma_free_value (buffer_p[index]); } - ecma_free_value (vm_stack_top_p[-4]); + ecma_collection_destroy (collection_p); + + ecma_deref_object (ecma_get_object_from_value (vm_stack_top_p[-4])); VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 0cc62e00f..20bb1dd64 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -2872,11 +2872,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p); ecma_value_t expr_obj_value = ECMA_VALUE_UNDEFINED; - ecma_collection_chunk_t *prop_names_p = opfunc_for_in (value, &expr_obj_value); + ecma_collection_t *prop_names_p = opfunc_for_in (value, &expr_obj_value); ecma_free_value (value); if (prop_names_p == NULL) { + /* The collection is already released */ byte_code_p = byte_code_start_p + branch_offset; continue; } @@ -2896,56 +2897,34 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { ecma_value_t *context_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth; - ecma_collection_chunk_t *chunk_p; - chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, context_top_p[-2]); + ecma_collection_t *collection_p; + collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_top_p[-2]); JERRY_ASSERT (VM_GET_CONTEXT_TYPE (context_top_p[-1]) == VM_CONTEXT_FOR_IN); uint32_t index = context_top_p[-3]; + ecma_value_t *buffer_p = collection_p->buffer_p; - JERRY_ASSERT (!ecma_is_value_pointer (chunk_p->items[index])); - - /* TODO: use collection iterator instead of directly accessing the collection chunks. */ - *stack_top_p++ = chunk_p->items[index]; - index++; - - if (JERRY_LIKELY (!ecma_is_value_pointer (chunk_p->items[index]))) - { - context_top_p[-3] = index; - continue; - } - - context_top_p[-3] = 0; - - ecma_collection_chunk_t *next_chunk_p; - next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (chunk_p->items[index]); - ECMA_SET_INTERNAL_VALUE_ANY_POINTER (context_top_p[-2], next_chunk_p); - - jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t)); + *stack_top_p++ = buffer_p[index]; + context_top_p[-3]++; continue; } case VM_OC_FOR_IN_HAS_NEXT: { JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p); - ecma_collection_chunk_t *chunk_p; - chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, stack_top_p[-2]); + ecma_collection_t *collection_p; + collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, stack_top_p[-2]); - uint32_t index = stack_top_p[-3]; + JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FOR_IN); + + ecma_value_t *buffer_p = collection_p->buffer_p; ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[-4]); + uint32_t index = stack_top_p[-3]; - while (true) + while (index < collection_p->item_count) { - if (chunk_p == NULL) - { - ecma_deref_object (object_p); - - VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); - stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; - break; - } - - ecma_string_t *prop_name_p = ecma_get_string_from_value (chunk_p->items[index]); + ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (buffer_p[index]); if (JERRY_LIKELY (ecma_op_object_has_property (object_p, prop_name_p))) { @@ -2953,27 +2932,20 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ break; } - index++; - ecma_value_t value = chunk_p->items[index]; - - if (JERRY_LIKELY (!ecma_is_value_pointer (value))) - { - stack_top_p[-3] = index; - } - else - { - index = 0; - stack_top_p[-3] = 0; - - ecma_collection_chunk_t *next_chunk_p; - next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value); - ECMA_SET_INTERNAL_VALUE_ANY_POINTER (stack_top_p[-2], next_chunk_p); - - jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t)); - chunk_p = next_chunk_p; - } - ecma_deref_ecma_string (prop_name_p); + index++; + } + + if (index == collection_p->item_count) + { + ecma_deref_object (object_p); + ecma_collection_destroy (collection_p); + VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION); + stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION; + } + else + { + stack_top_p[-3] = index; } continue; }