APPROVE COMMIT
NOTE: This patch has been committed
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1534033852 -3600
# Sun Aug 12 01:30:52 2018 +0100
# Node ID 593de3c3ee78030276540da59f71602e7ea7e1a4
# Parent 4280f7a3c20943225b9761f20d152881fc4c3c95
Use explicit weak list objects for syntax table, specifier chains
src/ChangeLog addition:
2018-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
Use an explicit weak list object for the syntax table and
specifier chains, no need for separate code and slots in the
chartab and specifier objects.
* chartab.c:
* chartab.c (prune_syntax_tables): Removed.
* chartab.c (decode_char_table_range):
* chartab.c (make_char_table):
* chartab.c (Fcopy_char_table):
* chartab.c (vars_of_chartab):
Vall_syntax_tables is now an explicit weak list object.
* chartab.h:
* chartab.h (struct Lisp_Char_Table):
Remove the next_table chain element from this struct.
* emacs.c (main_1):
Move vars_of_data() even earlier in the startup sequence, so
Vall_weak_lists is available.
* gc.c (gc_finish_mark):
No longer call prune_specifiers(), prune_syntax_tables().
* specifier.c:
* specifier.c (cleanup_specifiers):
* specifier.c (kill_specifier_buffer_locals):
* specifier.c (make_specifier_internal):
* specifier.c (vars_of_specifier):
* specifier.h (struct Lisp_Specifier):
Remove prune_specifiers and the next_specifier element in the
struct.
* syntax.c (update_syntax_table):
Loop through the weak list list of Vall_syntax_tables, rather than
chaining through the next_table slot.
diff -r 4280f7a3c209 -r 593de3c3ee78 src/ChangeLog
--- a/src/ChangeLog Sat Aug 11 21:09:02 2018 +0100
+++ b/src/ChangeLog Sun Aug 12 01:30:52 2018 +0100
@@ -1,3 +1,35 @@
+2018-08-12 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ Use an explicit weak list object for the syntax table and
+ specifier chains, no need for separate code and slots in the
+ chartab and specifier objects.
+ * chartab.c:
+ * chartab.c (prune_syntax_tables): Removed.
+ * chartab.c (decode_char_table_range):
+ * chartab.c (make_char_table):
+ * chartab.c (Fcopy_char_table):
+ * chartab.c (vars_of_chartab):
+ Vall_syntax_tables is now an explicit weak list object.
+ * chartab.h:
+ * chartab.h (struct Lisp_Char_Table):
+ Remove the next_table chain element from this struct.
+ * emacs.c (main_1):
+ Move vars_of_data() even earlier in the startup sequence, so
+ Vall_weak_lists is available.
+ * gc.c (gc_finish_mark):
+ No longer call prune_specifiers(), prune_syntax_tables().
+ * specifier.c:
+ * specifier.c (cleanup_specifiers):
+ * specifier.c (kill_specifier_buffer_locals):
+ * specifier.c (make_specifier_internal):
+ * specifier.c (vars_of_specifier):
+ * specifier.h (struct Lisp_Specifier):
+ Remove prune_specifiers and the next_specifier element in the
+ struct.
+ * syntax.c (update_syntax_table):
+ Loop through the weak list list of Vall_syntax_tables, rather than
+ chaining through the next_table slot.
+
2018-08-09 Aidan Kehoe <kehoea(a)parhasard.net>
* lisp.h (XSET_STRING_ASCII_BEGIN):
diff -r 4280f7a3c209 -r 593de3c3ee78 src/chartab.c
--- a/src/chartab.c Sat Aug 11 21:09:02 2018 +0100
+++ b/src/chartab.c Sun Aug 12 01:30:52 2018 +0100
@@ -1145,7 +1145,6 @@
{ XD_LISP_OBJECT, offsetof (Lisp_Char_Table, table) },
{ XD_LISP_OBJECT, offsetof (Lisp_Char_Table, parent) },
{ XD_LISP_OBJECT, offsetof (Lisp_Char_Table, default_) },
- { XD_LO_LINK, offsetof (Lisp_Char_Table, next_table) },
#ifdef MIRROR_TABLE
{ XD_LISP_OBJECT, offsetof (Lisp_Char_Table, mirror_table) },
#endif /* MIRROR_TABLE */
@@ -1158,31 +1157,6 @@
char_table_description,
Lisp_Char_Table);
-/* WARNING: All functions of this nature need to be written extremely
- carefully to avoid crashes during GC. Cf. prune_specifiers()
- and prune_weak_hash_tables(). */
-
-void
-prune_syntax_tables (void)
-{
- Lisp_Object rest, prev = Qnil;
-
- for (rest = Vall_syntax_tables;
- !NILP (rest);
- rest = XCHAR_TABLE (rest)->next_table)
- {
- if (! marked_p (rest))
- {
- /* This table is garbage. Remove it from the list. */
- if (NILP (prev))
- Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
- else
- XCHAR_TABLE (prev)->next_table =
- XCHAR_TABLE (rest)->next_table;
- }
- }
-}
-
static void
decode_char_table_range (Lisp_Object range, struct chartab_range *outrange)
{
@@ -1361,13 +1335,12 @@
else
ct->mirror_table = Qnil;
#endif /* MIRROR_TABLE */
- ct->next_table = Qnil;
ct->parent = Qnil;
ct->default_ = Qnil;
if (ty == CHAR_TABLE_TYPE_SYNTAX)
{
- ct->next_table = Vall_syntax_tables;
- Vall_syntax_tables = obj;
+ XWEAK_LIST_LIST (Vall_syntax_tables)
+ = Fcons (obj, XWEAK_LIST_LIST (Vall_syntax_tables));
}
Freset_char_table (obj);
return obj;
@@ -1484,12 +1457,10 @@
else
ctnew->mirror_table = Qnil;
#endif /* MIRROR_TABLE */
-
- ctnew->next_table = Qnil;
if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
{
- ctnew->next_table = Vall_syntax_tables;
- Vall_syntax_tables = obj;
+ XWEAK_LIST_LIST (Vall_syntax_tables)
+ = Fcons (obj, XWEAK_LIST_LIST (Vall_syntax_tables));
}
return obj;
}
@@ -2522,8 +2493,8 @@
(char_table, memusage_stats_list, list2 (Qt, Qpage_tables));
#endif /* MEMORY_USAGE_STATS */
- /* DO NOT staticpro this. It works just like Vweak_hash_tables. */
- DUMP_ADD_WEAK_OBJECT_CHAIN (Vall_syntax_tables);
+ staticpro (&Vall_syntax_tables);
+ Vall_syntax_tables = make_weak_list (WEAK_LIST_SIMPLE);
/* The value at level 4 is not 2^32 - 1. With 32-bit EMACS_INTs, it's
2^30 - 1 because characters are only 30 bits wide. */
diff -r 4280f7a3c209 -r 593de3c3ee78 src/chartab.h
--- a/src/chartab.h Sat Aug 11 21:09:02 2018 +0100
+++ b/src/chartab.h Sun Aug 12 01:30:52 2018 +0100
@@ -183,7 +183,6 @@
enum char_table_type type;
- Lisp_Object next_table; /* DO NOT mark through this. */
#ifdef MIRROR_TABLE
/* stuff used for syntax tables */
Lisp_Object mirror_table; /* points to mirror table for this table
@@ -224,7 +223,6 @@
#endif /* (not) MULE */
#define XCHAR_TABLE_CATEGORY_P(ct) CHAR_TABLE_CATEGORY_P (XCHAR_TABLE (ct))
-#define XCHAR_TABLE_NEXT_TABLE(ct) (XCHAR_TABLE (ct)->next_table)
#ifdef MIRROR_TABLE
#define XCHAR_TABLE_MIRROR_TABLE(ct) (XCHAR_TABLE (ct)->mirror_table)
#define XCHAR_TABLE_DIRTY(ct) (XCHAR_TABLE (ct)->dirty)
diff -r 4280f7a3c209 -r 593de3c3ee78 src/emacs.c
--- a/src/emacs.c Sat Aug 11 21:09:02 2018 +0100
+++ b/src/emacs.c Sun Aug 12 01:30:52 2018 +0100
@@ -2067,8 +2067,9 @@
/* Now allow Fprovide() statements to be made. */
init_provide_once ();
+ vars_of_data ();
+ vars_of_alloc ();
vars_of_abbrev ();
- vars_of_alloc ();
vars_of_buffer ();
vars_of_bytecode ();
vars_of_callint ();
@@ -2077,7 +2078,6 @@
vars_of_cmdloop ();
vars_of_cmds ();
vars_of_console ();
- vars_of_data ();
vars_of_specifier ();
#ifdef DEBUG_XEMACS
diff -r 4280f7a3c209 -r 593de3c3ee78 src/gc.c
--- a/src/gc.c Sat Aug 11 21:09:02 2018 +0100
+++ b/src/gc.c Sun Aug 12 01:30:52 2018 +0100
@@ -2152,9 +2152,6 @@
method */
prune_weak_hash_tables ();
prune_weak_lists ();
- prune_specifiers ();
- prune_syntax_tables ();
-
prune_ephemerons ();
prune_weak_boxes ();
}
diff -r 4280f7a3c209 -r 593de3c3ee78 src/specifier.c
--- a/src/specifier.c Sat Aug 11 21:09:02 2018 +0100
+++ b/src/specifier.c Sun Aug 12 01:30:52 2018 +0100
@@ -95,9 +95,7 @@
static Lisp_Object Vspecifier_type_list;
static Lisp_Object Vcached_specifiers;
-/* Do NOT mark through this, or specifiers will never be GC'd. */
static Lisp_Object Vall_specifiers;
-
static Lisp_Object Vunlock_ghost_specifiers;
/* #### The purpose of this is to check for inheritance loops
@@ -207,13 +205,9 @@
void
cleanup_specifiers (void)
{
- Lisp_Object rest;
-
- for (rest = Vall_specifiers;
- !NILP (rest);
- rest = XSPECIFIER (rest)->next_specifier)
+ LIST_LOOP_2 (elt, XWEAK_LIST_LIST (Vall_specifiers))
{
- Lisp_Specifier *sp = XSPECIFIER (rest);
+ Lisp_Specifier *sp = XSPECIFIER (elt);
/* This effectively changes the specifier specs.
However, there's no need to call
recompute_cached_specifier_everywhere() or the
@@ -234,20 +228,16 @@
void
kill_specifier_buffer_locals (Lisp_Object buffer)
{
- Lisp_Object rest;
-
- for (rest = Vall_specifiers;
- !NILP (rest);
- rest = XSPECIFIER (rest)->next_specifier)
+ LIST_LOOP_2 (elt, XWEAK_LIST_LIST (Vall_specifiers))
{
- Lisp_Specifier *sp = XSPECIFIER (rest);
+ Lisp_Specifier *sp = XSPECIFIER (elt);
/* Make sure we're actually going to be changing something.
Fremove_specifier() always calls
recompute_cached_specifier_everywhere() (#### but should
be smarter about this). */
if (!NILP (assq_no_quit (buffer, sp->buffer_specs)))
- Fremove_specifier (rest, buffer, Qnil, Qnil);
+ Fremove_specifier (elt, buffer, Qnil, Qnil);
}
}
@@ -283,38 +273,10 @@
converted to live ones again if the dead object is in a window
configuration. Therefore, for windows, "no longer in use"
corresponds to when the window object is garbage-collected.
- We now use weak lists for this purpose.
-
-*/
-
-void
-prune_specifiers (void)
-{
- Lisp_Object rest, prev = Qnil;
-
- for (rest = Vall_specifiers;
- !NILP (rest);
- rest = XSPECIFIER (rest)->next_specifier)
- {
- if (! marked_p (rest))
- {
- Lisp_Specifier* sp = XSPECIFIER (rest);
- /* A bit of assertion that we're removing both parts of the
- magic one altogether */
- assert (!MAGIC_SPECIFIER_P (sp)
- || (BODILY_SPECIFIER_P (sp) && marked_p (sp->fallback))
- || (GHOST_SPECIFIER_P (sp) && marked_p (sp->magic_parent)));
- /* This specifier is garbage. Remove it from the list. */
- if (NILP (prev))
- Vall_specifiers = sp->next_specifier;
- else
- XSPECIFIER (prev)->next_specifier = sp->next_specifier;
- }
- else
- prev = rest;
- }
-}
-
+ We now use weak lists for this purpose.
+
+ [old prune_specifiers () elided.] */
+
static Lisp_Object specifier_get_external_inst_list (Lisp_Object specifier,
Lisp_Object locale,
enum spec_locale_type,
@@ -483,7 +445,6 @@
const struct memory_description specifier_description[] = {
{ XD_BLOCK_PTR, offsetof (Lisp_Specifier, methods), 1,
{ &specifier_methods_description } },
- { XD_LO_LINK, offsetof (Lisp_Specifier, next_specifier) },
{ XD_LISP_OBJECT, offsetof (Lisp_Specifier, global_specs) },
{ XD_LISP_OBJECT, offsetof (Lisp_Specifier, device_specs) },
{ XD_LISP_OBJECT, offsetof (Lisp_Specifier, frame_specs) },
@@ -593,9 +554,9 @@
sp->fallback = Qnil;
sp->magic_parent = Qnil;
sp->caching = 0;
- sp->next_specifier = Vall_specifiers;
-
- Vall_specifiers = specifier;
+
+ XWEAK_LIST_LIST (Vall_specifiers)
+ = Fcons (specifier, XWEAK_LIST_LIST (Vall_specifiers));
if (call_create_meth)
{
@@ -4015,9 +3976,8 @@
Vcached_specifiers = Qnil;
staticpro (&Vcached_specifiers);
- /* Do NOT mark through this, or specifiers will never be GC'd.
- This is the same deal as for weak hash tables. */
- DUMP_ADD_WEAK_OBJECT_CHAIN (Vall_specifiers);
+ Vall_specifiers = make_weak_list (WEAK_LIST_SIMPLE);
+ staticpro (&Vall_specifiers);
Vuser_defined_tags = Qnil;
staticpro (&Vuser_defined_tags);
diff -r 4280f7a3c209 -r 593de3c3ee78 src/specifier.h
--- a/src/specifier.h Sat Aug 11 21:09:02 2018 +0100
+++ b/src/specifier.h Sun Aug 12 01:30:52 2018 +0100
@@ -222,11 +222,6 @@
NORMAL_LISP_OBJECT_HEADER header;
struct specifier_methods *methods;
- /* we keep a chained list of all current specifiers, for GC cleanup
- purposes. Do NOT mark through this, or specifiers will never
- be GC'd. */
- Lisp_Object next_specifier;
-
/* This is a straight list of instantiators. */
Lisp_Object global_specs;
diff -r 4280f7a3c209 -r 593de3c3ee78 src/syntax.c
--- a/src/syntax.c Sat Aug 11 21:09:02 2018 +0100
+++ b/src/syntax.c Sun Aug 12 01:30:52 2018 +0100
@@ -2378,11 +2378,10 @@
assert (XCHAR_TABLE (table)->mirror_table_p);
if (EQ (nonmirror, Vstandard_syntax_table))
{
- Lisp_Object syntab;
-
- for (syntab = Vall_syntax_tables; !NILP (syntab);
- syntab = XCHAR_TABLE (syntab)->next_table)
- update_just_this_syntax_table (syntab);
+ LIST_LOOP_2 (syntab, XWEAK_LIST_LIST (Vall_syntax_tables))
+ {
+ update_just_this_syntax_table (syntab);
+ }
}
else
update_just_this_syntax_table (nonmirror);
--
‘As I sat looking up at the Guinness ad, I could never figure out /
How your man stayed up on the surfboard after forty pints of stout’
(C. Moore)