Skip to content

Commit 050ea0b

Browse files
committed
Support multiple primary functions in a single snapshot.
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 [email protected]
1 parent 2404117 commit 050ea0b

File tree

12 files changed

+569
-187
lines changed

12 files changed

+569
-187
lines changed

CMakeLists.txt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ string(TOUPPER "${PLATFORM}" PLATFORM)
2323
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS )
2424

2525
# Components
26-
set(JERRY_CMDLINE ON CACHE BOOL "Build jerry command line tool?")
27-
set(JERRY_CMDLINE_MINIMAL OFF CACHE BOOL "Build jerry minimal command line tool?")
28-
set(JERRY_PORT_DEFAULT ON CACHE BOOL "Build default jerry port implementation?")
29-
set(JERRY_LIBC ON CACHE BOOL "Build and use jerry-libc?")
30-
set(JERRY_LIBM ON CACHE BOOL "Build and use jerry-libm?")
31-
set(UNITTESTS OFF CACHE BOOL "Build unit tests?")
26+
set(JERRY_CMDLINE ON CACHE BOOL "Build jerry command line tool?")
27+
set(JERRY_CMDLINE_MINIMAL OFF CACHE BOOL "Build jerry minimal command line tool?")
28+
set(JERRY_CMDLINE_SNAPSHOT OFF CACHE BOOL "Build jerry snapshot command line tool?")
29+
set(JERRY_PORT_DEFAULT ON CACHE BOOL "Build default jerry port implementation?")
30+
set(JERRY_LIBC ON CACHE BOOL "Build and use jerry-libc?")
31+
set(JERRY_LIBM ON CACHE BOOL "Build and use jerry-libm?")
32+
set(UNITTESTS OFF CACHE BOOL "Build unit tests?")
3233

3334
# Optional build settings
3435
set(ENABLE_ALL_IN_ONE OFF CACHE BOOL "Enable all-in-one build?")
@@ -40,7 +41,7 @@ if(NOT CMAKE_BUILD_TYPE)
4041
set(CMAKE_BUILD_TYPE "MinSizeRel")
4142
endif()
4243

43-
if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL)
44+
if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL OR JERRY_CMDLINE_SNAPSHOT)
4445
set(JERRY_PORT_DEFAULT "ON")
4546

4647
set(JERRY_PORT_DEFAULT_MESSAGE " (FORCED BY CMDLINE)")
@@ -93,6 +94,7 @@ message(STATUS "ENABLE_STATIC_LINK " ${ENABLE_STATIC_LINK} ${ENABLE_STATI
9394
message(STATUS "ENABLE_STRIP " ${ENABLE_STRIP} ${ENABLE_STRIP_MESSAGE})
9495
message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE})
9596
message(STATUS "JERRY_CMDLINE_MINIMAL " ${JERRY_CMDLINE_MINIMAL})
97+
message(STATUS "JERRY_CMDLINE_SNAPSHOT " ${JERRY_CMDLINE_SNAPSHOT})
9698
message(STATUS "JERRY_PORT_DEFAULT " ${JERRY_PORT_DEFAULT} ${JERRY_PORT_DEFAULT_MESSAGE})
9799
message(STATUS "JERRY_LIBC " ${JERRY_LIBC} ${JERRY_LIBC_MESSAGE})
98100
message(STATUS "JERRY_LIBM " ${JERRY_LIBM} ${JERRY_LIBM_MESSAGE})
@@ -239,7 +241,7 @@ if(JERRY_PORT_DEFAULT)
239241
endif()
240242

241243
# Jerry command line tool
242-
if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL)
244+
if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL OR JERRY_CMDLINE_SNAPSHOT)
243245
add_subdirectory(jerry-main)
244246
endif()
245247

docs/02.API-REFERENCE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3810,11 +3810,13 @@ is no longer needed.
38103810
jerry_value_t
38113811
jerry_exec_snapshot (const uint32_t *snapshot_p,
38123812
size_t snapshot_size,
3813+
size_t func_index,
38133814
bool copy_bytecode);
38143815
```
38153816

38163817
- `snapshot_p` - pointer to snapshot
38173818
- `snapshot_size` - size of snapshot
3819+
- `func_index` - index of executed function
38183820
- `copy_bytecode` - flag, indicating whether the passed snapshot buffer should be copied to the
38193821
engine's memory. If set the engine should not reference the buffer after the function returns
38203822
(in this case, the passed buffer could be freed after the call). Otherwise (if the flag is not
@@ -3844,6 +3846,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p,
38443846

38453847
res = (jerry_exec_snapshot (global_mode_snapshot_buffer,
38463848
global_mode_snapshot_size,
3849+
0,
38473850
false);
38483851

38493852
jerry_cleanup ();

jerry-core/ecma/base/ecma-literal-storage.c

Lines changed: 32 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,11 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
232232
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
233233
* to the literal offsets
234234
* in snapshot */
235-
uint32_t *out_map_len_p, /**< [out] number of literals */
236-
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
235+
uint32_t *out_map_len_p) /**< [out] number of literals */
237236
{
238237
/* Count literals and literal space. */
239-
uint32_t string_count = 0;
240-
uint32_t number_count = 0;
241-
uint32_t lit_table_size = 2 * sizeof (uint32_t);
238+
uint32_t lit_table_size = sizeof (uint32_t);
239+
uint32_t total_count = 0;
242240

243241
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
244242

@@ -253,13 +251,15 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
253251

254252
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
255253
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
256-
string_count++;
254+
total_count++;
257255
}
258256
}
259257

260258
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
261259
}
262260

261+
uint32_t number_offset = lit_table_size;
262+
263263
ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p);
264264

265265
while (number_list_p != NULL)
@@ -269,7 +269,7 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
269269
if (number_list_p->values[i] != JMEM_CP_NULL)
270270
{
271271
lit_table_size += (uint32_t) sizeof (ecma_number_t);
272-
number_count++;
272+
total_count++;
273273
}
274274
}
275275

@@ -288,7 +288,6 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
288288
return false;
289289
}
290290

291-
uint32_t total_count = string_count + number_count;
292291
lit_mem_to_snapshot_id_map_entry_t *map_p;
293292

294293
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
@@ -299,17 +298,14 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
299298
*in_out_buffer_offset_p += lit_table_size;
300299
*out_map_p = map_p;
301300
*out_map_len_p = total_count;
302-
*out_lit_table_size_p = lit_table_size;
303301

304302
/* Write data into the buffer. */
305303

306304
/* The zero value is reserved for NULL (no literal)
307305
* constant so the first literal must have offset one. */
308306
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
309307

310-
buffer_p[0] = string_count;
311-
buffer_p[1] = number_count;
312-
buffer_p += 2;
308+
*buffer_p++ = number_offset;
313309

314310
string_list_p = JERRY_CONTEXT (string_list_first_p);
315311

@@ -385,132 +381,47 @@ ecma_save_literals_for_snapshot (uint32_t *buffer_p, /**< [out] output snapshot
385381
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
386382

387383
/**
388-
* Helper function for ecma_load_literals_from_snapshot.
389-
*
390-
* Note: always inline because it is used only once.
384+
* Computes the base pointer of the literals and starting offset of numbers.
391385
*
392-
* @return true - if load was performed successfully
393-
* false - otherwise (i.e. buffer length is incorrect)
386+
* @return the base pointer of the literals
394387
*/
395-
static inline bool __attr_always_inline___
396-
ecma_load_literals_from_buffer (const uint16_t *buffer_p, /**< buffer with literal table in snapshot */
397-
uint32_t lit_table_size, /**< size of literal table in snapshot */
398-
lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */
399-
uint32_t string_count, /**< number of strings */
400-
uint32_t number_count) /**< number of numbers */
388+
const uint8_t *
389+
ecma_snapshot_get_literals_base (uint32_t *buffer_p, /**< literal buffer start */
390+
const uint8_t **number_base_p) /**< [out] literal number start */
401391
{
402-
/* The zero value is reserved for NULL (no literal)
403-
* constant so the first literal must have offset one. */
404-
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
405-
406-
/* Load strings first. */
407-
while (string_count > 0)
408-
{
409-
if (lit_table_size < literal_offset + sizeof (uint32_t))
410-
{
411-
/* Buffer is not sufficent. */
412-
return false;
413-
}
414-
415-
lit_utf8_size_t length = *buffer_p;
416-
lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
417-
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
392+
*number_base_p = ((uint8_t *) buffer_p) + buffer_p[0];
418393

419-
if (lit_table_size < literal_offset + aligned_length)
420-
{
421-
/* Buffer is not sufficent. */
422-
return false;
423-
}
424-
425-
map_p->literal_id = ecma_find_or_create_literal_string (((lit_utf8_byte_t *) buffer_p) + sizeof (uint16_t), length);
426-
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
427-
map_p++;
428-
429-
JERRY_ASSERT ((aligned_length % sizeof (uint16_t)) == 0);
430-
buffer_p += aligned_length / sizeof (uint16_t);
431-
literal_offset += aligned_length;
432-
433-
string_count--;
434-
}
435-
436-
/* Load numbers. */
437-
while (number_count > 0)
438-
{
439-
if (lit_table_size < literal_offset + sizeof (ecma_number_t))
440-
{
441-
/* Buffer is not sufficent. */
442-
return false;
443-
}
444-
445-
ecma_number_t num;
446-
memcpy (&num, buffer_p, sizeof (ecma_number_t));
447-
448-
map_p->literal_id = ecma_find_or_create_literal_number (num);
449-
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
450-
map_p++;
451-
452-
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
453-
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
454-
455-
JERRY_ASSERT ((length % sizeof (uint16_t)) == 0);
456-
buffer_p += length / sizeof (uint16_t);
457-
literal_offset += length;
458-
459-
number_count--;
460-
}
461-
462-
return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT));
463-
} /* ecma_load_literals_from_buffer */
394+
return ((uint8_t *) (buffer_p + 1)) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
395+
} /* ecma_snapshot_get_literals_base */
464396

465397
/**
466-
* Load literals from snapshot.
398+
* Get the compressed pointer of a given literal.
467399
*
468-
* @return true - if load was performed successfully (i.e. literals saved in the snapshot are consistent),
469-
* false - otherwise (i.e. snapshot is incorrect)
400+
* @return literal compressed pointer
470401
*/
471-
bool
472-
ecma_load_literals_from_snapshot (const uint32_t *buffer_p, /**< buffer with literal table in snapshot */
473-
uint32_t lit_table_size, /**< size of literal table in snapshot */
474-
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
475-
* in snapshot to identifiers
476-
* of loaded literals in literal
477-
* storage */
478-
uint32_t *out_map_len_p) /**< [out] literals number */
402+
jmem_cpointer_t
403+
ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
404+
const uint8_t *number_base_p, /**< literal number start */
405+
jmem_cpointer_t offset)
479406
{
480-
*out_map_p = NULL;
481-
482-
if (lit_table_size < 2 * sizeof (uint32_t))
407+
if (offset == 0)
483408
{
484-
/* Buffer is not sufficent. */
485-
return false;
409+
return ECMA_NULL_POINTER;
486410
}
487411

488-
uint32_t string_count = buffer_p[0];
489-
uint32_t number_count = buffer_p[1];
490-
buffer_p += 2;
412+
const uint8_t *literal_p = literal_base_p + (((size_t) offset) << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
491413

492-
uint32_t total_count = string_count + number_count;
493-
lit_mem_to_snapshot_id_map_entry_t *map_p;
494-
495-
*out_map_len_p = total_count;
496-
497-
if (total_count == 0)
414+
if (literal_p >= number_base_p)
498415
{
499-
return true;
416+
ecma_number_t num;
417+
memcpy (&num, literal_p, sizeof (ecma_number_t));
418+
return ecma_find_or_create_literal_number (num);
500419
}
501420

502-
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
503-
*out_map_p = map_p;
504-
505-
if (ecma_load_literals_from_buffer ((uint16_t *) buffer_p, lit_table_size, map_p, string_count, number_count))
506-
{
507-
return true;
508-
}
421+
uint16_t length = *(const uint16_t *) literal_p;
509422

510-
jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
511-
*out_map_p = NULL;
512-
return false;
513-
} /* ecma_load_literals_from_snapshot */
423+
return ecma_find_or_create_literal_string (literal_p + sizeof (uint16_t), length);
424+
} /* ecma_snapshot_get_literal */
514425

515426
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
516427

jerry-core/ecma/base/ecma-literal-storage.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,16 @@ jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t number_arg);
4343

4444
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
4545
bool
46-
ecma_save_literals_for_snapshot (uint32_t *, size_t, size_t *,
47-
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *);
46+
ecma_save_literals_for_snapshot (uint32_t *buffer_p, size_t buffer_size, size_t *in_out_buffer_offset_p,
47+
lit_mem_to_snapshot_id_map_entry_t **out_map_p, uint32_t *out_map_len_p);
4848
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
4949

5050
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
51-
bool
52-
ecma_load_literals_from_snapshot (const uint32_t *, uint32_t,
53-
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *);
51+
const uint8_t *
52+
ecma_snapshot_get_literals_base (uint32_t *buffer_p, const uint8_t **number_base_p);
53+
jmem_cpointer_t
54+
ecma_snapshot_get_literal (const uint8_t *literal_base_p, const uint8_t *number_base_p,
55+
jmem_cpointer_t offset);
5456
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
5557

5658
/**

0 commit comments

Comments
 (0)