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
This commit is contained in:
Zoltan Herczeg 2016-11-17 13:26:02 +01:00 committed by GitHub
parent b2fec888d4
commit 7131243dda
6 changed files with 66 additions and 69 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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)];

View File

@ -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

View File

@ -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);