diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index ac8252d36..5d214a421 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -809,7 +809,6 @@ typedef struct */ typedef enum { - ECMA_STRING_CONTAINER_LIT_TABLE, /**< actual data is in literal table */ ECMA_STRING_CONTAINER_HEAP_ASCII_STRING, /**< actual data is on the heap as an ascii string */ ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 string */ ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number @@ -817,7 +816,11 @@ typedef enum ECMA_STRING_CONTAINER_MAGIC_STRING, /**< the ecma-string is equal to one of ECMA magic strings */ ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */ - ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_MAGIC_STRING_EX /**< maximum value */ + ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage + * 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; /** @@ -847,6 +850,12 @@ typedef enum #define ECMA_STRING_GET_CONTAINER(string_desc_p) \ ((ecma_string_container_t) ((string_desc_p)->refs_and_container & ECMA_STRING_CONTAINER_MASK)) +/** + * Checks whether the reference counter is 1. + */ +#define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \ + (((string_desc_p)->refs_and_container >> 3) == 1) + /** * ECMA string-value descriptor */ @@ -892,6 +901,9 @@ typedef struct ecma_string_t /** Identifier of external magic string */ lit_magic_string_ex_id_t magic_string_ex_id; + /** Literal number */ + ecma_value_t lit_number; + /** For zeroing and comparison in some cases */ uint32_t common_field; } u; diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 655426e70..2bdb03f2f 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -22,10 +22,7 @@ #include "jrt.h" #include "jrt-libc-includes.h" #include "lit-char-helpers.h" -#include "lit-literal.h" #include "lit-magic-strings.h" -#include "lit-literal-storage.h" -#include "vm.h" /** \addtogroup ecma ECMA * @{ @@ -72,9 +69,6 @@ typedef struct uint16_t length; /* Number of characters in the string */ } ecma_string_heap_header_t; -static void -ecma_init_ecma_string_from_lit_cp (ecma_string_t *string_p, - lit_cpointer_t lit_index); static void ecma_init_ecma_string_from_magic_string_id (ecma_string_t *string_p, lit_magic_string_id_t magic_string_id); @@ -83,39 +77,6 @@ static void ecma_init_ecma_string_from_magic_string_ex_id (ecma_string_t *string_p, lit_magic_string_ex_id_t magic_string_ex_id); -/** - * Initialize ecma-string descriptor with string described by index in literal table - */ -static void -ecma_init_ecma_string_from_lit_cp (ecma_string_t *string_p, /**< descriptor to initialize */ - lit_cpointer_t lit_cp) /**< compressed pointer to literal */ -{ - lit_literal_t lit = lit_cpointer_decompress (lit_cp); - - if (LIT_RECORD_IS_MAGIC_STR (lit)) - { - ecma_init_ecma_string_from_magic_string_id (string_p, - lit_magic_literal_get_magic_str_id (lit)); - - return; - } - - if (LIT_RECORD_IS_MAGIC_STR_EX (lit)) - { - ecma_init_ecma_string_from_magic_string_ex_id (string_p, - lit_magic_literal_get_magic_str_ex_id (lit)); - return; - } - - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - string_p->refs_and_container = ECMA_STRING_CONTAINER_LIT_TABLE | ECMA_STRING_REF_ONE; - string_p->hash = lit_charset_literal_get_hash (lit); - - string_p->u.common_field = 0; - string_p->u.lit_cp = lit_cp; -} /* ecma_init_ecma_string_from_lit_cp */ - /** * Initialize ecma-string descriptor with specified magic string */ @@ -320,21 +281,6 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */ return string_desc_p; } /* ecma_new_ecma_string_from_number */ -/** - * Allocate new ecma-string and fill it with reference to string literal - * - * @return pointer to ecma-string descriptor - */ -ecma_string_t * -ecma_new_ecma_string_from_lit_cp (lit_cpointer_t lit_cp) /**< index in the literal table */ -{ - ecma_string_t *string_desc_p = ecma_alloc_string (); - - ecma_init_ecma_string_from_lit_cp (string_desc_p, lit_cp); - - return string_desc_p; -} /* ecma_new_ecma_string_from_lit_cp */ - /** * Allocate new ecma-string and fill it with reference to ECMA magic string * @@ -502,7 +448,6 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ break; } - case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_UINT32_IN_DESC: case ECMA_STRING_CONTAINER_MAGIC_STRING: case ECMA_STRING_CONTAINER_MAGIC_STRING_EX: @@ -510,6 +455,15 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */ /* only the string descriptor itself should be freed */ break; } + case ECMA_STRING_LITERAL_NUMBER: + { + ecma_fast_free_value (string_p->u.lit_number); + break; + } + default: + { + JERRY_UNREACHABLE (); + } } ecma_dealloc_string (string_p); @@ -532,7 +486,6 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */ return ((ecma_number_t) uint32_number); } - case ECMA_STRING_CONTAINER_LIT_TABLE: case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING: case ECMA_STRING_CONTAINER_HEAP_ASCII_STRING: case ECMA_STRING_CONTAINER_MAGIC_STRING: @@ -553,9 +506,12 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */ return num; } - } - JERRY_UNREACHABLE (); + default: + { + JERRY_UNREACHABLE (); + } + } } /* ecma_string_to_number */ /** @@ -628,14 +584,6 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecma-s memcpy (buffer_p, data_p, size); break; } - case ECMA_STRING_CONTAINER_LIT_TABLE: - { - const lit_literal_t lit = lit_get_literal_by_cp (string_desc_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - size = lit_charset_literal_get_size (lit); - memcpy (buffer_p, lit_charset_literal_get_charset (lit), size); - break; - } case ECMA_STRING_CONTAINER_UINT32_IN_DESC: { const uint32_t uint32_number = string_desc_p->u.uint32_number; @@ -762,16 +710,6 @@ ecma_string_raw_chars (const ecma_string_t *string_p, /**< ecma-string */ switch (ECMA_STRING_GET_CONTAINER (string_p)) { - case ECMA_STRING_CONTAINER_LIT_TABLE: - { - lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - length = lit_charset_literal_get_length (lit); - size = lit_charset_literal_get_size (lit); - result_p = lit_charset_literal_get_charset (lit); - break; - } case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING: { const ecma_string_heap_header_t *data_p = ECMA_GET_NON_NULL_POINTER (ecma_string_heap_header_t, @@ -861,11 +799,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri { switch (ECMA_STRING_GET_CONTAINER (string1_p)) { - case ECMA_STRING_CONTAINER_LIT_TABLE: - { - JERRY_ASSERT (string1_p->u.lit_cp != string2_p->u.lit_cp); - return false; - } case ECMA_STRING_CONTAINER_MAGIC_STRING: { JERRY_ASSERT (string1_p->u.magic_string_id != string2_p->u.magic_string_id); @@ -958,13 +891,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri utf8_string1_p = data_p; } - else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_LIT_TABLE) - { - const lit_literal_t lit = lit_get_literal_by_cp (string1_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - utf8_string1_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit); - } else { utf8_string1_p = (lit_utf8_byte_t *) jmem_heap_alloc_block ((size_t) strings_size); @@ -988,13 +914,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri utf8_string2_p = data_p; } - else if (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_LIT_TABLE) - { - const lit_literal_t lit = lit_get_literal_by_cp (string2_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - utf8_string2_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit); - } else { utf8_string2_p = (lit_utf8_byte_t *) jmem_heap_alloc_block ((size_t) strings_size); @@ -1088,14 +1007,6 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma- utf8_string1_p = data_p; utf8_string1_size = (lit_utf8_size_t) string1_p->u.ascii_string.size; } - else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_LIT_TABLE) - { - const lit_literal_t lit = lit_get_literal_by_cp (string1_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - utf8_string1_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit); - utf8_string1_size = (lit_utf8_size_t) lit_charset_literal_get_size (lit); - } else { utf8_string1_size = ecma_string_get_size (string1_p); @@ -1129,14 +1040,6 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma- utf8_string2_p = data_p; utf8_string2_size = (lit_utf8_size_t) string2_p->u.ascii_string.size; } - else if (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_LIT_TABLE) - { - const lit_literal_t lit = lit_get_literal_by_cp (string2_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - utf8_string2_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit); - utf8_string2_size = (lit_utf8_size_t) lit_charset_literal_get_size (lit); - } else { utf8_string2_size = ecma_string_get_size (string2_p); @@ -1182,12 +1085,6 @@ ecma_string_get_length (const ecma_string_t *string_p) /**< ecma-string */ { switch (ECMA_STRING_GET_CONTAINER (string_p)) { - case ECMA_STRING_CONTAINER_LIT_TABLE: - { - lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - return lit_charset_literal_get_length (lit); - } case ECMA_STRING_CONTAINER_MAGIC_STRING: { JERRY_ASSERT (ECMA_STRING_IS_ASCII (lit_get_magic_string_utf8 (string_p->u.magic_string_id), @@ -1229,13 +1126,6 @@ ecma_string_get_size (const ecma_string_t *string_p) /**< ecma-string */ { switch (ECMA_STRING_GET_CONTAINER (string_p)) { - case ECMA_STRING_CONTAINER_LIT_TABLE: - { - lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp); - JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit)); - - return lit_charset_literal_get_size (lit); - } case ECMA_STRING_CONTAINER_MAGIC_STRING: { return lit_get_magic_string_size (string_p->u.magic_string_id); diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index dc637f199..f38072c3e 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -1429,14 +1429,14 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) { - lit_cpointer_t *literal_start_p = NULL; + jmem_cpointer_t *literal_start_p = NULL; uint32_t literal_end; uint32_t const_literal_end; if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { uint8_t *byte_p = (uint8_t *) bytecode_p; - literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); + literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p; literal_end = args_p->literal_end; @@ -1445,7 +1445,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ else { uint8_t *byte_p = (uint8_t *) bytecode_p; - literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); + literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p; literal_end = args_p->literal_end; diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 214881b6e..41867524c 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -19,7 +19,6 @@ #include "ecma-globals.h" #include "jmem-allocator.h" -#include "lit-cpointer.h" #include "lit-strings.h" /** \addtogroup ecma ECMA @@ -165,7 +164,6 @@ extern ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *, l extern ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t); extern ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t); extern ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t); -extern ecma_string_t *ecma_new_ecma_string_from_lit_cp (lit_cpointer_t); extern ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t); extern ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t); extern ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *, ecma_string_t *); diff --git a/jerry-core/ecma/base/ecma-init-finalize.c b/jerry-core/ecma/base/ecma-init-finalize.c index 24959da16..6fedd456b 100644 --- a/jerry-core/ecma/base/ecma-init-finalize.c +++ b/jerry-core/ecma/base/ecma-init-finalize.c @@ -19,6 +19,7 @@ #include "ecma-init-finalize.h" #include "ecma-lcache.h" #include "ecma-lex-env.h" +#include "ecma-literal-storage.h" #include "jmem-allocator.h" /** \addtogroup ecma ECMA @@ -37,6 +38,7 @@ ecma_init (void) ecma_gc_init (); ecma_init_builtins (); ecma_lcache_init (); + ecma_init_lit_storage (); ecma_init_environment (); jmem_register_free_unused_memory_callback (ecma_free_unused_memory); @@ -53,6 +55,7 @@ ecma_finalize (void) ecma_finalize_environment (); ecma_finalize_builtins (); ecma_gc_run (); + ecma_finalize_lit_storage (); } /* ecma_finalize */ /** diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c new file mode 100644 index 000000000..dd65c59ab --- /dev/null +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -0,0 +1,541 @@ +/* Copyright 2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-literal-storage.h" +#include "ecma-helpers.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmalitstorage Literal storage + * @{ + */ + +/** + * Number of values in a literal storage item + */ +#define ECMA_LIT_STORAGE_VALUE_COUNT 3 + +/** + * Literal 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_lit_storage_item_t; + +JERRY_STATIC_ASSERT (sizeof (ecma_lit_storage_item_t) <= sizeof (uint64_t), + size_of_ecma_lit_storage_item_t_must_be_less_than_or_equal_to_8_bytes); + +static ecma_lit_storage_item_t *string_list_first_p; +static ecma_lit_storage_item_t *number_list_first_p; + +/** + * Initialize literal storage + */ +void +ecma_init_lit_storage (void) +{ + string_list_first_p = NULL; + number_list_first_p = NULL; +} /* ecma_init_lit_storage */ + +/** + * Free string list + */ +static void +ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list */ +{ + while (string_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (string_list_p->values[i] != JMEM_CP_NULL) + { + ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + string_list_p->values[i]); + + JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p)); + ecma_deref_ecma_string (string_p); + } + } + + ecma_lit_storage_item_t *prev_item = string_list_p; + string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); + jmem_pools_free (prev_item); + } +} /* ecma_free_string_list */ + +/** + * Finalize literal storage + */ +void +ecma_finalize_lit_storage (void) +{ + ecma_free_string_list (string_list_first_p); + ecma_free_string_list (number_list_first_p); +} /* ecma_finalize_lit_storage */ + +/** + * Find or create a literal string. + * + * @return ecma_string_t compressed pointer + */ +jmem_cpointer_t +ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */ + lit_utf8_size_t size) /**< size of the string */ +{ + ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size); + + ecma_lit_storage_item_t *string_list_p = string_list_first_p; + jmem_cpointer_t *empty_cpointer_p = NULL; + + while (string_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (string_list_p->values[i] == JMEM_CP_NULL) + { + if (empty_cpointer_p == NULL) + { + empty_cpointer_p = string_list_p->values + i; + } + } + else + { + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + string_list_p->values[i]); + + if (ecma_compare_ecma_strings (string_p, value_p)) + { + /* Return with string if found in the list. */ + ecma_deref_ecma_string (string_p); + return string_list_p->values[i]; + } + } + } + + string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); + } + + jmem_cpointer_t result; + JMEM_CP_SET_NON_NULL_POINTER (result, string_p); + + if (empty_cpointer_p != NULL) + { + *empty_cpointer_p = result; + return result; + } + + ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (); + + new_item_p->values[0] = result; + for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + new_item_p->values[i] = JMEM_CP_NULL; + } + + JMEM_CP_SET_POINTER (new_item_p->next_cp, string_list_first_p); + string_list_first_p = new_item_p; + + return result; +} /* ecma_find_or_create_literal_string */ + +/** + * Find or create a literal number. + * + * @return ecma_string_t compressed pointer + */ +jmem_cpointer_t +ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be searched */ +{ + ecma_value_t num = ecma_make_number_value (number_arg); + + ecma_lit_storage_item_t *number_list_p = number_list_first_p; + jmem_cpointer_t *empty_cpointer_p = NULL; + + while (number_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (number_list_p->values[i] == JMEM_CP_NULL) + { + if (empty_cpointer_p == NULL) + { + empty_cpointer_p = number_list_p->values + i; + } + } + else + { + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + number_list_p->values[i]); + + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER); + + if (ecma_is_value_integer_number (num)) + { + if (value_p->u.lit_number == num) + { + return number_list_p->values[i]; + } + } + else + { + if (ecma_is_value_float_number (value_p->u.lit_number) + && ecma_get_float_from_value (value_p->u.lit_number) == ecma_get_float_from_value (num)) + { + ecma_free_value (num); + return number_list_p->values[i]; + } + } + } + } + + number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp); + } + + ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc (); + string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER; + string_p->u.lit_number = num; + + jmem_cpointer_t result; + JMEM_CP_SET_NON_NULL_POINTER (result, string_p); + + if (empty_cpointer_p != NULL) + { + *empty_cpointer_p = result; + return result; + } + + ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (); + + new_item_p->values[0] = result; + for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + new_item_p->values[i] = JMEM_CP_NULL; + } + + JMEM_CP_SET_POINTER (new_item_p->next_cp, number_list_first_p); + number_list_first_p = new_item_p; + + return result; +} /* ecma_find_or_create_literal_number */ + +/** + * Log2 of snapshot literal alignment. + */ +#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 2 + +/** + * Snapshot literal alignment. + */ +#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT (1u << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) + +#ifdef JERRY_ENABLE_SNAPSHOT_SAVE + +/** + * Save literals to specified snapshot buffer. + * + * @return true, if save was performed successfully (i.e. buffer size is sufficient), + * false - otherwise. + */ +bool +ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */ + size_t buffer_size, /**< size of the buffer */ + size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */ + lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers + * to the literal offsets + * in snapshot */ + uint32_t *out_map_len_p, /**< [out] number of literals */ + uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */ +{ + /* Count literals and literal space. */ + uint32_t string_count = 0; + uint32_t number_count = 0; + uint32_t lit_table_size = 2 * sizeof (uint32_t); + + ecma_lit_storage_item_t *string_list_p = string_list_first_p; + + while (string_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (string_list_p->values[i] != JMEM_CP_NULL) + { + ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + string_list_p->values[i]); + + lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p), + JERRY_SNAPSHOT_LITERAL_ALIGNMENT); + string_count++; + } + } + + string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); + } + + ecma_lit_storage_item_t *number_list_p = number_list_first_p; + + while (number_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (number_list_p->values[i] != JMEM_CP_NULL) + { + lit_table_size += (uint32_t) sizeof (ecma_number_t); + number_count++; + } + } + + number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp); + } + + /* Check whether enough space is available. */ + if (*in_out_buffer_offset_p + lit_table_size > buffer_size) + { + return false; + } + + /* Check whether the maximum literal table size is reached. */ + if ((lit_table_size >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) > UINT16_MAX) + { + return false; + } + + uint32_t total_count = string_count + number_count; + lit_mem_to_snapshot_id_map_entry_t *map_p; + + map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t)); + + /* Set return values (no error is possible from here). */ + buffer_p += *in_out_buffer_offset_p; + *in_out_buffer_offset_p += lit_table_size; + *out_map_p = map_p; + *out_map_len_p = total_count; + *out_lit_table_size_p = lit_table_size; + + /* Write data into the buffer. */ + + /* The zero value is reserved for NULL (no literal) + * constant so the first literal must have offset one. */ + uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT; + + ((uint32_t *) buffer_p)[0] = string_count; + ((uint32_t *) buffer_p)[1] = number_count; + buffer_p += 2 * sizeof (uint32_t); + + string_list_p = string_list_first_p; + + while (string_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (string_list_p->values[i] != JMEM_CP_NULL) + { + map_p->literal_id = string_list_p->values[i]; + map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG); + map_p++; + + ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + string_list_p->values[i]); + + ecma_length_t length = ecma_string_get_size (string_p); + + *((uint16_t *) buffer_p) = (uint16_t) length; + ecma_string_to_utf8_bytes (string_p, buffer_p + sizeof (uint16_t), length); + + length = JERRY_ALIGNUP (sizeof (uint16_t) + length, + JERRY_SNAPSHOT_LITERAL_ALIGNMENT); + + buffer_p += length; + literal_offset += length; + } + } + + string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); + } + + number_list_p = number_list_first_p; + + while (number_list_p != NULL) + { + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (number_list_p->values[i] != JMEM_CP_NULL) + { + map_p->literal_id = number_list_p->values[i]; + map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG); + map_p++; + + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + number_list_p->values[i]); + + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER); + + ecma_number_t num = ecma_get_number_from_value (value_p->u.lit_number); + memcpy (buffer_p, &num, sizeof (ecma_number_t)); + + ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t), + JERRY_SNAPSHOT_LITERAL_ALIGNMENT); + + buffer_p += length; + literal_offset += length; + } + } + + number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp); + } + + return true; +} /* ecma_save_literals_for_snapshot */ + +#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */ + +#ifdef JERRY_ENABLE_SNAPSHOT_EXEC + +/** + * Helper function for ecma_load_literals_from_snapshot. + * + * Note: always inline because it is used only once. + * + * @return true, if load was performed successfully + * false - otherwise (i.e. buffer length is incorrect). + */ +static inline bool __attr_always_inline___ +ecma_load_literals_from_buffer (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */ + uint32_t lit_table_size, /**< size of literal table in snapshot */ + lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */ + uint32_t string_count, /**< number of strings */ + uint32_t number_count) /**< number of numbers */ +{ + /* The zero value is reserved for NULL (no literal) + * constant so the first literal must have offset one. */ + uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT; + + /* Load strings first. */ + while (string_count > 0) + { + if (lit_table_size < literal_offset + sizeof (uint32_t)) + { + /* Buffer is not sufficent. */ + return false; + } + + lit_utf8_size_t length = *((uint16_t *) buffer_p); + lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length, + JERRY_SNAPSHOT_LITERAL_ALIGNMENT); + + if (lit_table_size < literal_offset + aligned_length) + { + /* Buffer is not sufficent. */ + return false; + } + + map_p->literal_id = ecma_find_or_create_literal_string (buffer_p + sizeof (uint16_t), length); + map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG); + map_p++; + + buffer_p += aligned_length; + literal_offset += aligned_length; + + string_count--; + } + + /* Load numbers. */ + while (number_count > 0) + { + if (lit_table_size < literal_offset + sizeof (ecma_number_t)) + { + /* Buffer is not sufficent. */ + return false; + } + + ecma_number_t num; + memcpy (&num, buffer_p, sizeof (ecma_number_t)); + + map_p->literal_id = ecma_find_or_create_literal_number (num); + map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG); + map_p++; + + ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t), + JERRY_SNAPSHOT_LITERAL_ALIGNMENT); + + buffer_p += length; + literal_offset += length; + + number_count--; + } + + return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT)); +} /* ecma_load_literals_from_buffer */ + +/** + * Load literals from snapshot. + * + * @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent), + * false - otherwise (i.e. snapshot is incorrect). + */ +bool +ecma_load_literals_from_snapshot (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */ + uint32_t lit_table_size, /**< size of literal table in snapshot */ + lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets + * in snapshot to identifiers + * of loaded literals in literal + * storage */ + uint32_t *out_map_len_p) /**< [out] literals number */ +{ + *out_map_p = NULL; + + if (lit_table_size < 2 * sizeof (uint32_t)) + { + /* Buffer is not sufficent. */ + return false; + } + + uint32_t string_count = ((uint32_t *) buffer_p)[0]; + uint32_t number_count = ((uint32_t *) buffer_p)[1]; + buffer_p += 2 * sizeof (uint32_t); + + uint32_t total_count = string_count + number_count; + lit_mem_to_snapshot_id_map_entry_t *map_p; + + *out_map_len_p = total_count; + + if (total_count == 0) + { + return true; + } + + map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t)); + *out_map_p = map_p; + + if (ecma_load_literals_from_buffer (buffer_p, lit_table_size, map_p, string_count, number_count)) + { + return true; + } + + jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t)); + *out_map_p = NULL; + return false; +} /* ecma_load_literals_from_snapshot */ + +#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */ + +/** + * @} + * @} + */ diff --git a/jerry-core/ecma/base/ecma-literal-storage.h b/jerry-core/ecma/base/ecma-literal-storage.h new file mode 100644 index 000000000..2a524b99c --- /dev/null +++ b/jerry-core/ecma/base/ecma-literal-storage.h @@ -0,0 +1,63 @@ +/* Copyright 2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMA_LIT_STORAGE_H +#define ECMA_LIT_STORAGE_H + +#include "ecma-globals.h" +#include "jmem-allocator.h" +#include "lit-globals.h" + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmalitstorage Literal storage + * @{ + */ + +/** + * Snapshot literal - offset map + */ +typedef struct +{ + jmem_cpointer_t literal_id; /**< literal id */ + jmem_cpointer_t literal_offset; /**< literal offset */ +} lit_mem_to_snapshot_id_map_entry_t; + +extern void ecma_init_lit_storage (void); +extern void ecma_finalize_lit_storage (void); + +extern jmem_cpointer_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *, lit_utf8_size_t); +extern jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t); + +#ifdef JERRY_ENABLE_SNAPSHOT_SAVE +extern bool +ecma_save_literals_for_snapshot (uint8_t *, size_t, size_t *, + lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *); +#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */ + +#ifdef JERRY_ENABLE_SNAPSHOT_EXEC +extern bool +ecma_load_literals_from_snapshot (const uint8_t *, uint32_t, + lit_mem_to_snapshot_id_map_entry_t **, uint32_t *); +#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */ + +/** + * @} + * @} + */ + +#endif /* !ECMA_LIT_STORAGE_H */ diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.c b/jerry-core/ecma/operations/ecma-objects-arguments.c index edcb82592..2786b06fa 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.c +++ b/jerry-core/ecma/operations/ecma-objects-arguments.c @@ -102,7 +102,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function if (bytecode_data_p != NULL) { ecma_length_t formal_params_number; - lit_cpointer_t *literal_p; + jmem_cpointer_t *literal_p; if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { @@ -110,7 +110,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function uint8_t *byte_p = (uint8_t *) bytecode_data_p; formal_params_number = args_p->argument_end; - literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); } else { @@ -118,7 +118,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function uint8_t *byte_p = (uint8_t *) bytecode_data_p; formal_params_number = args_p->argument_end; - literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); } if (!is_strict @@ -139,7 +139,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function continue; } - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_p[indx]); + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]); ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx); prop_desc.is_value_defined = true; @@ -155,7 +155,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (indx_string_p); - ecma_deref_ecma_string (name_p); } // 12. diff --git a/jerry-core/jerry-snapshot.h b/jerry-core/jerry-snapshot.h index 2d64d7929..b8caae741 100644 --- a/jerry-core/jerry-snapshot.h +++ b/jerry-core/jerry-snapshot.h @@ -37,6 +37,6 @@ typedef struct /** * Jerry snapshot format version */ -#define JERRY_SNAPSHOT_VERSION (4u) +#define JERRY_SNAPSHOT_VERSION (5u) #endif /* !JERRY_SNAPSHOT_H */ diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index 006b352a2..9031fe114 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -25,13 +25,12 @@ #include "ecma-gc.h" #include "ecma-helpers.h" #include "ecma-init-finalize.h" +#include "ecma-literal-storage.h" #include "ecma-objects.h" #include "ecma-objects-general.h" #include "ecma-try-catch-macro.h" #include "jerry-snapshot.h" -#include "lit-literal.h" #include "lit-magic-strings.h" -#include "lit-snapshot.h" #include "js-parser.h" #include "re-compiler.h" @@ -1359,7 +1358,6 @@ jerry_init (jerry_flag_t flags) /**< combination of Jerry flags */ jerry_make_api_available (); jmem_init (); - lit_init (); ecma_init (); } /* jerry_init */ @@ -1375,7 +1373,6 @@ jerry_cleanup (void) vm_finalize (); ecma_finalize (); - lit_finalize (); jmem_finalize (is_show_mem_stats); } /* jerry_cleanup */ @@ -1604,15 +1601,15 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p) /**< compiled /* Sub-functions and regular expressions are stored recursively. */ uint8_t *src_buffer_p = (uint8_t *) compiled_code_p; uint8_t *dst_buffer_p = (uint8_t *) copied_compiled_code_p; - lit_cpointer_t *src_literal_start_p; - uint16_t *dst_literal_start_p; + jmem_cpointer_t *src_literal_start_p; + jmem_cpointer_t *dst_literal_start_p; uint32_t const_literal_end; uint32_t literal_end; if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { - src_literal_start_p = (lit_cpointer_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t)); - dst_literal_start_p = (uint16_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t)); + src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t)); + dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t)); cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) src_buffer_p; literal_end = args_p->literal_end; @@ -1620,8 +1617,8 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p) /**< compiled } else { - src_literal_start_p = (lit_cpointer_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t)); - dst_literal_start_p = (uint16_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t)); + src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t)); + dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t)); cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) src_buffer_p; literal_end = args_p->literal_end; @@ -1663,14 +1660,14 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */ if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) { - lit_cpointer_t *literal_start_p; + jmem_cpointer_t *literal_start_p; uint32_t argument_end; uint32_t register_end; uint32_t const_literal_end; if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { - literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t)); + literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t)); cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p; argument_end = args_p->argument_end; @@ -1679,7 +1676,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */ } else { - literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t)); + literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t)); cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p; argument_end = args_p->argument_end; @@ -1703,7 +1700,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */ current_p++; } - literal_start_p[i] = (uint16_t) current_p->literal_offset; + literal_start_p[i] = current_p->literal_offset; } } @@ -1726,7 +1723,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */ current_p++; } - literal_start_p[i] = (uint16_t) current_p->literal_offset; + literal_start_p[i] = current_p->literal_offset; } } @@ -1811,12 +1808,12 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL; uint32_t literals_num; - if (!lit_save_literals_for_snapshot (buffer_p, - buffer_size, - &snapshot_buffer_write_offset, - &lit_map_p, - &literals_num, - &header.lit_table_size)) + if (!ecma_save_literals_for_snapshot (buffer_p, + buffer_size, + &snapshot_buffer_write_offset, + &lit_map_p, + &literals_num, + &header.lit_table_size)) { JERRY_ASSERT (lit_map_p == NULL); return 0; @@ -1836,7 +1833,7 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source if (lit_map_p != NULL) { - jmem_heap_free_block_size_stored (lit_map_p); + jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t)); } ecma_bytecode_deref (bytecode_data_p); @@ -1929,7 +1926,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data } else { - code_size = (uint32_t) (header_size + literal_end * sizeof (lit_cpointer_t)); + code_size = (uint32_t) (header_size + literal_end * sizeof (jmem_cpointer_t)); uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + code_size; uint32_t total_size = JERRY_ALIGNUP (code_size + 1 + sizeof (uint8_t *), JMEM_ALIGNMENT); @@ -1948,7 +1945,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data JERRY_ASSERT (bytecode_p->refs == 1); - lit_cpointer_t *literal_start_p = (lit_cpointer_t *) (((uint8_t *) bytecode_p) + header_size); + jmem_cpointer_t *literal_start_p = (jmem_cpointer_t *) (((uint8_t *) bytecode_p) + header_size); for (uint32_t i = 0; i < const_literal_end; i++) { @@ -2038,10 +2035,10 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */ return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_VERSION; } - if (!lit_load_literals_from_snapshot (snapshot_data_p + header_p->lit_table_offset, - header_p->lit_table_size, - &lit_map_p, - &literals_num)) + if (!ecma_load_literals_from_snapshot (snapshot_data_p + header_p->lit_table_offset, + header_p->lit_table_size, + &lit_map_p, + &literals_num)) { JERRY_ASSERT (lit_map_p == NULL); return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT; @@ -2055,7 +2052,7 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */ if (lit_map_p != NULL) { - jmem_heap_free_block_size_stored (lit_map_p); + jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t)); } if (bytecode_p == NULL) diff --git a/jerry-core/lit/lit-cpointer.c b/jerry-core/lit/lit-cpointer.c deleted file mode 100644 index 1545d0b6d..000000000 --- a/jerry-core/lit/lit-cpointer.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright 2015 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lit-cpointer.h" -#include "jrt-bit-fields.h" - -/** - * Compress pointer to extended compressed pointer. - * - * @return dynamic storage-specific extended compressed pointer - */ -inline lit_cpointer_t __attr_pure___ __attr_always_inline___ -lit_cpointer_compress (lit_record_t *pointer) /**< pointer to compress */ -{ - if (pointer == NULL) - { - return JMEM_CP_NULL; - } - - return (lit_cpointer_t) jmem_compress_pointer (pointer); -} /* lit_cpointer_compress */ - -/** - * Decompress extended compressed pointer. - * - * @return decompressed pointer - */ -inline lit_record_t * __attr_pure___ __attr_always_inline___ -lit_cpointer_decompress (lit_cpointer_t compressed_pointer) /**< recordset-specific compressed pointer */ -{ - if (compressed_pointer == JMEM_CP_NULL) - { - return NULL; - } - - return (lit_record_t *) jmem_decompress_pointer (compressed_pointer); -} /* lit_cpointer_decompress */ - -/** - * Create NULL compressed pointer. - * - * @return NULL compressed pointer - */ -inline lit_cpointer_t __attr_pure___ __attr_always_inline___ -lit_cpointer_null_cp (void) -{ - return JMEM_CP_NULL; -} /* lit_cpointer_null_cp */ diff --git a/jerry-core/lit/lit-cpointer.h b/jerry-core/lit/lit-cpointer.h deleted file mode 100644 index 69304e43f..000000000 --- a/jerry-core/lit/lit-cpointer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright 2015 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIT_CPOINTER_H -#define LIT_CPOINTER_H - -#include "lit-literal-storage.h" -#include "jmem-allocator.h" - -#define LIT_CPOINTER_WIDTH (JMEM_CP_WIDTH + JMEM_ALIGNMENT_LOG - JMEM_ALIGNMENT_LOG) - -/** - * Dynamic storage-specific extended compressed pointer - * - * Note: - * the pointer can represent addresses aligned by lit_DYN_STORAGE_LENGTH_UNIT, - * while jmem_cpointer_t can only represent addresses aligned by JMEM_ALIGNMENT. - */ -typedef uint16_t lit_cpointer_t; - -extern lit_cpointer_t lit_cpointer_compress (lit_record_t *); -extern lit_record_t *lit_cpointer_decompress (lit_cpointer_t); -extern lit_cpointer_t lit_cpointer_null_cp (); - -#endif /* !LIT_CPOINTER_H */ diff --git a/jerry-core/lit/lit-literal-storage.c b/jerry-core/lit/lit-literal-storage.c deleted file mode 100644 index 030a50ff8..000000000 --- a/jerry-core/lit/lit-literal-storage.c +++ /dev/null @@ -1,265 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lit-literal-storage.h" -#include "lit-cpointer.h" - -#include "ecma-helpers.h" - -lit_record_t *lit_storage = NULL; - -/** - * Create charset record in the literal storage - * - * @return pointer to the created record - */ -lit_record_t * -lit_create_charset_literal (const lit_utf8_byte_t *str_p, /**< string to be placed into the record */ - const lit_utf8_size_t buf_size) /**< size in bytes of the buffer which holds the string */ -{ - lit_charset_record_t *rec_p = (lit_charset_record_t *) jmem_heap_alloc_block (buf_size + LIT_CHARSET_HEADER_SIZE); - - rec_p->type = LIT_RECORD_TYPE_CHARSET; - rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage); - lit_storage = (lit_record_t *) rec_p; - - rec_p->hash = (uint8_t) lit_utf8_string_calc_hash (str_p, buf_size); - rec_p->size = (uint16_t) buf_size; - rec_p->length = (uint16_t) lit_utf8_string_length (str_p, buf_size); - memcpy (rec_p + 1, str_p, buf_size); - - return (lit_record_t *) rec_p; -} /* lit_create_charset_literal */ - -/** - * Create magic string record in the literal storage. - * - * @return pointer to the created record - */ -lit_record_t * -lit_create_magic_literal (const lit_magic_string_id_t id) /**< id of magic string */ -{ - lit_magic_record_t *rec_p = (lit_magic_record_t *) jmem_heap_alloc_block (sizeof (lit_magic_record_t)); - rec_p->type = LIT_RECORD_TYPE_MAGIC_STR; - rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage); - lit_storage = (lit_record_t *) rec_p; - - rec_p->magic_id = (uint32_t) id; - - return (lit_record_t *) rec_p; -} /* lit_create_magic_literal */ - -/** - * Create external magic string record in the literal storage. - * - * @return pointer to the created record - */ -lit_record_t * -lit_create_magic_literal_ex (const lit_magic_string_ex_id_t id) /**< id of magic string */ -{ - lit_magic_record_t *rec_p = (lit_magic_record_t *) jmem_heap_alloc_block (sizeof (lit_magic_record_t)); - rec_p->type = LIT_RECORD_TYPE_MAGIC_STR_EX; - rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage); - lit_storage = (lit_record_t *) rec_p; - - rec_p->magic_id = (uint32_t) id; - - return (lit_record_t *) rec_p; -} /* lit_create_magic_literal_ex */ - -/** - * Create number record in the literal storage. - * - * @return pointer to the created record - */ -lit_record_t * -lit_create_number_literal (const ecma_number_t num) /**< numeric value */ -{ - lit_number_record_t *rec_p = (lit_number_record_t *) jmem_heap_alloc_block (sizeof (lit_number_record_t)); - - rec_p->type = (uint8_t) LIT_RECORD_TYPE_NUMBER; - rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage); - lit_storage = (lit_record_t *) rec_p; - - rec_p->number = num; - - return (lit_record_t *) rec_p; -} /* lit_create_number_literal */ - -/** - * Get size of stored literal - * - * @return size of literal - */ -size_t __attr_pure___ -lit_get_literal_size (const lit_record_t *lit_p) /**< literal record */ -{ - const lit_record_type_t type = (const lit_record_type_t) lit_p->type; - size_t size = 0; - - switch (type) - { - case LIT_RECORD_TYPE_NUMBER: - { - size = sizeof (lit_number_record_t); - break; - } - case LIT_RECORD_TYPE_CHARSET: - { - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit_p; - size = rec_p->size + LIT_CHARSET_HEADER_SIZE; - break; - } - case LIT_RECORD_TYPE_MAGIC_STR: - case LIT_RECORD_TYPE_MAGIC_STR_EX: - { - size = sizeof (lit_magic_record_t); - break; - } - default: - { - JERRY_UNREACHABLE (); - break; - } - } - - JERRY_ASSERT (size > 0); - return size; -} /* lit_get_literal_size */ - - -/** - * Free stored literal - * - * @return pointer to the next literal in the list - */ -lit_record_t * -lit_free_literal (lit_record_t *lit_p) /**< literal record */ -{ - lit_record_t *const ret_p = lit_cpointer_decompress (lit_p->next); - jmem_heap_free_block (lit_p, lit_get_literal_size (lit_p)); - return ret_p; -} /* lit_free_literal */ - -/** - * Count literal records in the storage - * - * @return number of literals - */ -uint32_t -lit_count_literals () -{ - uint32_t num = 0; - lit_record_t *rec_p; - - for (rec_p = lit_storage; - rec_p != NULL; - rec_p = lit_cpointer_decompress (rec_p->next)) - { - if (rec_p->type > LIT_RECORD_TYPE_FREE) - { - num++; - } - } - - return num; -} /* lit_count_literals */ - -#ifdef JERRY_ENABLE_LOG -/** - * Dump the contents of the literal storage. - */ -void -lit_dump_literals () -{ - lit_record_t *rec_p; - size_t i; - - JERRY_DLOG ("LITERALS:\n"); - - for (rec_p = lit_storage; - rec_p != NULL; - rec_p = lit_cpointer_decompress (rec_p->next)) - { - JERRY_DLOG ("%p ", rec_p); - JERRY_DLOG ("[%3zu] ", lit_get_literal_size (rec_p)); - - switch (rec_p->type) - { - case LIT_RECORD_TYPE_CHARSET: - { - const lit_charset_record_t *const record_p = (const lit_charset_record_t *) rec_p; - char *str = (char *) (record_p + 1); - for (i = 0; i < record_p->size; ++i, ++str) - { - /* TODO: Support proper printing of characters which occupy more than one byte. */ - - JERRY_DLOG ("%c", *str); - } - - JERRY_DLOG (" : STRING"); - - break; - } - case LIT_RECORD_TYPE_MAGIC_STR: - { - lit_magic_string_id_t id = (lit_magic_string_id_t) ((lit_magic_record_t *) rec_p)->magic_id; - JERRY_DLOG ("%s : MAGIC STRING", lit_get_magic_string_utf8 (id)); - JERRY_DLOG (" [id=%d] ", id); - - break; - } - case LIT_RECORD_TYPE_MAGIC_STR_EX: - { - lit_magic_string_ex_id_t id = ((lit_magic_record_t *) rec_p)->magic_id; - JERRY_DLOG ("%s : EXT MAGIC STRING", lit_get_magic_string_ex_utf8 (id)); - JERRY_DLOG (" [id=%d] ", id); - - break; - } - case LIT_RECORD_TYPE_NUMBER: - { - const lit_number_record_t *const record_p = (const lit_number_record_t *) rec_p; - ecma_number_t value; - memcpy (&value, &record_p->number, sizeof (ecma_number_t)); - - if (ecma_number_is_nan (value)) - { - JERRY_DLOG ("%s : NUMBER", "NaN"); - } - else - { - lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER + 1u]; - memset (buff, 0, sizeof (buff)); - - lit_utf8_size_t sz = ecma_number_to_utf8_string (value, buff, sizeof (buff)); - JERRY_ASSERT (sz <= ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER); - - JERRY_DLOG ("%s : NUMBER", buff); - } - - break; - } - default: - { - JERRY_UNREACHABLE (); - } - } - - JERRY_DLOG ("\n"); - } -} /* lit_dump_literals */ -#endif /* JERRY_ENABLE_LOG */ diff --git a/jerry-core/lit/lit-literal-storage.h b/jerry-core/lit/lit-literal-storage.h deleted file mode 100644 index 50480b8c9..000000000 --- a/jerry-core/lit/lit-literal-storage.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIT_LITERAL_STORAGE_H -#define LIT_LITERAL_STORAGE_H - -#include "lit-magic-strings.h" -#include "lit-globals.h" -#include "ecma-globals.h" - -/** - * Represents the type of the record. - */ -typedef enum -{ - LIT_RECORD_TYPE_FREE = 0, /**< Free record that marks an empty space. It doesn't hold any values. */ - LIT_RECORD_TYPE_CHARSET = 1, /**< Charset record that holds characters. */ - LIT_RECORD_TYPE_MAGIC_STR = 2, /**< Magic string record that holds a magic string id. */ - LIT_RECORD_TYPE_MAGIC_STR_EX = 3, /**< External magic string record that holds an extrernal magic string id. */ - LIT_RECORD_TYPE_NUMBER = 4 /**< Number record that holds a numeric value. */ -} lit_record_type_t; - -/** - * Record header - */ -typedef struct -{ - uint16_t next; /* Compressed pointer to next record */ - uint8_t type; /* Type of record */ -} lit_record_t; - -/** - * Head pointer to literal storage - */ -extern lit_record_t *lit_storage; - -typedef lit_record_t *lit_literal_t; - -/** - * Charset record header - * - * String is stored after the header. - */ -typedef struct -{ - uint16_t next; /* Compressed pointer to next record */ - uint8_t type; /* Type of record */ - uint8_t hash; /* Hash of the string */ - uint16_t size; /* Size of the string in bytes */ - uint16_t length; /* Number of character in the string */ -} lit_charset_record_t; - -/** - * Number record header - */ -typedef struct -{ - uint16_t next; /* Compressed pointer to next record */ - uint8_t type; /* Type of record */ - ecma_number_t number; /* Number stored in the record */ -} lit_number_record_t; - -/** - * Magic record header - */ -typedef struct -{ - uint16_t next; /* Compressed pointer to next record */ - uint8_t type; /* Type of record */ - uint32_t magic_id; /* Magic ID stored in the record */ -} lit_magic_record_t; - -#define LIT_CHARSET_HEADER_SIZE (sizeof(lit_charset_record_t)) - -extern lit_record_t *lit_create_charset_literal (const lit_utf8_byte_t *, const lit_utf8_size_t); -extern lit_record_t *lit_create_magic_literal (const lit_magic_string_id_t); -extern lit_record_t *lit_create_magic_literal_ex (const lit_magic_string_ex_id_t); -extern lit_record_t *lit_create_number_literal (const ecma_number_t); -extern lit_record_t *lit_free_literal (lit_record_t *); -extern size_t lit_get_literal_size (const lit_record_t *); - -extern uint32_t lit_count_literals (); - -#ifdef JERRY_ENABLE_LOG -extern void lit_dump_literals (); -#endif /* JERRY_ENABLE_LOG */ - -#define LIT_RECORD_IS_CHARSET(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_CHARSET) -#define LIT_RECORD_IS_MAGIC_STR(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_MAGIC_STR) -#define LIT_RECORD_IS_MAGIC_STR_EX(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_MAGIC_STR_EX) -#define LIT_RECORD_IS_NUMBER(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_NUMBER) - -#endif /* !LIT_LITERAL_STORAGE_H */ diff --git a/jerry-core/lit/lit-literal.c b/jerry-core/lit/lit-literal.c deleted file mode 100644 index be2b0d3fc..000000000 --- a/jerry-core/lit/lit-literal.c +++ /dev/null @@ -1,384 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2016 University of Szeged. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lit-literal.h" - -#include "ecma-helpers.h" -#include "lit-cpointer.h" -#include "lit-magic-strings.h" -#include "lit-literal-storage.h" - - -/** - * Initialize literal storage - */ -void -lit_init (void) -{ - lit_magic_strings_ex_init (); -} /* lit_init */ - -/** - * Finalize literal storage - */ -void -lit_finalize (void) -{ -#ifdef JERRY_ENABLE_LOG - lit_dump_literals (); -#endif /* JERRY_ENABLE_LOG */ - - while (lit_storage) - { - lit_storage = lit_free_literal (lit_storage); - } -} /* lit_finalize */ - -/** - * Create new literal in literal storage from characters buffer. - * Don't check if the same literal already exists. - * - * @return pointer to created record - */ -lit_literal_t -lit_create_literal_from_utf8_string (const lit_utf8_byte_t *str_p, /**< string to initialize the record, - * could be non-zero-terminated */ - lit_utf8_size_t str_size) /**< length of the string */ -{ - JERRY_ASSERT (str_p || !str_size); - - lit_magic_string_id_t m_str_id; - for (m_str_id = (lit_magic_string_id_t) 0; - m_str_id < LIT_MAGIC_STRING__COUNT; - m_str_id = (lit_magic_string_id_t) (m_str_id + 1)) - { - if (lit_get_magic_string_size (m_str_id) != str_size) - { - continue; - } - - if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_utf8 (m_str_id), str_size)) - { - return lit_create_magic_literal (m_str_id); - } - } - - lit_magic_string_ex_id_t m_str_ex_id; - for (m_str_ex_id = (lit_magic_string_ex_id_t) 0; - m_str_ex_id < lit_get_magic_string_ex_count (); - m_str_ex_id = (lit_magic_string_ex_id_t) (m_str_ex_id + 1)) - { - if (lit_get_magic_string_ex_size (m_str_ex_id) != str_size) - { - continue; - } - - if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_ex_utf8 (m_str_ex_id), str_size)) - { - return lit_create_magic_literal_ex (m_str_ex_id); - } - } - - return lit_create_charset_literal (str_p, str_size); -} /* lit_create_literal_from_utf8_string */ - -/** - * Find a literal in literal storage. - * Only charset and magic string records are checked during search. - * - * @return pointer to a literal or NULL if no corresponding literal exists - */ -lit_literal_t -lit_find_literal_by_utf8_string (const lit_utf8_byte_t *str_p, /**< a string to search for */ - lit_utf8_size_t str_size) /**< length of the string */ -{ - JERRY_ASSERT (str_p || !str_size); - - lit_string_hash_t str_hash = lit_utf8_string_calc_hash (str_p, str_size); - - lit_literal_t lit; - - for (lit = lit_storage; - lit != NULL; - lit = lit_cpointer_decompress (lit->next)) - { - const lit_record_type_t type = (lit_record_type_t) lit->type; - - switch (type) - { - case LIT_RECORD_TYPE_CHARSET: - { - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - if (rec_p->hash != str_hash) - { - continue; - } - - if (rec_p->size != str_size) - { - continue; - } - - if (!strncmp ((const char *) (rec_p + 1), (const char *) str_p, str_size)) - { - return lit; - } - - break; - } - case LIT_RECORD_TYPE_MAGIC_STR: - { - lit_magic_string_id_t magic_id = (lit_magic_string_id_t) ((lit_magic_record_t *) lit)->magic_id; - const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (magic_id); - - if (lit_get_magic_string_size (magic_id) != str_size) - { - continue; - } - - if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size)) - { - return lit; - } - - break; - } - case LIT_RECORD_TYPE_MAGIC_STR_EX: - { - lit_magic_string_ex_id_t magic_id = ((lit_magic_record_t *) lit)->magic_id; - const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_ex_utf8 (magic_id); - - if (lit_get_magic_string_ex_size (magic_id) != str_size) - { - continue; - } - - if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size)) - { - return lit; - } - - break; - } - default: - { - JERRY_ASSERT (type == LIT_RECORD_TYPE_NUMBER); - break; - } - } - } - - return NULL; -} /* lit_find_literal_by_utf8_string */ - -/** - * Check if a literal which holds the passed string exists. - * If it doesn't exist, create a new one. - * - * @return pointer to existing or newly created record - */ -lit_literal_t -lit_find_or_create_literal_from_utf8_string (const lit_utf8_byte_t *str_p, /**< string, could be non-zero-terminated */ - const lit_utf8_size_t str_size) /**< length of the string */ -{ - lit_literal_t lit = lit_find_literal_by_utf8_string (str_p, str_size); - - if (lit == NULL) - { - lit = lit_create_literal_from_utf8_string (str_p, str_size); - } - - return lit; -} /* lit_find_or_create_literal_from_utf8_string */ - - -/** - * Create new literal in literal storage from number. - * - * @return pointer to a newly created record - */ -inline lit_literal_t __attr_always_inline___ -lit_create_literal_from_num (const ecma_number_t num) /**< number to initialize a new number literal */ -{ - return lit_create_number_literal (num); -} /* lit_create_literal_from_num */ - -/** - * Find existing or create new number literal in literal storage. - * - * @return pointer to existing or a newly created record - */ -lit_literal_t -lit_find_or_create_literal_from_num (ecma_number_t num) /**< number which a literal should contain */ -{ - lit_literal_t lit = lit_find_literal_by_num (num); - - if (lit == NULL) - { - lit = lit_create_literal_from_num (num); - } - - return lit; -} /* lit_find_or_create_literal_from_num */ - -/** - * Find an existing number literal which contains the passed number - * - * @return pointer to existing or null - */ -lit_literal_t -lit_find_literal_by_num (const ecma_number_t num) /**< a number to search for */ -{ - lit_literal_t lit; - for (lit = lit_storage; - lit != NULL; - lit = lit_cpointer_decompress (lit->next)) - { - const lit_record_type_t type = (lit_record_type_t) lit->type; - - if (type != LIT_RECORD_TYPE_NUMBER) - { - continue; - } - - const ecma_number_t lit_num = lit_number_literal_get_number (lit); - - if (lit_num == num) - { - return lit; - } - } - - return NULL; -} /* lit_find_literal_by_num */ - -#ifndef JERRY_NDEBUG -/** - * Check if literal really exists in the storage - * - * @return true if literal exists in the storage - * false otherwise - */ -static bool -lit_literal_exists (lit_literal_t lit) /**< literal to check for existence */ -{ - lit_literal_t current_lit; - - for (current_lit = lit_storage; - current_lit != NULL; - current_lit = lit_cpointer_decompress (current_lit->next)) - { - if (current_lit == lit) - { - return true; - } - } - - return false; -} /* lit_literal_exists */ -#endif /* !JERRY_NDEBUG */ - -/** - * Convert compressed pointer to literal - * - * @return literal - */ -lit_literal_t -lit_get_literal_by_cp (lit_cpointer_t lit_cp) /**< compressed pointer to literal */ -{ - lit_literal_t lit = lit_cpointer_decompress (lit_cp); -#ifndef JERRY_NDEBUG - JERRY_ASSERT (lit_literal_exists (lit)); -#endif /* !JERRY_NDEBUG */ - - return lit; -} /* lit_get_literal_by_cp */ - -lit_string_hash_t -lit_charset_literal_get_hash (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET); - - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - return (lit_string_hash_t) rec_p->hash; -} /* lit_charset_literal_get_hash */ - -lit_magic_string_id_t -lit_magic_literal_get_magic_str_id (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_MAGIC_STR); - - const lit_magic_record_t *const rec_p = (const lit_magic_record_t *) lit; - - return (lit_magic_string_id_t) rec_p->magic_id; -} /* lit_magic_literal_get_magic_str_id */ - -lit_magic_string_ex_id_t -lit_magic_literal_get_magic_str_ex_id (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_MAGIC_STR_EX); - - const lit_magic_record_t *const rec_p = (const lit_magic_record_t *) lit; - - return (lit_magic_string_ex_id_t) rec_p->magic_id; -} /* lit_magic_literal_get_magic_str_ex_id */ - -inline lit_utf8_size_t __attr_always_inline___ __attr_pure___ -lit_charset_literal_get_size (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET); - - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - return (lit_utf8_size_t) rec_p->size; -} /* lit_charset_literal_get_size */ - -/** - * Get length of the literal - * - * @return code units count - */ -inline ecma_length_t __attr_always_inline___ __attr_pure___ -lit_charset_literal_get_length (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET); - - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - return (ecma_length_t) rec_p->length; -} /* lit_charset_literal_get_length */ - -inline ecma_number_t __attr_always_inline___ __attr_pure___ -lit_number_literal_get_number (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_NUMBER); - - const lit_number_record_t *const rec_p = (const lit_number_record_t *) lit; - - return rec_p->number; -} /* lit_number_literal_get_number */ - -inline lit_utf8_byte_t * __attr_always_inline___ __attr_pure___ -lit_charset_literal_get_charset (lit_literal_t lit) /**< literal */ -{ - JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET); - - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - return (lit_utf8_byte_t *) (rec_p + 1); -} /* lit_charset_literal_get_charset */ diff --git a/jerry-core/lit/lit-literal.h b/jerry-core/lit/lit-literal.h deleted file mode 100644 index 536f24e8c..000000000 --- a/jerry-core/lit/lit-literal.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2016 University of Szeged. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIT_LITERAL_H -#define LIT_LITERAL_H - -#include "ecma-globals.h" -#include "lit-globals.h" -#include "lit-literal-storage.h" -#include "lit-cpointer.h" - -/** - * Invalid literal - */ -#define NOT_A_LITERAL (lit_cpointer_null_cp ()) - -extern void lit_init (); -extern void lit_finalize (); - -extern lit_literal_t lit_create_literal_from_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t); -extern lit_literal_t lit_find_literal_by_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t); -extern lit_literal_t lit_find_or_create_literal_from_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t); - -extern lit_literal_t lit_create_literal_from_num (ecma_number_t); -extern lit_literal_t lit_find_literal_by_num (ecma_number_t); -extern lit_literal_t lit_find_or_create_literal_from_num (ecma_number_t); - -extern lit_literal_t lit_get_literal_by_cp (lit_cpointer_t); - -extern ecma_number_t lit_number_literal_get_number (lit_literal_t); -extern lit_string_hash_t lit_charset_literal_get_hash (lit_literal_t); -extern lit_utf8_size_t lit_charset_literal_get_size (lit_literal_t); -extern ecma_length_t lit_charset_literal_get_length (lit_literal_t); -extern lit_utf8_byte_t *lit_charset_literal_get_charset (lit_literal_t); - -extern lit_magic_string_id_t lit_magic_literal_get_magic_str_id (lit_literal_t); -extern lit_magic_string_ex_id_t lit_magic_literal_get_magic_str_ex_id (lit_literal_t); - -#endif /* !LIT_LITERAL_H */ diff --git a/jerry-core/lit/lit-snapshot.c b/jerry-core/lit/lit-snapshot.c deleted file mode 100644 index 27e37ab59..000000000 --- a/jerry-core/lit/lit-snapshot.c +++ /dev/null @@ -1,402 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lit-snapshot.h" - -#include "lit-literal.h" -#include "lit-literal-storage.h" - -#ifdef JERRY_ENABLE_SNAPSHOT_SAVE - -/** - * Save a record to specified snapshot buffer. - * - * @return number of bytes saved, - * or 0 - upon save failure - */ -static uint32_t -lit_snapshot_save (lit_literal_t lit, /**< literal to save */ - uint8_t *buffer_p, /**< buffer to save to */ - size_t buffer_size, /**< buffer size */ - size_t *in_out_buffer_offset_p) /**< [in,out] buffer write offset */ -{ - const lit_record_type_t record_type = (lit_record_type_t) lit->type; - switch (record_type) - { - case LIT_RECORD_TYPE_CHARSET: - { - const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit; - - lit_utf8_size_t size = lit_charset_literal_get_size (lit); - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &size, - sizeof (size))) - { - return 0; - } - - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - (void *) (rec_p + 1), - size)) - { - return 0; - } - - return (uint32_t) (sizeof (uint32_t) + size * sizeof (uint8_t)); - - } - case LIT_RECORD_TYPE_NUMBER: - { - double num_value = lit_number_literal_get_number (lit); - const size_t size = sizeof (num_value); - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &num_value, - size)) - { - return 0; - } - - return (uint32_t) size; - } - case LIT_RECORD_TYPE_MAGIC_STR: - { - lit_magic_string_id_t id = lit_magic_literal_get_magic_str_id (lit); - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &id, - sizeof (id))) - { - return 0; - } - - return (uint32_t) sizeof (lit_magic_string_id_t); - } - case LIT_RECORD_TYPE_MAGIC_STR_EX: - { - lit_magic_string_ex_id_t id = lit_magic_literal_get_magic_str_ex_id (lit); - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &id, - sizeof (id))) - { - return 0; - } - - return (uint32_t) sizeof (lit_magic_string_ex_id_t); - } - default: - { - JERRY_UNREACHABLE (); - break; - } - } - - JERRY_UNREACHABLE (); - return 0; -} /* lit_snapshot_save */ - -/** - * Save literals to specified snapshot buffer. - * - * @return true, if save was performed successfully (i.e. buffer size is sufficient), - * false - otherwise. - */ -bool -lit_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */ - size_t buffer_size, /**< size of the buffer */ - size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */ - lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers - * to the literal offsets - * in snapshot */ - uint32_t *out_map_num_p, /**< [out] number of literals */ - uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */ -{ - uint32_t literals_num = lit_count_literals (); - uint32_t lit_table_size = 0; - - *out_map_p = NULL; - *out_map_num_p = 0; - *out_lit_table_size_p = 0; - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &literals_num, - sizeof (literals_num))) - { - return false; - } - - lit_table_size += (uint32_t) sizeof (literals_num); - - if (literals_num != 0) - { - bool is_ok = true; - - size_t id_map_size = sizeof (lit_mem_to_snapshot_id_map_entry_t) * literals_num; - lit_mem_to_snapshot_id_map_entry_t *id_map_p; - id_map_p = (lit_mem_to_snapshot_id_map_entry_t *) jmem_heap_alloc_block_store_size (id_map_size); - - uint32_t literal_index = 0; - lit_literal_t lit; - - for (lit = lit_storage; - lit != NULL; - lit = lit_cpointer_decompress (lit->next)) - { - lit_record_type_t record_type = (lit_record_type_t) lit->type; - - if (record_type == LIT_RECORD_TYPE_FREE) - { - continue; - } - - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &record_type, - sizeof (record_type))) - { - is_ok = false; - break; - } - - uint32_t bytes = lit_snapshot_save (lit, buffer_p, buffer_size, in_out_buffer_offset_p); - - if (bytes == 0) - { - /* write failed */ - is_ok = false; - break; - } - - lit_cpointer_t lit_cp = lit_cpointer_compress (lit); - id_map_p[literal_index].literal_id = lit_cp; - id_map_p[literal_index].literal_offset = lit_table_size; - - lit_table_size += (uint32_t) sizeof (record_type); - lit_table_size += bytes; - - literal_index++; - } - - if (!is_ok) - { - jmem_heap_free_block_size_stored (id_map_p); - return false; - } - - JERRY_ASSERT (literal_index == literals_num); - *out_map_p = id_map_p; - } - - uint32_t aligned_size = JERRY_ALIGNUP (lit_table_size, JMEM_ALIGNMENT); - - if (aligned_size != lit_table_size) - { - JERRY_ASSERT (aligned_size > lit_table_size); - - uint8_t padding = 0; - uint32_t padding_bytes_num = (uint32_t) (aligned_size - lit_table_size); - uint32_t i; - - for (i = 0; i < padding_bytes_num; i++) - { - if (!jrt_write_to_buffer_by_offset (buffer_p, - buffer_size, - in_out_buffer_offset_p, - &padding, - sizeof (uint8_t))) - { - return false; - } - } - } - - *out_map_num_p = literals_num; - *out_lit_table_size_p = aligned_size; - return true; -} /* lit_save_literals_for_snapshot */ - -#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */ - -#ifdef JERRY_ENABLE_SNAPSHOT_EXEC - -/** - * Load literals from snapshot. - * - * @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent), - * false - otherwise (i.e. snapshot is incorrect). - */ -bool -lit_load_literals_from_snapshot (const uint8_t *lit_table_p, /**< buffer with literal table in snapshot */ - uint32_t lit_table_size, /**< size of literal table in snapshot */ - lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets - * in snapshot to identifiers - * of loaded literals in literal - * storage */ - uint32_t *out_map_num_p) /**< [out] literals number */ -{ - *out_map_p = NULL; - *out_map_num_p = 0; - - size_t lit_table_read = 0; - - uint32_t literals_num; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &literals_num, - sizeof (literals_num))) - { - return false; - } - - if (literals_num == 0) - { - return true; - } - - size_t id_map_size = sizeof (lit_mem_to_snapshot_id_map_entry_t) * literals_num; - lit_mem_to_snapshot_id_map_entry_t *id_map_p; - id_map_p = (lit_mem_to_snapshot_id_map_entry_t *) jmem_heap_alloc_block_store_size (id_map_size); - - bool is_ok = true; - uint32_t lit_index; - - for (lit_index = 0; lit_index < literals_num; ++lit_index) - { - uint32_t offset = (uint32_t) lit_table_read; - JERRY_ASSERT (offset == lit_table_read); - - lit_record_type_t type; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &type, - sizeof (type))) - { - is_ok = false; - break; - } - - lit_literal_t lit; - - if (type == LIT_RECORD_TYPE_CHARSET) - { - lit_utf8_size_t length; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &length, - sizeof (length)) - || (lit_table_read + length > lit_table_size)) - { - is_ok = false; - break; - } - - lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (lit_table_p + lit_table_read, length); - lit_table_read += length; - } - else if (type == LIT_RECORD_TYPE_MAGIC_STR) - { - lit_magic_string_id_t id; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &id, - sizeof (id))) - { - is_ok = false; - break; - } - - const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (id); - lit_utf8_size_t magic_str_sz = lit_get_magic_string_size (id); - - /* TODO: Consider searching literal storage by magic string identifier instead of by its value */ - lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (magic_str_p, magic_str_sz); - } - else if (type == LIT_RECORD_TYPE_MAGIC_STR_EX) - { - lit_magic_string_ex_id_t id; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &id, - sizeof (id))) - { - is_ok = false; - break; - } - - const lit_utf8_byte_t *magic_str_ex_p = lit_get_magic_string_ex_utf8 (id); - lit_utf8_size_t magic_str_ex_sz = lit_get_magic_string_ex_size (id); - - /* TODO: Consider searching literal storage by magic string identifier instead of by its value */ - lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (magic_str_ex_p, magic_str_ex_sz); - } - else if (type == LIT_RECORD_TYPE_NUMBER) - { - double num; - if (!jrt_read_from_buffer_by_offset (lit_table_p, - lit_table_size, - &lit_table_read, - &num, - sizeof (num))) - { - is_ok = false; - break; - } - - lit = (lit_literal_t) lit_find_or_create_literal_from_num ((ecma_number_t) num); - } - else - { - is_ok = false; - break; - } - - id_map_p[lit_index].literal_offset = offset; - id_map_p[lit_index].literal_id = lit_cpointer_compress (lit); - } - - if (is_ok) - { - *out_map_p = id_map_p; - *out_map_num_p = literals_num; - - return true; - } - - jmem_heap_free_block_size_stored (id_map_p); - return false; -} /* lit_load_literals_from_snapshot */ - -#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */ diff --git a/jerry-core/lit/lit-snapshot.h b/jerry-core/lit/lit-snapshot.h deleted file mode 100644 index b6b115ba5..000000000 --- a/jerry-core/lit/lit-snapshot.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2015-2016 Samsung Electronics Co., Ltd. - * Copyright 2015-2016 University of Szeged - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIT_SNAPSHOT_H -#define LIT_SNAPSHOT_H - -#include "lit-cpointer.h" -#include "ecma-globals.h" - -typedef struct -{ - lit_cpointer_t literal_id; - uint32_t literal_offset; -} lit_mem_to_snapshot_id_map_entry_t; - -#ifdef JERRY_ENABLE_SNAPSHOT_SAVE -extern bool -lit_save_literals_for_snapshot (uint8_t *, - size_t, - size_t *, - lit_mem_to_snapshot_id_map_entry_t **, - uint32_t *, - uint32_t *); -#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */ - -#ifdef JERRY_ENABLE_SNAPSHOT_EXEC -extern bool -lit_load_literals_from_snapshot (const uint8_t *, - uint32_t, - lit_mem_to_snapshot_id_map_entry_t **, - uint32_t *); -#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */ - -#endif /* !LIT_SNAPSHOT_H */ diff --git a/jerry-core/parser/js/common.c b/jerry-core/parser/js/common.c index b08587045..cf62da095 100644 --- a/jerry-core/parser/js/common.c +++ b/jerry-core/parser/js/common.c @@ -106,9 +106,12 @@ util_print_literal (lexer_literal_t *literal_p) /**< literal */ } else if (literal_p->type == LEXER_NUMBER_LITERAL) { - lit_literal_t literal = lit_get_literal_by_cp (literal_p->u.value); + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p->u.value); + + JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER); + printf ("number("); - util_print_number (lit_number_literal_get_number (literal)); + util_print_number (ecma_get_number_from_value (value_p->u.lit_number)); } else if (literal_p->type == LEXER_REGEXP_LITERAL) { diff --git a/jerry-core/parser/js/common.h b/jerry-core/parser/js/common.h index e8ff5cea4..e2fafd68c 100644 --- a/jerry-core/parser/js/common.h +++ b/jerry-core/parser/js/common.h @@ -44,7 +44,6 @@ #include "ecma-globals.h" #include "ecma-regexp-object.h" -#include "lit-literal.h" #include "jmem-heap.h" /* Immediate management. */ @@ -90,7 +89,7 @@ typedef struct { union { - lit_cpointer_t value; /**< literal value (not processed by the parser) */ + jmem_cpointer_t value; /**< literal value (not processed by the parser) */ const uint8_t *char_p; /**< character value */ ecma_compiled_code_t *bytecode_p; /**< compiled function or regexp pointer */ uint32_t source_data; /**< encoded source literal */ diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index d02331a05..f49cd6a8c 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -17,7 +17,7 @@ #include "ecma-alloc.h" #include "ecma-helpers.h" #include "ecma-function-object.h" -#include "jerry-snapshot.h" +#include "ecma-literal-storage.h" #include "js-parser-internal.h" #include "lit-char-helpers.h" @@ -1523,7 +1523,6 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */ { parser_list_iterator_t literal_iterator; lexer_literal_t *literal_p; - lit_cpointer_t lit_cp; ecma_number_t num; uint32_t literal_index = 0; uint16_t length = context_p->token.lit_location.length; @@ -1567,7 +1566,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */ num = -num; } - lit_cp = lit_cpointer_compress (lit_find_or_create_literal_from_num (num)); + jmem_cpointer_t lit_cp = ecma_find_or_create_literal_number (num); parser_list_iterator_init (&context_p->literal_pool, &literal_iterator); while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL) diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index e956d1903..d838a5b12 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -15,10 +15,8 @@ */ #include "ecma-helpers.h" -#include "jerry-snapshot.h" +#include "ecma-literal-storage.h" #include "js-parser-internal.h" -#include "lit-literal.h" -#include "lit-cpointer.h" #ifdef PARSER_DUMP_BYTE_CODE static int parser_show_instrs = PARSER_FALSE; @@ -99,9 +97,8 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */ if (char_p != NULL) { - lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (char_p, - literal_p->prop.length); - literal_p->u.value = lit_cpointer_compress (lit); + literal_p->u.value = ecma_find_or_create_literal_string (char_p, + literal_p->prop.length); if (!(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR)) { @@ -424,7 +421,7 @@ parser_encode_literal (uint8_t *dst_p, /**< destination buffer */ static uint8_t * parser_generate_initializers (parser_context_t *context_p, /**< context */ uint8_t *dst_p, /**< destination buffer */ - lit_cpointer_t *literal_pool_p, /**< start of literal pool */ + jmem_cpointer_t *literal_pool_p, /**< start of literal pool */ uint16_t uninitialized_var_end, /**< end of the uninitialized var group */ uint16_t initialized_var_end, /**< end of the initialized var group */ uint16_t const_literal_end, /**< end of the const literal group */ @@ -520,9 +517,9 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */ || literal_p->type == LEXER_STRING_LITERAL) { #ifdef PARSER_DUMP_BYTE_CODE - lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (literal_p->u.char_p, - literal_p->prop.length); - literal_pool_p[literal_p->prop.index] = lit_cpointer_compress (lit); + jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (literal_p->u.char_p, + literal_p->prop.length); + literal_pool_p[literal_p->prop.index] = lit_cp; if (!context_p->is_show_opcodes && !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR)) @@ -1095,7 +1092,7 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code byte_code_start_p += sizeof (cbc_uint8_arguments_t); } - byte_code_start_p += literal_end * sizeof (lit_cpointer_t); + byte_code_start_p += literal_end * sizeof (jmem_cpointer_t); byte_code_end_p = byte_code_start_p + length; byte_code_p = byte_code_start_p; @@ -1263,7 +1260,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ int needs_uint16_arguments; cbc_opcode_t last_opcode = CBC_EXT_OPCODE; ecma_compiled_code_t *compiled_code_p; - lit_cpointer_t *literal_pool_p; + jmem_cpointer_t *literal_pool_p; uint8_t *dst_p; if ((size_t) context_p->stack_limit + (size_t) context_p->register_count > PARSER_MAXIMUM_STACK_LIMIT) @@ -1460,7 +1457,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ total_size = sizeof (cbc_uint16_arguments_t); } - total_size += length + context_p->literal_count * sizeof (lit_cpointer_t); + total_size += length + context_p->literal_count * sizeof (jmem_cpointer_t); total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT); compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size); @@ -1520,8 +1517,8 @@ parser_post_processing (parser_context_t *context_p) /**< context */ compiled_code_p->status_flags |= CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED; } - literal_pool_p = (lit_cpointer_t *) byte_code_p; - byte_code_p += context_p->literal_count * sizeof (lit_cpointer_t); + literal_pool_p = (jmem_cpointer_t *) byte_code_p; + byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t); dst_p = parser_generate_initializers (context_p, byte_code_p, @@ -1713,9 +1710,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */ { uint32_t source_data = literal_p->u.source_data; const uint8_t *char_p = context_p->source_end_p - (source_data & 0xfffff); - lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (char_p, - source_data >> 20); - literal_pool_p[literal_p->prop.index] = lit_cpointer_compress (lit); + jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (char_p, + source_data >> 20); + literal_pool_p[literal_p->prop.index] = lit_cp; } } } @@ -1745,7 +1742,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ { if (literal_p->u.char_p == NULL) { - literal_pool_p[argument_count] = lit_cpointer_null_cp (); + literal_pool_p[argument_count] = JMEM_CP_NULL; argument_count++; continue; } diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 60cfca2dd..1ea03ea0a 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -259,15 +259,14 @@ vm_op_delete_prop (ecma_value_t object, /**< base object */ * Returned value must be freed with ecma_free_value */ ecma_value_t -vm_op_delete_var (lit_cpointer_t name_literal, /**< name literal */ +vm_op_delete_var (jmem_cpointer_t name_literal, /**< name literal */ ecma_object_t *lex_env_p, /**< lexical environment */ bool is_strict) /**< strict mode */ { ecma_value_t completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); - ecma_string_t *var_name_str_p; + ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, name_literal); - var_name_str_p = ecma_new_ecma_string_from_lit_cp (name_literal); ecma_reference_t ref = ecma_op_get_identifier_reference (lex_env_p, var_name_str_p, is_strict); @@ -297,7 +296,6 @@ vm_op_delete_var (lit_cpointer_t name_literal, /**< name literal */ } ecma_free_reference (ref); - ecma_deref_ecma_string (var_name_str_p); return completion_value; } /* vm_op_delete_var */ diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index 35452e1c3..61285e519 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -107,7 +107,7 @@ ecma_value_t vm_op_delete_prop (ecma_value_t, ecma_value_t, bool); ecma_value_t -vm_op_delete_var (lit_cpointer_t, ecma_object_t *, bool); +vm_op_delete_var (jmem_cpointer_t, ecma_object_t *, bool); ecma_collection_header_t * opfunc_for_in (ecma_value_t, ecma_value_t *); diff --git a/jerry-core/vm/vm-defines.h b/jerry-core/vm/vm-defines.h index cfed96253..ee43c9033 100644 --- a/jerry-core/vm/vm-defines.h +++ b/jerry-core/vm/vm-defines.h @@ -47,7 +47,7 @@ typedef struct uint8_t *byte_code_start_p; /**< byte code start pointer */ ecma_value_t *registers_p; /**< register start pointer */ ecma_value_t *stack_top_p; /**< stack top pointer */ - lit_cpointer_t *literal_start_p; /**< literal list start pointer */ + jmem_cpointer_t *literal_start_p; /**< literal list start pointer */ ecma_object_t *lex_env_p; /**< current lexical environment */ ecma_value_t this_binding; /**< this binding */ ecma_value_t call_block_result; /**< preserve block result during a call */ diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 8d6fdeb91..c3de029fc 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -31,7 +31,6 @@ #include "ecma-objects-general.h" #include "ecma-regexp-object.h" #include "ecma-try-catch-macro.h" -#include "lit-literal-storage.h" #include "opcodes.h" #include "vm.h" #include "vm-stack.h" @@ -295,7 +294,7 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ */ static ecma_value_t vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ - lit_cpointer_t lit_cp) /**< literal */ + jmem_cpointer_t lit_cp) /**< literal */ { ecma_compiled_code_t *bytecode_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t, lit_cp); @@ -504,7 +503,8 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } \ else \ { \ - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); \ + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \ + literal_start_p[literal_index]); \ ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, \ name_p); \ if (ref_base_lex_env_p != NULL) \ @@ -518,8 +518,6 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ result = ecma_raise_reference_error (ECMA_ERR_MSG ("")); \ } \ \ - ecma_deref_ecma_string (name_p); \ - \ if (ECMA_IS_VALUE_ERROR (result)) \ { \ goto error; \ @@ -529,17 +527,17 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } \ else if (literal_index < const_literal_end) \ { \ - lit_cpointer_t lit_cpointer = literal_start_p[literal_index]; \ - lit_literal_t lit = lit_cpointer_decompress (lit_cpointer); \ - if (unlikely (LIT_RECORD_IS_NUMBER (lit))) \ + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \ + literal_start_p[literal_index]); \ + \ + if (unlikely (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER)) \ { \ - ecma_number_t number = lit_number_literal_get_number (lit); \ - (target_value) = ecma_make_number_value (number); \ + (target_value) = ecma_fast_copy_value (value_p->u.lit_number); \ } \ else \ { \ - ecma_string_t *string_p = ecma_new_ecma_string_from_lit_cp (lit_cpointer); \ - (target_value) = ecma_make_string_value (string_p); \ + ecma_ref_ecma_string (value_p); \ + (target_value) = ecma_make_string_value (value_p); \ } \ } \ else \ @@ -578,7 +576,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ uint16_t encoding_limit; uint16_t encoding_delta; uint16_t register_end; - lit_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p; + jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p; bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0); /* Prepare. */ @@ -618,9 +616,9 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ while (literal_index <= literal_index_end) { - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); vm_var_decl (frame_ctx_p, name_p); - ecma_deref_ecma_string (name_p); literal_index++; } break; @@ -649,7 +647,8 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { uint32_t value_index; ecma_value_t lit_value; - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); vm_var_decl (frame_ctx_p, name_p); @@ -678,7 +677,6 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ ecma_free_value (lit_value); } - ecma_deref_ecma_string (name_p); literal_index++; } break; @@ -714,7 +712,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p; uint8_t *byte_code_p = frame_ctx_p->byte_code_p; - lit_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p; + jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p; ecma_value_t *stack_top_p; uint16_t encoding_limit; @@ -1109,7 +1107,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } else { - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); ecma_object_t *ref_base_lex_env_p; ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, @@ -1128,11 +1127,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ if (ECMA_IS_VALUE_ERROR (result)) { - ecma_deref_ecma_string (name_p); goto error; } ecma_ref_object (ref_base_lex_env_p); + ecma_ref_ecma_string (name_p); *stack_top_p++ = ecma_make_object_value (ref_base_lex_env_p); *stack_top_p++ = ecma_make_string_value (name_p); *stack_top_p++ = result; @@ -1611,7 +1610,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } else { - ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); + ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); + ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, name_p); @@ -1627,8 +1628,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } - ecma_deref_ecma_string (name_p); - if (ECMA_IS_VALUE_ERROR (result)) { goto error; @@ -2158,20 +2157,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ } else { - ecma_string_t *var_name_str_p; - ecma_object_t *ref_base_lex_env_p; - - var_name_str_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); - ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, - var_name_str_p); + ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); + ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, + var_name_str_p); ecma_value_t put_value_result = ecma_op_put_value_lex_env_base (ref_base_lex_env_p, var_name_str_p, is_strict, result); - ecma_deref_ecma_string (var_name_str_p); - if (ECMA_IS_VALUE_ERROR (put_value_result)) { ecma_free_value (result); @@ -2325,12 +2320,11 @@ error: catch_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p); - catch_name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); + catch_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, + literal_start_p[literal_index]); ecma_op_create_mutable_binding (catch_env_p, catch_name_p, false); - ecma_deref_ecma_string (catch_name_p); - stack_top_p[-2 - 1] = ecma_make_object_value (frame_ctx_p->lex_env_p); frame_ctx_p->lex_env_p = catch_env_p; } @@ -2498,7 +2492,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade const ecma_value_t *arg_list_p, /**< arguments list */ ecma_length_t arg_list_len) /**< length of arguments list */ { - lit_cpointer_t *literal_p; + jmem_cpointer_t *literal_p; vm_frame_ctx_t frame_ctx; uint32_t call_stack_size; @@ -2507,7 +2501,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p; uint8_t *byte_p = (uint8_t *) bytecode_header_p; - literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); frame_ctx.literal_start_p = literal_p; literal_p += args_p->literal_end; call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit); @@ -2517,7 +2511,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p; uint8_t *byte_p = (uint8_t *) bytecode_header_p; - literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); + literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); frame_ctx.literal_start_p = literal_p; literal_p += args_p->literal_end; call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit); diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index ab369f392..b15858266 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -18,7 +18,6 @@ #define VM_H #include "ecma-globals.h" -#include "lit-cpointer.h" #include "jrt.h" #include "vm-defines.h" diff --git a/tests/unit/test-lit-char-helpers.c b/tests/unit/test-lit-char-helpers.c index d41c166cd..8f157607d 100644 --- a/tests/unit/test-lit-char-helpers.c +++ b/tests/unit/test-lit-char-helpers.c @@ -16,7 +16,6 @@ #include "ecma-helpers.h" #include "lit-strings.h" #include "ecma-init-finalize.h" -#include "lit-literal.h" #include "lit-char-helpers.h" #include "js-parser-internal.h" @@ -28,7 +27,6 @@ main () TEST_INIT (); jmem_init (); - lit_init (); ecma_init (); const uint8_t _1_byte_long1[] = "\\u007F"; @@ -76,7 +74,6 @@ main () JERRY_ASSERT (length == 3); ecma_finalize (); - lit_finalize (); jmem_finalize (true); return 0; diff --git a/tests/unit/test-literal-storage.c b/tests/unit/test-literal-storage.c index 9be807e30..dc07e3786 100644 --- a/tests/unit/test-literal-storage.c +++ b/tests/unit/test-literal-storage.c @@ -15,8 +15,7 @@ */ #include "ecma-helpers.h" -#include "lit-literal.h" -#include "lit-literal-storage.h" +#include "ecma-literal-storage.h" #include "test-common.h" // Iterations count @@ -55,31 +54,6 @@ generate_number () return num; } /* generate_number */ -static bool -compare_utf8_string_and_string_literal (const lit_utf8_byte_t *str_p, lit_utf8_size_t str_size, lit_literal_t lit) -{ - if (LIT_RECORD_IS_CHARSET (lit)) - { - lit_utf8_byte_t *lit_str_p = lit_charset_literal_get_charset (lit); - lit_utf8_size_t lit_str_size = lit_charset_literal_get_size (lit); - return lit_compare_utf8_strings (str_p, str_size, lit_str_p, lit_str_size); - } - else if (LIT_RECORD_IS_MAGIC_STR (lit)) - { - lit_magic_string_id_t magic_id = lit_magic_literal_get_magic_str_id (lit); - return lit_compare_utf8_string_and_magic_string (str_p, str_size, magic_id); - - } - else if (LIT_RECORD_IS_MAGIC_STR_EX (lit)) - { - lit_magic_string_ex_id_t magic_id = lit_magic_literal_get_magic_str_ex_id (lit); - return lit_compare_utf8_string_and_magic_string_ex (str_p, str_size, magic_id); - - } - - return false; -} /* compare_utf8_string_and_string_literal */ - int main () { @@ -91,7 +65,7 @@ main () lit_utf8_size_t lengths[test_sub_iters]; jmem_init (); - lit_init (); + ecma_init_lit_storage (); for (uint32_t i = 0; i < test_iters; i++) { @@ -106,7 +80,7 @@ main () { lengths[j] = (lit_utf8_size_t) (rand () % max_characters_in_string + 1); generate_string (strings[j], lengths[j]); - lit_create_literal_from_utf8_string (strings[j], lengths[j]); + ecma_find_or_create_literal_string (strings[j], lengths[j]); strings[j][lengths[j]] = '\0'; ptrs[j] = strings[j]; JERRY_ASSERT (ptrs[j]); @@ -117,36 +91,34 @@ main () ptrs[j] = lit_get_magic_string_utf8 (msi); JERRY_ASSERT (ptrs[j]); lengths[j] = (lit_utf8_size_t) lit_zt_utf8_string_size (ptrs[j]); - lit_create_literal_from_utf8_string (ptrs[j], lengths[j]); + ecma_find_or_create_literal_string (ptrs[j], lengths[j]); } else { ecma_number_t num = generate_number (); lengths[j] = ecma_number_to_utf8_string (num, strings[j], max_characters_in_string); - lit_create_literal_from_num (num); + ecma_find_or_create_literal_number (num); } } // Add empty string - lit_create_literal_from_utf8_string (NULL, 0); + ecma_find_or_create_literal_string (NULL, 0); for (uint32_t j = 0; j < test_sub_iters; j++) { - lit_literal_t lit1; - lit_literal_t lit2; + jmem_cpointer_t lit1; + jmem_cpointer_t lit2; if (ptrs[j]) { - lit1 = lit_find_or_create_literal_from_utf8_string (ptrs[j], lengths[j]); - lit2 = lit_find_literal_by_utf8_string (ptrs[j], lengths[j]); - JERRY_ASSERT (compare_utf8_string_and_string_literal (ptrs[j], lengths[j], lit1)); - JERRY_ASSERT (compare_utf8_string_and_string_literal (ptrs[j], lengths[j], lit2)); + lit1 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]); + lit2 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]); + JERRY_ASSERT (lit1 == lit2); } else { - lit1 = lit_find_or_create_literal_from_num (numbers[j]); - lit2 = lit_find_literal_by_num (numbers[j]); - JERRY_ASSERT (numbers[j] == lit_number_literal_get_number (lit1)); - JERRY_ASSERT (numbers[j] == lit_number_literal_get_number (lit2)); + lit1 = ecma_find_or_create_literal_number (numbers[j]); + lit2 = ecma_find_or_create_literal_number (numbers[j]); + JERRY_ASSERT (lit1 == lit2); } JERRY_ASSERT (lit1); JERRY_ASSERT (lit2); @@ -154,10 +126,10 @@ main () } // Check empty string exists - JERRY_ASSERT (lit_find_literal_by_utf8_string (NULL, 0)); + JERRY_ASSERT (ecma_find_or_create_literal_string (NULL, 0) != JMEM_CP_NULL); } - lit_finalize (); + ecma_finalize_lit_storage (); jmem_finalize (true); return 0; } /* main */ diff --git a/tests/unit/test-strings.c b/tests/unit/test-strings.c index e4a47e951..d432f6350 100644 --- a/tests/unit/test-strings.c +++ b/tests/unit/test-strings.c @@ -17,7 +17,6 @@ #include "ecma-helpers.h" #include "lit-strings.h" #include "ecma-init-finalize.h" -#include "lit-literal.h" #include "test-common.h" @@ -107,7 +106,6 @@ main () TEST_INIT (); jmem_init (); - lit_init (); ecma_init (); lit_utf8_byte_t cesu8_string[max_bytes_in_string]; @@ -219,7 +217,6 @@ main () JERRY_ASSERT (res_buf[2] == 0xBF); ecma_finalize (); - lit_finalize (); jmem_finalize (true); return 0;