Improve ecma_string_t descriptor (#3016)

This patch introduces several changes conntect to ecma-strings:
 - Extend the size of the reference counter to 28 bytes from 13
 - Extend the size of the string hash to 32 bytes from 16 to use the extact FNV-1a hash
 - Introduce ECMA_STATIC_STRING_FLAG to reduce the number of string ref/derefs for static strings.
 - Introduce ECMA_STRING_CONTAINER_ASCII_STRING to store run-time allocated ASCII strings more efficiently
 - Remove ECMA_STRING_CONTAINER_LIT_NUMBER to half the storage size of the parsing time allocated floating point numbers
 - Rework the global number storage, to store only the floating point numbers
 - Optimize the lookup in the global number/string/symbol tables via reduce the number of NULL checks during decompressing the next element pointers
 - Reduce the code duplication in ecma_concat_ecma_strings and ecma_append_chars_to_string
 - Improve ecma_string_get_char with optional arguments to make it more reusable.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik 2019-08-30 15:16:27 +02:00 committed by GitHub
parent f0578b2c25
commit c6a4a86257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 799 additions and 618 deletions

View File

@ -24,9 +24,6 @@ JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t),
JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0, JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0,
size_of_ecma_property_value_t_must_be_power_of_2); size_of_ecma_property_value_t_must_be_power_of_2);
JERRY_STATIC_ASSERT (sizeof (ecma_string_t) == sizeof (uint64_t),
size_of_ecma_string_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <= sizeof (uint64_t), JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <= sizeof (uint64_t),
size_of_ecma_extended_object_part_must_be_less_than_or_equal_to_8_bytes); size_of_ecma_extended_object_part_must_be_less_than_or_equal_to_8_bytes);
@ -155,7 +152,35 @@ ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */
} /* ecma_dealloc_string */ } /* ecma_dealloc_string */
/** /**
* Allocate memory for string with character data * Allocate memory for extended ecma-string descriptor
*
* @return pointer to allocated memory
*/
inline ecma_extended_string_t * JERRY_ATTR_ALWAYS_INLINE
ecma_alloc_extended_string (void)
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_allocate_string_bytes (sizeof (ecma_extended_string_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
return (ecma_extended_string_t *) jmem_heap_alloc_block (sizeof (ecma_extended_string_t));
} /* ecma_alloc_extended_string */
/**
* Dealloc memory from extended ecma-string descriptor
*/
inline void JERRY_ATTR_ALWAYS_INLINE
ecma_dealloc_extended_string (ecma_extended_string_t *ext_string_p) /**< extended string to be freed */
{
#if ENABLED (JERRY_MEM_STATS)
jmem_stats_free_string_bytes (sizeof (ecma_extended_string_t));
#endif /* ENABLED (JERRY_MEM_STATS) */
jmem_heap_free_block (ext_string_p, sizeof (ecma_extended_string_t));
} /* ecma_dealloc_extended_string */
/**
* Allocate memory for an string with character data
* *
* @return pointer to allocated memory * @return pointer to allocated memory
*/ */

View File

@ -73,6 +73,18 @@ ecma_string_t *ecma_alloc_string (void);
*/ */
void ecma_dealloc_string (ecma_string_t *string_p); void ecma_dealloc_string (ecma_string_t *string_p);
/**
* Allocate memory for extended ecma-string descriptor
*
* @return pointer to allocated memory
*/
ecma_extended_string_t *ecma_alloc_extended_string (void);
/**
* Dealloc memory from extended ecma-string descriptor
*/
void ecma_dealloc_extended_string (ecma_extended_string_t *string_p);
/** /**
* Allocate memory for string with character data * Allocate memory for string with character data
* *

View File

@ -266,7 +266,7 @@ ecma_gc_mark_container_object (ecma_object_t *object_p) /**< object */
if (ECMA_STRING_GET_CONTAINER (prop_name_p) == ECMA_STRING_CONTAINER_MAP_KEY) if (ECMA_STRING_GET_CONTAINER (prop_name_p) == ECMA_STRING_CONTAINER_MAP_KEY)
{ {
ecma_value_t key_arg = prop_name_p->u.value; ecma_value_t key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
if (ecma_is_value_object (key_arg)) if (ecma_is_value_object (key_arg))
{ {

View File

@ -1330,9 +1330,6 @@ typedef enum
#define ECMA_GET_DIRECT_STRING_VALUE(string_p) \ #define ECMA_GET_DIRECT_STRING_VALUE(string_p) \
(((uintptr_t) (string_p)) >> ECMA_DIRECT_STRING_SHIFT) (((uintptr_t) (string_p)) >> ECMA_DIRECT_STRING_SHIFT)
/**
* Identifier for ecma-string's actual data container
*/
typedef enum typedef enum
{ {
ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 (cesu8) string
@ -1341,17 +1338,15 @@ typedef enum
* maximum size is 2^32. */ * maximum size is 2^32. */
ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number
stored locally in the string's descriptor */ stored locally in the string's descriptor */
ECMA_STRING_CONTAINER_HEAP_ASCII_STRING, /**< actual data is on the heap as an ASCII string
* maximum size is 2^16. */
ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */ ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */
ECMA_STRING_CONTAINER_SYMBOL, /**< the ecma-string is a symbol */ ECMA_STRING_CONTAINER_SYMBOL, /**< the ecma-string is a symbol */
ECMA_STRING_CONTAINER_MAP_KEY, /**< the ecma-string is a map key string */ ECMA_STRING_CONTAINER_MAP_KEY, /**< the ecma-string is a map key string */
ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_MAP_KEY /**< maximum value */
* so no string processing function supports this type except
* the ecma_deref_ecma_string function. */
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_LITERAL_NUMBER /**< maximum value */
} ecma_string_container_t; } ecma_string_container_t;
/** /**
@ -1362,12 +1357,29 @@ typedef enum
/** /**
* Value for increasing or decreasing the reference counter. * Value for increasing or decreasing the reference counter.
*/ */
#define ECMA_STRING_REF_ONE (1u << 3) #define ECMA_STRING_REF_ONE (1u << 4)
/** /**
* Maximum value of the reference counter (8191). * Maximum value of the reference counter (4294967280).
*/ */
#define ECMA_STRING_MAX_REF (0x1fffu << 3) #define ECMA_STRING_MAX_REF (0xFFFFFFF0)
/**
* Flag that identifies that the string is static which means it is stored in JERRY_CONTEXT (string_list_cp)
*/
#define ECMA_STATIC_STRING_FLAG (1 << 3)
/**
* Set an ecma-string as static string
*/
#define ECMA_SET_STRING_AS_STATIC(string_p) \
(string_p)->refs_and_container |= ECMA_STATIC_STRING_FLAG
/**
* Checks whether the ecma-string is static string
*/
#define ECMA_STRING_IS_STATIC(string_p) \
((string_p)->refs_and_container & ECMA_STATIC_STRING_FLAG)
/** /**
* Returns with the container type of a string. * Returns with the container type of a string.
@ -1379,7 +1391,7 @@ typedef enum
* Checks whether the reference counter is 1. * Checks whether the reference counter is 1.
*/ */
#define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \ #define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \
(((string_desc_p)->refs_and_container >> 3) == 1) (((string_desc_p)->refs_and_container >> 4) == 1)
/** /**
* ECMA string-value descriptor * ECMA string-value descriptor
@ -1387,43 +1399,79 @@ typedef enum
typedef struct typedef struct
{ {
/** Reference counter for the string */ /** Reference counter for the string */
uint16_t refs_and_container; uint32_t refs_and_container;
/** Hash of the string (calculated from two last characters of the string) */
lit_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)
*/ */
union union
{ {
/** lit_string_hash_t hash; /**< hash of the ASCII/UTF8 string */
* Actual data of an utf-8 string type
*/
struct
{
uint16_t size; /**< size of this utf-8 string in bytes */
uint16_t length; /**< length of this utf-8 string in characters */
} utf8_string;
lit_utf8_size_t long_utf8_string_size; /**< size of this long utf-8 string in bytes */
uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */
uint32_t magic_string_ex_id; /**< identifier of an external magic string (lit_magic_string_ex_id_t) */ uint32_t magic_string_ex_id; /**< identifier of an external magic string (lit_magic_string_ex_id_t) */
ecma_value_t lit_number; /**< number (see ECMA_STRING_LITERAL_NUMBER) */ uint32_t uint32_number; /**< uint32-represented number placed locally in the descriptor */
uint32_t common_uint32_field; /**< for zeroing and comparison in some cases */
ecma_value_t symbol_descriptor; /**< symbol descriptor string-value */
ecma_value_t value; /**< original key value corresponds to the map key string */
} u; } u;
} ecma_string_t; } ecma_string_t;
/** /**
* Long ECMA string-value descriptor * ECMA ASCII string-value descriptor
*/ */
typedef struct typedef struct
{ {
ecma_string_t header; /**< string header */ ecma_string_t header; /**< string header */
lit_utf8_size_t long_utf8_string_length; /**< length of this long utf-8 string in bytes */ uint16_t size; /**< size of this ASCII string in bytes */
} ecma_long_string_t; } ecma_ascii_string_t;
/**
* ECMA long UTF8 string-value descriptor
*/
typedef struct
{
ecma_string_t header; /**< string header */
uint16_t size; /**< size of this utf-8 string in bytes */
uint16_t length; /**< length of this utf-8 string in bytes */
} ecma_utf8_string_t;
/**
* ECMA UTF8 string-value descriptor
*/
typedef struct
{
ecma_string_t header; /**< string header */
lit_utf8_size_t size; /**< size of this long utf-8 string in bytes */
lit_utf8_size_t length; /**< length of this long utf-8 string in bytes */
} ecma_long_utf8_string_t;
/**
* Get the start position of the string buffer of an ecma ASCII string
*/
#define ECMA_ASCII_STRING_GET_BUFFER(string_p) \
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_ascii_string_t)))
/**
* Get the start position of the string buffer of an ecma UTF8 string
*/
#define ECMA_UTF8_STRING_GET_BUFFER(string_p) \
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_utf8_string_t)))
/**
* Get the start position of the string buffer of an ecma long UTF8 string
*/
#define ECMA_LONG_UTF8_STRING_GET_BUFFER(string_p) \
((lit_utf8_byte_t *) ((lit_utf8_byte_t *) (string_p) + sizeof (ecma_long_utf8_string_t)))
/**
* ECMA extended string-value descriptor
*/
typedef struct
{
ecma_string_t header; /**< string header */
union
{
ecma_value_t symbol_descriptor; /**< symbol descriptor string-value */
ecma_value_t value; /**< original key value corresponds to the map key string */
} u;
} ecma_extended_string_t;
/** /**
* String builder header * String builder header
@ -1437,13 +1485,13 @@ typedef struct
* Get pointer to the beginning of the stored string in the string builder * Get pointer to the beginning of the stored string in the string builder
*/ */
#define ECMA_STRINGBUILDER_STRING_PTR(header_p) \ #define ECMA_STRINGBUILDER_STRING_PTR(header_p) \
((lit_utf8_byte_t *) (((ecma_string_t *) header_p) + 1)) ((lit_utf8_byte_t *) (((lit_utf8_byte_t *) header_p) + sizeof (ecma_ascii_string_t)))
/** /**
* Get the size of the stored string in the string builder * Get the size of the stored string in the string builder
*/ */
#define ECMA_STRINGBUILDER_STRING_SIZE(header_p) \ #define ECMA_STRINGBUILDER_STRING_SIZE(header_p) \
((lit_utf8_size_t) (header_p->current_size - sizeof (ecma_string_t))) ((lit_utf8_size_t) (header_p->current_size - sizeof (ecma_ascii_string_t)))
/** /**
* String builder handle * String builder handle
@ -1507,6 +1555,15 @@ typedef struct
jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */ jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */
} ecma_lit_storage_item_t; } ecma_lit_storage_item_t;
/**
* Number storage item
*/
typedef struct
{
jmem_cpointer_t next_cp; /**< cpointer ot next item */
jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */
} ecma_number_storage_item_t;
#if ENABLED (JERRY_LCACHE) #if ENABLED (JERRY_LCACHE)
/** /**
* Container of an LCache entry identifier * Container of an LCache entry identifier

File diff suppressed because it is too large Load Diff

View File

@ -459,6 +459,17 @@ ecma_create_float_number (ecma_number_t ecma_number) /**< value of the float num
return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT; return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
} /* ecma_create_float_number */ } /* ecma_create_float_number */
/**
* Encode float number without checks.
*
* @return ecma-value
*/
ecma_value_t
ecma_make_float_value (ecma_number_t *ecma_num_p) /**< pointer to the float number */
{
return ecma_pointer_to_ecma_value (ecma_num_p) | ECMA_TYPE_FLOAT;
} /* ecma_make_float_value */
/** /**
* Create a new NaN value. * Create a new NaN value.
* *
@ -696,6 +707,19 @@ ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value); return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_float_from_value */ } /* ecma_get_float_from_value */
/**
* Get floating point value pointer from an ecma value
*
* @return floating point value
*/
inline ecma_number_t * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_pointer_from_float_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
return (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_pointer_from_float_value */
/** /**
* Get floating point value from an ecma value * Get floating point value from an ecma value
* *

View File

@ -50,11 +50,17 @@
*/ */
#define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer) #define ECMA_SET_POINTER(field, non_compressed_pointer) JMEM_CP_SET_POINTER (field, non_compressed_pointer)
/**
* Status flags for ecma_string_get_chars function
*/
typedef enum typedef enum
{ {
ECMA_STRING_FLAG_EMPTY = 0, ECMA_STRING_FLAG_EMPTY = 0, /**< No options are provided. */
ECMA_STRING_FLAG_IS_ASCII, ECMA_STRING_FLAG_IS_ASCII = (1 << 0), /**< The string contains only ASCII characters. */
ECMA_STRING_FLAG_MUST_BE_FREED ECMA_STRING_FLAG_REHASH_NEEDED = (1 << 1), /**< The hash of the string must be recalculated.
* For more details see ecma_append_chars_to_string */
ECMA_STRING_FLAG_IS_UINT32 = (1 << 2), /**< The string repesents an UINT32 number */
ECMA_STRING_FLAG_MUST_BE_FREED = (1 << 3), /**< The returned buffer must be freed */
} ecma_string_flag_t; } ecma_string_flag_t;
/** /**
@ -65,7 +71,11 @@ typedef enum
utf8_str_size) /**< [out] output buffer size */ \ utf8_str_size) /**< [out] output buffer size */ \
lit_utf8_size_t utf8_str_size; \ lit_utf8_size_t utf8_str_size; \
uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \ uint8_t utf8_ptr ## flags = ECMA_STRING_FLAG_EMPTY; \
const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, &utf8_str_size, &utf8_ptr ## flags); const lit_utf8_byte_t *utf8_ptr = ecma_string_get_chars (ecma_str_ptr, \
&utf8_str_size, \
NULL, \
NULL, \
&utf8_ptr ## flags);
/** /**
* Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING' * Free the cesu-8 string buffer allocated by 'ECMA_STRING_TO_UTF8_STRING'
@ -181,6 +191,7 @@ void ecma_check_value_type_is_spec_defined (ecma_value_t value);
ecma_value_t JERRY_ATTR_CONST ecma_make_boolean_value (bool boolean_value); ecma_value_t JERRY_ATTR_CONST ecma_make_boolean_value (bool boolean_value);
ecma_value_t JERRY_ATTR_CONST ecma_make_integer_value (ecma_integer_value_t integer_value); ecma_value_t JERRY_ATTR_CONST ecma_make_integer_value (ecma_integer_value_t integer_value);
ecma_value_t ecma_make_nan_value (void); ecma_value_t ecma_make_nan_value (void);
ecma_value_t ecma_make_float_value (ecma_number_t *ecma_num_p);
ecma_value_t ecma_make_number_value (ecma_number_t ecma_number); ecma_value_t ecma_make_number_value (ecma_number_t ecma_number);
ecma_value_t ecma_make_int32_value (int32_t int32_number); ecma_value_t ecma_make_int32_value (int32_t int32_number);
ecma_value_t ecma_make_uint32_value (uint32_t uint32_number); ecma_value_t ecma_make_uint32_value (uint32_t uint32_number);
@ -195,6 +206,7 @@ ecma_value_t JERRY_ATTR_PURE ecma_make_error_reference_value (const ecma_error_r
ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p); ecma_value_t JERRY_ATTR_PURE ecma_make_pointer_value (const void *any_p);
ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value); ecma_integer_value_t JERRY_ATTR_CONST ecma_get_integer_from_value (ecma_value_t value);
ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value); ecma_number_t JERRY_ATTR_PURE ecma_get_float_from_value (ecma_value_t value);
ecma_number_t * ecma_get_pointer_from_float_value (ecma_value_t value);
ecma_number_t JERRY_ATTR_PURE ecma_get_number_from_value (ecma_value_t value); ecma_number_t JERRY_ATTR_PURE ecma_get_number_from_value (ecma_value_t value);
ecma_string_t JERRY_ATTR_PURE *ecma_get_string_from_value (ecma_value_t value); ecma_string_t JERRY_ATTR_PURE *ecma_get_string_from_value (ecma_value_t value);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
@ -246,6 +258,7 @@ ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t
ecma_string_t *ecma_append_magic_string_to_string (ecma_string_t *string1_p, lit_magic_string_id_t string2_id); ecma_string_t *ecma_append_magic_string_to_string (ecma_string_t *string1_p, lit_magic_string_id_t string2_id);
void ecma_ref_ecma_string (ecma_string_t *string_p); void ecma_ref_ecma_string (ecma_string_t *string_p);
void ecma_deref_ecma_string (ecma_string_t *string_p); void ecma_deref_ecma_string (ecma_string_t *string_p);
void ecma_destroy_ecma_string (ecma_string_t *string_p);
ecma_number_t ecma_string_to_number (const ecma_string_t *str_p); ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);
uint32_t ecma_string_get_array_index (const ecma_string_t *str_p); uint32_t ecma_string_get_array_index (const ecma_string_t *str_p);
@ -271,7 +284,11 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p,
lit_utf8_size_t buffer_size); lit_utf8_size_t buffer_size);
void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p, void ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, lit_utf8_byte_t *buffer_p,
lit_utf8_size_t buffer_size); lit_utf8_size_t buffer_size);
const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p, lit_utf8_size_t *size_p, uint8_t *flags_p); const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p,
lit_utf8_size_t *size_p,
lit_utf8_size_t *length_p,
lit_utf8_byte_t *uint32_buff_p,
uint8_t *flags_p);
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id); bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
bool ecma_string_is_empty (const ecma_string_t *string_p); bool ecma_string_is_empty (const ecma_string_t *string_p);
bool ecma_string_is_length (const ecma_string_t *string_p); bool ecma_string_is_length (const ecma_string_t *string_p);

View File

@ -25,14 +25,46 @@
* @{ * @{
*/ */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
/**
* Free symbol list
*/
static void
ecma_free_symbol_list (jmem_cpointer_t symbol_list_cp) /**< symbol list */
{
while (symbol_list_cp != JMEM_CP_NULL)
{
ecma_lit_storage_item_t *symbol_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, symbol_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (symbol_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
symbol_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
ecma_deref_ecma_string (string_p);
}
}
jmem_cpointer_t next_item_cp = symbol_list_p->next_cp;
jmem_pools_free (symbol_list_p, sizeof (ecma_lit_storage_item_t));
symbol_list_cp = next_item_cp;
}
} /* ecma_free_symbol_list */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
/** /**
* Free string list * Free string list
*/ */
static void static void
ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list */ ecma_free_string_list (jmem_cpointer_t string_list_cp) /**< string list */
{ {
while (string_list_p != NULL) while (string_list_cp != JMEM_CP_NULL)
{ {
ecma_lit_storage_item_t *string_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, string_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{ {
if (string_list_p->values[i] != JMEM_CP_NULL) if (string_list_p->values[i] != JMEM_CP_NULL)
@ -41,16 +73,42 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list
string_list_p->values[i]); string_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p)); JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
ecma_deref_ecma_string (string_p); ecma_destroy_ecma_string (string_p);
} }
} }
ecma_lit_storage_item_t *prev_item = string_list_p; jmem_cpointer_t next_item_cp = string_list_p->next_cp;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); jmem_pools_free (string_list_p, sizeof (ecma_lit_storage_item_t));
jmem_pools_free (prev_item, sizeof (ecma_lit_storage_item_t)); string_list_cp = next_item_cp;
} }
} /* ecma_free_string_list */ } /* ecma_free_string_list */
/**
* Free number list
*/
static void
ecma_free_number_list (jmem_cpointer_t number_list_cp) /**< string list */
{
while (number_list_cp != JMEM_CP_NULL)
{
ecma_number_storage_item_t *number_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_storage_item_t,
number_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
ecma_number_t *num_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_t, number_list_p->values[i]);
ecma_dealloc_number (num_p);
}
}
jmem_cpointer_t next_item_cp = number_list_p->next_cp;
jmem_pools_free (number_list_p, sizeof (ecma_number_storage_item_t));
number_list_cp = next_item_cp;
}
} /* ecma_free_number_list */
/** /**
* Finalize literal storage * Finalize literal storage
*/ */
@ -58,10 +116,10 @@ void
ecma_finalize_lit_storage (void) ecma_finalize_lit_storage (void)
{ {
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
ecma_free_string_list (JERRY_CONTEXT (symbol_list_first_p)); ecma_free_symbol_list (JERRY_CONTEXT (symbol_list_first_cp));
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_free_string_list (JERRY_CONTEXT (string_list_first_p)); ecma_free_string_list (JERRY_CONTEXT (string_list_first_cp));
ecma_free_string_list (JERRY_CONTEXT (number_list_first_p)); ecma_free_number_list (JERRY_CONTEXT (number_list_first_cp));
} /* ecma_finalize_lit_storage */ } /* ecma_finalize_lit_storage */
/** /**
@ -80,11 +138,13 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
return ecma_make_string_value (string_p); return ecma_make_string_value (string_p);
} }
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p); jmem_cpointer_t string_list_cp = JERRY_CONTEXT (string_list_first_cp);
jmem_cpointer_t *empty_cpointer_p = NULL; jmem_cpointer_t *empty_cpointer_p = NULL;
while (string_list_p != NULL) while (string_list_cp != JMEM_CP_NULL)
{ {
ecma_lit_storage_item_t *string_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, string_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{ {
if (string_list_p->values[i] == JMEM_CP_NULL) if (string_list_p->values[i] == JMEM_CP_NULL)
@ -108,9 +168,10 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
} }
} }
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); string_list_cp = string_list_p->next_cp;
} }
ECMA_SET_STRING_AS_STATIC (string_p);
jmem_cpointer_t result; jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p); JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
@ -129,8 +190,8 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
new_item_p->values[i] = JMEM_CP_NULL; new_item_p->values[i] = JMEM_CP_NULL;
} }
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p)); new_item_p->next_cp = JERRY_CONTEXT (string_list_first_cp);
JERRY_CONTEXT (string_list_first_p) = new_item_p; JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (string_list_first_cp), new_item_p);
return ecma_make_string_value (string_p); return ecma_make_string_value (string_p);
} /* ecma_find_or_create_literal_string */ } /* ecma_find_or_create_literal_string */
@ -152,11 +213,14 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
JERRY_ASSERT (ecma_is_value_float_number (num)); JERRY_ASSERT (ecma_is_value_float_number (num));
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p); jmem_cpointer_t number_list_cp = JERRY_CONTEXT (number_list_first_cp);
jmem_cpointer_t *empty_cpointer_p = NULL; jmem_cpointer_t *empty_cpointer_p = NULL;
while (number_list_p != NULL) while (number_list_cp != JMEM_CP_NULL)
{ {
ecma_number_storage_item_t *number_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_storage_item_t,
number_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{ {
if (number_list_p->values[i] == JMEM_CP_NULL) if (number_list_p->values[i] == JMEM_CP_NULL)
@ -168,29 +232,24 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
} }
else else
{ {
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, ecma_number_t *number_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_number_t,
number_list_p->values[i]); number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER); if (*number_p == number_arg)
JERRY_ASSERT (ecma_is_value_float_number (value_p->u.lit_number));
if (ecma_get_float_from_value (value_p->u.lit_number) == number_arg)
{ {
ecma_free_value (num); ecma_free_value (num);
return value_p->u.lit_number; return ecma_make_float_value (number_p);
} }
} }
} }
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp); number_list_cp = number_list_p->next_cp;
} }
ecma_string_t *string_p = ecma_alloc_string (); ecma_number_t *num_p = ecma_get_pointer_from_float_value (num);
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
string_p->u.lit_number = num;
jmem_cpointer_t result; jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p); JMEM_CP_SET_NON_NULL_POINTER (result, num_p);
if (empty_cpointer_p != NULL) if (empty_cpointer_p != NULL)
{ {
@ -198,8 +257,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
return num; return num;
} }
ecma_lit_storage_item_t *new_item_p; ecma_number_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t)); new_item_p = (ecma_number_storage_item_t *) jmem_pools_alloc (sizeof (ecma_number_storage_item_t));
new_item_p->values[0] = result; new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
@ -207,8 +266,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
new_item_p->values[i] = JMEM_CP_NULL; new_item_p->values[i] = JMEM_CP_NULL;
} }
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p)); new_item_p->next_cp = JERRY_CONTEXT (number_list_first_cp);
JERRY_CONTEXT (number_list_first_p) = new_item_p; JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (number_list_first_cp), new_item_p);
return num; return num;
} /* ecma_find_or_create_literal_number */ } /* ecma_find_or_create_literal_number */

View File

@ -102,11 +102,14 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
string_p = ecma_get_symbol_from_value (value_to_find); string_p = ecma_get_symbol_from_value (value_to_find);
} }
ecma_lit_storage_item_t *symbol_list_p = JERRY_CONTEXT (symbol_list_first_p); jmem_cpointer_t symbol_list_cp = JERRY_CONTEXT (symbol_list_first_cp);
jmem_cpointer_t *empty_cpointer_p = NULL; jmem_cpointer_t *empty_cpointer_p = NULL;
while (symbol_list_p != NULL) while (symbol_list_cp != JMEM_CP_NULL)
{ {
ecma_lit_storage_item_t *symbol_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t,
symbol_list_cp);
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{ {
if (symbol_list_p->values[i] != JMEM_CP_NULL) if (symbol_list_p->values[i] != JMEM_CP_NULL)
@ -145,7 +148,7 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
} }
} }
symbol_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, symbol_list_p->next_cp); symbol_list_cp = symbol_list_p->next_cp;
} }
if (!is_for) if (!is_for)
@ -175,8 +178,8 @@ ecma_builtin_symbol_for_helper (ecma_value_t value_to_find) /**< symbol or ecma-
new_item_p->values[i] = JMEM_CP_NULL; new_item_p->values[i] = JMEM_CP_NULL;
} }
JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (symbol_list_first_p)); new_item_p->next_cp = JERRY_CONTEXT (symbol_list_first_cp);
JERRY_CONTEXT (symbol_list_first_p) = new_item_p; JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (symbol_list_first_cp), new_item_p);
return ecma_copy_value (ecma_make_symbol_value (new_symbol_p)); return ecma_copy_value (ecma_make_symbol_value (new_symbol_p));
} /* ecma_builtin_symbol_for_helper */ } /* ecma_builtin_symbol_for_helper */

View File

@ -659,9 +659,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (string_p))) if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (string_p)))
{ {
if (string_p->hash & ECMA_GLOBAL_SYMBOL_FLAG) if (string_p->u.hash & ECMA_GLOBAL_SYMBOL_FLAG)
{ {
magic_string_id = (string_p->hash >> ECMA_GLOBAL_SYMBOL_SHIFT); magic_string_id = (string_p->u.hash >> ECMA_GLOBAL_SYMBOL_SHIFT);
} }
} }
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
@ -802,7 +802,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (symbol_desc_value); ecma_string_t *symbol_p = ecma_new_symbol_from_descriptor_string (symbol_desc_value);
lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->value; lit_magic_string_id_t symbol_id = (lit_magic_string_id_t) curr_property_p->value;
symbol_p->hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG); symbol_p->u.hash = (uint16_t) ((symbol_id << ECMA_GLOBAL_SYMBOL_SHIFT) | ECMA_GLOBAL_SYMBOL_FLAG);
value = ecma_make_symbol_value (symbol_p); value = ecma_make_symbol_value (symbol_p);
break; break;

View File

@ -476,7 +476,7 @@ ecma_op_container_foreach (ecma_value_t this_arg, /**< this argument */
} }
else if (ecma_prop_name_is_map_key (prop_name_p)) else if (ecma_prop_name_is_map_key (prop_name_p))
{ {
key_arg = prop_name_p->u.value; key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
} }
else else
{ {
@ -730,7 +730,7 @@ ecma_op_container_iterator_next (ecma_value_t this_val, /**< this argument */
} }
else if (ecma_prop_name_is_map_key (prop_name_p)) else if (ecma_prop_name_is_map_key (prop_name_p))
{ {
key_arg = prop_name_p->u.value; key_arg = ((ecma_extended_string_t *) prop_name_p)->u.value;
} }
else else
{ {

View File

@ -111,7 +111,7 @@ ecma_get_symbol_description (ecma_string_t *symbol_p) /**< ecma-symbol */
JERRY_ASSERT (symbol_p != NULL); JERRY_ASSERT (symbol_p != NULL);
JERRY_ASSERT (ecma_prop_name_is_symbol (symbol_p)); JERRY_ASSERT (ecma_prop_name_is_symbol (symbol_p));
return ecma_get_string_from_value (symbol_p->u.symbol_descriptor); return ecma_get_string_from_value (((ecma_extended_string_t *) symbol_p)->u.symbol_descriptor);
} /* ecma_get_symbol_description */ } /* ecma_get_symbol_description */
/** /**

View File

@ -136,11 +136,11 @@ struct jerry_context_t
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */ const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */
const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */ const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */
ecma_lit_storage_item_t *string_list_first_p; /**< first item of the literal string list */ jmem_cpointer_t string_list_first_cp; /**< first item of the literal string list */
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
ecma_lit_storage_item_t *symbol_list_first_p; /**< first item of the global symbol list */ jmem_cpointer_t symbol_list_first_cp; /**< first item of the global symbol list */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_lit_storage_item_t *number_list_first_p; /**< first item of the literal number list */ jmem_cpointer_t number_list_first_cp; /**< first item of the literal number list */
jmem_cpointer_t ecma_global_lex_env_cp; /**< global lexical environment */ jmem_cpointer_t ecma_global_lex_env_cp; /**< global lexical environment */
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) #if ENABLED (JERRY_ES2015_MODULE_SYSTEM)

View File

@ -121,16 +121,11 @@ typedef uint32_t lit_code_point_t;
/** /**
* ECMA string hash * ECMA string hash
*/ */
typedef uint16_t lit_string_hash_t; typedef uint32_t lit_string_hash_t;
/** /**
* Maximum value of ECMA string hash + 1 * Maximum value of ECMA string hash
*
* 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_LIMIT 0x10000u #define LIT_STRING_HASH_LIMIT UINT32_MAX
#endif /* !LIT_GLOBALS_H */ #endif /* !LIT_GLOBALS_H */

View File

@ -275,6 +275,8 @@ parser_module_context_init (void)
const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (path_str_p, const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (path_str_p,
&path_str_size, &path_str_size,
NULL,
NULL,
&flags); &flags);
ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p, ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p,