mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Improve property search. (#2232)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
b9f96a64d9
commit
7b0e1672ae
@ -192,8 +192,8 @@ ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair
|
||||
}
|
||||
case ECMA_PROPERTY_TYPE_SPECIAL:
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_GET_SPECIAL_PROPERTY_TYPE (&property) == ECMA_SPECIAL_PROPERTY_DELETED
|
||||
|| ECMA_PROPERTY_GET_SPECIAL_PROPERTY_TYPE (&property) == ECMA_SPECIAL_PROPERTY_HASHMAP);
|
||||
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
|
||||
|| property == ECMA_PROPERTY_TYPE_DELETED);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -491,10 +491,6 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
}
|
||||
}
|
||||
|
||||
/* Both must be deleted. */
|
||||
JERRY_ASSERT (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_DELETED
|
||||
&& prop_iter_p->types[1] == ECMA_PROPERTY_TYPE_DELETED);
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
|
||||
|
||||
@ -274,20 +274,6 @@ typedef struct
|
||||
} u;
|
||||
} ecma_native_pointer_t;
|
||||
|
||||
/**
|
||||
* Special property identifiers.
|
||||
*/
|
||||
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_SPECIAL_PROPERTY__COUNT /**< Number of special property types */
|
||||
} ecma_internal_property_id_t;
|
||||
|
||||
/**
|
||||
* Property's 'Writable' attribute's values description.
|
||||
*/
|
||||
@ -350,32 +336,6 @@ typedef enum
|
||||
*/
|
||||
#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
|
||||
|
||||
/**
|
||||
* Type of property not found and no more searching in the proto chain.
|
||||
*/
|
||||
#define ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP ECMA_PROPERTY_TYPE_HASHMAP
|
||||
|
||||
/**
|
||||
* Property flag list (for ECMA_PROPERTY_TYPE_NAMEDDATA
|
||||
* and ECMA_PROPERTY_TYPE_NAMEDACCESSOR).
|
||||
@ -422,6 +382,54 @@ typedef enum
|
||||
*/
|
||||
#define ECMA_PROPERTY_NAME_TYPE_SHIFT (ECMA_PROPERTY_FLAG_SHIFT + 4)
|
||||
|
||||
/**
|
||||
* Special property identifiers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* Note: when new special types are added
|
||||
* ECMA_PROPERTY_IS_PROPERTY_PAIR must be updated as well. */
|
||||
ECMA_SPECIAL_PROPERTY_HASHMAP, /**< hashmap property */
|
||||
ECMA_SPECIAL_PROPERTY_DELETED, /**< deleted property */
|
||||
|
||||
ECMA_SPECIAL_PROPERTY__COUNT /**< Number of special property types */
|
||||
} ecma_internal_property_id_t;
|
||||
|
||||
/**
|
||||
* Define special property type.
|
||||
*/
|
||||
#define ECMA_SPECIAL_PROPERTY_VALUE(type) \
|
||||
((uint8_t) (ECMA_PROPERTY_TYPE_SPECIAL | ((type) << ECMA_PROPERTY_NAME_TYPE_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)
|
||||
|
||||
/**
|
||||
* Name constant of a deleted property.
|
||||
*/
|
||||
#ifdef JERRY_CPOINTER_32_BIT
|
||||
#define ECMA_PROPERTY_DELETED_NAME 0xffffffffu
|
||||
#else /* !JERRY_CPOINTER_32_BIT */
|
||||
#define ECMA_PROPERTY_DELETED_NAME 0xffffu
|
||||
#endif /* JERRY_CPOINTER_32_BIT */
|
||||
|
||||
/**
|
||||
* Type of property not found.
|
||||
*/
|
||||
#define ECMA_PROPERTY_TYPE_NOT_FOUND ECMA_PROPERTY_TYPE_HASHMAP
|
||||
|
||||
/**
|
||||
* Type of property not found and no more searching in the proto chain.
|
||||
*/
|
||||
#define ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP ECMA_PROPERTY_TYPE_DELETED
|
||||
|
||||
/**
|
||||
* Abstract property representation.
|
||||
*
|
||||
@ -523,12 +531,6 @@ typedef struct
|
||||
#define ECMA_PROPERTY_IS_NAMED_PROPERTY(property) \
|
||||
(ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_SPECIAL)
|
||||
|
||||
/**
|
||||
* Returns the internal property type
|
||||
*/
|
||||
#define ECMA_PROPERTY_GET_SPECIAL_PROPERTY_TYPE(property_p) \
|
||||
((ecma_internal_property_id_t) (*(property_p) >> ECMA_PROPERTY_FLAG_SHIFT))
|
||||
|
||||
/**
|
||||
* Add the offset part to a property for computing its property data pointer.
|
||||
*/
|
||||
|
||||
@ -1708,8 +1708,13 @@ ecma_string_compare_to_property_name (ecma_property_t property, /**< property na
|
||||
return ecma_property_to_string (property, prop_name_cp) == string_p;
|
||||
}
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (string_p))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prop_name_cp);
|
||||
return ecma_compare_ecma_strings (prop_name_p, string_p);
|
||||
return ecma_compare_ecma_non_direct_strings (prop_name_p, string_p);
|
||||
} /* ecma_string_compare_to_property_name */
|
||||
|
||||
/**
|
||||
@ -1722,8 +1727,8 @@ ecma_string_compare_to_property_name (ecma_property_t property, /**< property na
|
||||
* false - otherwise
|
||||
*/
|
||||
static bool __attr_noinline___
|
||||
ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-string */
|
||||
const ecma_string_t *string2_p) /* ecma-string */
|
||||
ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /**< ecma-string */
|
||||
const ecma_string_t *string2_p) /**< ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_GET_CONTAINER (string2_p));
|
||||
|
||||
@ -1756,14 +1761,14 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
|
||||
} /* ecma_compare_ecma_strings_longpath */
|
||||
|
||||
/**
|
||||
* Compare ecma-string to ecma-string
|
||||
* Compare two ecma-strings
|
||||
*
|
||||
* @return true - if strings are equal;
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
||||
const ecma_string_t *string2_p) /* ecma-string */
|
||||
ecma_compare_ecma_strings (const ecma_string_t *string1_p, /**< ecma-string */
|
||||
const ecma_string_t *string2_p) /**< ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
||||
|
||||
@ -1799,6 +1804,45 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
||||
return ecma_compare_ecma_strings_longpath (string1_p, string2_p);
|
||||
} /* ecma_compare_ecma_strings */
|
||||
|
||||
/**
|
||||
* Compare two non-direct ecma-strings
|
||||
*
|
||||
* @return true - if strings are equal;
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_compare_ecma_non_direct_strings (const ecma_string_t *string1_p, /**< ecma-string */
|
||||
const ecma_string_t *string2_p) /**< ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
||||
JERRY_ASSERT (!ECMA_IS_DIRECT_STRING (string1_p) && !ECMA_IS_DIRECT_STRING (string2_p));
|
||||
|
||||
/* Fast paths first. */
|
||||
if (string1_p == string2_p)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string1_p->hash != string2_p->hash)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_string_container_t string1_container = ECMA_STRING_GET_CONTAINER (string1_p);
|
||||
|
||||
if (string1_container != ECMA_STRING_GET_CONTAINER (string2_p))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string1_container >= ECMA_STRING_CONTAINER_UINT32_IN_DESC)
|
||||
{
|
||||
return string1_p->u.common_uint32_field == string2_p->u.common_uint32_field;
|
||||
}
|
||||
|
||||
return ecma_compare_ecma_strings_longpath (string1_p, string2_p);
|
||||
} /* ecma_compare_ecma_non_direct_strings */
|
||||
|
||||
/**
|
||||
* Relational compare of ecma-strings.
|
||||
*
|
||||
|
||||
@ -36,48 +36,33 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The ecma property types must be lower than the container mask.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_MASK >= ECMA_PROPERTY_TYPE__MAX,
|
||||
ecma_property_types_must_be_lower_than_the_container_mask);
|
||||
|
||||
/**
|
||||
* The ecma object types must be lower than the container mask.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_OBJECT_TYPE__MAX - 1,
|
||||
ecma_object_types_must_be_lower_than_the_container_mask);
|
||||
|
||||
/**
|
||||
* The ecma lexical environment types must be lower than the container mask.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX,
|
||||
ecma_lexical_environment_types_must_be_lower_than_the_container_mask);
|
||||
|
||||
/**
|
||||
* The ecma built in flag must follow the object type.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK + 1 == ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV,
|
||||
ecma_built_in_flag_must_follow_the_object_type);
|
||||
|
||||
/**
|
||||
* The ecma extensible flag must follow the gc visited flag.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_FLAG_EXTENSIBLE == (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV << 1),
|
||||
ecma_extensible_flag_must_follow_the_built_in_flag);
|
||||
|
||||
/**
|
||||
* The ecma object ref one must follow the extensible flag.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1),
|
||||
ecma_object_ref_one_must_follow_the_extensible_flag);
|
||||
|
||||
/**
|
||||
* The ecma object max ref does not fill the remaining bits.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX,
|
||||
ecma_object_max_ref_does_not_fill_the_remaining_bits);
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT),
|
||||
ecma_property_type_deleted_must_have_magic_string_name_type);
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_PROPERTY_DELETED_NAME >= LIT_MAGIC_STRING__COUNT,
|
||||
ecma_property_deleted_name_must_not_be_valid_maigc_string_id);
|
||||
|
||||
/**
|
||||
* Create an object with specified prototype object
|
||||
* (or NULL prototype if there is not prototype for the object)
|
||||
@ -486,7 +471,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
|
||||
/* Just copy the previous value (no need to decompress, compress). */
|
||||
first_property_pair_p->header.next_property_cp = *property_list_head_p;
|
||||
first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
first_property_pair_p->names_cp[0] = ECMA_NULL_POINTER;
|
||||
first_property_pair_p->names_cp[0] = ECMA_PROPERTY_DELETED_NAME;
|
||||
|
||||
if (name_p == NULL)
|
||||
{
|
||||
@ -628,47 +613,85 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
}
|
||||
#endif /* !CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE */
|
||||
|
||||
property_p = NULL;
|
||||
jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER;
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
uint32_t steps = 0;
|
||||
jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER;
|
||||
|
||||
while (prop_iter_p != NULL)
|
||||
if (ECMA_IS_DIRECT_STRING (name_p))
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
ecma_property_t prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (name_p);
|
||||
property_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (name_p);
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
JERRY_ASSERT (prop_name_type > 0);
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[0]))
|
||||
while (prop_iter_p != NULL)
|
||||
{
|
||||
if (ecma_string_compare_to_property_name (prop_iter_p->types[0],
|
||||
prop_pair_p->names_cp[0],
|
||||
name_p))
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
|
||||
if (prop_pair_p->names_cp[0] == property_name_cp
|
||||
&& ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[0]) == prop_name_type)
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[0];
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[0]));
|
||||
|
||||
property_p = prop_iter_p->types + 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[1]))
|
||||
{
|
||||
if (ecma_string_compare_to_property_name (prop_iter_p->types[1],
|
||||
prop_pair_p->names_cp[1],
|
||||
name_p))
|
||||
if (prop_pair_p->names_cp[1] == property_name_cp
|
||||
&& ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[1]) == prop_name_type)
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[1];
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[1]));
|
||||
|
||||
property_p = prop_iter_p->types + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
steps++;
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (prop_iter_p != NULL)
|
||||
{
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
|
||||
|
||||
steps++;
|
||||
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[0]) == ECMA_DIRECT_STRING_PTR)
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[0];
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_name_cp);
|
||||
|
||||
if (ecma_compare_ecma_non_direct_strings (name_p, prop_name_p))
|
||||
{
|
||||
property_p = prop_iter_p->types + 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[1]) == ECMA_DIRECT_STRING_PTR)
|
||||
{
|
||||
property_name_cp = prop_pair_p->names_cp[1];
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_name_cp);
|
||||
|
||||
if (ecma_compare_ecma_non_direct_strings (name_p, prop_name_p))
|
||||
{
|
||||
property_p = prop_iter_p->types + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
steps++;
|
||||
|
||||
prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
|
||||
prop_iter_p->next_property_cp);
|
||||
}
|
||||
}
|
||||
|
||||
if (steps >= (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2))
|
||||
@ -763,8 +786,6 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
}
|
||||
|
||||
*property_p = ECMA_PROPERTY_TYPE_DELETED;
|
||||
} /* ecma_free_property */
|
||||
|
||||
/**
|
||||
@ -809,6 +830,8 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
|
||||
}
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
|
||||
cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
prop_pair_p->names_cp[i] = ECMA_PROPERTY_DELETED_NAME;
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
|
||||
|
||||
@ -949,8 +972,8 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
}
|
||||
|
||||
ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
|
||||
|
||||
JERRY_ASSERT (current_prop_p->types[i] == ECMA_PROPERTY_TYPE_DELETED);
|
||||
current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
|
||||
prop_pair_p->names_cp[i] = ECMA_PROPERTY_DELETED_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,6 +247,7 @@ bool ecma_string_compare_to_property_name (ecma_property_t property, jmem_cpoint
|
||||
const ecma_string_t *string_p);
|
||||
|
||||
bool ecma_compare_ecma_strings (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
|
||||
bool ecma_compare_ecma_non_direct_strings (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
|
||||
bool ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, const ecma_string_t *string2_p);
|
||||
ecma_length_t ecma_string_get_length (const ecma_string_t *string_p);
|
||||
ecma_length_t ecma_string_get_utf8_length (const ecma_string_t *string_p);
|
||||
|
||||
@ -175,13 +175,36 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
|
||||
jmem_cpointer_t object_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, ecma_string_hash (prop_name_p));
|
||||
ecma_property_t prop_name_type;
|
||||
jmem_cpointer_t prop_name_cp;
|
||||
lit_string_hash_t name_hash;
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (prop_name_p))
|
||||
{
|
||||
prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (prop_name_p);
|
||||
|
||||
uintptr_t value = ECMA_GET_DIRECT_STRING_VALUE (prop_name_p);
|
||||
prop_name_cp = (jmem_cpointer_t) value;
|
||||
name_hash = (lit_string_hash_t) value;
|
||||
|
||||
if (prop_name_type == ECMA_DIRECT_STRING_MAGIC_EX)
|
||||
{
|
||||
name_hash = (lit_string_hash_t) (name_hash + LIT_MAGIC_STRING__COUNT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prop_name_type = ECMA_DIRECT_STRING_PTR;
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (prop_name_cp, prop_name_p);
|
||||
name_hash = prop_name_p->hash;
|
||||
}
|
||||
|
||||
size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
|
||||
|
||||
ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
|
||||
ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
|
||||
|
||||
ecma_property_t prop_name_type;
|
||||
jmem_cpointer_t prop_name_cp = ecma_string_to_lcache_property_name (prop_name_p, &prop_name_type);
|
||||
|
||||
while (entry_p < entry_end_p)
|
||||
{
|
||||
if (entry_p->object_cp == object_cp
|
||||
|
||||
@ -134,7 +134,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.types[1] = 0;
|
||||
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;
|
||||
@ -146,17 +146,10 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
|
||||
|
||||
uint8_t shift_counter = 0;
|
||||
|
||||
if (max_property_count <= LIT_STRING_HASH_LIMIT)
|
||||
while (max_property_count > LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
hashmap_p->header.types[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (max_property_count > LIT_STRING_HASH_LIMIT)
|
||||
{
|
||||
shift_counter++;
|
||||
max_property_count >>= 1;
|
||||
}
|
||||
shift_counter++;
|
||||
max_property_count >>= 1;
|
||||
}
|
||||
|
||||
hashmap_p->header.types[1] = shift_counter;
|
||||
@ -492,6 +485,64 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
uint32_t start_entry_index = entry_index;
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
if (ECMA_IS_DIRECT_STRING (name_p))
|
||||
{
|
||||
ecma_property_t prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (name_p);
|
||||
jmem_cpointer_t property_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (name_p);
|
||||
|
||||
JERRY_ASSERT (prop_name_type > 0);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
|
||||
{
|
||||
size_t offset = 0;
|
||||
if (ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
|
||||
{
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
ecma_property_pair_t *property_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_property_pair_t,
|
||||
pair_list_p[entry_index]);
|
||||
|
||||
ecma_property_t *property_p = property_pair_p->header.types + offset;
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p));
|
||||
|
||||
if (property_pair_p->names_cp[offset] == property_name_cp
|
||||
&& ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == prop_name_type)
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (property_found);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
*property_real_name_cp = property_name_cp;
|
||||
return property_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ECMA_PROPERTY_HASHMAP_GET_BIT (bits_p, entry_index))
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (!property_found);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Otherwise it is a deleted entry. */
|
||||
}
|
||||
|
||||
entry_index = (entry_index + step) & mask;
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (entry_index != start_entry_index);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (pair_list_p[entry_index] != ECMA_NULL_POINTER)
|
||||
@ -509,15 +560,19 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
|
||||
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (*property_p));
|
||||
|
||||
if (ecma_string_compare_to_property_name (*property_p,
|
||||
property_pair_p->names_cp[offset],
|
||||
name_p))
|
||||
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
|
||||
{
|
||||
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_pair_p->names_cp[offset]);
|
||||
|
||||
if (ecma_compare_ecma_non_direct_strings (prop_name_p, name_p))
|
||||
{
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (property_found);
|
||||
JERRY_ASSERT (property_found);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
*property_real_name_cp = property_pair_p->names_cp[offset];
|
||||
return property_p;
|
||||
|
||||
*property_real_name_cp = property_pair_p->names_cp[offset];
|
||||
return property_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -527,6 +582,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_ASSERT (!property_found);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Otherwise it is a deleted entry. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user