24
24
#include "ecma-helpers.h"
25
25
#include "ecma-lcache.h"
26
26
#include "ecma-property-hashmap.h"
27
+ #include "jcontext.h"
27
28
#include "jrt.h"
28
29
#include "jrt-libc-includes.h"
29
30
#include "jrt-bit-fields.h"
44
45
*/
45
46
46
47
/**
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:
48
50
*
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:
68
51
* visited_field | visited_flip_flag | real_value
69
52
* false | false | false
70
53
* false | true | true
71
54
* true | false | true
72
55
* true | true | false
73
56
*/
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 ;
85
57
86
58
static void ecma_gc_mark (ecma_object_t * object_p );
87
59
static void ecma_gc_sweep (ecma_object_t * object_p );
@@ -119,7 +91,7 @@ ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
119
91
120
92
bool flag_value = (object_p -> type_flags_refs & ECMA_OBJECT_FLAG_GC_VISITED ) != 0 ;
121
93
122
- return flag_value != ecma_gc_visited_flip_flag ;
94
+ return flag_value != JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) ;
123
95
} /* ecma_gc_is_object_visited */
124
96
125
97
/**
@@ -131,7 +103,7 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */
131
103
{
132
104
JERRY_ASSERT (object_p != NULL );
133
105
134
- if (is_visited != ecma_gc_visited_flip_flag )
106
+ if (is_visited != JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) )
135
107
{
136
108
object_p -> type_flags_refs = (uint16_t ) (object_p -> type_flags_refs | ECMA_OBJECT_FLAG_GC_VISITED );
137
109
}
@@ -147,16 +119,16 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */
147
119
inline void
148
120
ecma_init_gc_info (ecma_object_t * object_p ) /**< object */
149
121
{
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 ) ++ ;
152
124
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 ) );
154
126
155
127
JERRY_ASSERT (object_p -> type_flags_refs < ECMA_OBJECT_REF_ONE );
156
128
object_p -> type_flags_refs = (uint16_t ) (object_p -> type_flags_refs | ECMA_OBJECT_REF_ONE );
157
129
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 ;
160
132
161
133
/* Should be set to false at the beginning of garbage collection */
162
134
ecma_gc_set_object_visited (object_p , false);
@@ -194,11 +166,11 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */
194
166
void
195
167
ecma_gc_init (void )
196
168
{
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 ;
202
174
} /* ecma_gc_init */
203
175
204
176
/**
@@ -474,8 +446,8 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
474
446
}
475
447
}
476
448
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 ) -- ;
479
451
480
452
if (!ecma_is_lexical_environment (object_p ))
481
453
{
@@ -508,12 +480,12 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
508
480
void
509
481
ecma_gc_run (jmem_free_unused_memory_severity_t severity ) /**< gc severity */
510
482
{
511
- ecma_gc_new_objects_since_last_gc = 0 ;
483
+ JERRY_CONTEXT ( ecma_gc_new_objects ) = 0 ;
512
484
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 );
514
486
515
487
/* 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 ]) ;
517
489
obj_iter_p != NULL ;
518
490
obj_iter_p = ecma_gc_get_object_next (obj_iter_p ))
519
491
{
@@ -531,17 +503,18 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
531
503
{
532
504
marked_anything_during_current_iteration = false;
533
505
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 )
537
510
{
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 );
539
512
540
513
if (ecma_gc_is_object_visited (obj_iter_p ))
541
514
{
542
515
/* 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 ;
545
518
546
519
if (likely (obj_prev_p != NULL ))
547
520
{
@@ -551,7 +524,7 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
551
524
}
552
525
else
553
526
{
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 ;
555
528
}
556
529
557
530
ecma_gc_mark (obj_iter_p );
@@ -561,20 +534,23 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
561
534
{
562
535
obj_prev_p = obj_iter_p ;
563
536
}
537
+
538
+ obj_iter_p = obj_next_p ;
564
539
}
565
540
}
566
541
while (marked_anything_during_current_iteration );
567
542
568
543
/* 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 )
572
547
{
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 );
574
549
575
550
JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p ));
576
551
577
552
ecma_gc_sweep (obj_iter_p );
553
+ obj_iter_p = obj_next_p ;
578
554
}
579
555
580
556
if (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH )
@@ -598,10 +574,11 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
598
574
}
599
575
600
576
/* Unmarking all objects */
601
- ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ] = ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ];
602
- ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ] = NULL ;
577
+ ecma_object_t * black_objects = JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]);
578
+ JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_WHITE_GRAY ]) = black_objects ;
579
+ JERRY_CONTEXT (ecma_gc_objects_lists [ECMA_GC_COLOR_BLACK ]) = NULL ;
603
580
604
- ecma_gc_visited_flip_flag = !ecma_gc_visited_flip_flag ;
581
+ JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) = !JERRY_CONTEXT ( ecma_gc_visited_flip_flag ) ;
605
582
606
583
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
607
584
/* Free RegExp bytecodes stored in cache */
@@ -621,7 +598,9 @@ ecma_free_unused_memory (jmem_free_unused_memory_severity_t severity) /**< sever
621
598
* If there is enough newly allocated objects since last GC, probably it is worthwhile to start GC now.
622
599
* Otherwise, probability to free sufficient space is considered to be low.
623
600
*/
624
- if (ecma_gc_new_objects_since_last_gc * CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC > ecma_gc_objects_number )
601
+ size_t new_objects_share = CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC ;
602
+
603
+ if (JERRY_CONTEXT (ecma_gc_new_objects ) * new_objects_share > JERRY_CONTEXT (ecma_gc_objects_number ))
625
604
{
626
605
ecma_gc_run (severity );
627
606
}
0 commit comments