Commits

Michele Bini committed 5e02436

Convert and connect tty_list to extra_gc_roots, and consequently remove special GC hook.

  • Participants
  • Parent commits b50d27d

Comments (0)

Files changed (11)

   GC_PHASE_MARK_BUFFERS,
   GC_PHASE_MARK_TERMINALS,
   GC_PHASE_MARK_KBOARDS,
-  GC_PHASE_MARK_TTYS,
   GC_PHASE_MARK_EXTRAROOTS
 };
 
   register struct specbinding *bind;
   char stack_top_variable;
   ptrdiff_t i;
-  int message_p;
   Lisp_Object total[8];
   EMACS_TIME t1, t2, t3;
 
     }
   mark_terminals ();
   mark_kboards ();
-  mark_ttys ();
 
 #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
      || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)

File src/dispnew.c

   int old_errno = errno;
 
   struct tty_display_info *tty;
+  Lisp_Object tty_l;
 
   signal (SIGWINCH, window_change_signal);
   SIGNAL_THREAD_CHECK (signalnum);
      termcap-controlled terminal, but we can't decide which.
      Therefore, we resize the frames corresponding to each tty.
   */
-  for (tty = tty_list; tty; tty = tty->next) {
-
+  FOR_EACH_TTY(tty, tty_l) {
     if (! tty->term_initted)
       continue;
 

File src/fringe.c

 
   if (face_id == DEFAULT_FACE_ID)
     {
-      Lisp_Object face = AREF(GET_GC_ROOT(fringe_faces), which);
+      Lisp_Object face = AREF(GC_ROOT(fringe_faces), which);
       face_id = NILP (face) ? lookup_named_face (f, Qfringe, 0)
 	: lookup_derived_face (f, face, FRINGE_FACE_ID, 0);
       if (face_id < 0)
 {
   struct fringe_bitmap **fbp;
 
-  ASET(GET_GC_ROOT(fringe_faces), n, Qnil);
+  ASET(GC_ROOT(fringe_faces), n, Qnil);
 
   fbp = &fringe_bitmaps[n];
   if (*fbp && (*fbp)->dynamic)
 	      {
 		Lisp_Object new_vector = Fmake_vector(make_number(bitmaps), Qnil);
 		for (i = 0; i < max_fringe_bitmaps; i++) {
-		  ASET(new_vector, n, AREF(GET_GC_ROOT(fringe_faces), n));
+		  ASET(new_vector, n, AREF(GC_ROOT(fringe_faces), n));
 		}
 		SET_GC_ROOT(fringe_faces, new_vector);
 	      }
 	error ("No such face");
     }
 
-  ASET(GET_GC_ROOT(fringe_faces), n, face);
+  ASET(GC_ROOT(fringe_faces), n, face);
 
   return Qnil;
 }

File src/gtkutil.c

 
     SET_GC_ROOT(xg_menu_cb_list,
 		xg_list_insert(cl_data_lisp, 
-			       GET_GC_ROOT(xg_menu_cb_list)));
+			       GC_ROOT(xg_menu_cb_list)));
   }
   return cl_data_lisp;
 }
         {
 	  SET_GC_ROOT(xg_menu_cb_list,
 		      xg_list_remove(cl_data_lisp,
-				     GET_GC_ROOT(xg_menu_cb_list)));
+				     GC_ROOT(xg_menu_cb_list)));
         }
     }
 }
     {
       SET_GC_ROOT(xg_menu_item_cb_list,
 		  xg_list_remove(data,
-				 GET_GC_ROOT(xg_menu_item_cb_list)));
+				 GC_ROOT(xg_menu_item_cb_list)));
     }
 }
 
 
   SET_GC_ROOT(xg_menu_item_cb_list,
 	      xg_list_insert(cb_data_lisp,
-			     GET_GC_ROOT(xg_menu_item_cb_list)));
+			     GC_ROOT(xg_menu_item_cb_list)));
 
   g_signal_connect (G_OBJECT (w),
                     "destroy",

File src/keyboard.c

   struct gcpro gcpro1;
   Lisp_Object hook;
 
-  if (tty_list && tty_list->next)
-    error ("There are other tty frames open; close them before suspending Emacs");
+  {
+    Lisp_Object tty = GC_ROOT(tty_list);
+    if (!NILP(tty) && !NILP(XTDINEXT(tty)))
+      error ("There are other tty frames open; close them before suspending Emacs");
+  }
 
   if (!NILP (stuffstring))
     CHECK_STRING (stuffstring);
 };
 
 extern Lisp_Object extra_gc_roots; /* Lisp list holding extra gc roots */
-#define DECLARE_GC_ROOT(var) static Lisp_Object var##__gc_root; static Lisp_Object var##__gc_root_cell;  static Lisp_Object var##__gc_root_init = 0
+
+#define GC_ROOT(var) LISP_MAKE_RVALUE(var##__gc_root)
 #define REFRESH_GC_ROOT(var) XSETCAR(var##__gc_root_cell, var##__gc_root)
-#define GET_GC_ROOT(var) LISP_MAKE_RVALUE(var##__gc_root)
+#define GC_ROOT_PAT(var) LISP_MAKE_RVALUE(var##__gc_root_init)
 #define SET_GC_ROOT(var, value) do { var##__gc_root = (value); REFRESH_GC_ROOT(var); } while (0)
+#define FIX_GC_ROOT(var) do { if (!var##__gc_root_init) { extra_gc_roots = var##__gc_root_cell = Fcons(Qnil, extra_gc_roots); var##__gc_root_init=1; } } while (0)
 #define INSTALL_GC_ROOT(var, value) do { var##__gc_root = value; if (!var##__gc_root_init) { extra_gc_roots = var##__gc_root_cell = Fcons(var##__gc_root, extra_gc_roots); var##__gc_root_init=1; } else { REFRESH_GC_ROOT(var); } } while (0)
 
+#define DECLARE_GC_ROOT(var)   	     static Lisp_Object var##__gc_root; static Lisp_Object var##__gc_root_cell; static Lisp_Object var##__gc_root_init = 0
+#define DECLARE_GLOBAL_GC_ROOT(var)         Lisp_Object var##__gc_root;        Lisp_Object var##__gc_root_cell;        Lisp_Object var##__gc_root_init
+#define DECLARE_EXTERN_GC_ROOT(var)  extern Lisp_Object var##__gc_root; extern Lisp_Object var##__gc_root_cell; extern Lisp_Object var##__gc_root_init
+
 #undef GC_MARK_STACK /* undef for developing incremental GC */
 
 /* Values of GC_MARK_STACK during compilation:

File src/sysdep.c

 #else /* not MSDOS */
   {
     struct tty_display_info *tty;
-    for (tty = tty_list; tty; tty = tty->next)
+    Lisp_Object tty_l;
+    FOR_EACH_TTY(tty, tty_l) 
       {
         if (tty->input)         /* Is the device suspended? */
           {
 init_all_sys_modes (void)
 {
   struct tty_display_info *tty;
-  for (tty = tty_list; tty; tty = tty->next)
+  Lisp_Object tty_l;
+  FOR_EACH_TTY(tty, tty_l)
     init_sys_modes (tty);
 }
 
 reset_all_sys_modes (void)
 {
   struct tty_display_info *tty;
-  for (tty = tty_list; tty; tty = tty->next)
+  Lisp_Object tty_l;
+  FOR_EACH_TTY(tty, tty_l)
     reset_sys_modes (tty);
 }
 
 /* Display space properties */
 
 /* Chain of all tty device parameters. */
-struct tty_display_info *tty_list;
+DECLARE_GLOBAL_GC_ROOT(tty_list);
 
 /* Meaning of bits in no_color_video.  Each bit set means that the
    corresponding attribute cannot be combined with colors.  */
   been_here = 1;
   tty = &the_only_display_info;
 #else
-  tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
+  tty = ALLOCATE_TTYDISPLAYINFO();
 #endif
   memset (tty, 0, sizeof (struct tty_display_info));
-  tty->next = tty_list;
-  tty_list = tty;
+  FIX_GC_ROOT(tty_list);
+  {
+    Lisp_Object x;
+    XSETTTYDISPLAYINFO(x, tty);
+    XSETTDINEXT      (x,         GC_ROOT(tty_list));
+    XSETTDITOPFRAME  (x,         Qnil);
+    SET_GC_ROOT      (tty_list,  x);
+  }
 
   terminal->type = output_termcap;
   terminal->display_info.tty = tty;
 delete_tty (struct terminal *terminal)
 {
   struct tty_display_info *tty;
+  Lisp_Object tty_l;
 
   /* Protect against recursive calls.  delete_frame in
      delete_terminal calls us back when it deletes our last frame.  */
     abort ();
 
   tty = terminal->display_info.tty;
+  XSETTTYDISPLAYINFO(tty_l, tty);
 
-  if (tty == tty_list)
-    tty_list = tty->next;
+  if (EQ(tty_l, GC_ROOT(tty_list)))
+    SET_GC_ROOT(tty_list, XTDINEXT(tty_l));
   else
     {
-      struct tty_display_info *p;
-      for (p = tty_list; p && p->next != tty; p = p->next)
-        ;
-
-      if (! p)
+      Lisp_Object t;
+      Lisp_Object p;
+      FOR_EACH_TTY_L(t) {
+	if (EQ(t, tty_l)) {
+	    break;
+	}
+	p = t;
+      }
+      if (NILP(t))
         /* This should not happen. */
         abort ();
 
-      p->next = tty->next;
-      tty->next = 0;
+      XSETTDINEXT(p, XTDINEXT(tty_l));
+      XSETTDINEXT(tty_l, Qnil);
     }
 
   /* reset_sys_modes needs a valid device, so this call needs to be
   xfree (tty->Wcm);
   xfree (tty->termcap_strings_buffer);
   xfree (tty->termcap_term_buffer);
-
-  memset (tty, 0, sizeof (struct tty_display_info));
-  xfree (tty);
-}
-
-
-
-/* Mark the pointers in the tty_display_info objects.
-   Called by the Fgarbage_collector.  */
-
-void
-mark_ttys (void)
-{
-  struct tty_display_info *tty;
-
-  for (tty = tty_list; tty; tty = tty->next)
-    mark_object (tty->top_frame);
 }
 
 

File src/termchar.h

 
 struct tty_display_info
 {
-  struct tty_display_info *next; /* Chain of all tty devices. */
+  struct vectorlike_header header;
+#define XTTYDISPLAYINFO(a) ((struct tty_display_info *)XPNTR_OR_NULL(a))
+#define XSETTTYDISPLAYINFO(a, b) XSETPSEUDOVECTOR(a, b, PVEC_OTHER)
 
+  Lisp_Object ___next; /* Chain of all tty devices. */
+#define XTDINEXT(cbdata) AREF(cbdata, 0)
+#define XSETTDINEXT(cbdata, x) ASET(cbdata, 0, x)
+  Lisp_Object top_frame;        /* The topmost frame on this tty. */
+#define XTDITOPFRAME(cbdata) AREF(cbdata, 1)
+#define XSETTDITOPFRAME(cbdata, x) ASET(cbdata, 1, x)
+
+#define ALLOCATE_TTYDISPLAYINFO()			\
+  ALLOCATE_PSEUDOVECTOR(struct tty_display_info,	\
+			name, PVEC_OTHER)
   char *name;                   /* The name of the device file or 0 if
                                    stdin/stdout. */
   char *type;                   /* The type of the tty. */
   /* Info on cursor positioning.  */
   struct cm *Wcm;
 
-  /* Redisplay. */
-
-  Lisp_Object top_frame;        /* The topmost frame on this tty. */
-
   /* The previous frame we displayed on this tty.  */
   struct frame *previous_frame;
   int previous_color_mode;
 
 };
 
+#define FOR_EACH_TTY(tty, tty_l) for (tty_l = GC_ROOT(tty_list); (tty = XTTYDISPLAYINFO(tty_l)) != NULL; tty_l = XTDINEXT(tty_l))
+
+#define FOR_EACH_TTY_L(tty_l) for (tty_l = GC_ROOT(tty_list); !NILP(tty_l); tty_l = XTDINEXT(tty_l))
+
 /* A chain of structures for all tty devices currently in use. */
-extern struct tty_display_info *tty_list;
+DECLARE_EXTERN_GC_ROOT(tty_list);
 
 
 #define FRAME_TTY(f)                            \

File src/terminal.c

 struct terminal *
 init_initial_terminal (void)
 {
-  if (initialized || terminal_list || tty_list)
+  if (initialized || terminal_list || GC_ROOT_PAT(tty_list))
     abort ();
 
   initial_terminal = create_terminal ();
 menu_highlight_callback (GtkWidget *widget, gpointer call_data)
 {
   Lisp_Object cb_data_lisp;
-  xg_menu_item_cb_data *cb_data;
   Lisp_Object help;
 
   cb_data_lisp =