diff --git a/src/libintstructs/lp-string.c b/src/libintstructs/lp-string.c index 3a05bf8c0..359beb0c7 100644 --- a/src/libintstructs/lp-string.c +++ b/src/libintstructs/lp-string.c @@ -14,6 +14,7 @@ */ #include "lp-string.h" +#include "jerry-libc.h" bool lp_string_equal (lp_string s1, lp_string s2) diff --git a/src/libintstructs/stack.h b/src/libintstructs/stack.h index fe091467a..8c73a833f 100644 --- a/src/libintstructs/stack.h +++ b/src/libintstructs/stack.h @@ -223,6 +223,11 @@ do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \ FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \ } } while (0) +#define STACK_ITERATE_VARG_SET(NAME, FUNC, FROM, ...) \ +do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \ + STACK_SET_ELEMENT (NAME, i, FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__)); \ +} } while (0) + #define STACK(NAME, DATA_TYPE, TYPE) \ DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \ NAME##_stack NAME; \ diff --git a/src/libjsparser/lexer.c b/src/libjsparser/lexer.c index e8f064f70..e304c64e8 100644 --- a/src/libjsparser/lexer.c +++ b/src/libjsparser/lexer.c @@ -38,6 +38,9 @@ static size_t buffer_size = 0; static const char *buffer_start = NULL; static const char *buffer = NULL; static const char *token_start; +static ecma_char_t *strings_cache; +static size_t strings_cache_size; +static size_t strings_cache_used_size; #define LA(I) (get_char (I)) @@ -146,6 +149,39 @@ current_token_equals_to_lp (lp_string str) return false; } +static lp_string +adjust_string_ptrs (lp_string lp, size_t diff) +{ + return (lp_string) + { + .length = lp.length, + .str = lp.str + diff + }; +} + +static lp_string +add_current_token_to_string_cache (void) +{ + lp_string res; + res.length = (ecma_length_t) (buffer - token_start); + if (strings_cache_used_size + res.length * sizeof (ecma_char_t) >= strings_cache_size) + { + strings_cache_size = mem_heap_recommend_allocation_size (strings_cache_used_size + + ((size_t) res.length + 1) * sizeof (ecma_char_t)); + ecma_char_t *temp = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size, + MEM_HEAP_ALLOC_SHORT_TERM); + __memcpy (temp, strings_cache, strings_cache_used_size); + mem_heap_free_block ((uint8_t *) strings_cache); + STACK_ITERATE_VARG_SET (strings, adjust_string_ptrs, 0, (size_t) (temp - strings_cache)); + strings_cache = temp; + } + __strncpy ((char *) (strings_cache + strings_cache_used_size), token_start, res.length); + res.str = strings_cache + strings_cache_used_size; + res.str[res.length] = '\0'; + strings_cache_used_size = (size_t) (((size_t) res.length + 1) * sizeof (ecma_char_t) + strings_cache_used_size); + return res; +} + static token convert_current_token_to_token (token_type tt) { @@ -172,11 +208,7 @@ convert_current_token_to_token (token_type tt) } } - const lp_string str = (lp_string) - { - .length = (uint8_t) (buffer - token_start), - .str = (ecma_char_t *) token_start - }; + const lp_string str = add_current_token_to_string_cache (); STACK_PUSH (strings, str); @@ -812,6 +844,7 @@ parse_number (void) __strncpy ((char *) temp, token_start, (size_t) (tok_length)); temp[tok_length] = '\0'; ecma_number_t res = ecma_zt_string_to_number (temp); + JERRY_ASSERT (!ecma_number_is_nan (res)); mem_heap_free_block (temp); known_token = convert_seen_num_to_token (res); token_start = NULL; @@ -1394,6 +1427,9 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes) allow_dump_lines = show_opcodes; buffer_size = source_size; lexer_set_source (source); + strings_cache_size = mem_heap_recommend_allocation_size (sizeof (ecma_char_t)); + strings_cache = (ecma_char_t *) mem_heap_alloc_block (strings_cache_size, MEM_HEAP_ALLOC_SHORT_TERM); + strings_cache_used_size = 0; STACK_INIT (strings); STACK_INIT (numbers); @@ -1403,6 +1439,10 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes) void lexer_free (void) { + if (STACK_SIZE (strings) == 0) + { + mem_heap_free_block (strings_cache); + } STACK_FREE (strings); STACK_FREE (numbers); STACK_FREE (num_ids); diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 413f93a97..bdcabd2d3 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -3952,7 +3952,6 @@ parser_parse_program (void) JERRY_ASSERT (token_is (TOK_EOF)); DUMP_OPCODE_1 (exitval, 0); - serializer_adjust_strings (); serializer_merge_scopes_into_bytecode (); scopes_tree_free (STACK_TOP (scopes)); diff --git a/src/liboptimizer/deserializer.c b/src/liboptimizer/deserializer.c index 5df25f3bf..21b73f048 100644 --- a/src/liboptimizer/deserializer.c +++ b/src/liboptimizer/deserializer.c @@ -72,6 +72,10 @@ deserializer_init (void) void deserializer_free (void) { + if (bytecode_data.strs_count > 0) + { + mem_heap_free_block ((uint8_t *) bytecode_data.strings[0].str); + } mem_heap_free_block ((uint8_t *) bytecode_data.strings); mem_heap_free_block ((uint8_t *) bytecode_data.nums); mem_heap_free_block ((uint8_t *) bytecode_data.opcodes); diff --git a/src/liboptimizer/serializer.c b/src/liboptimizer/serializer.c index 4af675289..021f6b24d 100644 --- a/src/liboptimizer/serializer.c +++ b/src/liboptimizer/serializer.c @@ -108,18 +108,6 @@ serializer_print_opcodes (void) #endif } -/* Make lp_strings also zero-terminated. */ -void -serializer_adjust_strings (void) -{ - for (uint8_t i = 0; i < bytecode_data.strs_count; ++i) - { - ecma_length_t len = bytecode_data.strings[i].length; - ecma_char_t *str = bytecode_data.strings[i].str; - str[len] = '\0'; - } -} - void serializer_init (bool show_opcodes) { diff --git a/src/liboptimizer/serializer.h b/src/liboptimizer/serializer.h index 8ea7412e6..a237a2209 100644 --- a/src/liboptimizer/serializer.h +++ b/src/liboptimizer/serializer.h @@ -31,7 +31,6 @@ void serializer_dump_opcode (opcode_t); void serializer_set_writing_position (opcode_counter_t); void serializer_rewrite_opcode (const opcode_counter_t, opcode_t); void serializer_print_opcodes (void); -void serializer_adjust_strings (void); void serializer_free (void); #endif // SERIALIZER_H