Implement direct strings. (#2196)

Direct strings are a new type of direct ecma-values (no memory allocation
is needed for encoding them) in JerryScript. Currently magic strings,
external magic strings and uint values are encoded as direct strings.

The constant pool of JerryScript byte-code is changed to hold ecma-values
rather than cpointers to support direct strings.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2018-02-23 00:21:46 +01:00
committed by yichoi
parent fbf5c32747
commit 51e3c4455a
37 changed files with 1493 additions and 1148 deletions
+73 -35
View File
@@ -534,7 +534,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 */
jmem_cpointer_t *literal_pool_p, /**< start of literal pool */
ecma_value_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 */
@@ -543,7 +543,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
{
parser_list_iterator_t literal_iterator;
lexer_literal_t *literal_p;
uint16_t argument_count;
uint16_t argument_count, register_count;
if (uninitialized_var_end > context_p->register_count)
{
@@ -618,6 +618,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
argument_count = 0;
register_count = context_p->register_count;
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)))
{
@@ -628,35 +629,42 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
if (literal_p->type == LEXER_IDENT_LITERAL
|| literal_p->type == LEXER_STRING_LITERAL)
{
if (literal_p->prop.index >= register_count)
{
#ifdef PARSER_DUMP_BYTE_CODE
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
{
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 (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
{
ecma_value_t lit_value = ecma_find_or_create_literal_string (literal_p->u.char_p,
literal_p->prop.length);
literal_pool_p[literal_p->prop.index] = lit_value;
}
if (!context_p->is_show_opcodes
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
{
jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
}
if (!context_p->is_show_opcodes
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
{
jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
}
#else /* !PARSER_DUMP_BYTE_CODE */
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
{
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
}
if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
{
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
}
#endif /* PARSER_DUMP_BYTE_CODE */
}
}
else if ((literal_p->type == LEXER_FUNCTION_LITERAL)
|| (literal_p->type == LEXER_REGEXP_LITERAL))
{
ECMA_SET_NON_NULL_POINTER (literal_pool_p[literal_p->prop.index],
literal_p->u.bytecode_p);
JERRY_ASSERT (literal_p->prop.index >= register_count);
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[literal_p->prop.index],
literal_p->u.bytecode_p);
}
else
{
JERRY_ASSERT (literal_p->type == LEXER_NUMBER_LITERAL);
JERRY_ASSERT (literal_p->type == LEXER_NUMBER_LITERAL
&& literal_p->prop.index >= register_count);
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
}
}
@@ -692,9 +700,12 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
JERRY_ASSERT (literal_p != NULL
&& literal_p->type == LEXER_FUNCTION_LITERAL);
init_index = literal_p->prop.index;
ECMA_SET_NON_NULL_POINTER (literal_pool_p[literal_p->prop.index],
literal_p->u.bytecode_p);
JERRY_ASSERT (init_index >= register_count);
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[init_index],
literal_p->u.bytecode_p);
}
*dst_p++ = CBC_INITIALIZE_VAR;
@@ -1216,7 +1227,12 @@ 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 (jmem_cpointer_t);
byte_code_start_p += (unsigned int) (literal_end - register_end) * sizeof (ecma_value_t);
if (unlikely (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED))
{
byte_code_start_p += argument_end * sizeof (ecma_value_t);
}
byte_code_end_p = byte_code_start_p + length;
byte_code_p = byte_code_start_p;
@@ -1378,6 +1394,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
size_t last_position;
size_t offset;
size_t length;
size_t literal_length;
size_t total_size;
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
size_t total_size_used;
@@ -1388,7 +1405,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
bool needs_uint16_arguments;
cbc_opcode_t last_opcode = CBC_EXT_OPCODE;
ecma_compiled_code_t *compiled_code_p;
jmem_cpointer_t *literal_pool_p;
ecma_value_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)
@@ -1612,7 +1629,16 @@ parser_post_processing (parser_context_t *context_p) /**< context */
total_size = sizeof (cbc_uint16_arguments_t);
}
total_size += length + context_p->literal_count * sizeof (jmem_cpointer_t);
literal_length = (size_t) (context_p->literal_count - context_p->register_count) * sizeof (ecma_value_t);
total_size += literal_length + length;
if ((context_p->status_flags & PARSER_ARGUMENTS_NEEDED)
&& !(context_p->status_flags & PARSER_IS_STRICT))
{
total_size += context_p->argument_count * sizeof (ecma_value_t);
}
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
total_size_used = total_size;
#endif
@@ -1678,6 +1704,12 @@ parser_post_processing (parser_context_t *context_p) /**< context */
if (context_p->status_flags & PARSER_ARGUMENTS_NEEDED)
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_ARGUMENTS_NEEDED;
if (!(context_p->status_flags & PARSER_IS_STRICT))
{
compiled_code_p->status_flags |= CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED;
}
/* Arguments is stored in the lexical environment. */
context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
}
@@ -1694,8 +1726,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */
}
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
literal_pool_p = (jmem_cpointer_t *) byte_code_p;
byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t);
literal_pool_p = (ecma_value_t *) byte_code_p;
literal_pool_p -= context_p->register_count;
byte_code_p += literal_length;
dst_p = parser_generate_initializers (context_p,
byte_code_p,
@@ -1896,17 +1929,19 @@ parser_post_processing (parser_context_t *context_p) /**< context */
{
parser_list_iterator_t literal_iterator;
lexer_literal_t *literal_p;
uint16_t register_count = context_p->register_count;
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)))
{
if (literal_p->status_flags & LEXER_FLAG_LATE_INIT)
if ((literal_p->status_flags & LEXER_FLAG_LATE_INIT)
&& literal_p->prop.index >= register_count)
{
uint32_t source_data = literal_p->u.source_data;
const uint8_t *char_p = context_p->source_end_p - (source_data & 0xfffff);
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (char_p,
ecma_value_t lit_value = ecma_find_or_create_literal_string (char_p,
source_data >> 20);
literal_pool_p[literal_p->prop.index] = lit_cp;
literal_pool_p[literal_p->prop.index] = lit_value;
}
}
}
@@ -1917,6 +1952,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */
{
parser_list_iterator_t literal_iterator;
uint16_t argument_count = 0;
uint16_t register_count = context_p->register_count;
ecma_value_t *argument_base_p = (ecma_value_t *) (((uint8_t *) compiled_code_p) + total_size);
argument_base_p -= context_p->argument_count;
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
while (argument_count < context_p->argument_count)
@@ -1936,7 +1974,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
{
if (literal_p->u.char_p == NULL)
{
literal_pool_p[argument_count] = JMEM_CP_NULL;
argument_base_p[argument_count] = ECMA_VALUE_EMPTY;
argument_count++;
continue;
}
@@ -1949,17 +1987,17 @@ parser_post_processing (parser_context_t *context_p) /**< context */
JERRY_ASSERT (literal_p->type == LEXER_IDENT_LITERAL
&& (literal_p->status_flags & LEXER_FLAG_VAR));
JERRY_ASSERT (argument_count < literal_p->prop.index);
JERRY_ASSERT (literal_p->prop.index >= register_count);
literal_pool_p[argument_count] = literal_pool_p[literal_p->prop.index];
argument_base_p[argument_count] = literal_pool_p[literal_p->prop.index];
argument_count++;
}
}
if (context_p->status_flags & PARSER_NAMED_FUNCTION_EXP)
{
ECMA_SET_NON_NULL_POINTER (literal_pool_p[const_literal_end],
compiled_code_p);
ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[const_literal_end],
compiled_code_p);
}
#ifdef JERRY_DEBUGGER