Skip to content

Commit e289583

Browse files
committed
Improve garbage collection of scripts and modules
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent d4178ae commit e289583

File tree

2 files changed

+103
-17
lines changed

2 files changed

+103
-17
lines changed

jerry-core/ecma/base/ecma-gc.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,32 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
871871
ecma_gc_mark_arguments_object (ext_object_p);
872872
break;
873873
}
874+
#if JERRY_PARSER
875+
case ECMA_OBJECT_CLASS_SCRIPT:
876+
{
877+
ecma_compiled_code_t *compiled_code_p;
878+
compiled_code_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
879+
ext_object_p->u.cls.u3.value);
880+
881+
JERRY_ASSERT (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
882+
883+
ecma_value_t script_value = ((cbc_uint8_arguments_t *) compiled_code_p)->script_value;
884+
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
885+
886+
if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT)
887+
{
888+
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
889+
890+
JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value));
891+
ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value));
892+
}
893+
894+
#if JERRY_BUILTIN_REALMS
895+
ecma_gc_set_object_visited (script_p->realm_p);
896+
#endif /* JERRY_BUILTIN_REALMS */
897+
break;
898+
}
899+
#endif /* JERRY_PARSER */
874900
#if JERRY_BUILTIN_TYPEDARRAY
875901
case ECMA_OBJECT_CLASS_TYPEDARRAY:
876902
{
@@ -903,6 +929,27 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
903929
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->namespace_object_p);
904930
}
905931

932+
if (!(module_p->header.u.cls.u2.module_flags & ECMA_MODULE_IS_NATIVE)
933+
&& module_p->u.compiled_code_p != NULL)
934+
{
935+
JERRY_ASSERT (!(module_p->u.compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION));
936+
937+
ecma_value_t script_value = ((cbc_uint8_arguments_t *) module_p->u.compiled_code_p)->script_value;
938+
cbc_script_t *script_p = ECMA_GET_INTERNAL_VALUE_POINTER (cbc_script_t, script_value);
939+
940+
if (CBC_SCRIPT_GET_TYPE (script_p) == CBC_SCRIPT_USER_OBJECT)
941+
{
942+
cbc_script_user_t *script_user_p = (cbc_script_user_t *) script_p;
943+
944+
JERRY_ASSERT (ecma_is_value_object (script_user_p->user_value));
945+
ecma_gc_set_object_visited (ecma_get_object_from_value (script_user_p->user_value));
946+
}
947+
948+
#if JERRY_BUILTIN_REALMS
949+
ecma_gc_set_object_visited (script_p->realm_p);
950+
#endif /* JERRY_BUILTIN_REALMS */
951+
}
952+
906953
ecma_module_node_t *node_p = module_p->imports_p;
907954

908955
while (node_p != NULL)

tests/unit-core/test-module-dynamic.c

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,15 @@ module_import_callback (const jerry_value_t specifier, /* string value */
7777
{
7878
TEST_ASSERT (user_p == (void *) &mode);
7979

80-
jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL,
81-
user_value,
82-
global_user_value);
80+
if (mode != 3)
81+
{
82+
jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL,
83+
user_value,
84+
global_user_value);
8385

84-
TEST_ASSERT (jerry_value_is_true (compare_value));
85-
jerry_release_value (compare_value);
86+
TEST_ASSERT (jerry_value_is_true (compare_value));
87+
jerry_release_value (compare_value);
88+
}
8689

8790
switch (mode)
8891
{
@@ -107,9 +110,21 @@ module_import_callback (const jerry_value_t specifier, /* string value */
107110
jerry_release_value (object_value);
108111
return promise_value;
109112
}
113+
case 3:
114+
{
115+
compare_specifier (specifier, 28);
116+
117+
TEST_ASSERT (jerry_value_is_object (user_value));
118+
jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1");
119+
jerry_value_t result = jerry_get_property (user_value, property_name);
120+
TEST_ASSERT (jerry_value_is_number (result) && jerry_get_number_value (result) == 3.5);
121+
jerry_release_value (result);
122+
jerry_release_value (property_name);
123+
return jerry_create_undefined ();
124+
}
110125
}
111126

112-
TEST_ASSERT (mode == 3 || mode == 4);
127+
TEST_ASSERT (mode == 4 || mode == 5);
113128

114129
jerry_parse_options_t parse_options;
115130
parse_options.options = JERRY_PARSE_MODULE;
@@ -121,7 +136,7 @@ module_import_callback (const jerry_value_t specifier, /* string value */
121136
TEST_ASSERT (!jerry_value_is_error (result_value));
122137
jerry_release_value (result_value);
123138

124-
if (mode == 3)
139+
if (mode == 4)
125140
{
126141
result_value = jerry_module_evaluate (parse_result_value);
127142
TEST_ASSERT (!jerry_value_is_error (result_value));
@@ -133,13 +148,20 @@ module_import_callback (const jerry_value_t specifier, /* string value */
133148

134149
static void
135150
run_script (const char *source_p, /* source code */
136-
jerry_parse_options_t *parse_options_p) /* parse options */
151+
jerry_parse_options_t *parse_options_p, /* parse options */
152+
bool release_user_value) /* release user value */
137153
{
138154
jerry_value_t parse_result_value;
139155

140156
parse_result_value = jerry_parse ((const jerry_char_t *) source_p, strlen (source_p), parse_options_p);
141157
TEST_ASSERT (!jerry_value_is_error (parse_result_value));
142158

159+
if (release_user_value)
160+
{
161+
jerry_release_value (parse_options_p->user_value);
162+
jerry_gc (JERRY_GC_PRESSURE_HIGH);
163+
}
164+
143165
jerry_value_t result_value;
144166
if (parse_options_p->options & JERRY_PARSE_MODULE)
145167
{
@@ -184,11 +206,11 @@ main (void)
184206

185207
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES))
186208
{
187-
run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options);
209+
run_script ("var expected_message = 'Module cannot be instantiated'", &parse_options, false);
188210
}
189211
else
190212
{
191-
run_script ("var expected_message = ''", &parse_options);
213+
run_script ("var expected_message = ''", &parse_options, false);
192214
}
193215

194216
global_user_value = jerry_create_object ();
@@ -203,7 +225,7 @@ main (void)
203225
mode = 0;
204226
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
205227
parse_options.user_value = global_user_value;
206-
run_script (source_p, &parse_options);
228+
run_script (source_p, &parse_options, false);
207229
jerry_release_value (global_user_value);
208230

209231
global_user_value = jerry_create_null ();
@@ -219,7 +241,7 @@ main (void)
219241
mode = 1;
220242
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
221243
parse_options.user_value = global_user_value;
222-
run_script (source_p, &parse_options);
244+
run_script (source_p, &parse_options, false);
223245
jerry_release_value (global_user_value);
224246

225247
global_user_value = jerry_create_number (5.6);
@@ -236,7 +258,7 @@ main (void)
236258
mode = 2;
237259
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
238260
parse_options.user_value = global_user_value;
239-
run_script (source_p, &parse_options);
261+
run_script (source_p, &parse_options, false);
240262
jerry_release_value (global_user_value);
241263

242264
global_user_value = jerry_create_string ((const jerry_char_t *) "Any string...");
@@ -249,10 +271,27 @@ main (void)
249271
"}\n"
250272
"f()\n");
251273

252-
mode = 3;
274+
for (int i = 0; i < 2; i++)
275+
{
276+
mode = 3;
277+
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | (i == 1 ? JERRY_PARSE_MODULE : 0);
278+
parse_options.user_value = jerry_create_object ();
279+
jerry_value_t property_name = jerry_create_string ((const jerry_char_t *) "MyProp1");
280+
jerry_value_t property_value = jerry_create_number (3.5);
281+
jerry_value_t result = jerry_set_property (parse_options.user_value, property_name, property_value);
282+
TEST_ASSERT (jerry_value_is_true (result));
283+
jerry_release_value (result);
284+
jerry_release_value (property_value);
285+
jerry_release_value (property_name);
286+
287+
source_p = TEST_STRING_LITERAL ("import('28_module.mjs')");
288+
run_script (source_p, &parse_options, true);
289+
}
290+
291+
mode = 4;
253292
parse_options.options = JERRY_PARSE_HAS_USER_VALUE;
254293
parse_options.user_value = global_user_value;
255-
run_script (source_p, &parse_options);
294+
run_script (source_p, &parse_options, false);
256295
jerry_release_value (global_user_value);
257296

258297
global_user_value = jerry_create_external_function (global_assert);
@@ -268,10 +307,10 @@ main (void)
268307
"}\n"
269308
"f()\n");
270309

271-
mode = 4;
310+
mode = 5;
272311
parse_options.options = JERRY_PARSE_HAS_USER_VALUE | JERRY_PARSE_MODULE;
273312
parse_options.user_value = global_user_value;
274-
run_script (source_p, &parse_options);
313+
run_script (source_p, &parse_options, false);
275314
jerry_release_value (global_user_value);
276315

277316
jerry_cleanup ();

0 commit comments

Comments
 (0)