From d5fdffecdfad305d9c933ae3cad75a5e4e73878c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 24 Nov 2015 18:08:39 +0200 Subject: [PATCH] Fix crash at startup related to GC of font entities * src/font.h (GC_FONT_SPEC_P, GC_FONT_ENTITY_P) (GC_FONT_OBJECT_P, GC_XFONT_SPEC, GC_XFONT_ENTITY) (GC_XFONT_OBJECT): New macros, for use in garbage collector. * src/alloc.c (compact_font_cache_entry, compact_font_caches): Don't ifdef away font cache compaction on NT_GUI, as the problems which led to that seem to have been solved. (compact_font_cache_entry): Use GC_FONT_SPEC_P, GC_XFONT_SPEC, GC_XFONT_ENTITY, and GC_XFONT_OBJECT, instead of their non-GC_ cousins. (Bug#21999) --- src/alloc.c | 19 ++++++------------- src/font.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 99f5cdcdea2..e83b3836aa4 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5317,10 +5317,6 @@ total_bytes_of_live_objects (void) #ifdef HAVE_WINDOW_SYSTEM -/* This code has a few issues on MS-Windows, see Bug#15876 and Bug#16140. */ - -#if !defined (HAVE_NTGUI) - /* Remove unmarked font-spec and font-entity objects from ENTRY, which is (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...), and return changed entry. */ @@ -5335,11 +5331,12 @@ compact_font_cache_entry (Lisp_Object entry) Lisp_Object obj = XCAR (tail); /* Consider OBJ if it is (font-spec . [font-entity font-entity ...]). */ - if (CONSP (obj) && FONT_SPEC_P (XCAR (obj)) - && !VECTOR_MARKED_P (XFONT_SPEC (XCAR (obj))) + if (CONSP (obj) && GC_FONT_SPEC_P (XCAR (obj)) + && !VECTOR_MARKED_P (GC_XFONT_SPEC (XCAR (obj))) && VECTORP (XCDR (obj))) { ptrdiff_t i, size = gc_asize (XCDR (obj)); + Lisp_Object obj_cdr = XCDR (obj); /* If font-spec is not marked, most likely all font-entities are not marked too. But we must be sure that nothing is @@ -5348,14 +5345,14 @@ compact_font_cache_entry (Lisp_Object entry) { Lisp_Object objlist; - if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i)))) + if (VECTOR_MARKED_P (GC_XFONT_ENTITY (AREF (obj_cdr, i)))) break; - objlist = AREF (AREF (XCDR (obj), i), FONT_OBJLIST_INDEX); + objlist = AREF (AREF (obj_cdr, i), FONT_OBJLIST_INDEX); for (; CONSP (objlist); objlist = XCDR (objlist)) { Lisp_Object val = XCAR (objlist); - struct font *font = XFONT_OBJECT (val); + struct font *font = GC_XFONT_OBJECT (val); if (!NILP (AREF (val, FONT_TYPE_INDEX)) && VECTOR_MARKED_P(font)) @@ -5383,8 +5380,6 @@ compact_font_cache_entry (Lisp_Object entry) return entry; } -#endif /* not HAVE_NTGUI */ - /* Compact font caches on all terminals and mark everything which is still here after compaction. */ @@ -5396,7 +5391,6 @@ compact_font_caches (void) for (t = terminal_list; t; t = t->next_terminal) { Lisp_Object cache = TERMINAL_FONT_CACHE (t); -#if !defined (HAVE_NTGUI) if (CONSP (cache)) { Lisp_Object entry; @@ -5404,7 +5398,6 @@ compact_font_caches (void) for (entry = XCDR (cache); CONSP (entry); entry = XCDR (entry)) XSETCAR (entry, compact_font_cache_entry (XCAR (entry))); } -#endif /* not HAVE_NTGUI */ mark_object (cache); } } diff --git a/src/font.h b/src/font.h index 1d13e1cb6b0..24c058dd88b 100644 --- a/src/font.h +++ b/src/font.h @@ -427,6 +427,13 @@ FONT_SPEC_P (Lisp_Object x) return FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_SPEC_MAX; } +/* Like FONT_SPEC_P, but can be used in the garbage collector. */ +INLINE bool +GC_FONT_SPEC_P (Lisp_Object x) +{ + return FONTP (x) && (gc_asize (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_SPEC_MAX; +} + /* True iff X is font-entity. */ INLINE bool FONT_ENTITY_P (Lisp_Object x) @@ -434,6 +441,13 @@ FONT_ENTITY_P (Lisp_Object x) return FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_ENTITY_MAX; } +/* Like FONT_ENTITY_P, but can be used in the garbage collector. */ +INLINE bool +GC_FONT_ENTITY_P (Lisp_Object x) +{ + return FONTP (x) && (gc_asize (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_ENTITY_MAX; +} + /* True iff X is font-object. */ INLINE bool FONT_OBJECT_P (Lisp_Object x) @@ -441,6 +455,13 @@ FONT_OBJECT_P (Lisp_Object x) return FONTP (x) && (ASIZE (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX; } +/* Like FONT_OBJECT_P, but can be used in the garbage collector. */ +INLINE bool +GC_FONT_OBJECT_P (Lisp_Object x) +{ + return FONTP (x) && (gc_asize (x) & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX; +} + /* Type checking functions for various font-related objects. */ INLINE void @@ -476,6 +497,13 @@ XFONT_SPEC (Lisp_Object p) return XUNTAG (p, Lisp_Vectorlike); } +INLINE struct font_spec * +GC_XFONT_SPEC (Lisp_Object p) +{ + eassert (GC_FONT_SPEC_P (p)); + return XUNTAG (p, Lisp_Vectorlike); +} + INLINE struct font_entity * XFONT_ENTITY (Lisp_Object p) { @@ -483,6 +511,13 @@ XFONT_ENTITY (Lisp_Object p) return XUNTAG (p, Lisp_Vectorlike); } +INLINE struct font_entity * +GC_XFONT_ENTITY (Lisp_Object p) +{ + eassert (GC_FONT_ENTITY_P (p)); + return XUNTAG (p, Lisp_Vectorlike); +} + INLINE struct font * XFONT_OBJECT (Lisp_Object p) { @@ -490,6 +525,13 @@ XFONT_OBJECT (Lisp_Object p) return XUNTAG (p, Lisp_Vectorlike); } +INLINE struct font * +GC_XFONT_OBJECT (Lisp_Object p) +{ + eassert (GC_FONT_OBJECT_P (p)); + return XUNTAG (p, Lisp_Vectorlike); +} + #define XSETFONT(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_FONT)) INLINE struct font * -- 2.39.2