Support static snapshots. (#2239)

Unlike normal snapshots, no part of a static snapshot is loaded into
the RAM when executed from ROM. Static snapshots rely heavily on
external magic strings.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2018-03-19 23:46:52 +01:00
committed by yichoi
parent dde09cc4b6
commit bb84466fcf
17 changed files with 850 additions and 166 deletions
+28 -4
View File
@@ -631,10 +631,22 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
/* Function with byte-code (not a built-in function). */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (ext_func_p->u.function.bytecode_cp != ECMA_NULL_POINTER)
{
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp));
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
}
else
{
ecma_dealloc_extended_object (object_p, sizeof (ecma_static_function_t));
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp));
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
return;
}
@@ -643,12 +655,24 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
ecma_bytecode_deref (ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
arrow_func_p->bytecode_cp));
ecma_free_value_if_not_object (arrow_func_p->this_binding);
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (arrow_func_p->bytecode_cp != ECMA_NULL_POINTER)
{
ecma_bytecode_deref (ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
arrow_func_p->bytecode_cp));
ecma_dealloc_extended_object (object_p, sizeof (ecma_arrow_function_t));
}
else
{
ecma_dealloc_extended_object (object_p, sizeof (ecma_static_arrow_function_t));
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
ecma_bytecode_deref (ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
arrow_func_p->bytecode_cp));
ecma_dealloc_extended_object (object_p, sizeof (ecma_arrow_function_t));
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
return;
}
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+40 -14
View File
@@ -797,6 +797,33 @@ typedef struct
ecma_built_in_props_t built_in; /**< built-in object part */
} ecma_extended_built_in_object_t;
/**
* Compiled byte code data.
*/
typedef struct
{
uint16_t size; /**< real size >> JMEM_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;
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Description of static function objects.
*/
typedef struct
{
ecma_extended_object_t header;
const ecma_compiled_code_t *bytecode_p;
} ecma_static_function_t;
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
/**
@@ -810,6 +837,19 @@ typedef struct
jmem_cpointer_t bytecode_cp; /**< function byte code */
} ecma_arrow_function_t;
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Description of static arrow function objects.
*/
typedef struct
{
ecma_arrow_function_t header;
const ecma_compiled_code_t *bytecode_p;
} ecma_static_arrow_function_t;
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
/**
@@ -1276,20 +1316,6 @@ typedef struct
ecma_value_t value; /**< referenced value */
} ecma_error_reference_t;
/**
* Compiled byte code data.
*/
typedef struct
{
uint16_t size; /**< real size >> JMEM_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;
#ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
/**
+12
View File
@@ -311,6 +311,18 @@ ecma_is_value_string (ecma_value_t value) /**< ecma value */
return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
} /* ecma_is_value_string */
/**
* Check if the value is direct_ecma-string.
*
* @return true - if the value contains ecma-string value,
* false - otherwise
*/
inline bool __attr_const___ __attr_always_inline___
ecma_is_value_direct_string (ecma_value_t value) /**< ecma value */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
} /* ecma_is_value_direct_string */
/**
* Check if the value is object.
*
+1
View File
@@ -1487,6 +1487,7 @@ void
ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
{
JERRY_ASSERT (bytecode_p->refs > 0);
JERRY_ASSERT (!(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
bytecode_p->refs--;
+1
View File
@@ -154,6 +154,7 @@ bool ecma_are_values_integer_numbers (ecma_value_t first_value, ecma_value_t sec
bool ecma_is_value_float_number (ecma_value_t value) __attr_const___;
bool ecma_is_value_number (ecma_value_t value) __attr_const___;
bool ecma_is_value_string (ecma_value_t value) __attr_const___;
bool ecma_is_value_direct_string (ecma_value_t value) __attr_const___;
bool ecma_is_value_object (ecma_value_t value) __attr_const___;
bool ecma_is_value_error_reference (ecma_value_t value) __attr_const___;
bool ecma_is_value_collection_chunk (ecma_value_t value) __attr_const___;
+104 -16
View File
@@ -124,8 +124,17 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
/* 1., 4., 13. */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
size_t function_object_size = sizeof (ecma_extended_object_t);
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
{
function_object_size = sizeof (ecma_static_function_t);
}
#endif
ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
function_object_size,
ECMA_OBJECT_TYPE_FUNCTION);
ecma_deref_object (prototype_obj_p);
@@ -150,8 +159,22 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.scope_cp, scope_p);
/* 10., 11., 12. */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
{
ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
}
else
{
ext_func_p->u.function.bytecode_cp = ECMA_NULL_POINTER;
((ecma_static_function_t *) func_p)->bytecode_p = bytecode_data_p;
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
#endif
/* 14., 15., 16., 17., 18. */
/*
@@ -179,8 +202,17 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's sc
{
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
size_t arrow_function_object_size = sizeof (ecma_arrow_function_t);
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
{
arrow_function_object_size = sizeof (ecma_static_arrow_function_t);
}
#endif
ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_arrow_function_t),
arrow_function_object_size,
ECMA_OBJECT_TYPE_ARROW_FUNCTION);
ecma_deref_object (prototype_obj_p);
@@ -190,8 +222,21 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's sc
ECMA_SET_NON_NULL_POINTER (arrow_func_p->scope_cp, scope_p);
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
{
ECMA_SET_NON_NULL_POINTER (arrow_func_p->bytecode_cp, bytecode_data_p);
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
}
else
{
arrow_func_p->bytecode_cp = ECMA_NULL_POINTER;
((ecma_static_arrow_function_t *) func_p)->bytecode_p = bytecode_data_p;
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
ECMA_SET_NON_NULL_POINTER (arrow_func_p->bytecode_cp, bytecode_data_p);
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
#endif
arrow_func_p->this_binding = ecma_copy_value_if_not_object (this_binding);
return func_p;
@@ -232,6 +277,58 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**
return function_obj_p;
} /* ecma_op_create_external_function_object */
/**
* Get compiled code of a function object.
*
* @return compiled code
*/
inline const ecma_compiled_code_t * __attr_always_inline___
ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< function pointer */
{
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (function_p->u.function.bytecode_cp != ECMA_NULL_POINTER)
{
return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
function_p->u.function.bytecode_cp);
}
else
{
return ((ecma_static_function_t *) function_p)->bytecode_p;
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
function_p->u.function.bytecode_cp);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
} /* ecma_op_function_get_compiled_code */
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
/**
* Get compiled code of an arrow function object.
*
* @return compiled code
*/
inline const ecma_compiled_code_t * __attr_always_inline___
ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_p) /**< arrow function pointer */
{
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
if (arrow_function_p->bytecode_cp != ECMA_NULL_POINTER)
{
return ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_function_p->bytecode_cp);
}
else
{
return ((ecma_static_arrow_function_t *) arrow_function_p)->bytecode_p;
}
#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
return ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_function_p->bytecode_cp);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
} /* ecma_op_arrow_function_get_compiled_code */
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
/**
* [[Call]] implementation for Function objects,
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
@@ -357,9 +454,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
bool is_strict;
bool is_no_lex_env;
const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
@@ -428,9 +523,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
bool is_no_lex_env;
const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_func_p->bytecode_cp);
const ecma_compiled_code_t *bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
@@ -782,15 +875,13 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_func_p->bytecode_cp);
bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
}
else
{
#endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
}
#endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
@@ -961,11 +1052,8 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE),
0);
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
const ecma_compiled_code_t *bytecode_data_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
{
@@ -43,6 +43,17 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, const ecma_compile
ecma_object_t *
ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
const ecma_compiled_code_t *
ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p);
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
const ecma_compiled_code_t *
ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_p);
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
ecma_value_t
ecma_op_function_has_instance (ecma_object_t *func_obj_p, ecma_value_t value);
ecma_value_t
ecma_op_function_call (ecma_object_t *func_obj_p, ecma_value_t this_arg_value,
const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
@@ -51,9 +62,6 @@ ecma_value_t
ecma_op_function_construct (ecma_object_t *func_obj_p, const ecma_value_t *arguments_list_p,
ecma_length_t arguments_list_len);
ecma_value_t
ecma_op_function_has_instance (ecma_object_t *func_obj_p, ecma_value_t value);
ecma_property_t *
ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
+6 -12
View File
@@ -208,19 +208,16 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
if (type != ECMA_OBJECT_TYPE_ARROW_FUNCTION)
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
}
else
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_func_p->bytecode_cp);
bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
}
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
uint32_t len;
@@ -532,19 +529,16 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
if (type != ECMA_OBJECT_TYPE_ARROW_FUNCTION)
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
}
else
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
arrow_func_p->bytecode_cp);
bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
}
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp);
bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
uint32_t len;