Branch: Tag:

2019-11-15

2019-11-15 14:46:34 by Tobias S. Josefowitz <tobij@tobij.de>

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.

5233:    }    }    -  /* 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) +  /* Called at gc_check time. */ +  GC_CHECK    { -  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; -  } -  } +  struct pike_list_node *node = THIS->head; +  struct pike_list_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; +  while ((next = node->next)) { +  debug_gc_check_svalues(&node->val, 1, "as a list node value"); +  node = next;    }    }    -  /* 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"); -  } -  +     /* Called at gc_mark time */    GC_RECURSE    {
5613:    }    }    -  /* 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.    */