summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Katzman <dougk@google.com>2023-03-26 13:01:20 -0400
committerDouglas Katzman <dougk@google.com>2023-03-26 13:04:40 -0400
commitd6dbe3db853dc3bb34dff0300a207070f5e171b5 (patch)
tree680a21aaabdab184b60cacef3c0d617c062bc71d
parente51406d9f5a0ab663173356eeabbfaf34265e864 (diff)
Clobber thread local storage in save-lisp-and-die
-rw-r--r--src/runtime/gencgc.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c
index 5dba2c508..f086effcb 100644
--- a/src/runtime/gencgc.c
+++ b/src/runtime/gencgc.c
@@ -5630,6 +5630,19 @@ gc_and_save(char *filename, boolean prepend_runtime, boolean purify,
prepare_immobile_space_for_final_gc(); // once is enough
prepare_dynamic_space_for_final_gc();
unwind_binding_stack();
+#ifdef LISP_FEATURE_SB_THREAD
+ /* During save, if the only pointer to a heap object is from a thread, then that
+ * heap object is effectively dead, because the binding stacks and TLS of the main
+ * thread will be recreated on startup and contain no pointers.
+ * Make it as if that already happened, otherwise excess garbage may be retained
+ * (as can be seen if DEBUG_CORE_LOADING is defined).
+ * non-thread builds do not use TLS */
+ {
+ char* from = (char*)&thread->lisp_thread;
+ char* to = SymbolValue(FREE_TLS_INDEX,0) + (char*)thread;
+ memset(from, 0, to-from);
+ }
+#endif
save_lisp_gc_iteration = 1;
gencgc_alloc_start_page = next_free_page;
collect_garbage(0);