mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Adding ecma-string's hash to ecma_string_t.
This commit is contained in:
parent
6c65c48772
commit
fe7e34d93e
@ -740,6 +740,16 @@ typedef enum
|
|||||||
ECMA_MAGIC_STRING__COUNT /**< number of magic strings */
|
ECMA_MAGIC_STRING__COUNT /**< number of magic strings */
|
||||||
} ecma_magic_string_id_t;
|
} ecma_magic_string_id_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECMA string hash
|
||||||
|
*/
|
||||||
|
typedef uint16_t ecma_string_hash_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of string's last characters to use for hash calculation
|
||||||
|
*/
|
||||||
|
#define ECMA_STRING_HASH_LAST_CHARS_COUNT (2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ECMA string-value descriptor
|
* ECMA string-value descriptor
|
||||||
*/
|
*/
|
||||||
@ -755,8 +765,8 @@ typedef struct
|
|||||||
* in a stack variable (not in the heap) */
|
* in a stack variable (not in the heap) */
|
||||||
unsigned int is_stack_var : 1;
|
unsigned int is_stack_var : 1;
|
||||||
|
|
||||||
/** Padding */
|
/** Hash of the string (calculated from two last characters of the string) */
|
||||||
ecma_length_t padding;
|
ecma_string_hash_t hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actual data or identifier of it's place in container (depending on 'container' field)
|
* Actual data or identifier of it's place in container (depending on 'container' field)
|
||||||
|
|||||||
@ -305,8 +305,8 @@ ecma_init_ecma_string_from_lit_index (ecma_string_t *string_p, /**< descriptor t
|
|||||||
|
|
||||||
string_p->refs = 1;
|
string_p->refs = 1;
|
||||||
string_p->is_stack_var = is_stack_var;
|
string_p->is_stack_var = is_stack_var;
|
||||||
|
|
||||||
string_p->container = ECMA_STRING_CONTAINER_LIT_TABLE;
|
string_p->container = ECMA_STRING_CONTAINER_LIT_TABLE;
|
||||||
|
string_p->hash = lit.data.lp.hash;
|
||||||
|
|
||||||
string_p->u.lit_index = lit_index;
|
string_p->u.lit_index = lit_index;
|
||||||
} /* ecma_init_ecma_string_from_lit_index */
|
} /* ecma_init_ecma_string_from_lit_index */
|
||||||
@ -327,8 +327,9 @@ ecma_init_ecma_string_from_magic_string_id (ecma_string_t *string_p, /**< descri
|
|||||||
|
|
||||||
string_p->refs = 1;
|
string_p->refs = 1;
|
||||||
string_p->is_stack_var = is_stack_var;
|
string_p->is_stack_var = is_stack_var;
|
||||||
|
|
||||||
string_p->container = ECMA_STRING_CONTAINER_MAGIC_STRING;
|
string_p->container = ECMA_STRING_CONTAINER_MAGIC_STRING;
|
||||||
|
string_p->hash = ecma_chars_buffer_calc_hash_last_chars (ecma_get_magic_string_zt (magic_string_id),
|
||||||
|
ecma_magic_string_lengths [magic_string_id]);
|
||||||
|
|
||||||
string_p->u.magic_string_id = magic_string_id;
|
string_p->u.magic_string_id = magic_string_id;
|
||||||
} /* ecma_init_ecma_string_from_magic_string_id */
|
} /* ecma_init_ecma_string_from_magic_string_id */
|
||||||
@ -363,6 +364,7 @@ ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string *
|
|||||||
string_desc_p->refs = 1;
|
string_desc_p->refs = 1;
|
||||||
string_desc_p->is_stack_var = false;
|
string_desc_p->is_stack_var = false;
|
||||||
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_CHUNKS;
|
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_CHUNKS;
|
||||||
|
string_desc_p->hash = ecma_chars_buffer_calc_hash_last_chars (string_p, length);
|
||||||
|
|
||||||
ecma_collection_header_t *collection_p = ecma_new_chars_collection (string_p, length);
|
ecma_collection_header_t *collection_p = ecma_new_chars_collection (string_p, length);
|
||||||
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.collection_cp, collection_p);
|
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.collection_cp, collection_p);
|
||||||
@ -384,6 +386,34 @@ ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< UInt32-represente
|
|||||||
string_desc_p->container = ECMA_STRING_CONTAINER_UINT32_IN_DESC;
|
string_desc_p->container = ECMA_STRING_CONTAINER_UINT32_IN_DESC;
|
||||||
string_desc_p->u.uint32_number = uint32_number;
|
string_desc_p->u.uint32_number = uint32_number;
|
||||||
|
|
||||||
|
uint32_t last_two_digits = uint32_number % 100;
|
||||||
|
uint32_t digit_pl = last_two_digits / 10;
|
||||||
|
uint32_t digit_l = last_two_digits % 10;
|
||||||
|
|
||||||
|
FIXME (/* Use digit to char conversion routine */);
|
||||||
|
const ecma_char_t digits[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||||
|
const bool is_one_char_or_more = (uint32_number >= 10);
|
||||||
|
const ecma_char_t last_chars [ECMA_STRING_HASH_LAST_CHARS_COUNT] =
|
||||||
|
{
|
||||||
|
is_one_char_or_more ? digits [digit_pl] : digits[digit_l],
|
||||||
|
is_one_char_or_more ? digits [digit_l] : ECMA_CHAR_NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Only last two chars are really used for hash calculation */
|
||||||
|
string_desc_p->hash = ecma_chars_buffer_calc_hash_last_chars (last_chars,
|
||||||
|
is_one_char_or_more ? 2 : 1);
|
||||||
|
|
||||||
|
#ifndef JERRY_NDEBUG
|
||||||
|
ecma_char_t char_buf [ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
|
||||||
|
ssize_t chars_copied = ecma_uint32_to_string (uint32_number,
|
||||||
|
char_buf,
|
||||||
|
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
|
||||||
|
JERRY_ASSERT ((ecma_length_t) chars_copied == chars_copied);
|
||||||
|
|
||||||
|
JERRY_ASSERT (string_desc_p->hash == ecma_chars_buffer_calc_hash_last_chars (char_buf,
|
||||||
|
ecma_zt_string_length (char_buf)));
|
||||||
|
#endif /* !JERRY_NDEBUG */
|
||||||
|
|
||||||
return string_desc_p;
|
return string_desc_p;
|
||||||
} /* ecma_new_ecma_string_from_uint32 */
|
} /* ecma_new_ecma_string_from_uint32 */
|
||||||
|
|
||||||
@ -401,10 +431,16 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
|
|||||||
return ecma_new_ecma_string_from_uint32 (uint32_num);
|
return ecma_new_ecma_string_from_uint32 (uint32_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecma_char_t str_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER + 1];
|
||||||
|
ecma_length_t length = ecma_number_to_zt_string (num,
|
||||||
|
str_buf,
|
||||||
|
sizeof (str_buf));
|
||||||
|
|
||||||
ecma_string_t* string_desc_p = ecma_alloc_string ();
|
ecma_string_t* string_desc_p = ecma_alloc_string ();
|
||||||
string_desc_p->refs = 1;
|
string_desc_p->refs = 1;
|
||||||
string_desc_p->is_stack_var = false;
|
string_desc_p->is_stack_var = false;
|
||||||
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_NUMBER;
|
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP_NUMBER;
|
||||||
|
string_desc_p->hash = ecma_chars_buffer_calc_hash_last_chars (str_buf, length);
|
||||||
|
|
||||||
ecma_number_t *num_p = ecma_alloc_number ();
|
ecma_number_t *num_p = ecma_alloc_number ();
|
||||||
*num_p = num;
|
*num_p = num;
|
||||||
@ -479,7 +515,19 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
|||||||
JERRY_ASSERT (string1_p != NULL
|
JERRY_ASSERT (string1_p != NULL
|
||||||
&& string2_p != NULL);
|
&& string2_p != NULL);
|
||||||
|
|
||||||
int64_t length = (int64_t)ecma_string_get_length (string1_p) + (int64_t) ecma_string_get_length (string2_p);
|
uint32_t str1_len = (uint32_t) ecma_string_get_length (string1_p);
|
||||||
|
uint32_t str2_len = (uint32_t) ecma_string_get_length (string2_p);
|
||||||
|
|
||||||
|
if (str1_len == 0)
|
||||||
|
{
|
||||||
|
return ecma_copy_or_ref_ecma_string (string2_p);
|
||||||
|
}
|
||||||
|
else if (str2_len == 0)
|
||||||
|
{
|
||||||
|
return ecma_copy_or_ref_ecma_string (string1_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t length = (int64_t) str1_len + (int64_t) str2_len;
|
||||||
|
|
||||||
ecma_string_t* string_desc_p = ecma_alloc_string ();
|
ecma_string_t* string_desc_p = ecma_alloc_string ();
|
||||||
string_desc_p->refs = 1;
|
string_desc_p->refs = 1;
|
||||||
@ -497,6 +545,24 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
|
|||||||
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string1_cp, string1_p);
|
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string1_cp, string1_p);
|
||||||
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string2_cp, string2_p);
|
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.concatenation.string2_cp, string2_p);
|
||||||
|
|
||||||
|
if (str2_len >= ECMA_STRING_HASH_LAST_CHARS_COUNT)
|
||||||
|
{
|
||||||
|
string_desc_p->hash = string2_p->hash;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
JERRY_STATIC_ASSERT (ECMA_STRING_HASH_LAST_CHARS_COUNT == 2);
|
||||||
|
JERRY_ASSERT (str2_len == 1);
|
||||||
|
|
||||||
|
ecma_char_t chars_buf[ECMA_STRING_HASH_LAST_CHARS_COUNT] =
|
||||||
|
{
|
||||||
|
ecma_string_get_char_at_pos (string1_p, str1_len - 1u),
|
||||||
|
ecma_string_get_char_at_pos (string2_p, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
string_desc_p->hash = ecma_chars_buffer_calc_hash_last_chars (chars_buf, ECMA_STRING_HASH_LAST_CHARS_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
return string_desc_p;
|
return string_desc_p;
|
||||||
} /* ecma_concat_ecma_strings */
|
} /* ecma_concat_ecma_strings */
|
||||||
|
|
||||||
@ -982,9 +1048,9 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /* ecma-string */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
||||||
|
|
||||||
if (unlikely (string1_p == string2_p))
|
if (string1_p->hash != string2_p->hash)
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string1_p->container == string2_p->container)
|
if (string1_p->container == string2_p->container)
|
||||||
@ -1583,6 +1649,27 @@ ecma_string_try_hash (const ecma_string_t *string_p, /**< ecma-string to calcula
|
|||||||
return false;
|
return false;
|
||||||
} /* ecma_string_try_hash */
|
} /* ecma_string_try_hash */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate hash from last ECMA_STRING_HASH_LAST_CHARS_COUNT characters from the buffer.
|
||||||
|
*
|
||||||
|
* @return ecma-string's hash
|
||||||
|
*/
|
||||||
|
ecma_string_hash_t
|
||||||
|
ecma_chars_buffer_calc_hash_last_chars (const ecma_char_t *chars, /**< characters buffer */
|
||||||
|
ecma_length_t length) /**< number of characters in the buffer */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (chars != NULL);
|
||||||
|
|
||||||
|
ecma_char_t char1 = (length > 0) ? chars[length - 1] : ECMA_CHAR_NULL;
|
||||||
|
ecma_char_t char2 = (length > 1) ? chars[length - 2] : ECMA_CHAR_NULL;
|
||||||
|
|
||||||
|
uint32_t t1 = (uint32_t) char1 + (uint32_t) char2;
|
||||||
|
uint32_t t2 = t1 * 0x24418b66;
|
||||||
|
uint32_t t3 = (t2 >> 16) ^ (t2 & 0xffffu);
|
||||||
|
|
||||||
|
return (ecma_string_hash_t) t3;
|
||||||
|
} /* ecma_chars_buffer_calc_hash_last_chars */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
|||||||
@ -157,6 +157,7 @@ extern ecma_string_t* ecma_get_magic_string (ecma_magic_string_id_t id);
|
|||||||
extern bool ecma_is_string_magic (const ecma_string_t *string_p, ecma_magic_string_id_t *out_id_p);
|
extern bool ecma_is_string_magic (const ecma_string_t *string_p, ecma_magic_string_id_t *out_id_p);
|
||||||
extern bool ecma_is_zt_string_magic (const ecma_char_t *zt_string_p, ecma_magic_string_id_t *out_id_p);
|
extern bool ecma_is_zt_string_magic (const ecma_char_t *zt_string_p, ecma_magic_string_id_t *out_id_p);
|
||||||
extern bool ecma_string_try_hash (const ecma_string_t *string_p, uint32_t hash_length_bits, uint32_t *out_hash_p);
|
extern bool ecma_string_try_hash (const ecma_string_t *string_p, uint32_t hash_length_bits, uint32_t *out_hash_p);
|
||||||
|
extern ecma_string_hash_t ecma_chars_buffer_calc_hash_last_chars (const ecma_char_t *chars, ecma_length_t length);
|
||||||
|
|
||||||
/* ecma-helpers-number.c */
|
/* ecma-helpers-number.c */
|
||||||
extern const ecma_number_t ecma_number_relative_eps;
|
extern const ecma_number_t ecma_number_relative_eps;
|
||||||
|
|||||||
@ -73,7 +73,8 @@ create_literal_from_zt (const ecma_char_t *s, ecma_length_t len)
|
|||||||
.data.lp = (lp_string)
|
.data.lp = (lp_string)
|
||||||
{
|
{
|
||||||
.length = len,
|
.length = len,
|
||||||
.str = s
|
.str = s,
|
||||||
|
.hash = ecma_chars_buffer_calc_hash_last_chars (s, len)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
const ecma_char_t *str;
|
const ecma_char_t *str;
|
||||||
ecma_length_t length;
|
ecma_length_t length;
|
||||||
|
ecma_string_hash_t hash;
|
||||||
}
|
}
|
||||||
lp_string;
|
lp_string;
|
||||||
|
|
||||||
|
|||||||
@ -165,6 +165,7 @@ adjust_string_ptrs (literal lit, size_t diff)
|
|||||||
.data.lp = (lp_string)
|
.data.lp = (lp_string)
|
||||||
{
|
{
|
||||||
.length = lit.data.lp.length,
|
.length = lit.data.lp.length,
|
||||||
|
.hash = lit.data.lp.hash,
|
||||||
.str = lit.data.lp.str + diff
|
.str = lit.data.lp.str + diff
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user