General GC optimizations (#3221)
- Enable recursive GC marking with a limited recursion count (this option is configurable) - No need to decrease the reference count of the gray objects anymore - Bound function object marking is seperated into a helper function JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
committed by
Dániel Bátyai
parent
3b73562fa5
commit
48f34adea5
@@ -41,6 +41,7 @@ set(JERRY_VM_EXEC_STOP OFF CACHE BOOL "Enable VM execution st
|
||||
set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes")
|
||||
set(JERRY_GC_LIMIT "(0)" CACHE STRING "Heap usage limit to trigger garbage collection")
|
||||
set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes")
|
||||
set(JERRY_GC_MARK_LIMIT "(8)" CACHE STRING "Maximum depth of recursion during GC mark phase")
|
||||
|
||||
# Option overrides
|
||||
if(USING_MSVC)
|
||||
@@ -104,6 +105,7 @@ message(STATUS "JERRY_VM_EXEC_STOP " ${JERRY_VM_EXEC_STOP})
|
||||
message(STATUS "JERRY_GLOBAL_HEAP_SIZE " ${JERRY_GLOBAL_HEAP_SIZE})
|
||||
message(STATUS "JERRY_GC_LIMIT " ${JERRY_GC_LIMIT})
|
||||
message(STATUS "JERRY_STACK_LIMIT " ${JERRY_STACK_LIMIT})
|
||||
message(STATUS "JERRY_GC_MARK_LIMIT " ${JERRY_GC_MARK_LIMIT})
|
||||
|
||||
# Include directories
|
||||
set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
@@ -305,6 +307,9 @@ set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GLOBAL_HEAP_SIZE=${JERRY_GLOBAL_HEAP_SI
|
||||
# Maximum size of stack memory usage
|
||||
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_STACK_LIMIT=${JERRY_STACK_LIMIT})
|
||||
|
||||
# Maximum depth of recursion during GC mark phase
|
||||
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_GC_MARK_LIMIT=${JERRY_GC_MARK_LIMIT})
|
||||
|
||||
## This function is to read "config.h" for default values
|
||||
function(read_set_defines FILE PREFIX OUTPUTVAR)
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}" INPUT_FILE_CONTENTS)
|
||||
|
||||
@@ -201,6 +201,15 @@
|
||||
# define JERRY_STACK_LIMIT (0)
|
||||
#endif /* !defined (JERRY_STACK_LIMIT) */
|
||||
|
||||
/**
|
||||
* Maximum depth of recursion during GC mark phase
|
||||
*
|
||||
* Default value: 8
|
||||
*/
|
||||
#ifndef JERRY_GC_MARK_LIMIT
|
||||
# define JERRY_GC_MARK_LIMIT (8)
|
||||
#endif /* !defined (JERRY_GC_MARK_LIMIT) */
|
||||
|
||||
/**
|
||||
* Enable/Disable property lookup cache.
|
||||
*
|
||||
@@ -572,6 +581,9 @@
|
||||
#if !defined (JERRY_STACK_LIMIT) || (JERRY_STACK_LIMIT < 0)
|
||||
# error "Invalid value for 'JERRY_STACK_LIMIT' macro."
|
||||
#endif
|
||||
#if !defined (JERRY_GC_MARK_LIMIT) || (JERRY_GC_MARK_LIMIT < 0)
|
||||
# error "Invalid value for 'JERRY_GC_MARK_LIMIT' macro."
|
||||
#endif
|
||||
#if !defined (JERRY_LCACHE) \
|
||||
|| ((JERRY_LCACHE != 0) && (JERRY_LCACHE != 1))
|
||||
# error "Invalid value for 'JERRY_LCACHE' macro."
|
||||
|
||||
+101
-76
@@ -64,30 +64,42 @@ ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
|
||||
return (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE);
|
||||
return (object_p->type_flags_refs < ECMA_OBJECT_NON_VISITED);
|
||||
} /* ecma_gc_is_object_visited */
|
||||
|
||||
/**
|
||||
* Set visited flag of the object.
|
||||
* Note: This macro can be inlined for performance critical code paths
|
||||
* Mark objects as visited starting from specified object as root
|
||||
*/
|
||||
#define ECMA_GC_SET_OBJECT_VISITED(object_p) \
|
||||
do \
|
||||
{ \
|
||||
if ((object_p)->type_flags_refs < ECMA_OBJECT_REF_ONE) \
|
||||
{ \
|
||||
(object_p)->type_flags_refs |= ECMA_OBJECT_REF_ONE; \
|
||||
} \
|
||||
} while (0)
|
||||
static void ecma_gc_mark (ecma_object_t *object_p);
|
||||
|
||||
/**
|
||||
* Set visited flag of the object.
|
||||
*/
|
||||
static void JERRY_ATTR_NOINLINE
|
||||
static void
|
||||
ecma_gc_set_object_visited (ecma_object_t *object_p) /**< object */
|
||||
{
|
||||
/* Set reference counter to one if it is zero. */
|
||||
ECMA_GC_SET_OBJECT_VISITED (object_p);
|
||||
if (object_p->type_flags_refs >= ECMA_OBJECT_NON_VISITED)
|
||||
{
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
if (JERRY_CONTEXT (ecma_gc_mark_recursion_limit) != 0)
|
||||
{
|
||||
JERRY_CONTEXT (ecma_gc_mark_recursion_limit)--;
|
||||
/* Set the reference count of gray object to 0 */
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1));
|
||||
ecma_gc_mark (object_p);
|
||||
JERRY_CONTEXT (ecma_gc_mark_recursion_limit)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the reference count of the non-marked gray object to 1 */
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ((ECMA_OBJECT_REF_ONE << 1) - 1));
|
||||
JERRY_ASSERT (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE);
|
||||
}
|
||||
#else /* (JERRY_GC_MARK_LIMIT == 0) */
|
||||
/* Set the reference count of gray object to 0 */
|
||||
object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1));
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
}
|
||||
} /* ecma_gc_set_object_visited */
|
||||
|
||||
/**
|
||||
@@ -154,7 +166,7 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa
|
||||
{
|
||||
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
|
||||
|
||||
ECMA_GC_SET_OBJECT_VISITED (value_obj_p);
|
||||
ecma_gc_set_object_visited (value_obj_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -193,8 +205,49 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa
|
||||
}
|
||||
} /* ecma_gc_mark_properties */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
/**
|
||||
* Mark objects referenced by bound function object.
|
||||
*/
|
||||
static void JERRY_ATTR_NOINLINE
|
||||
ecma_gc_mark_bound_function_object (ecma_object_t *object_p) /**< bound function object */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||
|
||||
ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
ecma_object_t *target_func_obj_p;
|
||||
target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_function_p->u.bound_function.target_function);
|
||||
|
||||
ecma_gc_set_object_visited (target_func_obj_p);
|
||||
|
||||
ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
|
||||
|
||||
if (!ecma_is_value_integer_number (args_len_or_this))
|
||||
{
|
||||
if (ecma_is_value_object (args_len_or_this))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (args_len_or_this));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
|
||||
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
||||
|
||||
JERRY_ASSERT (args_length > 0);
|
||||
|
||||
for (ecma_integer_value_t i = 0; i < args_length; i++)
|
||||
{
|
||||
if (ecma_is_value_object (args_p[i]))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (args_p[i]));
|
||||
}
|
||||
}
|
||||
} /* ecma_gc_mark_bound_function_object */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
/**
|
||||
* Mark objects referenced by Promise built-in.
|
||||
*/
|
||||
@@ -315,7 +368,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
if (outer_lex_env_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp));
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp));
|
||||
}
|
||||
|
||||
if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
|
||||
@@ -332,7 +385,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
if (proto_cp != JMEM_CP_NULL)
|
||||
{
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp));
|
||||
}
|
||||
|
||||
switch (ecma_get_object_type (object_p))
|
||||
@@ -431,18 +484,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
if (ext_object_p->u.array.is_fast_mode)
|
||||
{
|
||||
if (object_p->u1.property_list_cp == JMEM_CP_NULL)
|
||||
if (object_p->u1.property_list_cp != JMEM_CP_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
|
||||
for (uint32_t i = 0; i < ext_object_p->u.array.length; i++)
|
||||
{
|
||||
if (ecma_is_value_object (values_p[i]))
|
||||
for (uint32_t i = 0; i < ext_object_p->u.array.length; i++)
|
||||
{
|
||||
ECMA_GC_SET_OBJECT_VISITED (ecma_get_object_from_value (values_p[i]));
|
||||
if (ecma_is_value_object (values_p[i]))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (values_p[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,37 +503,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
{
|
||||
ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
ecma_object_t *target_func_obj_p;
|
||||
target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_function_p->u.bound_function.target_function);
|
||||
|
||||
ecma_gc_set_object_visited (target_func_obj_p);
|
||||
|
||||
ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
|
||||
|
||||
if (!ecma_is_value_integer_number (args_len_or_this))
|
||||
{
|
||||
if (ecma_is_value_object (args_len_or_this))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (args_len_or_this));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
|
||||
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
||||
|
||||
JERRY_ASSERT (args_length > 0);
|
||||
|
||||
for (ecma_integer_value_t i = 0; i < args_length; i++)
|
||||
{
|
||||
if (ecma_is_value_object (args_p[i]))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (args_p[i]));
|
||||
}
|
||||
}
|
||||
ecma_gc_mark_bound_function_object (object_p);
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
@@ -491,7 +512,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
{
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
ECMA_GC_SET_OBJECT_VISITED (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||
ext_func_p->u.function.scope_cp));
|
||||
}
|
||||
break;
|
||||
@@ -623,7 +644,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL
|
||||
&& !ecma_gc_is_object_visited (object_p)
|
||||
&& object_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
|
||||
&& ((object_p->type_flags_refs & ECMA_OBJECT_REF_MASK) == ECMA_OBJECT_NON_VISITED));
|
||||
|
||||
bool obj_is_not_lex_env = !ecma_is_lexical_environment (object_p);
|
||||
|
||||
@@ -984,6 +1005,10 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
void
|
||||
ecma_gc_run (void)
|
||||
{
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_mark_recursion_limit) == JERRY_GC_MARK_LIMIT);
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
|
||||
JERRY_CONTEXT (ecma_gc_new_objects) = 0;
|
||||
|
||||
ecma_object_t black_list_head;
|
||||
@@ -1006,7 +1031,7 @@ ecma_gc_run (void)
|
||||
JERRY_ASSERT (obj_prev_p == NULL
|
||||
|| ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_prev_p->gc_next_cp) == obj_iter_p);
|
||||
|
||||
if (ecma_gc_is_object_visited (obj_iter_p))
|
||||
if (obj_iter_p->type_flags_refs >= ECMA_OBJECT_REF_ONE)
|
||||
{
|
||||
/* Moving the object to list of marked objects. */
|
||||
obj_prev_p->gc_next_cp = obj_next_cp;
|
||||
@@ -1016,6 +1041,7 @@ ecma_gc_run (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_iter_p->type_flags_refs |= ECMA_OBJECT_NON_VISITED;
|
||||
obj_prev_p = obj_iter_p;
|
||||
}
|
||||
|
||||
@@ -1023,7 +1049,6 @@ ecma_gc_run (void)
|
||||
}
|
||||
|
||||
black_end_p->gc_next_cp = JMEM_CP_NULL;
|
||||
ecma_object_t *const last_root_object_p = black_end_p;
|
||||
|
||||
/* Mark root objects. */
|
||||
obj_iter_cp = black_list_head.gc_next_cp;
|
||||
@@ -1039,6 +1064,10 @@ ecma_gc_run (void)
|
||||
|
||||
do
|
||||
{
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_mark_recursion_limit) == JERRY_GC_MARK_LIMIT);
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
|
||||
marked_anything_during_current_iteration = false;
|
||||
|
||||
obj_prev_p = &white_gray_list_head;
|
||||
@@ -1060,8 +1089,17 @@ ecma_gc_run (void)
|
||||
black_end_p->gc_next_cp = obj_iter_cp;
|
||||
black_end_p = obj_iter_p;
|
||||
|
||||
ecma_gc_mark (obj_iter_p);
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
if (obj_iter_p->type_flags_refs >= ECMA_OBJECT_REF_ONE)
|
||||
{
|
||||
/* Set the reference count of non-marked gray object to 0 */
|
||||
obj_iter_p->type_flags_refs = (uint16_t) (obj_iter_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1));
|
||||
ecma_gc_mark (obj_iter_p);
|
||||
marked_anything_during_current_iteration = true;
|
||||
}
|
||||
#else /* (JERRY_GC_MARK_LIMIT == 0) */
|
||||
marked_anything_during_current_iteration = true;
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1089,19 +1127,6 @@ ecma_gc_run (void)
|
||||
obj_iter_cp = obj_next_cp;
|
||||
}
|
||||
|
||||
/* Reset the reference counter of non-root black objects. */
|
||||
obj_iter_cp = last_root_object_p->gc_next_cp;
|
||||
|
||||
while (obj_iter_cp != JMEM_CP_NULL)
|
||||
{
|
||||
/* The reference counter must be 1. */
|
||||
obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp);
|
||||
ecma_deref_object (obj_iter_p);
|
||||
JERRY_ASSERT (obj_iter_p->type_flags_refs < ECMA_OBJECT_REF_ONE);
|
||||
|
||||
obj_iter_cp = obj_iter_p->gc_next_cp;
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (ecma_gc_objects_cp) = black_list_head.gc_next_cp;
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REGEXP)
|
||||
|
||||
@@ -714,14 +714,29 @@ typedef enum
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
|
||||
/**
|
||||
* Value for increasing or decreasing the object reference counter.
|
||||
* Bitshift index for an ecma-object reference count field
|
||||
*/
|
||||
#define ECMA_OBJECT_REF_ONE (1u << 6)
|
||||
#define ECMA_OBJECT_REF_SHIFT 6
|
||||
|
||||
/**
|
||||
* Maximum value of the object reference counter (1023).
|
||||
* Bitmask for an ecma-object reference count field
|
||||
*/
|
||||
#define ECMA_OBJECT_MAX_REF (0x3ffu << 6)
|
||||
#define ECMA_OBJECT_REF_MASK (((1u << 10) - 1) << ECMA_OBJECT_REF_SHIFT)
|
||||
|
||||
/**
|
||||
* Value for increasing or decreasing the object reference counter.
|
||||
*/
|
||||
#define ECMA_OBJECT_REF_ONE (1u << ECMA_OBJECT_REF_SHIFT)
|
||||
|
||||
/**
|
||||
* Represents non-visited white object
|
||||
*/
|
||||
#define ECMA_OBJECT_NON_VISITED (0x3ffu << ECMA_OBJECT_REF_SHIFT)
|
||||
|
||||
/**
|
||||
* Maximum value of the object reference counter (1022).
|
||||
*/
|
||||
#define ECMA_OBJECT_MAX_REF (ECMA_OBJECT_NON_VISITED - ECMA_OBJECT_REF_ONE)
|
||||
|
||||
/**
|
||||
* Description of ECMA-object or lexical environment
|
||||
@@ -733,7 +748,7 @@ typedef struct
|
||||
depending on ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
|
||||
flags : 2 bit : ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV,
|
||||
ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_NON_CLOSURE
|
||||
refs : 10 bit (max 1023) */
|
||||
refs : 10 bit (max 1022) */
|
||||
uint16_t type_flags_refs;
|
||||
|
||||
/** next in the object chain maintained by the garbage collector */
|
||||
|
||||
@@ -54,8 +54,8 @@ JERRY_STATIC_ASSERT (ECMA_OBJECT_FLAG_EXTENSIBLE == (ECMA_OBJECT_FLAG_BUILT_IN_O
|
||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1),
|
||||
ecma_object_ref_one_must_follow_the_extensible_flag);
|
||||
|
||||
JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX,
|
||||
ecma_object_max_ref_does_not_fill_the_remaining_bits);
|
||||
JERRY_STATIC_ASSERT (((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX,
|
||||
ecma_object_max_ref_does_not_fill_the_remaining_bits);
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT),
|
||||
ecma_property_type_deleted_must_have_magic_string_name_type);
|
||||
|
||||
@@ -47,6 +47,10 @@ ecma_init (void)
|
||||
JERRY_CONTEXT (stack_base) = (uintptr_t)&sp;
|
||||
#endif /* (JERRY_STACK_LIMIT != 0) */
|
||||
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
JERRY_CONTEXT (ecma_gc_mark_recursion_limit) = JERRY_GC_MARK_LIMIT;
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
|
||||
ecma_job_queue_init ();
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
|
||||
|
||||
@@ -159,6 +159,9 @@ struct jerry_context_t
|
||||
uint32_t lit_magic_string_ex_count; /**< external magic strings count */
|
||||
uint32_t jerry_init_flags; /**< run-time configuration flags */
|
||||
uint32_t status_flags; /**< run-time flags (the top 8 bits are used for passing class parsing options) */
|
||||
#if (JERRY_GC_MARK_LIMIT != 0)
|
||||
uint32_t ecma_gc_mark_recursion_limit; /**< GC mark recursion limit */
|
||||
#endif /* (JERRY_GC_MARK_LIMIT != 0) */
|
||||
|
||||
#if ENABLED (JERRY_PROPRETY_HASHMAP)
|
||||
uint8_t ecma_prop_hashmap_alloc_state; /**< property hashmap allocation state: 0-4,
|
||||
|
||||
Reference in New Issue
Block a user