mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Improve garbage collection of scripts and modules (#4722)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
d4178ae386
commit
d69fe41085
@ -417,6 +417,30 @@ ecma_gc_mark_properties (ecma_object_t *object_p, /**< object */
|
||||
}
|
||||
} /* ecma_gc_mark_properties */
|
||||
|
||||
/**
|
||||
* Mark compiled code.
|
||||
*/
|
||||
static void
|
||||
ecma_gc_mark_compiled_code (const ecma_compiled_code_t *compiled_code_p) /**< compiled code */
|
||||
{
|
||||
JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
|
||||
|
||||
ecma_value_t script_value = ((cbc_uint8_arguments_t *) compiled_code_p)->script_value;
|
||||
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
|
||||
|
||||
if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT)
|
||||
{
|
||||
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value));
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value));
|
||||
}
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
ecma_gc_set_object_visited (script_p->realm_p);
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
} /* ecma_gc_mark_compiled_code */
|
||||
|
||||
/**
|
||||
* Mark objects referenced by bound function object.
|
||||
*/
|
||||
@ -871,6 +895,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
ecma_gc_mark_arguments_object (ext_object_p);
|
||||
break;
|
||||
}
|
||||
#if JERRY_PARSER
|
||||
case ECMA_OBJECT_CLASS_SCRIPT:
|
||||
{
|
||||
const ecma_compiled_code_t *compiled_code_p;
|
||||
compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||
ext_object_p->u.cls.u3.value);
|
||||
ecma_gc_mark_compiled_code (compiled_code_p);
|
||||
break;
|
||||
}
|
||||
#endif /* JERRY_PARSER */
|
||||
#if JERRY_BUILTIN_TYPEDARRAY
|
||||
case ECMA_OBJECT_CLASS_TYPEDARRAY:
|
||||
{
|
||||
@ -903,6 +937,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->namespace_object_p);
|
||||
}
|
||||
|
||||
if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE)
|
||||
&& module_p->u.compiled_code_p != NULL)
|
||||
{
|
||||
ecma_gc_mark_compiled_code (module_p->u.compiled_code_p);
|
||||
}
|
||||
|
||||
ecma_module_node_t *node_p = module_p->imports_p;
|
||||
|
||||
while (node_p != NULL)
|
||||
@ -1095,20 +1135,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
}
|
||||
#endif /* JERRY_SNAPSHOT_EXEC */
|
||||
|
||||
ecma_value_t script_value = ((cbc_uint8_arguments_t *) byte_code_p)->script_value;
|
||||
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
|
||||
|
||||
if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT)
|
||||
{
|
||||
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value));
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value));
|
||||
}
|
||||
|
||||
#if JERRY_BUILTIN_REALMS
|
||||
ecma_gc_set_object_visited (script_p->realm_p);
|
||||
#endif /* JERRY_BUILTIN_REALMS */
|
||||
ecma_gc_mark_compiled_code (byte_code_p);
|
||||
break;
|
||||
}
|
||||
#if JERRY_ESNEXT || JERRY_BUILTIN_REALMS
|
||||
|
||||
@ -77,12 +77,15 @@ module_import_callback (const jerry_value_t specifier, /* string value */
|
||||
{
|
||||
TEST_ASSERT (user_p == (void *) &mode);
|
||||
|
||||
jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL,
|
||||
user_value,
|
||||
global_user_value);
|
||||
if (mode != 3)
|
||||
{
|
||||
jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL,
|
||||
user_value,
|
||||
global_user_value);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_true (compare_value));
|
||||
jerry_release_value (compare_value);
|
||||
TEST_ASSERT (jerry_value_is_true (compare_value));
|
||||
jerry_release_value (compare_value);
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
@ -107,9 +110,21 @@ module_import_callback (const jerry_value_t specifier, /* string value */
|
||||
jerry_release_value (object_value);
|
||||
return promise_value;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
compare_specifier (specifier, 28);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_object (user_value));
|
||||
jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1");
|
||||
jerry_value_t result = jerry_get_property (user_value, property_name);
|
||||
TEST_ASSERT (jerry_value_is_number (result) && jerry_get_number_value (result) == 3.5);
|
||||
jerry_release_value (result);
|
||||
jerry_release_value (property_name);
|
||||
return jerry_create_undefined ();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT (mode == 3 || mode == 4);
|
||||
TEST_ASSERT (mode == 4 || mode == 5);
|
||||
|
||||
jerry_parse_options_t parse_options;
|
||||
parse_options.options = JERRY_PARSE_MODULE;
|
||||
@ -121,7 +136,7 @@ module_import_callback (const jerry_value_t specifier, /* string value */
|
||||
TEST_ASSERT (!jerry_value_is_error (result_value));
|
||||
jerry_release_value (result_value);
|
||||
|
||||
if (mode == 3)
|
||||
if (mode == 4)
|
||||
{
|
||||
result_value = jerry_module_evaluate (parse_result_value);
|
||||
TEST_ASSERT (!jerry_value_is_error (result_value));
|
||||
@ -133,13 +148,20 @@ module_import_callback (const jerry_value_t specifier, /* string value */
|
||||
|
||||
static void
|
||||
run_script (const char *source_p, /* source code */
|
||||
jerry_parse_options_t *parse_options_p) /* parse options */
|
||||
jerry_parse_options_t *parse_options_p, /* parse options */
|
||||
bool release_user_value) /* release user value */
|
||||
{
|
||||
jerry_value_t parse_result_value;
|
||||
|
||||
parse_result_value = jerry_parse ((const jerry_char_t *) source_p, strlen (source_p), parse_options_p);
|
||||
TEST_ASSERT (!jerry_value_is_error (parse_result_value));
|
||||
|
||||
if (release_user_value)
|
||||
{
|
||||
jerry_release_value (parse_options_p->user_value);
|
||||
jerry_gc (JERRY_GC_PRESSURE_HIGH);
|
||||
}
|
||||
|
||||
jerry_value_t result_value;
|
||||
if (parse_options_p->options & JERRY_PARSE_MODULE)
|
||||
{
|
||||
@ -184,11 +206,11 @@ main (void)
|
||||
|
||||
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES))
|
||||
{
|
||||
run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options);
|
||||
run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
run_script ("var expected_message = ''", &parse_options);
|
||||
run_script ("var expected_message = ''", &parse_options, false);
|
||||
}
|
||||
|
||||
global_user_value = jerry_create_object ();
|
||||
@ -203,7 +225,7 @@ main (void)
|
||||
mode = 0;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
|
||||
parse_options.user_value = global_user_value;
|
||||
run_script (source_p, &parse_options);
|
||||
run_script (source_p, &parse_options, false);
|
||||
jerry_release_value (global_user_value);
|
||||
|
||||
global_user_value = jerry_create_null ();
|
||||
@ -219,7 +241,7 @@ main (void)
|
||||
mode = 1;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
|
||||
parse_options.user_value = global_user_value;
|
||||
run_script (source_p, &parse_options);
|
||||
run_script (source_p, &parse_options, false);
|
||||
jerry_release_value (global_user_value);
|
||||
|
||||
global_user_value = jerry_create_number (5.6);
|
||||
@ -236,7 +258,7 @@ main (void)
|
||||
mode = 2;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
|
||||
parse_options.user_value = global_user_value;
|
||||
run_script (source_p, &parse_options);
|
||||
run_script (source_p, &parse_options, false);
|
||||
jerry_release_value (global_user_value);
|
||||
|
||||
global_user_value = jerry_create_string ((const jerry_char_t *) "Any string...");
|
||||
@ -249,10 +271,27 @@ main (void)
|
||||
"}\n"
|
||||
"f()\n");
|
||||
|
||||
mode = 3;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
mode = 3;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | (i == 1 ? JERRY_PARSE_MODULE : 0);
|
||||
parse_options.user_value = jerry_create_object ();
|
||||
jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1");
|
||||
jerry_value_t property_value = jerry_create_number (3.5);
|
||||
jerry_value_t result = jerry_set_property (parse_options.user_value, property_name, property_value);
|
||||
TEST_ASSERT (jerry_value_is_true (result));
|
||||
jerry_release_value (result);
|
||||
jerry_release_value (property_value);
|
||||
jerry_release_value (property_name);
|
||||
|
||||
source_p = TEST_STRING_LITERAL ("import('28_module.mjs')");
|
||||
run_script (source_p, &parse_options, true);
|
||||
}
|
||||
|
||||
mode = 4;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
|
||||
parse_options.user_value = global_user_value;
|
||||
run_script (source_p, &parse_options);
|
||||
run_script (source_p, &parse_options, false);
|
||||
jerry_release_value (global_user_value);
|
||||
|
||||
global_user_value = jerry_create_external_function (global_assert);
|
||||
@ -268,10 +307,10 @@ main (void)
|
||||
"}\n"
|
||||
"f()\n");
|
||||
|
||||
mode = 4;
|
||||
mode = 5;
|
||||
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
|
||||
parse_options.user_value = global_user_value;
|
||||
run_script (source_p, &parse_options);
|
||||
run_script (source_p, &parse_options, false);
|
||||
jerry_release_value (global_user_value);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user