From 6221b670d10e3eacfb7f9220c062ba289ad25377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20B=C3=A1tyai?= Date: Wed, 11 Sep 2019 10:54:03 +0200 Subject: [PATCH] Keep GC object list in the order of traversal (#3087) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By appending to the end of the black object list during garbage collection, the resulting object list will be sorted in the order of traversal. This allows subsequent gc runs to mark surviving sub-trees in a single iteration. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu --- jerry-core/ecma/base/ecma-gc.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index bdf42a020..28f07ed6d 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -970,9 +970,12 @@ ecma_gc_run (void) { JERRY_CONTEXT (ecma_gc_new_objects) = 0; + ecma_object_t black_list_head; + black_list_head.gc_next_cp = JMEM_CP_NULL; + ecma_object_t *black_end_p = &black_list_head; + ecma_object_t white_gray_list_head; white_gray_list_head.gc_next_cp = JERRY_CONTEXT (ecma_gc_objects_cp); - jmem_cpointer_t black_objects_cp = JMEM_CP_NULL; ecma_object_t *obj_prev_p = &white_gray_list_head; jmem_cpointer_t obj_iter_cp = obj_prev_p->gc_next_cp; @@ -992,8 +995,8 @@ ecma_gc_run (void) /* Moving the object to list of marked objects. */ obj_prev_p->gc_next_cp = obj_next_cp; - obj_iter_p->gc_next_cp = black_objects_cp; - black_objects_cp = obj_iter_cp; + black_end_p->gc_next_cp = obj_iter_cp; + black_end_p = obj_iter_p; } else { @@ -1003,10 +1006,11 @@ ecma_gc_run (void) obj_iter_cp = obj_next_cp; } - jmem_cpointer_t first_root_object_cp = black_objects_cp; + 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 = first_root_object_cp; + obj_iter_cp = black_list_head.gc_next_cp; while (obj_iter_cp != JMEM_CP_NULL) { obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); @@ -1037,8 +1041,8 @@ ecma_gc_run (void) /* Moving the object to list of marked objects */ obj_prev_p->gc_next_cp = obj_next_cp; - obj_iter_p->gc_next_cp = black_objects_cp; - black_objects_cp = obj_iter_cp; + black_end_p->gc_next_cp = obj_iter_cp; + black_end_p = obj_iter_p; ecma_gc_mark (obj_iter_p); marked_anything_during_current_iteration = true; @@ -1053,13 +1057,15 @@ ecma_gc_run (void) } while (marked_anything_during_current_iteration); + black_end_p->gc_next_cp = JMEM_CP_NULL; + /* Sweep objects that are currently unmarked. */ obj_iter_cp = white_gray_list_head.gc_next_cp; while (obj_iter_cp != JMEM_CP_NULL) { obj_iter_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_object_t, obj_iter_cp); - jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp; + const jmem_cpointer_t obj_next_cp = obj_iter_p->gc_next_cp; JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p)); @@ -1068,10 +1074,9 @@ ecma_gc_run (void) } /* Reset the reference counter of non-root black objects. */ - obj_iter_cp = black_objects_cp; - JERRY_CONTEXT (ecma_gc_objects_cp) = black_objects_cp; + obj_iter_cp = last_root_object_p->gc_next_cp; - while (obj_iter_cp != first_root_object_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); @@ -1081,6 +1086,8 @@ ecma_gc_run (void) 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) /* Free RegExp bytecodes stored in cache */ re_cache_gc_run ();