Storing byte code size in the byte code header. This reduces the
memory consumption, because the new allocator uses less memory if the size as available when a block is freed. Snapshot generation is also simplified. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -741,17 +741,15 @@ typedef uintptr_t ecma_external_pointer_t;
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t status_flags; /**< various status flags */
|
||||
uint16_t size; /**< real size >> MEM_ALIGNMENT_LOG */
|
||||
uint16_t refs; /**< reference counter for the byte code */
|
||||
uint16_t status_flags; /**< various status flags:
|
||||
* CBC_CODE_FLAGS_FUNCTION flag tells whether
|
||||
* the byte code is function or regular expression.
|
||||
* If function, the other flags must be CBC_CODE_FLAGS...
|
||||
* If regexp, the other flags must be RE_FLAG... */
|
||||
} ecma_compiled_code_t;
|
||||
|
||||
/**
|
||||
* Shift value for byte code reference counting.
|
||||
* The last 10 bit of the first uint16_t value
|
||||
* of compact byte code or regexp byte code
|
||||
* is reserved for reference counting.
|
||||
*/
|
||||
#define ECMA_BYTECODE_REF_SHIFT 6
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1316,12 +1316,12 @@ void
|
||||
ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
{
|
||||
/* Abort program if maximum reference number is reached. */
|
||||
if ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) >= 0x3ff)
|
||||
if (bytecode_p->refs >= UINT16_MAX)
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
}
|
||||
|
||||
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags + (1u << ECMA_BYTECODE_REF_SHIFT));
|
||||
bytecode_p->refs++;
|
||||
} /* ecma_bytecode_ref */
|
||||
|
||||
/**
|
||||
@@ -1331,11 +1331,11 @@ ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
void
|
||||
ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
{
|
||||
JERRY_ASSERT ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) > 0);
|
||||
JERRY_ASSERT (bytecode_p->refs > 0);
|
||||
|
||||
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags - (1u << ECMA_BYTECODE_REF_SHIFT));
|
||||
bytecode_p->refs--;
|
||||
|
||||
if (bytecode_p->status_flags >= (1u << ECMA_BYTECODE_REF_SHIFT))
|
||||
if (bytecode_p->refs > 0)
|
||||
{
|
||||
/* Non-zero reference counter. */
|
||||
return;
|
||||
@@ -1388,7 +1388,8 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */
|
||||
}
|
||||
|
||||
mem_heap_free_block_size_stored (bytecode_p);
|
||||
mem_heap_free_block (bytecode_p,
|
||||
((size_t) bytecode_p->size) << MEM_ALIGNMENT_LOG);
|
||||
} /* ecma_bytecode_deref */
|
||||
|
||||
/**
|
||||
|
||||
@@ -256,7 +256,7 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**<
|
||||
/* Initialize RegExp object properties */
|
||||
re_initialize_props (obj_p,
|
||||
ECMA_GET_NON_NULL_POINTER (ecma_string_t, bytecode_p->pattern_cp),
|
||||
bytecode_p->flags);
|
||||
bytecode_p->header.status_flags);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_regexp_object_from_bytecode */
|
||||
@@ -1298,7 +1298,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
re_ctx.input_end_p = input_end_p;
|
||||
|
||||
/* 1. Read bytecode header and init regexp matcher context. */
|
||||
re_ctx.flags = bc_p->flags;
|
||||
re_ctx.flags = bc_p->header.status_flags;
|
||||
|
||||
if (ignore_global)
|
||||
{
|
||||
|
||||
@@ -24,27 +24,19 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t last_compiled_code_offset; /**< offset of the last compiled code */
|
||||
/* The size of this structure is recommended to be divisible by
|
||||
* MEM_ALIGNMENT. Otherwise some bytes after the header are wasted. */
|
||||
uint32_t version; /**< version number */
|
||||
uint32_t lit_table_offset; /**< offset of the literal table */
|
||||
uint32_t lit_table_size; /**< size of literal table */
|
||||
__extension__ uint32_t is_run_global : 1; /**< flag, indicating whether the snapshot
|
||||
* was dumped as 'Global scope'-mode code (true)
|
||||
* or as eval-mode code (false) */
|
||||
uint32_t is_run_global; /**< flag, indicating whether the snapshot
|
||||
* was dumped as 'Global scope'-mode code (true)
|
||||
* or as eval-mode code (false) */
|
||||
} jerry_snapshot_header_t;
|
||||
|
||||
/**
|
||||
* Jerry snapshot format version
|
||||
*/
|
||||
#define JERRY_SNAPSHOT_VERSION (3u)
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
/* Snapshot support functions */
|
||||
|
||||
extern bool snapshot_report_byte_code_compilation;
|
||||
|
||||
extern void
|
||||
snapshot_add_compiled_code (ecma_compiled_code_t *, const uint8_t *, uint32_t);
|
||||
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
#define JERRY_SNAPSHOT_VERSION (4u)
|
||||
|
||||
#endif /* !JERRY_SNAPSHOT_H */
|
||||
|
||||
+174
-216
@@ -1831,42 +1831,25 @@ jerry_register_external_magic_strings (const jerry_api_char_ptr_t *ex_str_items,
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
/*
|
||||
* Tells whether snapshot taking is in progress.
|
||||
*/
|
||||
bool snapshot_report_byte_code_compilation = false;
|
||||
|
||||
/*
|
||||
* Mapping snapshot to offset.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
mem_cpointer_t next_cp;
|
||||
mem_cpointer_t compiled_code_cp;
|
||||
uint16_t offset;
|
||||
} compiled_code_map_entry_t;
|
||||
|
||||
/*
|
||||
* Variables required to take a snapshot.
|
||||
*/
|
||||
static size_t snapshot_buffer_write_offset;
|
||||
static size_t snapshot_last_compiled_code_offset;
|
||||
static bool snapshot_error_occured;
|
||||
static size_t snapshot_buffer_write_offset;
|
||||
static uint8_t *snapshot_buffer_p;
|
||||
static size_t snapshot_buffer_size;
|
||||
static compiled_code_map_entry_t *snapshot_map_entries_p;
|
||||
|
||||
/**
|
||||
* Snapshot callback for byte codes.
|
||||
*
|
||||
* @return start offset
|
||||
*/
|
||||
void
|
||||
snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
|
||||
const uint8_t *regexp_pattern, /**< regular expression pattern */
|
||||
uint32_t size) /**< compiled code or regular expression size */
|
||||
static uint16_t
|
||||
snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p) /**< compiled code */
|
||||
{
|
||||
if (snapshot_error_occured)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
JERRY_ASSERT ((snapshot_buffer_write_offset & (MEM_ALIGNMENT - 1)) == 0);
|
||||
@@ -1874,81 +1857,117 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
|
||||
if ((snapshot_buffer_write_offset >> MEM_ALIGNMENT_LOG) > 0xffffu)
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
snapshot_last_compiled_code_offset = snapshot_buffer_write_offset;
|
||||
uint16_t start_offset = (uint16_t) (snapshot_buffer_write_offset >> MEM_ALIGNMENT_LOG);
|
||||
ecma_compiled_code_t *copied_compiled_code_p;
|
||||
|
||||
compiled_code_map_entry_t *new_entry;
|
||||
new_entry = (compiled_code_map_entry_t *) mem_heap_alloc_block (sizeof (compiled_code_map_entry_t));
|
||||
|
||||
if (new_entry == NULL)
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (new_entry->next_cp, snapshot_map_entries_p);
|
||||
ECMA_SET_POINTER (new_entry->compiled_code_cp, compiled_code_p);
|
||||
|
||||
new_entry->offset = (uint16_t) (snapshot_buffer_write_offset >> MEM_ALIGNMENT_LOG);
|
||||
snapshot_map_entries_p = new_entry;
|
||||
|
||||
const void *data_p = (const void *) compiled_code_p;
|
||||
copied_compiled_code_p = (ecma_compiled_code_t *) (snapshot_buffer_p + snapshot_buffer_write_offset);
|
||||
|
||||
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
{
|
||||
size += (uint32_t) sizeof (uint16_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (regexp_pattern == NULL);
|
||||
}
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
|
||||
/* Regular expression. */
|
||||
if (snapshot_buffer_write_offset + sizeof (ecma_compiled_code_t) > snapshot_buffer_size)
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
|
||||
snapshot_buffer_size,
|
||||
&snapshot_buffer_write_offset,
|
||||
&size,
|
||||
sizeof (uint32_t)))
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
}
|
||||
snapshot_buffer_write_offset += sizeof (ecma_compiled_code_t);
|
||||
|
||||
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
{
|
||||
size -= (uint32_t) sizeof (uint16_t);
|
||||
mem_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_length_t pattern_size = ecma_string_get_size (pattern_string_p);
|
||||
|
||||
MEM_DEFINE_LOCAL_ARRAY (buffer_p, pattern_size, lit_utf8_byte_t);
|
||||
|
||||
lit_utf8_size_t sz = ecma_string_to_utf8_string (pattern_string_p, buffer_p, pattern_size);
|
||||
JERRY_ASSERT (sz == pattern_size);
|
||||
|
||||
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
|
||||
snapshot_buffer_size,
|
||||
&snapshot_buffer_write_offset,
|
||||
&compiled_code_p->status_flags,
|
||||
sizeof (uint16_t)))
|
||||
buffer_p,
|
||||
pattern_size))
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
}
|
||||
|
||||
data_p = regexp_pattern;
|
||||
MEM_FINALIZE_LOCAL_ARRAY (buffer_p);
|
||||
|
||||
snapshot_buffer_write_offset = JERRY_ALIGNUP (snapshot_buffer_write_offset, MEM_ALIGNMENT);
|
||||
|
||||
/* Regexp character size is stored in refs. */
|
||||
copied_compiled_code_p->refs = (uint16_t) pattern_size;
|
||||
|
||||
pattern_size += (ecma_length_t) sizeof (ecma_compiled_code_t);
|
||||
copied_compiled_code_p->size = (uint16_t) ((pattern_size + MEM_ALIGNMENT - 1) >> MEM_ALIGNMENT_LOG);
|
||||
|
||||
copied_compiled_code_p->status_flags = compiled_code_p->status_flags;
|
||||
|
||||
#else
|
||||
JERRY_UNIMPLEMENTED ("RegExp is not supported in compact profile.");
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */
|
||||
return start_offset;
|
||||
}
|
||||
|
||||
if (!jrt_write_to_buffer_by_offset (snapshot_buffer_p,
|
||||
snapshot_buffer_size,
|
||||
&snapshot_buffer_write_offset,
|
||||
data_p,
|
||||
size))
|
||||
compiled_code_p,
|
||||
((size_t) compiled_code_p->size) << MEM_ALIGNMENT_LOG))
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
snapshot_buffer_write_offset = JERRY_ALIGNUP (snapshot_buffer_write_offset, MEM_ALIGNMENT);
|
||||
/* 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;
|
||||
uint32_t const_literal_end;
|
||||
uint32_t literal_end;
|
||||
|
||||
if (snapshot_buffer_write_offset > snapshot_buffer_size)
|
||||
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
snapshot_error_occured = true;
|
||||
return;
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
if (bytecode_p == compiled_code_p)
|
||||
{
|
||||
dst_literal_start_p[i] = start_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_literal_start_p[i] = snapshot_add_compiled_code (bytecode_p);
|
||||
}
|
||||
}
|
||||
|
||||
return start_offset;
|
||||
} /* snapshot_add_compiled_code */
|
||||
|
||||
/**
|
||||
@@ -1963,20 +1982,12 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
|
||||
|
||||
do
|
||||
{
|
||||
uint32_t code_size = *(uint32_t *) buffer_p;
|
||||
|
||||
buffer_p += sizeof (uint32_t);
|
||||
|
||||
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
|
||||
|
||||
/* Set reference counter to 1. */
|
||||
bytecode_p->status_flags &= (1u << ECMA_BYTECODE_REF_SHIFT) - 1;
|
||||
bytecode_p->status_flags |= 1u << ECMA_BYTECODE_REF_SHIFT;
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << MEM_ALIGNMENT_LOG;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
lit_cpointer_t *literal_start_p;
|
||||
uint32_t literal_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
@@ -1984,7 +1995,6 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
|
||||
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
}
|
||||
else
|
||||
@@ -1992,7 +2002,6 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
|
||||
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
}
|
||||
|
||||
@@ -2011,24 +2020,11 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
{
|
||||
compiled_code_map_entry_t *current_p = snapshot_map_entries_p;
|
||||
|
||||
while (current_p->compiled_code_cp != literal_start_p[i])
|
||||
{
|
||||
current_p = ECMA_GET_NON_NULL_POINTER (compiled_code_map_entry_t,
|
||||
current_p->next_cp);
|
||||
}
|
||||
|
||||
literal_start_p[i] = (uint16_t) current_p->offset;
|
||||
}
|
||||
/* Set reference counter to 1. */
|
||||
bytecode_p->refs = 1;
|
||||
}
|
||||
|
||||
code_size += (uint32_t) sizeof (uint32_t);
|
||||
code_size = JERRY_ALIGNUP (code_size, MEM_ALIGNMENT);
|
||||
|
||||
buffer_p += code_size - sizeof (uint32_t);
|
||||
buffer_p += code_size;
|
||||
size -= code_size;
|
||||
}
|
||||
while (size > 0);
|
||||
@@ -2056,42 +2052,19 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t *source_p, /**< script sou
|
||||
jsp_status_t parse_status;
|
||||
ecma_compiled_code_t *bytecode_data_p;
|
||||
|
||||
snapshot_buffer_write_offset = 0;
|
||||
snapshot_last_compiled_code_offset = 0;
|
||||
snapshot_buffer_write_offset = JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t),
|
||||
MEM_ALIGNMENT);
|
||||
snapshot_error_occured = false;
|
||||
snapshot_buffer_p = buffer_p;
|
||||
snapshot_buffer_size = buffer_size;
|
||||
snapshot_map_entries_p = NULL;
|
||||
|
||||
uint64_t version = JERRY_SNAPSHOT_VERSION;
|
||||
if (!jrt_write_to_buffer_by_offset (buffer_p,
|
||||
buffer_size,
|
||||
&snapshot_buffer_write_offset,
|
||||
&version,
|
||||
sizeof (version)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
snapshot_buffer_write_offset = JERRY_ALIGNUP (snapshot_buffer_write_offset, MEM_ALIGNMENT);
|
||||
|
||||
size_t header_offset = snapshot_buffer_write_offset;
|
||||
|
||||
snapshot_buffer_write_offset += JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT);
|
||||
|
||||
if (snapshot_buffer_write_offset > buffer_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t compiled_code_start = snapshot_buffer_write_offset;
|
||||
|
||||
snapshot_report_byte_code_compilation = true;
|
||||
jerry_api_object_t *error_obj_p = NULL;
|
||||
|
||||
if (is_for_global)
|
||||
{
|
||||
parse_status = parser_parse_script (source_p, source_size, &bytecode_data_p, &error_obj_p);
|
||||
parse_status = parser_parse_script (source_p,
|
||||
source_size,
|
||||
&bytecode_data_p,
|
||||
&error_obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2108,64 +2081,56 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t *source_p, /**< script sou
|
||||
ecma_deref_object (error_obj_p);
|
||||
}
|
||||
|
||||
snapshot_report_byte_code_compilation = false;
|
||||
|
||||
if (parse_status == JSP_STATUS_OK
|
||||
&& !snapshot_error_occured)
|
||||
if (parse_status != JSP_STATUS_OK)
|
||||
{
|
||||
JERRY_ASSERT (snapshot_last_compiled_code_offset != 0);
|
||||
|
||||
jerry_snapshot_header_t header;
|
||||
header.last_compiled_code_offset = (uint32_t) snapshot_last_compiled_code_offset;
|
||||
header.is_run_global = is_for_global;
|
||||
|
||||
size_t compiled_code_size = snapshot_buffer_write_offset - compiled_code_start;
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
|
||||
uint32_t literals_num;
|
||||
|
||||
if (!lit_dump_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);
|
||||
snapshot_buffer_write_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_snapshot_set_offsets (buffer_p + compiled_code_start,
|
||||
(uint32_t) compiled_code_size,
|
||||
lit_map_p);
|
||||
|
||||
jrt_write_to_buffer_by_offset (buffer_p,
|
||||
buffer_size,
|
||||
&header_offset,
|
||||
&header,
|
||||
sizeof (header));
|
||||
|
||||
mem_heap_free_block_size_stored (lit_map_p);
|
||||
}
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
snapshot_buffer_write_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
compiled_code_map_entry_t *current_p = snapshot_map_entries_p;
|
||||
snapshot_add_compiled_code (bytecode_data_p);
|
||||
|
||||
while (current_p != NULL)
|
||||
if (snapshot_error_occured)
|
||||
{
|
||||
compiled_code_map_entry_t *next_p = ECMA_GET_POINTER (compiled_code_map_entry_t,
|
||||
current_p->next_cp);
|
||||
mem_heap_free_block (current_p, sizeof (compiled_code_map_entry_t));
|
||||
current_p = next_p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
jerry_snapshot_header_t header;
|
||||
header.version = JERRY_SNAPSHOT_VERSION;
|
||||
header.lit_table_offset = (uint32_t) snapshot_buffer_write_offset;
|
||||
header.is_run_global = is_for_global;
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
|
||||
uint32_t literals_num;
|
||||
|
||||
if (!lit_dump_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;
|
||||
}
|
||||
|
||||
jerry_snapshot_set_offsets (buffer_p + JERRY_ALIGNUP (sizeof (jerry_snapshot_header_t), MEM_ALIGNMENT),
|
||||
(uint32_t) (header.lit_table_offset - sizeof (jerry_snapshot_header_t)),
|
||||
lit_map_p);
|
||||
|
||||
size_t header_offset = 0;
|
||||
|
||||
jrt_write_to_buffer_by_offset (buffer_p,
|
||||
buffer_size,
|
||||
&header_offset,
|
||||
&header,
|
||||
sizeof (header));
|
||||
|
||||
if (lit_map_p != NULL)
|
||||
{
|
||||
mem_heap_free_block_size_stored (lit_map_p);
|
||||
}
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
return snapshot_buffer_write_offset;
|
||||
#else /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
(void) source_p;
|
||||
@@ -2180,6 +2145,13 @@ jerry_parse_and_save_snapshot (const jerry_api_char_t *source_p, /**< script sou
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
|
||||
|
||||
/**
|
||||
* Byte code blocks shorter than this treshold are always copied into the memory.
|
||||
* The memory / performance trade-of of byte code redirection does not worth
|
||||
* in such cases.
|
||||
*/
|
||||
#define BYTECODE_NO_COPY_TRESHOLD 8
|
||||
|
||||
/**
|
||||
* Load byte code from snapshot.
|
||||
*
|
||||
@@ -2191,23 +2163,19 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /**< literal map */
|
||||
bool copy_bytecode) /**< byte code should be copied to memory */
|
||||
{
|
||||
uint32_t code_size = *(uint32_t *) (snapshot_data_p + offset);
|
||||
|
||||
ecma_compiled_code_t *bytecode_p;
|
||||
|
||||
bytecode_p = (ecma_compiled_code_t *) (snapshot_data_p + offset + sizeof (uint32_t));
|
||||
ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) (snapshot_data_p + offset);
|
||||
uint32_t code_size = ((uint32_t) bytecode_p->size) << MEM_ALIGNMENT_LOG;
|
||||
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
|
||||
{
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
|
||||
const re_compiled_code_t *re_bytecode_p = NULL;
|
||||
|
||||
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (uint16_t);
|
||||
|
||||
code_size -= (uint32_t) sizeof (uint16_t);
|
||||
const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (ecma_compiled_code_t);
|
||||
|
||||
/* Real size is stored in refs. */
|
||||
ecma_string_t *pattern_str_p = ecma_new_ecma_string_from_utf8 (regex_start_p,
|
||||
code_size);
|
||||
bytecode_p->refs);
|
||||
|
||||
re_compile_bytecode (&re_bytecode_p,
|
||||
pattern_str_p,
|
||||
@@ -2242,21 +2210,25 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
|
||||
header_size = sizeof (cbc_uint8_arguments_t);
|
||||
}
|
||||
|
||||
if (copy_bytecode)
|
||||
if (copy_bytecode
|
||||
|| (header_size + (literal_end * sizeof (uint16_t)) + BYTECODE_NO_COPY_TRESHOLD > code_size))
|
||||
{
|
||||
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block_store_size (code_size);
|
||||
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block (code_size);
|
||||
|
||||
memcpy (bytecode_p, snapshot_data_p + offset + sizeof (uint32_t), code_size);
|
||||
memcpy (bytecode_p, snapshot_data_p + offset, code_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
code_size = (uint32_t) (header_size + literal_end * sizeof (lit_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 *), MEM_ALIGNMENT);
|
||||
|
||||
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block_store_size (code_size + 1 + sizeof (uint8_t *));
|
||||
bytecode_p = (ecma_compiled_code_t *) mem_heap_alloc_block (total_size);
|
||||
|
||||
memcpy (bytecode_p, snapshot_data_p + offset + sizeof (uint32_t), code_size);
|
||||
memcpy (bytecode_p, snapshot_data_p + offset, code_size);
|
||||
|
||||
bytecode_p->size = (uint16_t) (total_size >> MEM_ALIGNMENT_LOG);
|
||||
|
||||
uint8_t *instructions_p = ((uint8_t *) bytecode_p);
|
||||
|
||||
@@ -2264,7 +2236,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
|
||||
memcpy (instructions_p + code_size + 1, &real_bytecode_p, sizeof (uint8_t *));
|
||||
}
|
||||
|
||||
JERRY_ASSERT ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) == 1);
|
||||
JERRY_ASSERT (bytecode_p->refs == 1);
|
||||
|
||||
lit_cpointer_t *literal_start_p = (lit_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
|
||||
|
||||
@@ -2335,39 +2307,28 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
|
||||
JERRY_ASSERT (snapshot_p != NULL);
|
||||
|
||||
const uint8_t *snapshot_data_p = (uint8_t *) snapshot_p;
|
||||
size_t snapshot_read = 0;
|
||||
uint64_t version;
|
||||
|
||||
if (!jrt_read_from_buffer_by_offset (snapshot_data_p,
|
||||
snapshot_size,
|
||||
&snapshot_read,
|
||||
&version,
|
||||
sizeof (version)))
|
||||
if (snapshot_size <= sizeof (jerry_snapshot_header_t))
|
||||
{
|
||||
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
|
||||
}
|
||||
|
||||
if (version != JERRY_SNAPSHOT_VERSION)
|
||||
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) snapshot_data_p;
|
||||
|
||||
if (header_p->version != JERRY_SNAPSHOT_VERSION)
|
||||
{
|
||||
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_VERSION;
|
||||
}
|
||||
|
||||
const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) (snapshot_data_p + snapshot_read);
|
||||
|
||||
snapshot_read = header_p->last_compiled_code_offset;
|
||||
|
||||
JERRY_ASSERT (snapshot_read == JERRY_ALIGNUP (snapshot_read, MEM_ALIGNMENT));
|
||||
|
||||
uint32_t last_code_size = *(uint32_t *) (snapshot_data_p + snapshot_read);
|
||||
|
||||
snapshot_read += JERRY_ALIGNUP (last_code_size + sizeof (uint32_t), MEM_ALIGNMENT);
|
||||
|
||||
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
|
||||
uint32_t literals_num;
|
||||
|
||||
JERRY_ASSERT (snapshot_read + header_p->lit_table_size <= snapshot_size);
|
||||
if (header_p->lit_table_offset >= snapshot_size)
|
||||
{
|
||||
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_VERSION;
|
||||
}
|
||||
|
||||
if (!lit_load_literals_from_snapshot (snapshot_data_p + snapshot_read,
|
||||
if (!lit_load_literals_from_snapshot (snapshot_data_p + header_p->lit_table_offset,
|
||||
header_p->lit_table_size,
|
||||
&lit_map_p,
|
||||
&literals_num))
|
||||
@@ -2377,11 +2338,8 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
|
||||
}
|
||||
|
||||
ecma_compiled_code_t *bytecode_p;
|
||||
|
||||
snapshot_read = header_p->last_compiled_code_offset;
|
||||
|
||||
bytecode_p = snapshot_load_compiled_code (snapshot_data_p,
|
||||
snapshot_read,
|
||||
sizeof (jerry_snapshot_header_t),
|
||||
lit_map_p,
|
||||
copy_bytecode);
|
||||
|
||||
|
||||
@@ -200,11 +200,11 @@ extern void __noreturn jerry_fatal (jerry_fatal_code_t);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Aligns @a value to @a alignment.
|
||||
* Aligns @a value to @a alignment. @a must be the power of 2.
|
||||
*
|
||||
* Returns minimum positive value, that divides @a alignment and is more than or equal to @a value
|
||||
*/
|
||||
#define JERRY_ALIGNUP(value, alignment) ((alignment) * (((value) + (alignment) - 1) / (alignment)))
|
||||
#define JERRY_ALIGNUP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment) - 1))
|
||||
|
||||
/**
|
||||
* min, max
|
||||
|
||||
@@ -617,7 +617,7 @@
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t status_flags; /**< various status flags */
|
||||
ecma_compiled_code_t header; /**< compiled code header */
|
||||
uint8_t stack_limit; /**< maximum number of values stored on the stack */
|
||||
uint8_t argument_end; /**< number of arguments expected by the function */
|
||||
uint8_t register_end; /**< end position of the register group */
|
||||
@@ -631,7 +631,7 @@ typedef struct
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t status_flags; /**< various status flags */
|
||||
ecma_compiled_code_t header; /**< compiled code header */
|
||||
uint16_t stack_limit; /**< maximum number of values stored on the stack */
|
||||
uint16_t argument_end; /**< number of arguments expected by the function */
|
||||
uint16_t register_end; /**< end position of the register group */
|
||||
|
||||
@@ -165,7 +165,7 @@ util_free_literal (lexer_literal_t *literal_p) /**< literal */
|
||||
{
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
PARSER_FREE ((uint8_t *) literal_p->u.char_p);
|
||||
mem_heap_free_block_size_stored ((void *) literal_p->u.char_p);
|
||||
}
|
||||
}
|
||||
else if ((literal_p->type == LEXER_FUNCTION_LITERAL)
|
||||
|
||||
@@ -47,17 +47,6 @@
|
||||
#include "lit-literal.h"
|
||||
#include "mem-heap.h"
|
||||
|
||||
/* The utilites here are just for compiling purposes, JS
|
||||
* engines should have an optimized version for them. */
|
||||
|
||||
/* Malloc functions. */
|
||||
|
||||
#define PARSER_MALLOC(size) mem_heap_alloc_block_store_size (size)
|
||||
#define PARSER_FREE(ptr) mem_heap_free_block_size_stored ((void *) ptr)
|
||||
|
||||
#define PARSER_MALLOC_LOCAL(size) mem_heap_alloc_block_store_size (size)
|
||||
#define PARSER_FREE_LOCAL(ptr) mem_heap_free_block_size_stored (ptr)
|
||||
|
||||
/* UTF character management. Only ASCII characters are
|
||||
* supported for simplicity. */
|
||||
|
||||
|
||||
@@ -1203,7 +1203,7 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
|
||||
|
||||
if (has_escape)
|
||||
{
|
||||
literal_p->u.char_p = (uint8_t *) PARSER_MALLOC (length);
|
||||
literal_p->u.char_p = (uint8_t *) mem_heap_alloc_block_store_size (length);
|
||||
memcpy ((uint8_t *) literal_p->u.char_p, char_p, length);
|
||||
}
|
||||
else
|
||||
@@ -1245,6 +1245,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
|
||||
{
|
||||
destination_start_p = (uint8_t *) parser_malloc_local (context_p, literal_p->length);
|
||||
context_p->allocated_buffer_p = destination_start_p;
|
||||
context_p->allocated_buffer_size = literal_p->length;
|
||||
}
|
||||
|
||||
destination_p = destination_start_p;
|
||||
@@ -1502,7 +1503,8 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
|
||||
JERRY_ASSERT (context_p->allocated_buffer_p == destination_start_p);
|
||||
|
||||
context_p->allocated_buffer_p = NULL;
|
||||
parser_free_local (destination_start_p);
|
||||
parser_free_local (destination_start_p,
|
||||
context_p->allocated_buffer_size);
|
||||
}
|
||||
|
||||
JERRY_ASSERT (context_p->allocated_buffer_p == NULL);
|
||||
@@ -1826,15 +1828,6 @@ lexer_construct_regexp_object (parser_context_t *context_p, /**< context */
|
||||
parser_raise_error (context_p, PARSER_ERR_INVALID_REGEXP);
|
||||
}
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
if (snapshot_report_byte_code_compilation)
|
||||
{
|
||||
snapshot_add_compiled_code ((ecma_compiled_code_t *) re_bytecode_p,
|
||||
regex_start_p,
|
||||
length);
|
||||
}
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
literal_p->type = LEXER_REGEXP_LITERAL;
|
||||
literal_p->u.bytecode_p = (ecma_compiled_code_t *) re_bytecode_p;
|
||||
|
||||
|
||||
@@ -236,6 +236,7 @@ typedef struct
|
||||
parser_error_t error; /**< error code */
|
||||
void *allocated_buffer_p; /**< dinamically allocated buffer
|
||||
* which needs to be freed on error */
|
||||
uint32_t allocated_buffer_size; /**< size of the dinamically allocated buffer */
|
||||
|
||||
/* Parser members. */
|
||||
uint32_t status_flags; /**< status flags */
|
||||
@@ -283,9 +284,9 @@ typedef struct
|
||||
/* Memory management.
|
||||
* Note: throws an error if unsuccessful. */
|
||||
void *parser_malloc (parser_context_t *, size_t);
|
||||
void parser_free (void *);
|
||||
void parser_free (void *, size_t);
|
||||
void *parser_malloc_local (parser_context_t *, size_t);
|
||||
void parser_free_local (void *);
|
||||
void parser_free_local (void *, size_t);
|
||||
|
||||
/* Parser byte stream. */
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
/* Maximum code size.
|
||||
* Limit: 16777215. Recommended: 65535, 16777215. */
|
||||
#ifndef PARSER_MAXIMUM_CODE_SIZE
|
||||
#define PARSER_MAXIMUM_CODE_SIZE 16777215
|
||||
#define PARSER_MAXIMUM_CODE_SIZE (65535 << (MEM_ALIGNMENT_LOG))
|
||||
#endif
|
||||
|
||||
/* Maximum number of values pushed onto the stack by a function.
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
*/
|
||||
void *
|
||||
parser_malloc (parser_context_t *context_p, /**< context */
|
||||
size_t size) /**< size of the memory */
|
||||
size_t size) /**< size of the memory block */
|
||||
{
|
||||
void *result;
|
||||
|
||||
JERRY_ASSERT (size > 0);
|
||||
result = PARSER_MALLOC (size);
|
||||
result = mem_heap_alloc_block (size);
|
||||
if (result == 0)
|
||||
{
|
||||
parser_raise_error (context_p, PARSER_ERR_OUT_OF_MEMORY);
|
||||
@@ -50,9 +50,10 @@ parser_malloc (parser_context_t *context_p, /**< context */
|
||||
/**
|
||||
* Free memory allocated by parser_malloc.
|
||||
*/
|
||||
void parser_free (void *ptr) /**< pointer to free */
|
||||
void parser_free (void *ptr, /**< pointer to free */
|
||||
size_t size) /**< size of the memory block */
|
||||
{
|
||||
PARSER_FREE (ptr);
|
||||
mem_heap_free_block (ptr, size);
|
||||
} /* parser_free */
|
||||
|
||||
/**
|
||||
@@ -67,7 +68,7 @@ parser_malloc_local (parser_context_t *context_p, /**< context */
|
||||
void *result;
|
||||
|
||||
JERRY_ASSERT (size > 0);
|
||||
result = PARSER_MALLOC_LOCAL (size);
|
||||
result = mem_heap_alloc_block (size);
|
||||
if (result == 0)
|
||||
{
|
||||
parser_raise_error (context_p, PARSER_ERR_OUT_OF_MEMORY);
|
||||
@@ -78,9 +79,10 @@ parser_malloc_local (parser_context_t *context_p, /**< context */
|
||||
/**
|
||||
* Free memory allocated by parser_malloc_local.
|
||||
*/
|
||||
void parser_free_local (void *ptr) /**< pointer to free */
|
||||
void parser_free_local (void *ptr, /**< pointer to free */
|
||||
size_t size) /**< size of the memory */
|
||||
{
|
||||
PARSER_FREE_LOCAL (ptr);
|
||||
mem_heap_free_block (ptr, size);
|
||||
} /* parser_free_local */
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -103,7 +105,8 @@ parser_data_init (parser_mem_data_t *data_p, /**< memory manager */
|
||||
* Free parse data.
|
||||
*/
|
||||
static void
|
||||
parser_data_free (parser_mem_data_t *data_p) /**< memory manager */
|
||||
parser_data_free (parser_mem_data_t *data_p, /**< memory manager */
|
||||
uint32_t page_size) /**< size of each page */
|
||||
{
|
||||
parser_mem_page_t *page_p = data_p->first_p;
|
||||
|
||||
@@ -111,7 +114,7 @@ parser_data_free (parser_mem_data_t *data_p) /**< memory manager */
|
||||
{
|
||||
parser_mem_page_t *next_p = page_p->next_p;
|
||||
|
||||
parser_free (page_p);
|
||||
parser_free (page_p, page_size);
|
||||
page_p = next_p;
|
||||
}
|
||||
} /* parser_data_free */
|
||||
@@ -135,7 +138,8 @@ parser_cbc_stream_init (parser_mem_data_t *data_p) /**< memory manager */
|
||||
void
|
||||
parser_cbc_stream_free (parser_mem_data_t *data_p) /**< memory manager */
|
||||
{
|
||||
parser_data_free (data_p);
|
||||
parser_data_free (data_p,
|
||||
sizeof (parser_mem_page_t *) + PARSER_CBC_STREAM_PAGE_SIZE);
|
||||
} /* parser_cbc_stream_free */
|
||||
|
||||
/**
|
||||
@@ -188,7 +192,8 @@ parser_list_init (parser_list_t *list_p, /**< parser list */
|
||||
void
|
||||
parser_list_free (parser_list_t *list_p) /**< parser list */
|
||||
{
|
||||
parser_data_free (&list_p->data);
|
||||
parser_data_free (&list_p->data,
|
||||
(uint32_t) (sizeof (parser_mem_page_t *) + list_p->page_size));
|
||||
} /* parser_list_free */
|
||||
|
||||
/**
|
||||
@@ -330,11 +335,13 @@ parser_stack_init (parser_context_t *context_p) /**< context */
|
||||
void
|
||||
parser_stack_free (parser_context_t *context_p) /**< context */
|
||||
{
|
||||
parser_data_free (&context_p->stack);
|
||||
parser_data_free (&context_p->stack,
|
||||
sizeof (parser_mem_page_t *) + PARSER_STACK_PAGE_SIZE);
|
||||
|
||||
if (context_p->free_page_p != NULL)
|
||||
{
|
||||
parser_free (context_p->free_page_p);
|
||||
parser_free (context_p->free_page_p,
|
||||
sizeof (parser_mem_page_t *) + PARSER_STACK_PAGE_SIZE);
|
||||
}
|
||||
} /* parser_stack_free */
|
||||
|
||||
@@ -363,7 +370,6 @@ parser_stack_push_uint8 (parser_context_t *context_p, /**< context */
|
||||
else
|
||||
{
|
||||
size_t size = sizeof (parser_mem_page_t *) + PARSER_STACK_PAGE_SIZE;
|
||||
|
||||
page_p = (parser_mem_page_t *) parser_malloc (context_p, size);
|
||||
}
|
||||
|
||||
@@ -400,7 +406,8 @@ parser_stack_pop_uint8 (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_free (page_p);
|
||||
parser_free (page_p,
|
||||
sizeof (parser_mem_page_t *) + PARSER_STACK_PAGE_SIZE);
|
||||
}
|
||||
|
||||
page_p = context_p->stack.first_p;
|
||||
@@ -575,7 +582,8 @@ parser_stack_pop (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
else
|
||||
{
|
||||
parser_free (page_p);
|
||||
parser_free (page_p,
|
||||
sizeof (parser_mem_page_t *) + PARSER_STACK_PAGE_SIZE);
|
||||
}
|
||||
} /* parser_stack_pop */
|
||||
|
||||
|
||||
@@ -1285,7 +1285,7 @@ parser_parse_case_statement (parser_context_t *context_p) /**< context */
|
||||
parser_stack_iterator_write (&iterator, &switch_statement, sizeof (parser_switch_statement_t));
|
||||
|
||||
parser_set_branch_to_current_position (context_p, &branch_p->branch);
|
||||
parser_free (branch_p);
|
||||
parser_free (branch_p, sizeof (parser_branch_node_t));
|
||||
} /* parser_parse_case_statement */
|
||||
|
||||
/**
|
||||
@@ -2102,7 +2102,7 @@ parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
|
||||
while (branch_list_p != NULL)
|
||||
{
|
||||
parser_branch_node_t *next_p = branch_list_p->next_p;
|
||||
parser_free (branch_list_p);
|
||||
parser_free (branch_list_p, sizeof (parser_branch_node_t));
|
||||
branch_list_p = next_p;
|
||||
}
|
||||
branch_list_p = loop.branch_list_p;
|
||||
@@ -2133,7 +2133,7 @@ parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
|
||||
while (branch_list_p != NULL)
|
||||
{
|
||||
parser_branch_node_t *next_p = branch_list_p->next_p;
|
||||
parser_free (branch_list_p);
|
||||
parser_free (branch_list_p, sizeof (parser_branch_node_t));
|
||||
branch_list_p = next_p;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ parser_set_breaks_to_current_position (parser_context_t *context_p, /**< context
|
||||
{
|
||||
parser_set_branch_to_current_position (context_p, ¤t_p->branch);
|
||||
}
|
||||
parser_free (current_p);
|
||||
parser_free (current_p, sizeof (parser_branch_node_t));
|
||||
current_p = next_p;
|
||||
}
|
||||
} /* parser_set_breaks_to_current_position */
|
||||
|
||||
@@ -105,7 +105,7 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
|
||||
|
||||
if (!(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
PARSER_FREE ((uint8_t *) char_p);
|
||||
mem_heap_free_block_size_stored ((void *) char_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -527,7 +527,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|
||||
if (!context_p->is_show_opcodes
|
||||
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
PARSER_FREE (literal_p->u.char_p);
|
||||
mem_heap_free_block_size_stored ((void *) literal_p->u.char_p);
|
||||
}
|
||||
#else /* PARSER_DUMP_BYTE_CODE */
|
||||
literal_pool_p[literal_p->prop.index] = literal_p->u.value;
|
||||
@@ -1460,10 +1460,14 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
|
||||
total_size += length + context_p->literal_count * sizeof (lit_cpointer_t);
|
||||
total_size = JERRY_ALIGNUP (total_size, MEM_ALIGNMENT);
|
||||
|
||||
compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size);
|
||||
|
||||
byte_code_p = (uint8_t *) compiled_code_p;
|
||||
compiled_code_p->status_flags = CBC_CODE_FLAGS_FUNCTION | (1u << ECMA_BYTECODE_REF_SHIFT);
|
||||
compiled_code_p->size = (uint16_t) (total_size >> MEM_ALIGNMENT_LOG);
|
||||
compiled_code_p->refs = 1;
|
||||
compiled_code_p->status_flags = CBC_CODE_FLAGS_FUNCTION;
|
||||
|
||||
if (needs_uint16_arguments)
|
||||
{
|
||||
@@ -1518,20 +1522,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
literal_pool_p = (lit_cpointer_t *) byte_code_p;
|
||||
byte_code_p += context_p->literal_count * sizeof (lit_cpointer_t);
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
if (snapshot_report_byte_code_compilation
|
||||
&& context_p->argument_count > 0)
|
||||
{
|
||||
/* Reset all arguments to NULL. */
|
||||
for (offset = 0; offset < context_p->argument_count; offset++)
|
||||
{
|
||||
literal_pool_p[offset] = NOT_A_LITERAL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
dst_p = parser_generate_initializers (context_p,
|
||||
byte_code_p,
|
||||
literal_pool_p,
|
||||
@@ -1705,7 +1695,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
if ((literal_p->type == LEXER_IDENT_LITERAL || literal_p->type == LEXER_STRING_LITERAL)
|
||||
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
|
||||
{
|
||||
PARSER_FREE (literal_p->u.char_p);
|
||||
mem_heap_free_block_size_stored ((void *) literal_p->u.char_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1780,15 +1770,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
||||
compiled_code_p);
|
||||
}
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
if (snapshot_report_byte_code_compilation)
|
||||
{
|
||||
snapshot_add_compiled_code (compiled_code_p, NULL, (uint32_t) total_size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return compiled_code_p;
|
||||
} /* parser_post_processing */
|
||||
|
||||
@@ -1924,7 +1905,8 @@ parser_parse_source (const uint8_t *source_p, /**< valid UTF-8 source code */
|
||||
|
||||
if (context.allocated_buffer_p != NULL)
|
||||
{
|
||||
parser_free_local (context.allocated_buffer_p);
|
||||
parser_free_local (context.allocated_buffer_p,
|
||||
context.allocated_buffer_size);
|
||||
}
|
||||
|
||||
if (error_location != NULL)
|
||||
|
||||
@@ -54,11 +54,11 @@ re_realloc_regexp_bytecode_block (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytec
|
||||
JERRY_ASSERT (bc_ctx_p->current_p >= bc_ctx_p->block_start_p);
|
||||
size_t current_ptr_offset = (size_t) (bc_ctx_p->current_p - bc_ctx_p->block_start_p);
|
||||
|
||||
uint8_t *new_block_start_p = (uint8_t *) mem_heap_alloc_block_store_size (new_block_size);
|
||||
uint8_t *new_block_start_p = (uint8_t *) mem_heap_alloc_block (new_block_size);
|
||||
if (bc_ctx_p->current_p)
|
||||
{
|
||||
memcpy (new_block_start_p, bc_ctx_p->block_start_p, (size_t) (current_ptr_offset));
|
||||
mem_heap_free_block_size_stored (bc_ctx_p->block_start_p);
|
||||
mem_heap_free_block (bc_ctx_p->block_start_p, old_size);
|
||||
}
|
||||
bc_ctx_p->block_start_p = new_block_start_p;
|
||||
bc_ctx_p->block_end_p = new_block_start_p + new_block_size;
|
||||
@@ -109,10 +109,10 @@ re_bytecode_list_insert (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode conte
|
||||
{
|
||||
uint8_t *dest_p = src_p + length;
|
||||
uint8_t *tmp_block_start_p;
|
||||
tmp_block_start_p = (uint8_t *) mem_heap_alloc_block_store_size (re_get_bytecode_length (bc_ctx_p) - offset);
|
||||
tmp_block_start_p = (uint8_t *) mem_heap_alloc_block (re_get_bytecode_length (bc_ctx_p) - offset);
|
||||
memcpy (tmp_block_start_p, src_p, (size_t) (re_get_bytecode_length (bc_ctx_p) - offset));
|
||||
memcpy (dest_p, tmp_block_start_p, (size_t) (re_get_bytecode_length (bc_ctx_p) - offset));
|
||||
mem_heap_free_block_size_stored (tmp_block_start_p);
|
||||
mem_heap_free_block (tmp_block_start_p, re_get_bytecode_length (bc_ctx_p) - offset);
|
||||
}
|
||||
memcpy (src_p, bytecode_p, length);
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ typedef enum
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t flags; /**< RegExp flags */
|
||||
ecma_compiled_code_t header; /**< compiled code header */
|
||||
mem_cpointer_t pattern_cp; /**< original RegExp pattern */
|
||||
uint32_t num_of_captures; /**< number of capturing brackets */
|
||||
uint32_t num_of_non_captures; /**< number of non capturing brackets */
|
||||
|
||||
@@ -468,7 +468,7 @@ re_find_bytecode_in_cache (ecma_string_t *pattern_str_p, /**< pattern string */
|
||||
ecma_string_t *cached_pattern_str_p;
|
||||
cached_pattern_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, cached_bytecode_p->pattern_cp);
|
||||
|
||||
if ((cached_bytecode_p->flags & RE_FLAGS_MASK) == flags
|
||||
if ((cached_bytecode_p->header.status_flags & RE_FLAGS_MASK) == flags
|
||||
&& ecma_compare_ecma_strings (cached_pattern_str_p, pattern_str_p))
|
||||
{
|
||||
JERRY_DDLOG ("RegExp is found in cache\n");
|
||||
@@ -497,9 +497,9 @@ re_cache_gc_run ()
|
||||
const re_compiled_code_t *cached_bytecode_p = re_cache[i];
|
||||
|
||||
if (cached_bytecode_p != NULL
|
||||
&& (cached_bytecode_p->flags >> ECMA_BYTECODE_REF_SHIFT) == 1)
|
||||
{ /* Only the cache has reference for the bytecode */
|
||||
|
||||
&& cached_bytecode_p->header.refs == 1)
|
||||
{
|
||||
/* Only the cache has reference for the bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) cached_bytecode_p);
|
||||
re_cache[i] = NULL;
|
||||
}
|
||||
@@ -578,7 +578,8 @@ re_compile_bytecode (const re_compiled_code_t **out_bytecode_p, /**< [out] point
|
||||
/* 3. Insert extra informations for bytecode header */
|
||||
re_compiled_code_t re_compiled_code;
|
||||
|
||||
re_compiled_code.flags = re_ctx.flags | (1u << ECMA_BYTECODE_REF_SHIFT);
|
||||
re_compiled_code.header.refs = 1;
|
||||
re_compiled_code.header.status_flags = re_ctx.flags;
|
||||
ECMA_SET_NON_NULL_POINTER (re_compiled_code.pattern_cp,
|
||||
ecma_copy_or_ref_ecma_string (pattern_str_p));
|
||||
re_compiled_code.num_of_captures = re_ctx.num_of_captures * 2;
|
||||
@@ -594,11 +595,13 @@ re_compile_bytecode (const re_compiled_code_t **out_bytecode_p, /**< [out] point
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (pattern_start_p);
|
||||
|
||||
size_t byte_code_size = (size_t) (bc_ctx.block_end_p - bc_ctx.block_start_p);
|
||||
|
||||
if (!ecma_is_value_empty (ret_value))
|
||||
{
|
||||
/* Compilation failed, free bytecode. */
|
||||
JERRY_DDLOG ("RegExp compilation failed!\n");
|
||||
mem_heap_free_block_size_stored (bc_ctx.block_start_p);
|
||||
mem_heap_free_block (bc_ctx.block_start_p, byte_code_size);
|
||||
*out_bytecode_p = NULL;
|
||||
}
|
||||
else
|
||||
@@ -611,6 +614,8 @@ re_compile_bytecode (const re_compiled_code_t **out_bytecode_p, /**< [out] point
|
||||
JERRY_ASSERT (bc_ctx.block_start_p != NULL);
|
||||
*out_bytecode_p = (re_compiled_code_t *) bc_ctx.block_start_p;
|
||||
|
||||
((re_compiled_code_t *) bc_ctx.block_start_p)->header.size = (uint16_t) (byte_code_size >> MEM_ALIGNMENT_LOG);
|
||||
|
||||
if (cache_idx == RE_CACHE_SIZE)
|
||||
{
|
||||
if (re_cache_idx == 0u)
|
||||
|
||||
Reference in New Issue
Block a user