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
+228 -139
View File
@@ -154,9 +154,8 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
globals_p->snapshot_buffer_write_offset += sizeof (ecma_compiled_code_t);
jmem_cpointer_t pattern_cp = ((re_compiled_code_t *) compiled_code_p)->pattern_cp;
ecma_string_t *pattern_string_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
pattern_cp);
ecma_value_t pattern = ((re_compiled_code_t *) compiled_code_p)->pattern;
ecma_string_t *pattern_string_p = ecma_get_string_from_value (pattern);
ecma_length_t pattern_size = 0;
@@ -206,34 +205,34 @@ 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_code_p;
jmem_cpointer_t *src_literal_start_p;
jmem_cpointer_t *dst_literal_start_p;
ecma_value_t *src_literal_start_p;
ecma_value_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 = (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));
src_literal_start_p = (ecma_value_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t));
dst_literal_start_p = (ecma_value_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;
const_literal_end = args_p->const_literal_end;
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
else
{
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));
src_literal_start_p = (ecma_value_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t));
dst_literal_start_p = (ecma_value_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;
const_literal_end = args_p->const_literal_end;
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
for (uint32_t i = const_literal_end; i < literal_end; i++)
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
src_literal_start_p[i]);
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
src_literal_start_p[i]);
if (bytecode_p == compiled_code_p)
{
@@ -268,39 +267,55 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
jmem_cpointer_t *literal_start_p;
ecma_value_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 = (jmem_cpointer_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint16_arguments_t));
literal_start_p = (ecma_value_t *) (((uint8_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;
register_end = args_p->register_end;
const_literal_end = args_p->const_literal_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
else
{
literal_start_p = (jmem_cpointer_t *) (((uint8_t *) buffer_p) + sizeof (cbc_uint8_arguments_t));
literal_start_p = (ecma_value_t *) (((uint8_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;
register_end = args_p->register_end;
const_literal_end = args_p->const_literal_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
uint32_t register_clear_start = 0;
if ((bytecode_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
&& !(bytecode_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
for (uint32_t i = 0; i < const_literal_end; i++)
{
if (ecma_is_value_string (literal_start_p[i])
|| ecma_is_value_float_number (literal_start_p[i]))
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
while (current_p->literal_id != literal_start_p[i])
{
current_p++;
}
literal_start_p[i] = current_p->literal_offset;
}
}
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
for (uint32_t i = 0; i < argument_end; i++)
{
if (literal_start_p[i] != JMEM_CP_NULL)
if (literal_start_p[i] != ECMA_VALUE_EMPTY)
{
JERRY_ASSERT (ecma_is_value_string (literal_start_p[i]));
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
while (current_p->literal_id != literal_start_p[i])
@@ -311,28 +326,6 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
literal_start_p[i] = current_p->literal_offset;
}
}
register_clear_start = argument_end;
}
for (uint32_t i = register_clear_start; i < register_end; i++)
{
literal_start_p[i] = JMEM_CP_NULL;
}
for (uint32_t i = register_end; i < const_literal_end; i++)
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
if (literal_start_p[i] != JMEM_CP_NULL)
{
while (current_p->literal_id != literal_start_p[i])
{
current_p++;
}
literal_start_p[i] = current_p->literal_offset;
}
}
/* Set reference counter to 1. */
@@ -367,7 +360,6 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
* current primary function */
size_t offset, /**< byte code offset */
const uint8_t *literal_base_p, /**< literal start */
const uint8_t *number_base_p, /**< literal number start */
bool copy_bytecode) /**< byte code should be copied to memory */
{
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) (base_addr_p + offset);
@@ -397,23 +389,36 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
}
size_t header_size;
uint32_t literal_end;
uint32_t argument_end = 0;
uint32_t const_literal_end;
uint32_t literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) byte_p;
literal_end = args_p->literal_end;
const_literal_end = args_p->const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
header_size = sizeof (cbc_uint16_arguments_t);
}
else
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) byte_p;
literal_end = args_p->literal_end;
const_literal_end = args_p->const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
{
argument_end = args_p->argument_end;
}
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
literal_end = (uint32_t) (args_p->literal_end - args_p->register_end);
header_size = sizeof (cbc_uint8_arguments_t);
}
@@ -430,25 +435,42 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
}
else
{
code_size = (uint32_t) (header_size + literal_end * sizeof (jmem_cpointer_t));
uint32_t start_offset = (uint32_t) (header_size + literal_end * sizeof (ecma_value_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);
uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + start_offset;
uint32_t new_code_size = (uint32_t) (start_offset + 1 + sizeof (uint8_t *));
bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (total_size);
if (argument_end != 0)
{
new_code_size += (uint32_t) (argument_end * sizeof (ecma_value_t));
}
new_code_size = JERRY_ALIGNUP (new_code_size, JMEM_ALIGNMENT);
bytecode_p = (ecma_compiled_code_t *) jmem_heap_alloc_block (new_code_size);
#ifdef JMEM_STATS
jmem_stats_allocate_byte_code_bytes (total_size);
jmem_stats_allocate_byte_code_bytes (new_code_size);
#endif /* JMEM_STATS */
memcpy (bytecode_p, base_addr_p + offset, code_size);
memcpy (bytecode_p, base_addr_p + offset, start_offset);
bytecode_p->size = (uint16_t) (total_size >> JMEM_ALIGNMENT_LOG);
bytecode_p->size = (uint16_t) (new_code_size >> JMEM_ALIGNMENT_LOG);
uint8_t *instructions_p = ((uint8_t *) bytecode_p);
uint8_t *byte_p = (uint8_t *) bytecode_p;
instructions_p[code_size] = CBC_SET_BYTECODE_PTR;
memcpy (instructions_p + code_size + 1, &real_bytecode_p, sizeof (uint8_t *));
if (argument_end != 0)
{
uint32_t argument_size = (uint32_t) (argument_end * sizeof (ecma_value_t));
memcpy (byte_p + new_code_size - argument_size,
base_addr_p + offset + code_size - argument_size,
argument_size);
}
byte_p[start_offset] = CBC_SET_BYTECODE_PTR;
memcpy (byte_p + start_offset + 1, &real_bytecode_p, sizeof (uint8_t *));
code_size = new_code_size;
}
JERRY_ASSERT (bytecode_p->refs == 1);
@@ -457,13 +479,14 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags | CBC_CODE_FLAGS_DEBUGGER_IGNORE);
#endif /* JERRY_DEBUGGER */
jmem_cpointer_t *literal_start_p = (jmem_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
ecma_value_t *literal_start_p = (ecma_value_t *) (((uint8_t *) bytecode_p) + header_size);
for (uint32_t i = 0; i < const_literal_end; i++)
{
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p,
number_base_p,
literal_start_p[i]);
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
{
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
}
}
for (uint32_t i = const_literal_end; i < literal_end; i++)
@@ -473,8 +496,8 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
if (literal_offset == offset)
{
/* Self reference */
ECMA_SET_NON_NULL_POINTER (literal_start_p[i],
bytecode_p);
ECMA_SET_INTERNAL_VALUE_POINTER (literal_start_p[i],
bytecode_p);
}
else
{
@@ -482,11 +505,24 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
literal_bytecode_p = snapshot_load_compiled_code (base_addr_p,
literal_offset,
literal_base_p,
number_base_p,
copy_bytecode);
ECMA_SET_NON_NULL_POINTER (literal_start_p[i],
literal_bytecode_p);
ECMA_SET_INTERNAL_VALUE_POINTER (literal_start_p[i],
literal_bytecode_p);
}
}
if (argument_end != 0)
{
literal_start_p = (ecma_value_t *) (((uint8_t *) bytecode_p) + code_size);
literal_start_p -= argument_end;
for (uint32_t i = 0; i < argument_end; i++)
{
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
{
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
}
}
}
@@ -561,7 +597,12 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
uint32_t literals_num;
if (!ecma_save_literals_for_snapshot (buffer_p,
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
if (!ecma_save_literals_for_snapshot (lit_pool_p,
buffer_p,
buffer_size,
&globals.snapshot_buffer_write_offset,
&lit_map_p,
@@ -672,34 +713,31 @@ jerry_snapshot_result_at (const uint32_t *snapshot_p, /**< snapshot */
|| header_p->version != JERRY_SNAPSHOT_VERSION
|| !snapshot_check_global_flags (header_p->global_flags))
{
return ecma_raise_type_error (invalid_version_error_p);
ecma_raise_type_error (invalid_version_error_p);
return ecma_create_error_reference_from_context ();
}
if (header_p->lit_table_offset >= snapshot_size)
if (header_p->lit_table_offset > snapshot_size)
{
return ecma_raise_type_error (invalid_version_error_p);
ecma_raise_type_error (invalid_version_error_p);
return ecma_create_error_reference_from_context ();
}
if (func_index >= header_p->number_of_funcs)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum"));
ecma_raise_range_error (ECMA_ERR_MSG ("Function index is higher than maximum"));
return ecma_create_error_reference_from_context ();
}
JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
const uint8_t *literal_base_p;
const uint8_t *number_base_p;
literal_base_p = ecma_snapshot_get_literals_base ((uint32_t *) (snapshot_data_p + header_p->lit_table_offset),
&number_base_p);
const uint8_t *literal_base_p = (uint8_t *) (snapshot_data_p + header_p->lit_table_offset);
ecma_compiled_code_t *bytecode_p;
uint32_t func_offset = header_p->func_offsets[func_index] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
bytecode_p = snapshot_load_compiled_code (snapshot_data_p + func_offset,
0,
literal_base_p,
number_base_p,
copy_bytecode);
if (bytecode_p == NULL)
@@ -813,8 +851,8 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */
static void
scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
const uint8_t *buffer_end_p, /**< snapshot buffer end */
const uint8_t *literal_base_p, /**< start of literal data */
const uint8_t *number_base_p) /**< start of number data */
ecma_collection_header_t *lit_pool_p, /**< list of known values */
const uint8_t *literal_base_p) /**< start of literal data */
{
JERRY_ASSERT (buffer_end_p > buffer_p);
@@ -825,29 +863,51 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
jmem_cpointer_t *literal_start_p;
ecma_value_t *literal_start_p;
uint32_t argument_end;
uint32_t const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
const_literal_end = args_p->const_literal_end;
argument_end = args_p->argument_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
else
{
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
const_literal_end = args_p->const_literal_end;
argument_end = args_p->argument_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
for (uint32_t i = 0; i < const_literal_end; i++)
{
if (literal_start_p[i] != JMEM_CP_NULL)
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
{
literal_start_p[i] = ecma_snapshot_get_literal (literal_base_p, number_base_p, literal_start_p[i]);
ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
literal_start_p[i] = lit_value;
ecma_save_literals_append_value (lit_value, lit_pool_p);
}
}
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
for (uint32_t i = 0; i < argument_end; i++)
{
if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
{
ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
literal_start_p[i] = lit_value;
ecma_save_literals_append_value (lit_value, lit_pool_p);
}
}
}
}
@@ -862,7 +922,7 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
*/
static void
update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
const uint8_t *buffer_end_p, /**< snapshot buffer start */
const uint8_t *buffer_end_p, /**< snapshot buffer end */
lit_mem_to_snapshot_id_map_entry_t *lit_map_p) /**< literal map */
{
JERRY_ASSERT (buffer_end_p > buffer_p);
@@ -874,27 +934,31 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
jmem_cpointer_t *literal_start_p;
ecma_value_t *literal_start_p;
uint32_t argument_end;
uint32_t const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
const_literal_end = args_p->const_literal_end;
argument_end = args_p->argument_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
else
{
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
literal_start_p = (ecma_value_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
const_literal_end = args_p->const_literal_end;
argument_end = args_p->argument_end;
const_literal_end = (uint32_t) (args_p->const_literal_end - args_p->register_end);
}
for (uint32_t i = 0; i < const_literal_end; i++)
{
if (literal_start_p[i] != JMEM_CP_NULL)
if (ecma_is_value_string (literal_start_p[i])
|| ecma_is_value_float_number (literal_start_p[i]))
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
@@ -906,6 +970,28 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
literal_start_p[i] = current_p->literal_offset;
}
}
if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
literal_start_p = ((ecma_value_t *) byte_p) - argument_end;
for (uint32_t i = 0; i < argument_end; i++)
{
if (literal_start_p[i] != ECMA_VALUE_EMPTY)
{
lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
while (current_p->literal_id != literal_start_p[i])
{
current_p++;
}
literal_start_p[i] = current_p->literal_offset;
}
}
}
}
buffer_p += code_size;
@@ -940,11 +1026,14 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
return 0;
}
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
for (uint32_t i = 0; i < number_of_snapshots; i++)
{
if (inp_buffer_sizes_p[i] < sizeof (jerry_snapshot_header_t))
{
*error_p = "invalid snapshot file";
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return 0;
}
@@ -955,6 +1044,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
|| !snapshot_check_global_flags (header_p->global_flags))
{
*error_p = "invalid snapshot version or unsupported features present";
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return 0;
}
@@ -962,11 +1052,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
uint32_t start_offset = header_p->func_offsets[0] & ~JERRY_SNAPSHOT_EVAL_CONTEXT;
const uint8_t *data_p = (const uint8_t *) inp_buffers_p[i];
const uint8_t *literal_base_p;
const uint8_t *number_base_p;
literal_base_p = ecma_snapshot_get_literals_base ((uint32_t *) (data_p + header_p->lit_table_offset),
&number_base_p);
const uint8_t *literal_base_p = (uint8_t *) (data_p + header_p->lit_table_offset);
JERRY_ASSERT (header_p->number_of_funcs > 0);
@@ -975,8 +1061,8 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
scan_snapshot_functions (data_p + start_offset,
data_p + header_p->lit_table_offset,
literal_base_p,
number_base_p);
lit_pool_p,
literal_base_p);
}
JERRY_ASSERT (number_of_funcs > 0);
@@ -986,6 +1072,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
if (functions_size >= out_buffer_size)
{
*error_p = "output buffer is too small";
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return 0;
}
@@ -1000,7 +1087,8 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
lit_mem_to_snapshot_id_map_entry_t *lit_map_p;
uint32_t literals_num;
if (!ecma_save_literals_for_snapshot (out_buffer_p,
if (!ecma_save_literals_for_snapshot (lit_pool_p,
out_buffer_p,
out_buffer_size,
&functions_size,
&lit_map_p,
@@ -1041,7 +1129,10 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
JERRY_ASSERT ((uint32_t) (dst_p - (uint8_t *) out_buffer_p) == header_p->lit_table_offset);
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
if (lit_map_p != NULL)
{
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
}
*error_p = NULL;
return functions_size;
@@ -1325,35 +1416,35 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
ecma_free_value (parse_status);
ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
ecma_bytecode_deref (bytecode_data_p);
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
lit_utf8_size_t literal_count = 0;
ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
/* Count the valid and non-magic identifiers in the list. */
while (string_list_p != NULL)
while (iterator_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
if (ecma_is_value_string (*iterator_p))
{
if (string_list_p->values[i] != JMEM_CP_NULL)
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
/* We don't save a literal which isn't a valid identifier or it's a magic string. */
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& ecma_string_is_valid_identifier (literal_p))
{
ecma_string_t *literal_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
/* We don't save a literal which isn't a valid identifier
or it's a magic string. */
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& ecma_string_is_valid_identifier (literal_p))
{
literal_count++;
}
literal_count++;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
iterator_p = ecma_collection_iterator_next (iterator_p);
}
if (literal_count == 0)
{
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
return 0;
}
@@ -1365,28 +1456,26 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *);
lit_utf8_size_t literal_idx = 0;
string_list_p = JERRY_CONTEXT (string_list_first_p);
iterator_p = ecma_collection_iterator_init (lit_pool_p);
while (string_list_p != NULL)
while (iterator_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
if (ecma_is_value_string (*iterator_p))
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *literal_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& ecma_string_is_valid_identifier (literal_p))
{
literal_array[literal_idx++] = literal_p;
}
if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
&& ecma_string_is_valid_identifier (literal_p))
{
literal_array[literal_idx++] = literal_p;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
iterator_p = ecma_collection_iterator_next (iterator_p);
}
ecma_free_values_collection (lit_pool_p, ECMA_COLLECTION_NO_COPY);
/* Sort the strings by size at first, then lexicographically. */
jerry_save_literals_sort (literal_array, literal_count);
+1 -1
View File
@@ -46,7 +46,7 @@ typedef struct
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (8u)
#define JERRY_SNAPSHOT_VERSION (9u)
/**
* Snapshot configuration flags.
+7 -6
View File
@@ -1846,11 +1846,12 @@ jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value *
return false;
}
ecma_string_t str_idx;
ecma_init_ecma_string_from_uint32 (&str_idx, index);
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_value),
&str_idx,
str_idx_p,
false);
ecma_deref_ecma_string (str_idx_p);
return ecma_is_value_true (ret_value);
} /* jerry_delete_property_by_index */
@@ -1905,9 +1906,9 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
}
ecma_string_t str_idx;
ecma_init_ecma_string_from_uint32 (&str_idx, index);
ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value), &str_idx);
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value), str_idx_p);
ecma_deref_ecma_string (str_idx_p);
return jerry_return (ret_value);
} /* jerry_get_property_by_index */