From 8d723a3ac8cf068e01f1162c527e1cf3f1254f1c Mon Sep 17 00:00:00 2001
From: Rickard Green <rickard@erlang.org>
Date: Mon, 15 Jul 2019 15:44:43 +0200
Subject: Fix node container refc tests of ETS

---
 erts/emulator/beam/erl_db.c          | 15 ++++++++++++---
 erts/emulator/beam/erl_db.h          |  4 +++-
 erts/emulator/beam/erl_db_catree.c   | 28 ++++++++++++++++++++++++++++
 erts/emulator/beam/erl_db_catree.h   |  3 +++
 erts/emulator/beam/erl_db_hash.c     |  6 ++++++
 erts/emulator/beam/erl_db_hash.h     |  3 +++
 erts/emulator/beam/erl_db_tree.c     |  6 ++++++
 erts/emulator/beam/erl_db_tree.h     |  4 ++++
 erts/emulator/beam/erl_node_tables.c | 11 ++++++++++-
 9 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index d24f30f126..3c74ef493b 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -4415,7 +4415,7 @@ void db_info(fmtfn_t to, void *to_arg, int show)    /* Called by break handler *
     pdbi.to_arg = to_arg;
     pdbi.show = show;
 
-    erts_db_foreach_table(db_info_print, &pdbi);
+    erts_db_foreach_table(db_info_print, &pdbi, !0);
 }
 
 Uint
@@ -4428,7 +4428,7 @@ erts_get_ets_misc_mem_size(void)
 
 /* SMP Note: May only be used when system is locked */
 void
-erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg)
+erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg, int alive_only)
 {
     int ix;
 
@@ -4440,7 +4440,7 @@ erts_db_foreach_table(void (*func)(DbTable *, void *), void *arg)
         if (first) {
             DbTable *tb = first;
             do {
-                if (is_table_alive(tb))
+                if (!alive_only || is_table_alive(tb))
                     (*func)(tb, arg);
                 tb = tb->common.all.next;
             } while (tb != first);
@@ -4457,6 +4457,15 @@ erts_db_foreach_offheap(DbTable *tb,
     tb->common.meth->db_foreach_offheap(tb, func, arg);
 }
 
+void
+erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *),
+                                 void *arg)
+{
+    erts_db_foreach_thr_prgr_offheap_hash(func, arg);
+    erts_db_foreach_thr_prgr_offheap_tree(func, arg);
+    erts_db_foreach_thr_prgr_offheap_catree(func, arg);
+}
+
 /* retrieve max number of ets tables */
 Uint
 erts_db_get_max_tabs()
diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h
index b3dc1b9ba3..c604744687 100644
--- a/erts/emulator/beam/erl_db.h
+++ b/erts/emulator/beam/erl_db.h
@@ -114,10 +114,12 @@ void init_db(ErtsDbSpinCount);
 int erts_db_process_exiting(Process *, ErtsProcLocks, void **);
 int erts_db_execute_free_fixation(Process*, DbFixation*);
 void db_info(fmtfn_t, void *, int);
-void erts_db_foreach_table(void (*)(DbTable *, void *), void *);
+void erts_db_foreach_table(void (*)(DbTable *, void *), void *, int);
 void erts_db_foreach_offheap(DbTable *,
 			     void (*func)(ErlOffHeap *, void *),
 			     void *);
+void erts_db_foreach_thr_prgr_offheap(void (*func)(ErlOffHeap *, void *),
+                                      void *);
 
 extern int erts_ets_rwmtx_spin_count;
 extern int user_requested_db_max_tabs; /* set in erl_init */
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c
index e0d5e44f58..454eed132d 100644
--- a/erts/emulator/beam/erl_db_catree.c
+++ b/erts/emulator/beam/erl_db_catree.c
@@ -2306,6 +2306,34 @@ void db_calc_stats_catree(DbTableCATree* tb, DbCATreeStats* stats)
     } while (depth > 0);
 }
 
+struct debug_catree_fa {
+    void (*func)(ErlOffHeap *, void *);
+    void *arg;
+};
+
+static void debug_free_route_node(void *vfap, ErtsThrPrgrVal val, void *vnp)
+{
+    DbTableCATreeNode *np = vnp;
+    if (np->u.route.key.oh) {
+        struct debug_catree_fa *fap = vfap;
+        ErlOffHeap oh;
+        ERTS_INIT_OFF_HEAP(&oh);
+        oh.first = np->u.route.key.oh;
+        (*fap->func)(&oh, fap->arg);
+    }
+}
+
+void
+erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *),
+                                        void *arg)
+{
+    struct debug_catree_fa fa;
+    fa.func = func;
+    fa.arg = arg;
+    erts_debug_later_op_foreach(do_free_route_node, debug_free_route_node, &fa);
+}
+
+
 #ifdef HARDDEBUG
 
 /*
diff --git a/erts/emulator/beam/erl_db_catree.h b/erts/emulator/beam/erl_db_catree.h
index cf3498dabb..90004c5380 100644
--- a/erts/emulator/beam/erl_db_catree.h
+++ b/erts/emulator/beam/erl_db_catree.h
@@ -132,6 +132,9 @@ typedef struct {
     Uint max_depth;
 } DbCATreeStats;
 void db_calc_stats_catree(DbTableCATree*, DbCATreeStats*);
+void
+erts_db_foreach_thr_prgr_offheap_catree(void (*func)(ErlOffHeap *, void *),
+                                        void *arg);
 
 
 #endif /* _DB_CATREE_H */
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index ceaccf7e44..4904d3fa42 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -3262,6 +3262,12 @@ Eterm erts_ets_hash_sizeof_ext_segtab(void)
     return make_small(((SIZEOF_EXT_SEGTAB(0)-1) / sizeof(UWord)) + 1);
 }
 
+void
+erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *),
+                                      void *arg)
+{
+}
+
 #ifdef ERTS_ENABLE_LOCK_COUNT
 void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable) {
     int i;
diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h
index eae5537ba4..9759d8b466 100644
--- a/erts/emulator/beam/erl_db_hash.h
+++ b/erts/emulator/beam/erl_db_hash.h
@@ -110,6 +110,9 @@ typedef struct {
 
 void db_calc_stats_hash(DbTableHash* tb, DbHashStats*);
 Eterm erts_ets_hash_sizeof_ext_segtab(void);
+void
+erts_db_foreach_thr_prgr_offheap_hash(void (*func)(ErlOffHeap *, void *),
+                                      void *arg);
 
 #ifdef ERTS_ENABLE_LOCK_COUNT
 void erts_lcnt_enable_db_hash_lock_count(DbTableHash *tb, int enable);
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index 492ea81b63..19b94b0634 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -3936,6 +3936,12 @@ static int doit_select_replace(DbTableCommon *tb, TreeDbTerm **this,
     return 1;
 }
 
+void
+erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *),
+                                      void *arg)
+{
+}
+
 #ifdef TREE_DEBUG
 static void do_dump_tree2(DbTableCommon* tb, int to, void *to_arg, int show,
 			  TreeDbTerm *t, int offset)
diff --git a/erts/emulator/beam/erl_db_tree.h b/erts/emulator/beam/erl_db_tree.h
index 54da2a6bc1..06e0005801 100644
--- a/erts/emulator/beam/erl_db_tree.h
+++ b/erts/emulator/beam/erl_db_tree.h
@@ -53,4 +53,8 @@ void db_initialize_tree(void);
 
 int db_create_tree(Process *p, DbTable *tbl);
 
+void
+erts_db_foreach_thr_prgr_offheap_tree(void (*func)(ErlOffHeap *, void *),
+                                      void *arg);
+
 #endif /* _DB_TREE_H */
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index c640253d8d..850176e1cf 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -1928,6 +1928,14 @@ insert_persistent_term(ErlOffHeap *ohp, void *arg)
                    TUPLE2(&heap[0], AM_system, AM_persistent_term));
 }
 
+static void
+insert_ets_offheap_thr_prgr(ErlOffHeap *ohp, void *arg)
+{
+    Eterm heap[3];
+    insert_offheap(ohp, ETS_REF,
+                   TUPLE2(&heap[0], AM_system, AM_ets));
+}
+
 #ifdef ERL_NODE_BOOKKEEP
 void
 erts_node_bookkeep(ErlNode *np, Eterm term, int what)
@@ -2103,7 +2111,8 @@ setup_reference_table(void)
     }
 
     /* Insert all ets tables */
-    erts_db_foreach_table(insert_ets_table, NULL);
+    erts_db_foreach_table(insert_ets_table, NULL, 0);
+    erts_db_foreach_thr_prgr_offheap(insert_ets_offheap_thr_prgr, NULL);
 
     /* Insert all bif timers */
     erts_debug_bif_timer_foreach(insert_bif_timer, NULL);
-- 
cgit v1.2.3