From e9a47aff95176405615ad60f628c2299d1073aa0 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Mon, 27 Jun 2016 03:04:50 -0700 Subject: [PATCH] Sixteen bit hash for strings. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers-string.c | 1 - jerry-core/ecma/base/ecma-property-hashmap.c | 12 ++++++------ jerry-core/ecma/operations/ecma-objects.c | 20 +++++++++++++------- jerry-core/lit/lit-globals.h | 11 ++++++++--- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 2bdb03f2f8..194f69d405 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -1286,7 +1286,6 @@ ecma_is_string_magic (const ecma_string_t *string_p, /**< ecma-string */ */ lit_string_hash_t ecma_string_hash (const ecma_string_t *string_p) /**< ecma-string to calculate hash for */ - { return (string_p->hash); } /* ecma_string_hash */ diff --git a/jerry-core/ecma/base/ecma-property-hashmap.c b/jerry-core/ecma/base/ecma-property-hashmap.c index ca8e244a08..549984bc61 100644 --- a/jerry-core/ecma/base/ecma-property-hashmap.c +++ b/jerry-core/ecma/base/ecma-property-hashmap.c @@ -124,13 +124,13 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ uint8_t shift_counter = 0; - if (max_property_count <= (1u << LIT_STRING_HASH_BITS)) + if (max_property_count <= LIT_STRING_HASH_LIMIT) { hashmap_p->header.types[1].type_and_flags = 0; } else { - while (max_property_count > (1u << LIT_STRING_HASH_BITS)) + while (max_property_count > LIT_STRING_HASH_LIMIT) { shift_counter++; max_property_count >>= 1; @@ -162,7 +162,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */ uint32_t entry_index = name_p->hash; uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)]; - if (mask < (1u << LIT_STRING_HASH_BITS)) + if (mask < LIT_STRING_HASH_LIMIT) { entry_index &= mask; } @@ -261,7 +261,7 @@ ecma_property_hashmap_insert (ecma_object_t *object_p, /**< object */ uint32_t step = ecma_property_hashmap_steps[entry_index & (ECMA_PROPERTY_HASHMAP_NUMBER_OF_STEPS - 1)]; uint32_t mask = hashmap_p->max_property_count - 1; - if (mask < (1u << LIT_STRING_HASH_BITS)) + if (mask < LIT_STRING_HASH_LIMIT) { entry_index &= mask; } @@ -336,7 +336,7 @@ ecma_property_hashmap_delete (ecma_object_t *object_p, /**< object */ jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1); uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count); - if (mask < (1u << LIT_STRING_HASH_BITS)) + if (mask < LIT_STRING_HASH_LIMIT) { entry_index &= mask; } @@ -446,7 +446,7 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */ jmem_cpointer_t *pair_list_p = (jmem_cpointer_t *) (hashmap_p + 1); uint8_t *bits_p = (uint8_t *) (pair_list_p + hashmap_p->max_property_count); - if (mask < (1u << LIT_STRING_HASH_BITS)) + if (mask < LIT_STRING_HASH_LIMIT) { entry_index &= mask; } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 85a9e08ef4..1be6df12b8 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -31,6 +31,11 @@ * @{ */ +/** + * Hash bitmap size for ecma objects + */ +#define ECMA_OBJECT_HASH_BITMAP_SIZE 256 + /** * Assert that specified object type value is valid * @@ -48,6 +53,7 @@ #else /* JERRY_NDEBUG */ #define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) #endif /* !JERRY_NDEBUG */ + /** * [[Get]] ecma object's operation * @@ -483,7 +489,7 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */ * * Order of names in the collection: * - integer indices in ascending order - * - other indices in creation order (for built-ins - in the order the properties are listed in specification). + * - other indices in creation order (for built-ins: the order of the properties are listed in specification). * * Note: * Implementation of the routine assumes that new properties are appended to beginning of corresponding object's @@ -510,7 +516,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ const bool obj_is_builtin = ecma_get_object_is_builtin (obj_p); const size_t bitmap_row_size = sizeof (uint32_t) * JERRY_BITSINBYTE; - uint32_t names_hashes_bitmap[(1u << LIT_STRING_HASH_BITS) / bitmap_row_size]; + uint32_t names_hashes_bitmap[ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size]; memset (names_hashes_bitmap, 0, sizeof (names_hashes_bitmap)); @@ -571,14 +577,14 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ ecma_collection_iterator_t iter; ecma_collection_iterator_init (&iter, prop_names_p); - uint32_t own_names_hashes_bitmap[(1u << LIT_STRING_HASH_BITS) / bitmap_row_size]; + uint32_t own_names_hashes_bitmap[ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size]; memset (own_names_hashes_bitmap, 0, sizeof (own_names_hashes_bitmap)); while (ecma_collection_iterator_next (&iter)) { ecma_string_t *name_p = ecma_get_string_from_value (*iter.current_value_p); - lit_string_hash_t hash = name_p->hash; + uint8_t hash = (uint8_t) name_p->hash; uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); @@ -613,7 +619,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ if (!(is_enumerable_only && !ecma_is_property_enumerable (property_p))) { - lit_string_hash_t hash = name_p->hash; + uint8_t hash = (uint8_t) name_p->hash; uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); @@ -652,7 +658,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ ecma_make_string_value (name_p), true); - lit_string_hash_t hash = name_p->hash; + uint8_t hash = (uint8_t) name_p->hash; uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); @@ -771,7 +777,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ ecma_string_t *name_p = names_p[i]; - lit_string_hash_t hash = name_p->hash; + uint8_t hash = (uint8_t) name_p->hash; uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); diff --git a/jerry-core/lit/lit-globals.h b/jerry-core/lit/lit-globals.h index 0bcc5d1324..c2109fee63 100644 --- a/jerry-core/lit/lit-globals.h +++ b/jerry-core/lit/lit-globals.h @@ -126,11 +126,16 @@ typedef uint32_t lit_code_point_t; /** * ECMA string hash */ -typedef uint8_t lit_string_hash_t; +typedef uint16_t lit_string_hash_t; /** - * ECMA string hash value length, in bits + * Maximum value of ECMA string hash + 1 + * + * Note: + * On ARM, this constant can be encoded as an immediate value + * while 0xffffu cannot be. Hence using this constant reduces + * binary size and improves performance. */ -#define LIT_STRING_HASH_BITS (sizeof (lit_string_hash_t) * JERRY_BITSINBYTE) +#define LIT_STRING_HASH_LIMIT 0x10000u #endif /* !LIT_GLOBALS_H */