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:
Zoltan Herczeg
2016-03-16 02:57:28 -07:00
parent 2a5d17e736
commit d190ca44ae
19 changed files with 265 additions and 338 deletions
+2 -2
View File
@@ -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 */
+1 -1
View File
@@ -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)
-11
View File
@@ -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. */
+4 -11
View File
@@ -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;
+3 -2
View File
@@ -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. */
+1 -1
View File
@@ -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.
+24 -16
View File
@@ -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 */
+3 -3
View File
@@ -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;
}
}
+1 -1
View File
@@ -619,7 +619,7 @@ parser_set_breaks_to_current_position (parser_context_t *context_p, /**< context
{
parser_set_branch_to_current_position (context_p, &current_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 */
+10 -28
View File
@@ -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)
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -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 */
+11 -6
View File
@@ -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)