Support multiple primary functions in a single snapshot. (#1797)
This patch adds an extension to snapshots which allows storing multiple position independent primary functions in a single snapshot data. A new application called jerry-snapshot is added to the project to manage snapshots. Currently the only option is merging snapshots. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -233,13 +233,11 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
|
||||
* to the literal offsets
|
||||
* in snapshot */
|
||||
uint32_t *out_map_len_p, /**< [out] number of literals */
|
||||
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
|
||||
uint32_t *out_map_len_p) /**< [out] number of literals */
|
||||
{
|
||||
/* Count literals and literal space. */
|
||||
uint32_t string_count = 0;
|
||||
uint32_t number_count = 0;
|
||||
uint32_t lit_table_size = 2 * sizeof (uint32_t);
|
||||
uint32_t lit_table_size = sizeof (uint32_t);
|
||||
uint32_t total_count = 0;
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
|
||||
@@ -254,13 +252,15 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
|
||||
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
string_count++;
|
||||
total_count++;
|
||||
}
|
||||
}
|
||||
|
||||
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
|
||||
}
|
||||
|
||||
uint32_t number_offset = lit_table_size;
|
||||
|
||||
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
|
||||
|
||||
while (number_list_p != NULL)
|
||||
@@ -270,7 +270,7 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
if (number_list_p->values[i] != JMEM_CP_NULL)
|
||||
{
|
||||
lit_table_size += (uint32_t) sizeof (ecma_number_t);
|
||||
number_count++;
|
||||
total_count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,6 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t total_count = string_count + number_count;
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p;
|
||||
|
||||
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
@@ -300,7 +299,6 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
*in_out_buffer_offset_p += lit_table_size;
|
||||
*out_map_p = map_p;
|
||||
*out_map_len_p = total_count;
|
||||
*out_lit_table_size_p = lit_table_size;
|
||||
|
||||
/* Write data into the buffer. */
|
||||
|
||||
@@ -308,9 +306,7 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
* constant so the first literal must have offset one. */
|
||||
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
|
||||
|
||||
buffer_p[0] = string_count;
|
||||
buffer_p[1] = number_count;
|
||||
buffer_p += 2;
|
||||
*buffer_p++ = number_offset;
|
||||
|
||||
string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
|
||||
@@ -383,137 +379,52 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
|
||||
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
|
||||
#if defined JERRY_ENABLE_SNAPSHOT_EXEC || defined JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
|
||||
/**
|
||||
* Helper function for ecma_load_literals_from_snapshot.
|
||||
* Computes the base pointer of the literals and starting offset of numbers.
|
||||
*
|
||||
* Note: always inline because it is used only once.
|
||||
*
|
||||
* @return true - if load was performed successfully
|
||||
* false - otherwise (i.e. buffer length is incorrect)
|
||||
* @return the base pointer of the literals
|
||||
*/
|
||||
static inline bool __attr_always_inline___
|
||||
ecma_load_literals_from_buffer (const uint16_t *buffer_p, /**< buffer with literal table in snapshot */
|
||||
uint32_t lit_table_size, /**< size of literal table in snapshot */
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */
|
||||
uint32_t string_count, /**< number of strings */
|
||||
uint32_t number_count) /**< number of numbers */
|
||||
const uint8_t *
|
||||
ecma_snapshot_get_literals_base (uint32_t *buffer_p, /**< literal buffer start */
|
||||
const uint8_t **number_base_p) /**< [out] literal number start */
|
||||
{
|
||||
/* The zero value is reserved for NULL (no literal)
|
||||
* constant so the first literal must have offset one. */
|
||||
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
|
||||
*number_base_p = ((uint8_t *) buffer_p) + buffer_p[0];
|
||||
|
||||
/* Load strings first. */
|
||||
while (string_count > 0)
|
||||
return ((uint8_t *) (buffer_p + 1)) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
|
||||
} /* ecma_snapshot_get_literals_base */
|
||||
|
||||
/**
|
||||
* Get the compressed pointer of a given literal.
|
||||
*
|
||||
* @return literal compressed pointer
|
||||
*/
|
||||
jmem_cpointer_t
|
||||
ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
|
||||
const uint8_t *number_base_p, /**< literal number start */
|
||||
jmem_cpointer_t offset)
|
||||
{
|
||||
if (offset == 0)
|
||||
{
|
||||
if (lit_table_size < literal_offset + sizeof (uint32_t))
|
||||
{
|
||||
/* Buffer is not sufficent. */
|
||||
return false;
|
||||
}
|
||||
|
||||
lit_utf8_size_t length = *buffer_p;
|
||||
lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
|
||||
if (lit_table_size < literal_offset + aligned_length)
|
||||
{
|
||||
/* Buffer is not sufficent. */
|
||||
return false;
|
||||
}
|
||||
|
||||
map_p->literal_id = ecma_find_or_create_literal_string (((lit_utf8_byte_t *) buffer_p) + sizeof (uint16_t), length);
|
||||
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
map_p++;
|
||||
|
||||
JERRY_ASSERT ((aligned_length % sizeof (uint16_t)) == 0);
|
||||
buffer_p += aligned_length / sizeof (uint16_t);
|
||||
literal_offset += aligned_length;
|
||||
|
||||
string_count--;
|
||||
return ECMA_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* Load numbers. */
|
||||
while (number_count > 0)
|
||||
{
|
||||
if (lit_table_size < literal_offset + sizeof (ecma_number_t))
|
||||
{
|
||||
/* Buffer is not sufficent. */
|
||||
return false;
|
||||
}
|
||||
const uint8_t *literal_p = literal_base_p + (((size_t) offset) << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
|
||||
if (literal_p >= number_base_p)
|
||||
{
|
||||
ecma_number_t num;
|
||||
memcpy (&num, buffer_p, sizeof (ecma_number_t));
|
||||
|
||||
map_p->literal_id = ecma_find_or_create_literal_number (num);
|
||||
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
|
||||
map_p++;
|
||||
|
||||
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
|
||||
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
|
||||
|
||||
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
|
||||
buffer_p += length / sizeof (uint16_t);
|
||||
literal_offset += length;
|
||||
|
||||
number_count--;
|
||||
memcpy (&num, literal_p, sizeof (ecma_number_t));
|
||||
return ecma_find_or_create_literal_number (num);
|
||||
}
|
||||
|
||||
return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT));
|
||||
} /* ecma_load_literals_from_buffer */
|
||||
uint16_t length = *(const uint16_t *) literal_p;
|
||||
|
||||
/**
|
||||
* Load literals from snapshot.
|
||||
*
|
||||
* @return true - if load was performed successfully (i.e. literals saved in the snapshot are consistent),
|
||||
* false - otherwise (i.e. snapshot is incorrect)
|
||||
*/
|
||||
bool
|
||||
ecma_load_literals_from_snapshot (const uint32_t *buffer_p, /**< buffer with literal table in snapshot */
|
||||
uint32_t lit_table_size, /**< size of literal table in snapshot */
|
||||
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
|
||||
* in snapshot to identifiers
|
||||
* of loaded literals in literal
|
||||
* storage */
|
||||
uint32_t *out_map_len_p) /**< [out] literals number */
|
||||
{
|
||||
*out_map_p = NULL;
|
||||
return ecma_find_or_create_literal_string (literal_p + sizeof (uint16_t), length);
|
||||
} /* ecma_snapshot_get_literal */
|
||||
|
||||
if (lit_table_size < 2 * sizeof (uint32_t))
|
||||
{
|
||||
/* Buffer is not sufficent. */
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t string_count = buffer_p[0];
|
||||
uint32_t number_count = buffer_p[1];
|
||||
buffer_p += 2;
|
||||
|
||||
uint32_t total_count = string_count + number_count;
|
||||
lit_mem_to_snapshot_id_map_entry_t *map_p;
|
||||
|
||||
*out_map_len_p = total_count;
|
||||
|
||||
if (total_count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
*out_map_p = map_p;
|
||||
|
||||
if (ecma_load_literals_from_buffer ((uint16_t *) buffer_p, lit_table_size, map_p, string_count, number_count))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
|
||||
*out_map_p = NULL;
|
||||
return false;
|
||||
} /* ecma_load_literals_from_snapshot */
|
||||
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC || JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -43,15 +43,17 @@ jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
bool
|
||||
ecma_save_literals_for_snapshot (uint32_t *, size_t, size_t *,
|
||||
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *);
|
||||
ecma_save_literals_for_snapshot (uint32_t *buffer_p, size_t buffer_size, size_t *in_out_buffer_offset_p,
|
||||
lit_mem_to_snapshot_id_map_entry_t **out_map_p, uint32_t *out_map_len_p);
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
|
||||
bool
|
||||
ecma_load_literals_from_snapshot (const uint32_t *, uint32_t,
|
||||
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *);
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
|
||||
#if defined JERRY_ENABLE_SNAPSHOT_EXEC || defined JERRY_ENABLE_SNAPSHOT_SAVE
|
||||
const uint8_t *
|
||||
ecma_snapshot_get_literals_base (uint32_t *buffer_p, const uint8_t **number_base_p);
|
||||
jmem_cpointer_t
|
||||
ecma_snapshot_get_literal (const uint8_t *literal_base_p, const uint8_t *number_base_p,
|
||||
jmem_cpointer_t offset);
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC || JERRY_ENABLE_SNAPSHOT_SAVE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
Reference in New Issue
Block a user