2424#include "ecma-helpers.h"
2525#include "ecma-lcache.h"
2626#include "ecma-property-hashmap.h"
27+ #include "jcontext.h"
2728#include "jrt.h"
2829#include "jrt-libc-includes.h"
2930#include "jrt-bit-fields.h"
4445 */
4546
4647/**
47- * An object's GC color
48+ * Current state of an object's visited flag that
49+ * indicates whether the object is in visited state:
4850 *
49- * Tri-color marking:
50- * WHITE_GRAY, unvisited -> WHITE // not referenced by a live object or the reference not found yet
51- * WHITE_GRAY, visited -> GRAY // referenced by some live object
52- * BLACK -> BLACK // all referenced objects are gray or black
53- */
54- typedef enum
55- {
56- ECMA_GC_COLOR_WHITE_GRAY , /**< white or gray */
57- ECMA_GC_COLOR_BLACK , /**< black */
58- ECMA_GC_COLOR__COUNT /**< number of colors */
59- } ecma_gc_color_t ;
60-
61- /**
62- * List of marked (visited during current GC session) and umarked objects
63- */
64- static ecma_object_t * ecma_gc_objects_lists [ECMA_GC_COLOR__COUNT ];
65-
66- /**
67- * Current state of an object's visited flag that indicates whether the object is in visited state:
6851 * visited_field | visited_flip_flag | real_value
6952 * false | false | false
7053 * false | true | true
7154 * true | false | true
7255 * true | true | false
7356 */
74- static bool ecma_gc_visited_flip_flag = false;
75-
76- /**
77- * Number of currently allocated objects
78- */
79- static size_t ecma_gc_objects_number = 0 ;
80-
81- /**
82- * Number of newly allocated objects since last GC session
83- */
84- static size_t ecma_gc_new_objects_since_last_gc = 0 ;
8557
8658static void ecma_gc_mark (ecma_object_t * object_p );
8759static void ecma_gc_sweep (ecma_object_t * object_p );
@@ -119,7 +91,7 @@ ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
11991
12092 bool flag_value = (object_p -> type_flags_refs & ECMA_OBJECT_FLAG_GC_VISITED ) != 0 ;
12193
122- return flag_value != ecma_gc_visited_flip_flag ;
94+ return flag_value != JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) ;
12395} /* ecma_gc_is_object_visited */
12496
12597/**
@@ -131,7 +103,7 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */
131103{
132104 JERRY_ASSERT (object_p != NULL );
133105
134- if (is_visited != ecma_gc_visited_flip_flag )
106+ if (is_visited != JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) )
135107 {
136108 object_p -> type_flags_refs = (uint16_t ) (object_p -> type_flags_refs | ECMA_OBJECT_FLAG_GC_VISITED );
137109 }
@@ -147,16 +119,16 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */
147119inline void
148120ecma_init_gc_info (ecma_object_t * object_p ) /**< object */
149121{
150- ecma_gc_objects_number ++ ;
151- ecma_gc_new_objects_since_last_gc ++ ;
122+ JERRY_CONTEXT ( ecma_gc_objects_number ) ++ ;
123+ JERRY_CONTEXT ( ecma_gc_new_objects ) ++ ;
152124
153- JERRY_ASSERT (ecma_gc_new_objects_since_last_gc <= ecma_gc_objects_number );
125+ JERRY_ASSERT (JERRY_CONTEXT ( ecma_gc_new_objects ) <= JERRY_CONTEXT ( ecma_gc_objects_number ) );
154126
155127 JERRY_ASSERT (object_p -> type_flags_refs < ECMA_OBJECT_REF_ONE );
156128 object_p -> type_flags_refs = (uint16_t ) (object_p -> type_flags_refs | ECMA_OBJECT_REF_ONE );
157129
158- ecma_gc_set_object_next (object_p , ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]);
159- ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ] = object_p ;
130+ ecma_gc_set_object_next (object_p , JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) );
131+ JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) = object_p ;
160132
161133 /* Should be set to false at the beginning of garbage collection */
162134 ecma_gc_set_object_visited (object_p , false);
@@ -194,11 +166,11 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
194166void
195167ecma_gc_init (void )
196168{
197- ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ] = NULL ;
198- ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ] = NULL ;
199- ecma_gc_visited_flip_flag = false;
200- ecma_gc_objects_number = 0 ;
201- ecma_gc_new_objects_since_last_gc = 0 ;
169+ JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) = NULL ;
170+ JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) = NULL ;
171+ JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) = false;
172+ JERRY_CONTEXT ( ecma_gc_objects_number ) = 0 ;
173+ JERRY_CONTEXT ( ecma_gc_new_objects ) = 0 ;
202174} /* ecma_gc_init */
203175
204176/**
@@ -474,8 +446,8 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
474446 }
475447 }
476448
477- JERRY_ASSERT (ecma_gc_objects_number > 0 );
478- ecma_gc_objects_number -- ;
449+ JERRY_ASSERT (JERRY_CONTEXT ( ecma_gc_objects_number ) > 0 );
450+ JERRY_CONTEXT ( ecma_gc_objects_number ) -- ;
479451
480452 if (!ecma_is_lexical_environment (object_p ))
481453 {
@@ -508,12 +480,12 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
508480void
509481ecma_gc_run (void )
510482{
511- ecma_gc_new_objects_since_last_gc = 0 ;
483+ JERRY_CONTEXT ( ecma_gc_new_objects ) = 0 ;
512484
513- JERRY_ASSERT (ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ] == NULL );
485+ JERRY_ASSERT (JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) == NULL );
514486
515487 /* if some object is referenced from stack or globals (i.e. it is root), mark it */
516- for (ecma_object_t * obj_iter_p = ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ];
488+ for (ecma_object_t * obj_iter_p = JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) ;
517489 obj_iter_p != NULL ;
518490 obj_iter_p = ecma_gc_get_object_next (obj_iter_p ))
519491 {
@@ -531,17 +503,18 @@ ecma_gc_run (void)
531503 {
532504 marked_anything_during_current_iteration = false;
533505
534- for (ecma_object_t * obj_iter_p = ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ], * obj_prev_p = NULL , * obj_next_p ;
535- obj_iter_p != NULL ;
536- obj_iter_p = obj_next_p )
506+ ecma_object_t * obj_prev_p = NULL ;
507+ ecma_object_t * obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]);
508+
509+ while (obj_iter_p != NULL )
537510 {
538- obj_next_p = ecma_gc_get_object_next (obj_iter_p );
511+ ecma_object_t * obj_next_p = ecma_gc_get_object_next (obj_iter_p );
539512
540513 if (ecma_gc_is_object_visited (obj_iter_p ))
541514 {
542515 /* Moving the object to list of marked objects */
543- ecma_gc_set_object_next (obj_iter_p , ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]);
544- ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ] = obj_iter_p ;
516+ ecma_gc_set_object_next (obj_iter_p , JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) );
517+ JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) = obj_iter_p ;
545518
546519 if (likely (obj_prev_p != NULL ))
547520 {
@@ -551,7 +524,7 @@ ecma_gc_run (void)
551524 }
552525 else
553526 {
554- ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ] = obj_next_p ;
527+ JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) = obj_next_p ;
555528 }
556529
557530 ecma_gc_mark (obj_iter_p );
@@ -561,27 +534,31 @@ ecma_gc_run (void)
561534 {
562535 obj_prev_p = obj_iter_p ;
563536 }
537+
538+ obj_iter_p = obj_next_p ;
564539 }
565540 }
566541 while (marked_anything_during_current_iteration );
567542
568543 /* Sweeping objects that are currently unmarked */
569- for ( ecma_object_t * obj_iter_p = ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ], * obj_next_p ;
570- obj_iter_p != NULL ;
571- obj_iter_p = obj_next_p )
544+ ecma_object_t * obj_iter_p = JERRY_CONTEXT ( ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) ;
545+
546+ while ( obj_iter_p != NULL )
572547 {
573- obj_next_p = ecma_gc_get_object_next (obj_iter_p );
548+ ecma_object_t * obj_next_p = ecma_gc_get_object_next (obj_iter_p );
574549
575550 JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p ));
576551
577552 ecma_gc_sweep (obj_iter_p );
553+ obj_iter_p = obj_next_p ;
578554 }
579555
580556 /* Unmarking all objects */
581- ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ] = ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ];
582- ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ] = NULL ;
557+ ecma_object_t * black_objects = JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]);
558+ JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) = black_objects ;
559+ JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) = NULL ;
583560
584- ecma_gc_visited_flip_flag = !ecma_gc_visited_flip_flag ;
561+ JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) = !JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) ;
585562
586563#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
587564 /* Free RegExp bytecodes stored in cache */
@@ -601,7 +578,9 @@ ecma_free_unused_memory (jmem_free_unused_memory_severity_t severity) /**< sever
601578 * If there is enough newly allocated objects since last GC, probably it is worthwhile to start GC now.
602579 * Otherwise, probability to free sufficient space is considered to be low.
603580 */
604- if (ecma_gc_new_objects_since_last_gc * CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC > ecma_gc_objects_number )
581+ size_t new_objects_share = CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC ;
582+
583+ if (JERRY_CONTEXT (ecma_gc_new_objects ) * new_objects_share > JERRY_CONTEXT (ecma_gc_objects_number ))
605584 {
606585 ecma_gc_run ();
607586 }
0 commit comments