From fca6f1720d44e5973e101d132bc4fcebd128320a Mon Sep 17 00:00:00 2001 From: "Tobias S. Josefowitz" <tobij@tobij.de> Date: Sat, 22 Jun 2019 23:42:10 +0200 Subject: [PATCH] ADT.List: Do not put struct pike_list_structs into the GC Backport from Pike master. Fixes Pike.count_memory() getting stuck in a loop on ADT.List. NB: The comments about inline markers below are not relevant to Pike 8.0. Original commit message from Pike master follows: Since the GC was changed to use inline markers, all items fed into the GC must comply with a certain memory layout - containing GC_MARKER_MEMBERS at the beginning of their region. struct pike_list_struct does not, and cannot easily be made to because struct List_struct (storage of ADT.List) and struct pike_list_struct need to stay compatible because the former is used to store sentinels being used as the latter type. While we lose reporting from the GC about issues in ADT.List's inner structure, GC checking of struct pike_list_structs seems to not be functionally required. On the upside, the GC no longer writes beyond or into struct pike_list_structs which did not reserve the memory areas for use by the GC. --- src/builtin.cmod | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/builtin.cmod b/src/builtin.cmod index 3033f1ac49..73b6b130cc 100644 --- a/src/builtin.cmod +++ b/src/builtin.cmod @@ -5233,38 +5233,16 @@ PIKECLASS List } } - /* These two functions perform the same thing, - * but are optimized to minimize recursion. - */ - static void gc_check_list_node_backward(struct pike_list_node *node, - const char *msg); - static void gc_check_list_node_forward(struct pike_list_node *node, - const char *msg) - { - while (node && !debug_gc_check(&node->refs, msg)) { - if (node->next) - debug_gc_check_svalues(&node->val, 1, " as a list node value"); - gc_check_list_node_backward(node->prev, msg); - node = node->next; - } - } - - static void gc_check_list_node_backward(struct pike_list_node *node, - const char *msg) - { - while (node && !debug_gc_check(&node->refs, msg)) { - if (node->prev) - debug_gc_check_svalues(&node->val, 1, " as a list node value"); - gc_check_list_node_forward(node->next, msg); - node = node->prev; - } - } - /* Called at gc_check time. */ GC_CHECK { - gc_check_list_node_backward(HEAD_SENTINEL(THIS), " as a list node"); - gc_check_list_node_forward(TAIL_SENTINEL(THIS), " as a list node"); + struct pike_list_node *node = THIS->head; + struct pike_list_node *next; + + while ((next = node->next)) { + debug_gc_check_svalues(&node->val, 1, "as a list node value"); + node = next; + } } /* Called at gc_mark time */ @@ -5613,12 +5591,6 @@ PIKECLASS List } } - /* Called at gc_check time. */ - GC_CHECK - { - gc_check_list_node_forward(THIS->cur, " held by an iterator"); - } - /* These two functions perform the same thing, * but are optimized to minimize recursion. */ -- GitLab