Commits

Michele Bini committed 232d1a3

Mark glyphs using mark-vectorlike; correctly initialize glyph struct to allow correct marking of the internal Lisp_Object field

  • Participants
  • Parent commits d9d0682

Comments (0)

Files changed (9)

 allocate_pseudovector (int memlen, int lisplen, EMACS_INT tag)
 {
   struct Lisp_Vector *v = allocate_vectorlike (memlen);
+  initialize_pseudovector(v, lisplen, tag);
+  return v;
+}
+
+void
+initialize_pseudovector (struct Lisp_Vector * v, int lisplen, EMACS_INT tag)
+{
   int i;
 
   /* Only the first lisplen slots will be traced normally by the GC.  */
 
   v->header.size_and_gcgroup = ARRAY_GC_UNMARK(0);
   XSETPVECTYPESIZE (v, tag, lisplen);
-  return v;
 }
 
 struct Lisp_Hash_Table *
   return Flist (sizeof total / sizeof *total, total);
 }
 
+static void mark_vectorlike (struct Lisp_Vector *);
 
 /* Mark Lisp objects in glyph matrix MATRIX.  Currently the
    only interesting objects referenced from glyphs are strings.  */
 	    struct glyph *end_glyph = glyph + row->used[area];
 
 	    for (; glyph < end_glyph; ++glyph)
-	      if (STRINGP (glyph->object)
-		  && !STRING_MARKED_P (XSTRING (glyph->object)))
-		mark_object (glyph->object);
+	      mark_vectorlike((struct Lisp_Vector *)glyph);
 	  }
       }
 }

File src/dispextern.h

 
 struct glyph
 {
+  struct vectorlike_header header;
+#define XGLYPH(a)  	     PVEC_TO_LISP  (glyph, (a))
+#define XSETGLYPH(a, b)      PVEC_SETLISP  (glyph, (a), (b))
+#define GLYPH_FIELD(n)       PVEC_FIELD    (glyph, n)
+#define GLYPH_VGET(v, f)     PVEC_GET      (glyph, (v), f)
+#define GLYPH_VSET(v, f, x)  PVEC_SET      (glyph, (v), f, (x))
+  /* Lisp object source of this glyph.  Currently either a buffer or
+     a string, if the glyph was produced from characters which came from
+     a buffer or a string; or 0 if the glyph was inserted by redisplay
+     for its own purposes such as padding.  */
+  Lisp_Object GLYPH_FIELD(object);
+#define GLYPH_C_OBJECT(x)        PVEC_C_GET(glyph, (x), object)
+#define GLYPH_OBJECT(x)          GLYPH_VGET((x), object)
+#define SET_GLYPH_OBJECT(x, y)   GLYPH_VSET((x), object, (y))
+  
+#define INITIALIZE_GLYPH(mem) INITIALIZE_PSEUDOVECTOR(mem, struct glyph, charpos, PVEC_OTHER)
+#define INITIALIZE_GLYPHS(mem, n) do { struct glyph *a = (mem); struct glyph *b = a + ((n)-1); while (a<=b) { INITIALIZE_GLYPH(a); a++; } } while (0)
   /* Position from which this glyph was drawn.  If `object' below is a
      Lisp string, this is a position in that string.  If it is a
      buffer, this is a position in that buffer.  A value of -1
      the start of a row.  */
   EMACS_INT charpos;
 
-  /* Lisp object source of this glyph.  Currently either a buffer or
-     a string, if the glyph was produced from characters which came from
-     a buffer or a string; or 0 if the glyph was inserted by redisplay
-     for its own purposes such as padding.  */
-  Lisp_Object object;
-
   /* Width in pixels.  */
   short pixel_width;
 

File src/dispnew.c

 	      row->glyphs[LEFT_MARGIN_AREA]
 		= xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
 			     dim.width, sizeof (struct glyph));
+	      INITIALIZE_GLYPHS(row->glyphs[LEFT_MARGIN_AREA], dim.width);
 
 	      /* The mode line never has marginal areas.  */
 	      if (row == matrix->rows + dim.height - 1
   /* Increment positions in glyphs.  */
   for (area = 0; area < LAST_AREA; ++area)
     for (i = 0; i < row->used[area]; ++i)
-      if (BUFFERP (row->glyphs[area][i].object)
+      if (BUFFERP (GLYPH_C_OBJECT(&(row->glyphs[area][i])))
 	  && row->glyphs[area][i].charpos > 0)
 	row->glyphs[area][i].charpos += delta;
 
 			      needed - old_nglyphs, -1, sizeof *pool->glyphs);
       memset (pool->glyphs + old_nglyphs, 0,
 	      (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
+      INITIALIZE_GLYPHS(pool->glyphs + old_nglyphs, pool->nglyphs - old_nglyphs);
     }
 
   /* Remember the number of rows and columns because (a) we use them
       *x = glyph - row->glyphs[TEXT_AREA];
       if (glyph < end)
 	{
-	  string = glyph->object;
+	  string = GLYPH_C_OBJECT(glyph);
 	  *charpos = glyph->charpos;
 	  *width = glyph->pixel_width;
 	  *height = glyph->ascent + glyph->descent;
       *x = glyph - row->glyphs[area];
       if (glyph < end)
 	{
-	  string = glyph->object;
+	  string = GLYPH_C_OBJECT(glyph);
 	  *charpos = glyph->charpos;
 	  *width = glyph->pixel_width;
 	  *height = glyph->ascent + glyph->descent;

File src/gtkutil.h

   Lisp_Object MENUCBDATA_FIELD(next);
   Lisp_Object MENUCBDATA_FIELD(prev);
 #define XMENUCBNEXT(cbdata)           MENUCBDATA_GET(cbdata, next)
-#define XSETMENUCBNEXT(cbdata, x)     MENUCBDATA_SET(cbdata, next, x)
+#define XSETMENUCBNEXT(cbdata, x)     MENUCBDATA_SET(cbdata, next, (x))
 #define XMENUCBPREV(cbdata)           MENUCBDATA_GET(cbdata, prev)
-#define XSETMENUCBPREV(cbdata, x)     MENUCBDATA_SET(cbdata, prev, x)
+#define XSETMENUCBPREV(cbdata, x)     MENUCBDATA_SET(cbdata, prev, (x))
 
   Lisp_Object MENUCBDATA_FIELD(menu_bar_vector);
 #define XMENUBARVECTOR(cbdata)        MENUCBDATA_GET(cbdata, menu_bar_vector)
-#define XSETMENUBARVECTOR(cbdata, x)  MENUCBDATA_SET(cbdata, menu_bar_vector, x)
+#define XSETMENUBARVECTOR(cbdata, x)  MENUCBDATA_SET(cbdata, menu_bar_vector, (x))
 
 #define ALLOCATE_MENUCBDATA()				\
   ALLOCATE_PSEUDOVECTOR(xg_menu_cb_data,		\
 #define PVEC_FIELD(pvecname,field) 	       field##__##pvecname##__##pvec
 #define PVEC_GET(pvecname, vec, field) 	       AREF((vec), PSEUDOVECSIZE(struct pvecname, PVEC_FIELD(pvecname, field)))
 #define PVEC_SET(pvecname, vec, field, value)  ASET((vec), PSEUDOVECSIZE(struct pvecname, PVEC_FIELD(pvecname, field)), (value))
+#define UNSAFE_PVEC_REF(pvecname, vec, field)  (((struct pvecname *)(vec))->PVEC_FIELD(pvecname, field))
+#define PVEC_C_GET(pvecname, vec, field)       LISP_MAKE_RVALUE(UNSAFE_PVEC_REF(pvecname, (vec), field))
 
 /* These macros extract various sorts of values from a Lisp_Object.
  For example, if tem is a Lisp_Object whose type is Lisp_Cons,
   ((typ*)								\
    allocate_pseudovector						\
        (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
+extern void initialize_pseudovector (struct Lisp_Vector * mem, int lisplen, EMACS_INT tag);
+/* This is to allocate pseudovectors independently from the garbage collector; used for struct glyph. */
+#define INITIALIZE_PSEUDOVECTOR(mem,typ,field,tag) do { initialize_pseudovector(((struct Lisp_Vector *)(void*)(typ*)(mem)), PSEUDOVECSIZE (typ, field), tag); ((struct vectorlike_header *)(void*)mem)->next.vector = NULL; } while (0)
 extern struct Lisp_Hash_Table *allocate_hash_table (void);
 extern struct window *allocate_window (void);
 extern struct frame *allocate_frame (void);
   /* We multiply width by 2 to account for possible control characters.
      FIXME: cater to non-ASCII characters in menus.  */
   text = (struct glyph *) xmalloc ((width * 2 + 2) * sizeof (struct glyph));
+  INITIALIZE_GLYPHS(text, (width * 2 + 2))
   ScreenGetCursor (&row, &col);
   mouse_get_xy (&mx, &my);
   IT_update_begin (sf);
       glyph->face_id = it->face_id;
       glyph->padding_p = i > 0;
       glyph->charpos = CHARPOS (it->position);
-      glyph->object = it->object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, GLYPH_C_OBJECT(it));
+      }
       if (it->bidi_p)
 	{
 	  glyph->resolved_level = it->bidi_it.resolved_level;
       glyph->face_id = it->face_id;
       glyph->padding_p = 0;
       glyph->charpos = CHARPOS (it->position);
-      glyph->object = it->object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, GLYPH_C_OBJECT(it));
+      }
       if (it->bidi_p)
 	{
 	  glyph->resolved_level = it->bidi_it.resolved_level;
   glyph->face_id = face_id;
   glyph->padding_p = 0;
   glyph->charpos = CHARPOS (it->position);
-  glyph->object = it->object;
+  {
+    Lisp_Object glyph_l;
+    XSETGLYPH(glyph_l, glyph);
+    SET_GLYPH_OBJECT(glyph_l, GLYPH_C_OBJECT(it));
+  }
   if (it->bidi_p)
     {
       glyph->resolved_level = it->bidi_it.resolved_level;
 		      struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
 					+ it3.glyph_row->used[TEXT_AREA];
 
-		      while (EQ ((g - 1)->object, string))
+		      while (EQ (GLYPH_C_OBJECT(g - 1), string))
 			{
 			  --g;
 			  top_x -= g->pixel_width;
       if (!row->reversed_p)
 	{
 	  while (glyph < end
-		 && INTEGERP (glyph->object)
+		 && INTEGERP (GLYPH_C_OBJECT(glyph))
 		 && glyph->charpos < 0)
 	    {
 	      x += glyph->pixel_width;
 	      ++glyph;
 	    }
 	  while (end > glyph
-		 && INTEGERP ((end - 1)->object)
+		 && INTEGERP (GLYPH_C_OBJECT(end - 1))
 		 /* CHARPOS is zero for blanks and stretch glyphs
 		    inserted by extend_face_to_end_of_line.  */
 		 && (end - 1)->charpos <= 0)
 	  glyph += row->used[TEXT_AREA] - 1;
 
 	  while (glyph > end + 1
-		 && INTEGERP (glyph->object)
+		 && INTEGERP (GLYPH_C_OBJECT(glyph))
 		 && glyph->charpos < 0)
 	    {
 	      --glyph;
 	      x -= glyph->pixel_width;
 	    }
-	  if (INTEGERP (glyph->object) && glyph->charpos < 0)
+	  if (INTEGERP (GLYPH_C_OBJECT(glyph)) && glyph->charpos < 0)
 	    --glyph;
 	  /* By default, in reversed rows we put the cursor on the
 	     rightmost (first in the reading order) glyph.  */
 	  for (g = end + 1; g < glyph; g++)
 	    x += g->pixel_width;
 	  while (end < glyph
-		 && INTEGERP ((end + 1)->object)
+		 && INTEGERP (GLYPH_C_OBJECT(end + 1))
 		 && (end + 1)->charpos <= 0)
 	    ++end;
 	  glyph_before = glyph + 1;
     while (/* not marched to end of glyph row */
 	   glyph < end
 	   /* glyph was not inserted by redisplay for internal purposes */
-	   && !INTEGERP (glyph->object))
+	   && !INTEGERP (GLYPH_C_OBJECT(glyph)))
       {
-	if (BUFFERP (glyph->object))
+	if (BUFFERP (GLYPH_C_OBJECT(glyph)))
 	  {
 	    EMACS_INT dpos = glyph->charpos - pt_old;
 
 	    else if (dpos == 0)
 	      match_with_avoid_cursor = 1;
 	  }
-	else if (STRINGP (glyph->object))
+	else if (STRINGP (GLYPH_C_OBJECT(glyph)))
 	  {
 	    Lisp_Object chprop;
 	    EMACS_INT glyph_pos = glyph->charpos;
 
 	    chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
-					 glyph->object);
+					 GLYPH_C_OBJECT(glyph));
 	    if (INTEGERP (chprop))
 	      {
 		bpos_covered = bpos_max + XINT (chprop);
 	++glyph;
       }
   else if (glyph > end)	/* row is reversed */
-    while (!INTEGERP (glyph->object))
+    while (!INTEGERP (GLYPH_C_OBJECT(glyph)))
       {
-	if (BUFFERP (glyph->object))
+	if (BUFFERP (GLYPH_C_OBJECT(glyph)))
 	  {
 	    EMACS_INT dpos = glyph->charpos - pt_old;
 
 	    else if (dpos == 0)
 	      match_with_avoid_cursor = 1;
 	  }
-	else if (STRINGP (glyph->object))
+	else if (STRINGP (GLYPH_C_OBJECT(glyph)))
 	  {
 	    Lisp_Object chprop;
 	    EMACS_INT glyph_pos = glyph->charpos;
 
 	    chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
-					 glyph->object);
+					 GLYPH_C_OBJECT(glyph));
 	    if (INTEGERP (chprop))
 	      {
 		bpos_covered = bpos_max + XINT (chprop);
      look for a proper place to put the cursor among glyphs between
      GLYPH_BEFORE and GLYPH_AFTER.  */
   if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
-	&& BUFFERP (glyph->object) && glyph->charpos == pt_old)
+	&& BUFFERP (GLYPH_C_OBJECT(glyph)) && glyph->charpos == pt_old)
       && bpos_covered < pt_old)
     {
       /* An empty line has a single glyph whose OBJECT is zero and
 	 CHARPOS is zero or negative.  */
       int empty_line_p =
 	(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
-	&& INTEGERP (glyph->object) && glyph->charpos > 0;
+	&& INTEGERP (GLYPH_C_OBJECT(glyph)) && glyph->charpos > 0;
 
       if (row->ends_in_ellipsis_p && pos_after == last_pos)
 	{
 	      /* Any glyphs that come from the buffer are here because
 		 of bidi reordering.  Skip them, and only pay
 		 attention to glyphs that came from some string.  */
-	      if (STRINGP (glyph->object))
+	      if (STRINGP (GLYPH_C_OBJECT(glyph)))
 		{
 		  Lisp_Object str;
 		  EMACS_INT tem;
 		    + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
 
 		  string_from_text_prop = 0;
-		  str = glyph->object;
+		  str = GLYPH_C_OBJECT(glyph);
 		  tem = string_buffer_position_lim (str, pos, lim, 0);
 		  if (tem == 0	/* from overlay */
 		      || pos <= tem)
 			    }
 			  for ( ;
 			       (row->reversed_p ? glyph > stop : glyph < stop)
-				 && EQ (glyph->object, str);
+				 && EQ (GLYPH_C_OBJECT(glyph), str);
 			       glyph += incr)
 			    {
 			      Lisp_Object cprop;
 
 			      cprop = Fget_char_property (make_number (gpos),
 							  Qcursor,
-							  glyph->object);
+							  GLYPH_C_OBJECT(glyph));
 			      if (!NILP (cprop))
 				{
 				  cursor = glyph;
 		  /* This string is not what we want; skip all of the
 		     glyphs that came from it.  */
 		  while ((row->reversed_p ? glyph > stop : glyph < stop)
-			 && EQ (glyph->object, str))
+			 && EQ (GLYPH_C_OBJECT(glyph), str))
 		    glyph += incr;
 		}
 	      else
 	     the cursor is not on this line.  */
 	  if (cursor == NULL
 	      && (row->reversed_p ? glyph <= end : glyph >= end)
-	      && STRINGP (end->object)
+	      && STRINGP (GLYPH_C_OBJECT(end))
 	      && row->continued_p)
 	    return 0;
 	}
       if (/* previous candidate is a glyph in TEXT_AREA of that row */
 	  w->cursor.hpos >= 0
 	  && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
-	  && ((BUFFERP (g1->object)
+	  && ((BUFFERP (GLYPH_C_OBJECT(g1))
 	       && (g1->charpos == pt_old /* an exact match always wins */
-		   || (BUFFERP (glyph->object)
+		   || (BUFFERP (GLYPH_C_OBJECT(glyph))
 		       && eabs (g1->charpos - pt_old)
 		       < eabs (glyph->charpos - pt_old))))
 	      /* previous candidate is a glyph from a string that has
 		 a non-nil `cursor' property */
-	      || (STRINGP (g1->object)
+	      || (STRINGP (GLYPH_C_OBJECT(g1))
 		  && (!NILP (Fget_char_property (make_number (g1->charpos),
-						Qcursor, g1->object))
+						 Qcursor, GLYPH_C_OBJECT(g1)))
 		      /* previous candidate is from the same display
 			 string as this one, and the display string
 			 came from a text property */
-		      || (EQ (g1->object, glyph->object)
+		      || (EQ (GLYPH_C_OBJECT(g1), GLYPH_C_OBJECT(glyph))
 			  && string_from_text_prop)
 		      /* this candidate is from newline and its
 			 position is not an exact match */
-		      || (INTEGERP (glyph->object)
+		      || (INTEGERP (GLYPH_C_OBJECT(glyph))
 			  && glyph->charpos != pt_old)))))
 	return 0;
       /* If this candidate gives an exact match, use that.  */
-      if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
+      if (!((BUFFERP (GLYPH_C_OBJECT(glyph)) && glyph->charpos == pt_old)
 	    /* If this candidate is a glyph created for the
 	       terminating newline of a line, and point is on that
 	       newline, it wins because it's an exact match.  */
 	    || (!row->continued_p
-		&& INTEGERP (glyph->object)
+		&& INTEGERP (GLYPH_C_OBJECT(glyph))
 		&& glyph->charpos == 0
 		&& pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
 	  /* Otherwise, keep the candidate that comes from a row
 		      EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
 
 		      exact_match_p =
-			(BUFFERP (g->object) && g->charpos == PT)
-			|| (INTEGERP (g->object)
+			(BUFFERP (GLYPH_C_OBJECT(g)) && g->charpos == PT)
+			|| (INTEGERP (GLYPH_C_OBJECT(g))
 			    && (g->charpos == PT
 				|| (g->charpos == 0 && endpos - 1 == PT)));
 		    }
 		{
 		  if (!(w->cursor.hpos >= 0
 			&& w->cursor.hpos < row->used[TEXT_AREA]
-			&& BUFFERP (glyph->object)
+			&& BUFFERP (GLYPH_C_OBJECT(glyph))
 			&& glyph->charpos == PT))
 		    return 0;
 		}
 	      else
 		for (; glyph < end
-		       && (!BUFFERP (glyph->object)
+		       && (!BUFFERP (GLYPH_C_OBJECT(glyph))
 			   || glyph->charpos < PT);
 		     glyph++)
 		  {
 	       g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
 	       g++)
 	    {
-	      if (!STRINGP (g->object))
+	      if (!STRINGP (GLYPH_C_OBJECT(g)))
 		{
 		  if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
 		    {
 	       glyph - row->glyphs[TEXT_AREA],
 	       'C',
 	       glyph->charpos,
-	       (BUFFERP (glyph->object)
+	       (BUFFERP (GLYPH_C_OBJECT(glyph))
 		? 'B'
-		: (STRINGP (glyph->object)
+		: (STRINGP (GLYPH_C_OBJECT(glyph))
 		   ? 'S'
 		   : '-')),
 	       glyph->pixel_width,
 	       glyph - row->glyphs[TEXT_AREA],
 	       'S',
 	       glyph->charpos,
-	       (BUFFERP (glyph->object)
+	       (BUFFERP (GLYPH_C_OBJECT(glyph))
 		? 'B'
-		: (STRINGP (glyph->object)
+		: (STRINGP (GLYPH_C_OBJECT(glyph))
 		   ? 'S'
 		   : '-')),
 	       glyph->pixel_width,
 	       glyph - row->glyphs[TEXT_AREA],
 	       'I',
 	       glyph->charpos,
-	       (BUFFERP (glyph->object)
+	       (BUFFERP (GLYPH_C_OBJECT(glyph))
 		? 'B'
-		: (STRINGP (glyph->object)
+		: (STRINGP (GLYPH_C_OBJECT(glyph))
 		   ? 'S'
 		   : '-')),
 	       glyph->pixel_width,
 	       glyph - row->glyphs[TEXT_AREA],
 	       '+',
 	       glyph->charpos,
-	       (BUFFERP (glyph->object)
+	       (BUFFERP (GLYPH_C_OBJECT(glyph))
 		? 'B'
-		: (STRINGP (glyph->object)
+		: (STRINGP (GLYPH_C_OBJECT(glyph))
 		   ? 'S'
 		   : '-')),
 	       glyph->pixel_width,
 	{
 	  while (glyph >= start
 		 && glyph->type == CHAR_GLYPH
-		 && INTEGERP (glyph->object))
+		 && INTEGERP (GLYPH_C_OBJECT(glyph)))
 	    --glyph;
 	}
       else
 	{
 	  while (glyph <= start
 		 && glyph->type == CHAR_GLYPH
-		 && INTEGERP (glyph->object))
+		 && INTEGERP (GLYPH_C_OBJECT(glyph)))
 	    ++glyph;
 	}
 
 	 whitespace, set the face of all trailing whitespace glyphs in
 	 IT->glyph_row to `trailing-whitespace'.  */
       if ((row->reversed_p ? glyph <= start : glyph >= start)
-	  && BUFFERP (glyph->object)
+	  && BUFFERP (GLYPH_C_OBJECT(glyph))
 	  && (glyph->type == STRETCH_GLYPH
 	      || (glyph->type == CHAR_GLYPH
 		  && glyph->u.ch == ' '))
 	  if (!row->reversed_p)
 	    {
 	      while (glyph >= start
-		     && BUFFERP (glyph->object)
+		     && BUFFERP (GLYPH_C_OBJECT(glyph))
 		     && (glyph->type == STRETCH_GLYPH
 			 || (glyph->type == CHAR_GLYPH
 			     && glyph->u.ch == ' ')))
 	  else
 	    {
 	      while (glyph <= start
-		     && BUFFERP (glyph->object)
+		     && BUFFERP (GLYPH_C_OBJECT(glyph))
 		     && (glyph->type == STRETCH_GLYPH
 			 || (glyph->type == CHAR_GLYPH
 			     && glyph->u.ch == ' ')))
 
 	      result = 0;
 	      for (glyph = end; glyph >= beg; --glyph)
-		if (STRINGP (glyph->object))
+		if (STRINGP (GLYPH_C_OBJECT(glyph)))
 		  {
 		    Lisp_Object prop
 		      = Fget_char_property (make_number (PT),
 					    Qdisplay, Qnil);
 		    result =
 		      (!NILP (prop)
-		       && display_prop_string_p (prop, glyph->object));
+		       && display_prop_string_p (prop, GLYPH_C_OBJECT(glyph)));
 		    break;
 		  }
 	    }
 	      /* Glyphs inserted by redisplay have an integer (zero)
 		 as their object.  */
 	      while (end > start
-		     && INTEGERP ((end - 1)->object)
+		     && INTEGERP (GLYPH_C_OBJECT(end - 1))
 		     && (end - 1)->charpos <= 0)
 		--end;
 	      if (end > start)
 		{
-		  if (EQ ((end - 1)->object, it->object))
+		  if (EQ (GLYPH_C_OBJECT(end - 1), GLYPH_C_OBJECT(it)))
 		    seen_this_string = 1;
 		}
 	      else
 	      end = r1->glyphs[TEXT_AREA] - 1;
 	      start = end + r1->used[TEXT_AREA];
 	      while (end < start
-		     && INTEGERP ((end + 1)->object)
+		     && INTEGERP (GLYPH_C_OBJECT(end + 1))
 		     && (end + 1)->charpos <= 0)
 		++end;
 	      if (end < start)
 		{
-		  if (EQ ((end + 1)->object, it->object))
+		  if (EQ (GLYPH_C_OBJECT(end + 1), GLYPH_C_OBJECT(it)))
 		    seen_this_string = 1;
 		}
 	      else
 
 			      for (i = 0; i < nwritten; ++i)
 				{
-				  glyph[i].object = elt;
+				  Lisp_Object glyph_l;
+				  XSETGLYPH(glyph_l, &glyph[i]);
+				  SET_GLYPH_OBJECT(glyph_l, elt);
 				  glyph[i].charpos = charpos;
 				}
 
 	  glyph = it->glyph_row->glyphs[area];
 	}
       glyph->charpos = CHARPOS (it->position);
-      glyph->object = it->object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, it->object);
+      }
       if (it->pixel_width > 0)
 	{
 	  glyph->pixel_width = it->pixel_width;
 	  glyph = it->glyph_row->glyphs[it->area];
 	}
       glyph->charpos = it->cmp_it.charpos;
-      glyph->object = it->object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, it->object);
+      }
       glyph->pixel_width = it->pixel_width;
       glyph->ascent = it->ascent;
       glyph->descent = it->descent;
       if (glyph < it->glyph_row->glyphs[area + 1])
 	{
 	  glyph->charpos = CHARPOS (it->position);
-	  glyph->object = it->object;
+	  {
+	    Lisp_Object glyph_l;
+	    XSETGLYPH(glyph_l, glyph);
+	    SET_GLYPH_OBJECT(glyph_l, it->object);
+	  }
 	  glyph->pixel_width = it->pixel_width;
 	  glyph->ascent = glyph_ascent;
 	  glyph->descent = it->descent;
 	  glyph = it->glyph_row->glyphs[area];
 	}
       glyph->charpos = CHARPOS (it->position);
-      glyph->object = object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, object);
+      }
       glyph->pixel_width = width;
       glyph->ascent = ascent;
       glyph->descent = height - ascent;
 	  glyph = it->glyph_row->glyphs[area];
 	}
       glyph->charpos = CHARPOS (it->position);
-      glyph->object = it->object;
+      {
+	Lisp_Object glyph_l;
+	XSETGLYPH(glyph_l, glyph);
+	SET_GLYPH_OBJECT(glyph_l, it->object);
+      }
       glyph->pixel_width = it->pixel_width;
       glyph->ascent = it->ascent;
       glyph->descent = it->descent;
 
 	  while (g < e)
 	    {
-	      if (((BUFFERP (g->object) || INTEGERP (g->object))
+	      if (((BUFFERP (GLYPH_C_OBJECT(g)) || INTEGERP (GLYPH_C_OBJECT(g)))
 		   && start_charpos <= g->charpos && g->charpos < end_charpos)
 		  /* A glyph that comes from DISP_STRING is by
 		     definition to be highlighted.  */
-		  || EQ (g->object, disp_string))
+		  || EQ (GLYPH_C_OBJECT(g), disp_string))
 		*start = row;
 	      g++;
 	    }
 
 	  while (g < e)
 	    {
-	      if (((BUFFERP (g->object) || INTEGERP (g->object))
+	      if (((BUFFERP (GLYPH_C_OBJECT(g)) || INTEGERP (GLYPH_C_OBJECT(g)))
 		   && ((start_charpos <= g->charpos && g->charpos < end_charpos)
 		       /* If the buffer position of the first glyph in
 			  the row is equal to END_CHARPOS, it means
 				   && next_start == end_charpos)))))
 		  /* A glyph that comes from DISP_STRING is by
 		     definition to be highlighted.  */
-		  || EQ (g->object, disp_string))
+		  || EQ (GLYPH_C_OBJECT(g), disp_string))
 		break;
 	      g++;
 	    }
 	{
 	  struct glyph *beg = prev->glyphs[TEXT_AREA];
 	  glyph = beg + prev->used[TEXT_AREA];
-	  while (--glyph >= beg && INTEGERP (glyph->object));
+	  while (--glyph >= beg && INTEGERP (GLYPH_C_OBJECT(glyph)));
 	  if (glyph < beg
-	      || !(EQ (glyph->object, before_string)
-		   || EQ (glyph->object, disp_string)))
+	      || !(EQ (GLYPH_C_OBJECT(glyph), before_string)
+		   || EQ (GLYPH_C_OBJECT(glyph), disp_string)))
 	    break;
 	  r1 = prev;
 	}
       for (next = r2 + 1;
 	   next <= last
 	     && next->used[TEXT_AREA] > 0
-	     && EQ (next->glyphs[TEXT_AREA]->object, after_string);
+	     && EQ (GLYPH_C_OBJECT(&(next->glyphs[TEXT_AREA])), after_string);
 	   ++next)
 	r2 = next;
     }
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (r1->displays_text_p)
 	for (; glyph < end
-	       && INTEGERP (glyph->object)
+	       && INTEGERP (GLYPH_C_OBJECT(glyph))
 	       && glyph->charpos < 0;
 	     ++glyph)
 	  x += glyph->pixel_width;
 	 or DISP_STRING, and the first glyph from buffer whose
 	 position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph < end
-	     && !INTEGERP (glyph->object)
-	     && !EQ (glyph->object, disp_string)
-	     && !(BUFFERP (glyph->object)
+	     && !INTEGERP (GLYPH_C_OBJECT(glyph))
+	     && !EQ (GLYPH_C_OBJECT(glyph), disp_string)
+	     && !(BUFFERP (GLYPH_C_OBJECT(glyph))
 		  && (glyph->charpos >= start_charpos
 		      && glyph->charpos < end_charpos));
 	   ++glyph)
 	  /* BEFORE_STRING or AFTER_STRING are only relevant if they
 	     are present at buffer positions between START_CHARPOS and
 	     END_CHARPOS, or if they come from an overlay.  */
-	  if (EQ (glyph->object, before_string))
+	  if (EQ (GLYPH_C_OBJECT(glyph), before_string))
 	    {
 	      pos = string_buffer_position (before_string,
 					    start_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 		break;
 	    }
-	  else if (EQ (glyph->object, after_string))
+	  else if (EQ (GLYPH_C_OBJECT(glyph), after_string))
 	    {
 	      pos = string_buffer_position (after_string, end_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
       /* Skip truncation glyphs at the start of the glyph row.  */
       if (r1->displays_text_p)
 	for (; glyph > end
-	       && INTEGERP (glyph->object)
+	       && INTEGERP (GLYPH_C_OBJECT(glyph))
 	       && glyph->charpos < 0;
 	     --glyph)
 	  ;
 	 or DISP_STRING, and the first glyph from buffer whose
 	 position is between START_CHARPOS and END_CHARPOS.  */
       for (; glyph > end
-	     && !INTEGERP (glyph->object)
-	     && !EQ (glyph->object, disp_string)
-	     && !(BUFFERP (glyph->object)
+	     && !INTEGERP (GLYPH_C_OBJECT(glyph))
+	     && !EQ (GLYPH_C_OBJECT(glyph), disp_string)
+	     && !(BUFFERP (GLYPH_C_OBJECT(glyph))
 		  && (glyph->charpos >= start_charpos
 		      && glyph->charpos < end_charpos));
 	   --glyph)
 	  /* BEFORE_STRING or AFTER_STRING are only relevant if they
 	     are present at buffer positions between START_CHARPOS and
 	     END_CHARPOS, or if they come from an overlay.  */
-	  if (EQ (glyph->object, before_string))
+	  if (EQ (GLYPH_C_OBJECT(glyph), before_string))
 	    {
 	      pos = string_buffer_position (before_string, start_charpos);
 	      /* If pos == 0, it means before_string came from an
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 		break;
 	    }
-	  else if (EQ (glyph->object, after_string))
+	  else if (EQ (GLYPH_C_OBJECT(glyph), after_string))
 	    {
 	      pos = string_buffer_position (after_string, end_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 	 row, and also blanks and stretch glyphs inserted by
 	 extend_face_to_end_of_line.  */
       while (end > glyph
-	     && INTEGERP ((end - 1)->object))
+	     && INTEGERP (GLYPH_C_OBJECT(end - 1)))
 	--end;
       /* Scan the rest of the glyph row from the end, looking for the
 	 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
 	 and END_CHARPOS */
       for (--end;
 	     end > glyph
-	     && !INTEGERP (end->object)
-	     && !EQ (end->object, disp_string)
-	     && !(BUFFERP (end->object)
+	     && !INTEGERP (GLYPH_C_OBJECT(end))
+	     && !EQ (GLYPH_C_OBJECT(end), disp_string)
+	     && !(BUFFERP (GLYPH_C_OBJECT(end))
 		  && (end->charpos >= start_charpos
 		      && end->charpos < end_charpos));
 	   --end)
 	  /* BEFORE_STRING or AFTER_STRING are only relevant if they
 	     are present at buffer positions between START_CHARPOS and
 	     END_CHARPOS, or if they come from an overlay.  */
-	  if (EQ (end->object, before_string))
+	  if (EQ (GLYPH_C_OBJECT(end), before_string))
 	    {
 	      pos = string_buffer_position (before_string, start_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 		break;
 	    }
-	  else if (EQ (end->object, after_string))
+	  else if (EQ (GLYPH_C_OBJECT(end), after_string))
 	    {
 	      pos = string_buffer_position (after_string, end_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
       x = r2->x;
       end++;
       while (end < glyph
-	     && INTEGERP (end->object))
+	     && INTEGERP (GLYPH_C_OBJECT(end)))
 	{
 	  x += end->pixel_width;
 	  ++end;
 	 and END_CHARPOS */
       for ( ;
 	     end < glyph
-	     && !INTEGERP (end->object)
-	     && !EQ (end->object, disp_string)
-	     && !(BUFFERP (end->object)
+	      && !INTEGERP (GLYPH_C_OBJECT(end))
+	      && !EQ (GLYPH_C_OBJECT(end), disp_string)
+	      && !(BUFFERP (GLYPH_C_OBJECT(end))
 		  && (end->charpos >= start_charpos
 		      && end->charpos < end_charpos));
 	   ++end)
 	  /* BEFORE_STRING or AFTER_STRING are only relevant if they
 	     are present at buffer positions between START_CHARPOS and
 	     END_CHARPOS, or if they come from an overlay.  */
-	  if (EQ (end->object, before_string))
+	  if (EQ (GLYPH_C_OBJECT(end), before_string))
 	    {
 	      pos = string_buffer_position (before_string, start_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 		break;
 	    }
-	  else if (EQ (end->object, after_string))
+	  else if (EQ (GLYPH_C_OBJECT(end), after_string))
 	    {
 	      pos = string_buffer_position (after_string, end_charpos);
 	      if (!pos || (pos >= start_charpos && pos < end_charpos))
 	 newline.  Bump the end column and x values to get past the
 	 last glyph.  */
       if (end == glyph
-	  && BUFFERP (end->object)
+	  && BUFFERP (GLYPH_C_OBJECT(end))
 	  && (end->charpos < start_charpos
 	      || end->charpos >= end_charpos))
 	{
 	  g = r->glyphs[TEXT_AREA];
 	  e = g + r->used[TEXT_AREA];
 	  for (gx = r->x; g < e; gx += g->pixel_width, ++g)
-	    if (EQ (g->object, object)
+	    if (EQ (GLYPH_C_OBJECT(g), object)
 		&& startpos <= g->charpos && g->charpos <= endpos)
 	      {
 		hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
 	  e = r->glyphs[TEXT_AREA];
 	  g = e + r->used[TEXT_AREA];
 	  for ( ; g > e; --g)
-	    if (EQ ((g-1)->object, object)
+	    if (EQ (GLYPH_C_OBJECT(g-1), object)
 		&& startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
 	      {
 		hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
       e = g + r->used[TEXT_AREA];
       found = 0;
       for ( ; g < e; ++g)
-	if (EQ (g->object, object)
+	if (EQ (GLYPH_C_OBJECT(g), object)
 	    && startpos <= g->charpos && g->charpos <= endpos)
 	  {
 	    found = 1;
       g = r->glyphs[TEXT_AREA];
       e = g + r->used[TEXT_AREA];
       for ( ; e > g; --e)
-	if (EQ ((e-1)->object, object)
+	if (EQ (GLYPH_C_OBJECT(e-1), object)
 	    && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
 	  break;
       hlinfo->mouse_face_end_col = e - g;
       g = e + r->used[TEXT_AREA];
       for (gx = r->x ; e < g; ++e)
 	{
-	  if (EQ (e->object, object)
+	  if (EQ (GLYPH_C_OBJECT(e), object)
 	      && startpos <= e->charpos && e->charpos <= endpos)
 	    break;
 	  gx += e->pixel_width;
 	     displayed string is the flattened string.  */
 	  tmp_glyph = row_start_glyph;
 	  while (tmp_glyph < glyph
-		 && (!(EQ (tmp_glyph->object, glyph->object)
+		 && (!(EQ (GLYPH_C_OBJECT(tmp_glyph), GLYPH_C_OBJECT(glyph))
 		       && begpos <= tmp_glyph->charpos
 		       && tmp_glyph->charpos < endpos)))
 	    tmp_glyph++;
 	     the internal string.  */
 	  for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
 	       tmp_glyph > glyph
-		 && (!(EQ (tmp_glyph->object, glyph->object)
+		 && (!(EQ (GLYPH_C_OBJECT(tmp_glyph), GLYPH_C_OBJECT(glyph))
 		       && begpos <= tmp_glyph->charpos
 		       && tmp_glyph->charpos < endpos));
 	       tmp_glyph--)
 		      if (!NILP (help_echo_string))
 			{
 			  help_echo_window = window;
-			  help_echo_object = glyph->object;
+			  help_echo_object = GLYPH_C_OBJECT(glyph);
 			  help_echo_pos = glyph->charpos;
 			}
 		    }
 	     and continuation glyphs and blanks beyond the end of
 	     line's text on text terminals.  If we are over such a
 	     glyph, we are not over any text.  */
-	  || INTEGERP (glyph->object)
+	  || INTEGERP (GLYPH_C_OBJECT(glyph))
 	  /* R2L rows have a stretch glyph at their front, which
 	     stands for no text, whereas L2R rows have no glyphs at
 	     all beyond the end of text.  Treat such stretch glyphs
 	}
 
       pos = glyph->charpos;
-      object = glyph->object;
+      object = GLYPH_C_OBJECT(glyph);
       if (!STRINGP (object) && !BUFFERP (object))
 	goto set_cursor;
 
 	  }
 	else
 	  {
-	    Lisp_Object obj = glyph->object;
+	    Lisp_Object obj = GLYPH_C_OBJECT(glyph);
 	    EMACS_INT charpos = glyph->charpos;
 
 	    /* Try text properties.  */
 
 	  if (NILP (pointer))
 	    {
-	      Lisp_Object obj = glyph->object;
+	      Lisp_Object obj = GLYPH_C_OBJECT(glyph);
 	      EMACS_INT charpos = glyph->charpos;
 
 	      /* Try text properties.  */
 	  if (!row->reversed_p)
 	    {
 	      last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-	      if (INTEGERP (last->object))
+	      if (INTEGERP (GLYPH_C_OBJECT(last)))
 		row_width -= last->pixel_width;
 	    }
 	  else
 		 Don't count that glyph.  */
 	      struct glyph *g = row->glyphs[TEXT_AREA];
 
-	      if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
+	      if (g->type == STRETCH_GLYPH && INTEGERP (GLYPH_C_OBJECT(g)))
 		{
 		  row_width -= g->pixel_width;
 		  seen_reversed_p = 1;
 	  if (row->used[TEXT_AREA] && !row->reversed_p)
 	    {
 	      last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
-	      if (INTEGERP (last->object))
+	      if (INTEGERP (GLYPH_C_OBJECT(last)))
 		row_width -= last->pixel_width;
 	    }