From 7131243ddafa54a9e81dfae2b7407f7f53e32a74 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Thu, 17 Nov 2016 13:26:02 +0100 Subject: [PATCH] Simplify ecma_property_types_t. (#1438) Free a new bit in the property descriptor by combining internal and special property types into one group. Also simplify checking special properties since bit-and operation is not needed anymore. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-gc.c | 33 ++++--------- jerry-core/ecma/base/ecma-globals.h | 49 +++++++++++++------ jerry-core/ecma/base/ecma-helpers.c | 40 ++++++--------- jerry-core/ecma/base/ecma-property-hashmap.c | 8 +-- .../ecma/operations/ecma-objects-general.c | 2 +- jerry-core/ecma/operations/ecma-objects.c | 3 +- 6 files changed, 66 insertions(+), 69 deletions(-) diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index 6fb595924..1a6676ead 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -197,7 +197,7 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */ } break; } - case ECMA_PROPERTY_TYPE_INTERNAL: + case ECMA_PROPERTY_TYPE_SPECIAL: { switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) { @@ -210,7 +210,8 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */ default: { - JERRY_UNREACHABLE (); + JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p) == ECMA_SPECIAL_PROPERTY_DELETED + || ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p) == ECMA_SPECIAL_PROPERTY_HASHMAP); break; } } @@ -312,26 +313,13 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */ { ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) - { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); - } - while (prop_iter_p != NULL) { - JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + JERRY_ASSERT (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP + || ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - if (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED) - { - ecma_gc_mark_property (prop_iter_p->types + 0); - } - - if (prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED) - { - ecma_gc_mark_property (prop_iter_p->types + 1); - } + ecma_gc_mark_property (prop_iter_p->types + 0); + ecma_gc_mark_property (prop_iter_p->types + 1); prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, prop_iter_p->next_property_cp); @@ -376,8 +364,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ { ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { ecma_property_hashmap_free (object_p); prop_iter_p = ecma_get_property_list (object_p); @@ -632,8 +619,8 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ || ecma_get_lex_env_type (obj_iter_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p); - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + + if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { ecma_property_hashmap_free (obj_iter_p); } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 8cc9ebd1d..b3f3971a0 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -197,6 +197,12 @@ typedef uintptr_t ecma_external_pointer_t; */ typedef enum { + ECMA_SPECIAL_PROPERTY_DELETED, /**< deleted property */ + + /* Note: when new special types are added + * ECMA_PROPERTY_IS_PROPERTY_PAIR must be updated as well. */ + ECMA_SPECIAL_PROPERTY_HASHMAP, /**< hashmap property */ + ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */ ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */ ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63, /**< Bit-mask of non-instantiated @@ -249,32 +255,44 @@ typedef enum */ typedef enum { - ECMA_PROPERTY_TYPE_DELETED, /**< deleted property */ - ECMA_PROPERTY_TYPE_INTERNAL, /**< internal property */ + ECMA_PROPERTY_TYPE_SPECIAL, /**< internal property */ ECMA_PROPERTY_TYPE_NAMEDDATA, /**< property is named data */ ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< property is named accessor */ + ECMA_PROPERTY_TYPE_VIRTUAL, /**< property is virtual */ - ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX = ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< highest value for - * property pair types. */ - - ECMA_PROPERTY_TYPE_HASHMAP, /**< hash map for fast property access */ - - ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_HASHMAP, /**< highest value for property types. */ - - /* Property type aliases. */ - ECMA_PROPERTY_TYPE_NOT_FOUND = ECMA_PROPERTY_TYPE_DELETED, /**< property is not found */ - ECMA_PROPERTY_TYPE_VIRTUAL = ECMA_PROPERTY_TYPE_HASHMAP, /**< property is virtual */ + ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_VIRTUAL, /**< highest value for property types. */ } ecma_property_types_t; /** * Property type mask. */ -#define ECMA_PROPERTY_TYPE_MASK 0x7 +#define ECMA_PROPERTY_TYPE_MASK 0x3 /** * Property flags base shift. */ -#define ECMA_PROPERTY_FLAG_SHIFT 3 +#define ECMA_PROPERTY_FLAG_SHIFT 2 + +/** + * Define special property type. + */ +#define ECMA_SPECIAL_PROPERTY_VALUE(type) \ + ((uint8_t) (ECMA_PROPERTY_TYPE_SPECIAL | ((type) << ECMA_PROPERTY_FLAG_SHIFT))) + +/** + * Type of deleted property. + */ +#define ECMA_PROPERTY_TYPE_DELETED ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_DELETED) + +/** + * Type of hash-map property. + */ +#define ECMA_PROPERTY_TYPE_HASHMAP ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_HASHMAP) + +/** + * Type of property not found. + */ +#define ECMA_PROPERTY_TYPE_NOT_FOUND ECMA_PROPERTY_TYPE_DELETED /** * Property flag list (for ECMA_PROPERTY_TYPE_NAMEDDATA @@ -397,7 +415,8 @@ typedef struct * Returns true if the property pointer is a property pair. */ #define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \ - (ECMA_PROPERTY_GET_TYPE ((property_header_p)->types[0]) <= ECMA_PROPERTY_TYPE_PROPERTY_PAIR__MAX) + (ECMA_PROPERTY_GET_TYPE ((property_header_p)->types[0]) != ECMA_PROPERTY_TYPE_VIRTUAL \ + && (property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP) /** * Returns the internal property type diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index ce48b7087..04ca1282c 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -394,7 +394,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ *property_list_head_p); bool has_hashmap = false; - if (ECMA_PROPERTY_GET_TYPE (first_property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { property_list_head_p = &first_property_p->next_property_cp; first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, @@ -452,7 +452,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */ ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, *property_list_head_p); - if (ECMA_PROPERTY_GET_TYPE (first_property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { property_list_head_p = &first_property_p->next_property_cp; has_hashmap = true; @@ -504,8 +504,7 @@ ecma_create_internal_property (ecma_object_t *object_p, /**< the object */ { JERRY_ASSERT (ecma_find_internal_property (object_p, property_id) == NULL); - uint8_t id_byte = (uint8_t) (property_id << ECMA_PROPERTY_FLAG_SHIFT); - uint8_t type_and_flags = (uint8_t) (ECMA_PROPERTY_TYPE_INTERNAL | id_byte); + uint8_t type_and_flags = ECMA_SPECIAL_PROPERTY_VALUE (property_id); ecma_property_value_t value; value.value = ECMA_NULL_POINTER; @@ -528,26 +527,20 @@ ecma_find_internal_property (ecma_object_t *object_p, /**< object descriptor */ ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p); - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) - { - prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, - prop_iter_p->next_property_cp); - } + uint8_t value = ECMA_SPECIAL_PROPERTY_VALUE (property_id); while (prop_iter_p != NULL) { - JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + JERRY_ASSERT (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP + || ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); - if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_INTERNAL - && ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 0) == property_id) + if (prop_iter_p->types[0] == value) { ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; return &prop_pair_p->values[0].value; } - if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[1]) == ECMA_PROPERTY_TYPE_INTERNAL - && ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_iter_p->types + 1) == property_id) + if (prop_iter_p->types[1] == value) { ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; return &prop_pair_p->values[1].value; @@ -664,8 +657,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p); #ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { ecma_string_t *property_real_name_p; property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p, @@ -769,7 +761,7 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property static void ecma_free_internal_property (ecma_property_t *property_p) /**< the property */ { - JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); + JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_SPECIAL); switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p)) { @@ -831,9 +823,10 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to } break; } - case ECMA_PROPERTY_TYPE_INTERNAL: + case ECMA_PROPERTY_TYPE_SPECIAL: { JERRY_ASSERT (name_p == NULL); + ecma_free_internal_property (property_p); break; } @@ -860,8 +853,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */ ecma_property_header_t *prev_prop_p = NULL; bool has_hashmap = false; - if (cur_prop_p != NULL - && ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (cur_prop_p != NULL && cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { prev_prop_p = cur_prop_p; cur_prop_p = ECMA_GET_POINTER (ecma_property_header_t, @@ -949,7 +941,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ return new_length; } - if (ECMA_PROPERTY_GET_TYPE (current_prop_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, current_prop_p->next_property_cp); @@ -995,7 +987,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ ecma_property_header_t *prev_prop_p = NULL; bool has_hashmap = false; - if (ECMA_PROPERTY_GET_TYPE (current_prop_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (current_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { prev_prop_p = current_prop_p; current_prop_p = ECMA_GET_POINTER (ecma_property_header_t, @@ -1077,7 +1069,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec JERRY_ASSERT (prop_iter_p != NULL); - if (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, prop_iter_p->next_property_cp); diff --git a/jerry-core/ecma/base/ecma-property-hashmap.c b/jerry-core/ecma/base/ecma-property-hashmap.c index 8856f3623..4c201f217 100644 --- a/jerry-core/ecma/base/ecma-property-hashmap.c +++ b/jerry-core/ecma/base/ecma-property-hashmap.c @@ -126,6 +126,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ memset (hashmap_p, 0, total_size); hashmap_p->header.types[0] = ECMA_PROPERTY_TYPE_HASHMAP; + hashmap_p->header.types[1] = ECMA_PROPERTY_TYPE_DELETED; hashmap_p->header.next_property_cp = object_p->property_list_or_bound_object_cp; hashmap_p->max_property_count = max_property_count; hashmap_p->null_count = max_property_count - named_property_count; @@ -230,8 +231,7 @@ ecma_property_hashmap_free (ecma_object_t *object_p) /**< object */ /* Property hash must be exists and must be the first property. */ ecma_property_header_t *property_p = ecma_get_property_list (object_p); - JERRY_ASSERT (property_p != NULL - && ECMA_PROPERTY_GET_TYPE (property_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP); + JERRY_ASSERT (property_p != NULL && property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP); ecma_property_hashmap_t *hashmap_p = (ecma_property_hashmap_t *) property_p; @@ -257,7 +257,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */ ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t, object_p->property_list_or_bound_object_cp); - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP); + JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP); /* The NULLs are reduced below 1/8 of the hashmap. */ if (hashmap_p->null_count < (hashmap_p->max_property_count >> 3)) @@ -340,7 +340,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */ ecma_property_hashmap_t *hashmap_p = ECMA_GET_NON_NULL_POINTER (ecma_property_hashmap_t, object_p->property_list_or_bound_object_cp); - JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (hashmap_p->header.types[0]) == ECMA_PROPERTY_TYPE_HASHMAP); + JERRY_ASSERT (hashmap_p->header.types[0] == ECMA_PROPERTY_TYPE_HASHMAP); uint32_t entry_index = name_p->hash; uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)]; diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 3fc2daa0e..aff79b288 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -268,7 +268,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */ /** * Special type for ecma_op_general_object_define_own_property. */ -#define ECMA_PROPERTY_TYPE_GENERIC ECMA_PROPERTY_TYPE_DELETED +#define ECMA_PROPERTY_TYPE_GENERIC ECMA_PROPERTY_TYPE_SPECIAL /** * [[DefineOwnProperty]] ecma general object's operation diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index c87662c26..1a069c062 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1189,8 +1189,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ ecma_property_header_t *prop_iter_p = ecma_get_property_list (prototype_chain_iter_p); - if (prop_iter_p != NULL - && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[0]) == ECMA_PROPERTY_TYPE_HASHMAP) + if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) { prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t, prop_iter_p->next_property_cp);