all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Make buffer- and frame-locals a misc object
@ 2012-08-15 10:50 Dmitry Antipov
  2012-08-15 14:20 ` Stefan Monnier
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Antipov @ 2012-08-15 10:50 UTC (permalink / raw)
  To: Emacs development discussions; +Cc: Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 191 bytes --]

This patch converts Lisp_Buffer_Local_Value to misc object (for the sake of
GC-aware management) and provides simple inline access functions (for the sake
of further GC development).

Dmitry

[-- Attachment #2: blv2.patch --]
[-- Type: text/plain, Size: 18110 bytes --]

=== modified file 'src/alloc.c'
--- src/alloc.c	2012-08-14 21:38:06 +0000
+++ src/alloc.c	2012-08-15 10:45:33 +0000
@@ -3697,7 +3697,21 @@
   free_misc (marker);
 }
 
-\f
+/* Return partially initialized buffer- or frame-local value.  */
+
+struct Lisp_Buffer_Local_Value *
+make_buffer_local_value (void)
+{
+  struct Lisp_Buffer_Local_Value *blv;
+
+  blv = XBLV (allocate_misc (Lisp_Misc_Buffer_Local_Value));
+  blv->frame_local = 0;
+  blv->local_if_set = 0;
+  set_blv_where (blv, Qnil);
+  set_blv_found (blv, 0);
+  return blv;
+}
+
 /* Return a newly created vector or string with specified arguments as
    elements.  If all the arguments are characters that can fit
    in a string of events, make a string; otherwise, make a vector.
@@ -6070,14 +6084,13 @@
 	    }
 	  case SYMBOL_LOCALIZED:
 	    {
-	      struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr);
+	      Lisp_Object tem;
+	      XSETMISC (tem, SYMBOL_BLV (ptr));
 	      /* If the value is forwarded to a buffer or keyboard field,
 		 these are marked when we see the corresponding object.
 		 And if it's forwarded to a C variable, either it's not
 		 a Lisp_Object var, or it's staticpro'd already.  */
-	      mark_object (blv->where);
-	      mark_object (blv->valcell);
-	      mark_object (blv->defcell);
+	      mark_object (tem);
 	      break;
 	    }
 	  case SYMBOL_FORWARDED:
@@ -6139,6 +6152,13 @@
 	  mark_overlay (XOVERLAY (obj));
 	  break;
 
+	case Lisp_Misc_Buffer_Local_Value:
+	  XMISCANY (obj)->gcmarkbit = 1;
+	  mark_object (XBLV (obj)->where);
+	  mark_object (XBLV (obj)->defcell);
+	  mark_object (XBLV (obj)->valcell);
+	  break;
+
 	default:
 	  abort ();
 	}
@@ -6460,8 +6480,6 @@
 
 	    if (!sym->s.gcmarkbit && !pure_p)
 	      {
-		if (sym->s.redirect == SYMBOL_LOCALIZED)
-		  xfree (SYMBOL_BLV (&sym->s));
 		sym->s.next = symbol_free_list;
 		symbol_free_list = &sym->s;
 #if GC_MARK_STACK

=== modified file 'src/data.c'
--- src/data.c	2012-08-14 17:10:38 +0000
+++ src/data.c	2012-08-15 10:39:00 +0000
@@ -543,7 +543,7 @@
 	else
 	  {
 	    swap_in_symval_forwarding (sym, blv);
-	    valcontents = BLV_VALUE (blv);
+	    valcontents = get_blv_value (blv);
 	  }
 	break;
       }
@@ -964,16 +964,16 @@
 
   /* Unload the previously loaded binding.  */
   if (blv->fwd)
-    SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
+    set_blv_value (blv, do_symval_forwarding (blv->fwd));
 
   /* Select the global binding in the symbol.  */
-  blv->valcell = blv->defcell;
+  set_blv_valcell (blv, blv->defcell);
   if (blv->fwd)
     store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL);
 
   /* Indicate that the global binding is set up now.  */
-  blv->where = Qnil;
-  SET_BLV_FOUND (blv, 0);
+  set_blv_where (blv, Qnil);
+  set_blv_found (blv, 0);
 }
 
 /* Set up the buffer-local symbol SYMBOL for validity in the current buffer.
@@ -1001,7 +1001,7 @@
       /* Unload the previously loaded binding.  */
       tem1 = blv->valcell;
       if (blv->fwd)
-	SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
+	set_blv_value (blv, do_symval_forwarding (blv->fwd));
       /* Choose the new binding.  */
       {
 	Lisp_Object var;
@@ -1009,7 +1009,7 @@
 	if (blv->frame_local)
 	  {
 	    tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist);
-	    blv->where = selected_frame;
+	    set_blv_where (blv, selected_frame);
 	  }
 	else
 	  {
@@ -1021,9 +1021,9 @@
 	tem1 = blv->defcell;
 
       /* Load the new binding.  */
-      blv->valcell = tem1;
+      set_blv_valcell (blv, tem1);
       if (blv->fwd)
-	store_symval_forwarding (blv->fwd, BLV_VALUE (blv), NULL);
+	store_symval_forwarding (blv->fwd, get_blv_value (blv), NULL);
     }
 }
 \f
@@ -1050,7 +1050,7 @@
       {
 	struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
 	swap_in_symval_forwarding (sym, blv);
-	return blv->fwd ? do_symval_forwarding (blv->fwd) : BLV_VALUE (blv);
+	return blv->fwd ? do_symval_forwarding (blv->fwd) : get_blv_value (blv);
       }
       /* FALLTHROUGH */
     case SYMBOL_FORWARDED:
@@ -1175,7 +1175,7 @@
 
 	    /* Write out `realvalue' to the old loaded binding.  */
 	    if (blv->fwd)
-	      SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
+	      set_blv_value (blv, do_symval_forwarding (blv->fwd));
 
 	    /* Find the new binding.  */
 	    XSETSYMBOL (symbol, sym); /* May have changed via aliasing.  */
@@ -1183,8 +1183,8 @@
 			  (blv->frame_local
 			   ? XFRAME (where)->param_alist
 			   : BVAR (XBUFFER (where), local_var_alist)));
-	    blv->where = where;
-	    blv->found = 1;
+	    set_blv_where (blv, where);
+	    set_blv_found (blv, 1);
 
 	    if (NILP (tem1))
 	      {
@@ -1199,7 +1199,7 @@
 		if (bindflag || !blv->local_if_set
 		    || let_shadows_buffer_binding_p (sym))
 		  {
-		    blv->found = 0;
+		    set_blv_found (blv, 0);
 		    tem1 = blv->defcell;
 		  }
 		/* If it's a local_if_set, being set not bound,
@@ -1219,11 +1219,11 @@
 	      }
 
 	    /* Record which binding is now loaded.  */
-	    blv->valcell = tem1;
+	    set_blv_valcell (blv, tem1);
 	  }
 
 	/* Store the new value in the cons cell.  */
-	SET_BLV_VALUE (blv, newval);
+	set_blv_value (blv, newval);
 
 	if (blv->fwd)
 	  {
@@ -1465,26 +1465,21 @@
 static struct Lisp_Buffer_Local_Value *
 make_blv (struct Lisp_Symbol *sym, int forwarded, union Lisp_Val_Fwd valcontents)
 {
-  struct Lisp_Buffer_Local_Value *blv = xmalloc (sizeof *blv);
-  Lisp_Object symbol;
-  Lisp_Object tem;
+  struct Lisp_Buffer_Local_Value *blv = make_buffer_local_value ();
+  Lisp_Object symbol, tem;
 
- XSETSYMBOL (symbol, sym);
- tem = Fcons (symbol, (forwarded
-                       ? do_symval_forwarding (valcontents.fwd)
-                       : valcontents.value));
+  XSETSYMBOL (symbol, sym);
+  tem = Fcons (symbol, (forwarded
+			? do_symval_forwarding (valcontents.fwd)
+			: valcontents.value));
 
   /* Buffer_Local_Values cannot have as realval a buffer-local
      or keyboard-local forwarding.  */
   eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd)));
   eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd)));
   blv->fwd = forwarded ? valcontents.fwd : NULL;
-  blv->where = Qnil;
-  blv->frame_local = 0;
-  blv->local_if_set = 0;
-  blv->defcell = tem;
-  blv->valcell = tem;
-  SET_BLV_FOUND (blv, 0);
+  set_blv_defcell (blv, tem);
+  set_blv_valcell (blv, tem);
   return blv;
 }
 
@@ -1660,10 +1655,8 @@
       /* Make sure symbol does not think it is set up for this buffer;
 	 force it to look once again for this buffer's value.  */
       if (current_buffer == XBUFFER (blv->where))
-	blv->where = Qnil;
-      /* blv->valcell = blv->defcell;
-       * SET_BLV_FOUND (blv, 0); */
-      blv->found = 0;
+	set_blv_where (blv, Qnil);
+      set_blv_found (blv, 0);
     }
 
   /* If the symbol forwards into a C variable, then load the binding
@@ -1733,10 +1726,8 @@
     Lisp_Object buf; XSETBUFFER (buf, current_buffer);
     if (EQ (buf, blv->where))
       {
-	blv->where = Qnil;
-	/* blv->valcell = blv->defcell;
-	 * SET_BLV_FOUND (blv, 0); */
-	blv->found = 0;
+	set_blv_where (blv, Qnil);
+	set_blv_found (blv, 0);
 	find_symbol_value (variable);
       }
   }
@@ -1857,11 +1848,11 @@
 	    if (EQ (variable, XCAR (elt)))
 	      {
 		eassert (!blv->frame_local);
-		eassert (BLV_FOUND (blv) || !EQ (blv->where, tmp));
+		eassert (get_blv_found (blv) || !EQ (blv->where, tmp));
 		return Qt;
 	      }
 	  }
-	eassert (!BLV_FOUND (blv) || !EQ (blv->where, tmp));
+	eassert (!get_blv_found (blv) || !EQ (blv->where, tmp));
 	return Qnil;
       }
     case SYMBOL_FORWARDED:
@@ -1951,7 +1942,7 @@
       if (!NILP (Flocal_variable_p (variable, Qnil)))
 	return Fcurrent_buffer ();
       else if (sym->redirect == SYMBOL_LOCALIZED
-	       && BLV_FOUND (SYMBOL_BLV (sym)))
+	       && get_blv_found (SYMBOL_BLV (sym)))
 	return SYMBOL_BLV (sym)->where;
       else
 	return Qnil;

=== modified file 'src/eval.c'
--- src/eval.c	2012-08-08 19:53:44 +0000
+++ src/eval.c	2012-08-15 10:11:49 +0000
@@ -3157,12 +3157,12 @@
 	    if (!NILP (Flocal_variable_p (symbol, Qnil)))
 	      {
 		eassert (sym->redirect != SYMBOL_LOCALIZED
-			 || (BLV_FOUND (SYMBOL_BLV (sym))
+			 || (get_blv_found (SYMBOL_BLV (sym))
 			     && EQ (cur_buf, SYMBOL_BLV (sym)->where)));
 		where = cur_buf;
 	      }
 	    else if (sym->redirect == SYMBOL_LOCALIZED
-		     && BLV_FOUND (SYMBOL_BLV (sym)))
+		     && get_blv_found (SYMBOL_BLV (sym)))
 	      where = SYMBOL_BLV (sym)->where;
 	    else
 	      where = Qnil;

=== modified file 'src/frame.c'
--- src/frame.c	2012-08-14 08:44:24 +0000
+++ src/frame.c	2012-08-15 10:11:49 +0000
@@ -2096,7 +2096,7 @@
 	case SYMBOL_PLAINVAL: case SYMBOL_FORWARDED: break;
 	case SYMBOL_LOCALIZED:
 	  { struct Lisp_Buffer_Local_Value *blv = sym->val.blv;
-	    if (blv->frame_local && BLV_FOUND (blv) && XFRAME (blv->where) == f)
+	    if (blv->frame_local && get_blv_found (blv) && XFRAME (blv->where) == f)
 	      swap_in_global_binding (sym);
 	    break;
 	  }

=== modified file 'src/lisp.h'
--- src/lisp.h	2012-08-14 17:45:25 +0000
+++ src/lisp.h	2012-08-15 10:43:09 +0000
@@ -280,6 +280,7 @@
     /* Currently floats are not a misc type,
        but let's define this in case we want to change that.  */
     Lisp_Misc_Float,
+    Lisp_Misc_Buffer_Local_Value,
     /* This is not a type code.  It is for range checking.  */
     Lisp_Misc_Limit
   };
@@ -515,10 +516,11 @@
 
 #define XMISC(a)	((union Lisp_Misc *) XUNTAG (a, Lisp_Misc))
 #define XMISCANY(a)	(eassert (MISCP (a)), &(XMISC (a)->u_any))
-#define XMISCTYPE(a)   (XMISCANY (a)->type)
+#define XMISCTYPE(a)	(XMISCANY (a)->type)
 #define XMARKER(a)	(eassert (MARKERP (a)), &(XMISC (a)->u_marker))
 #define XOVERLAY(a)	(eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay))
 #define XSAVE_VALUE(a)	(eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value))
+#define XBLV(a) 	(eassert (BLVP (a)), &(XMISC (a)->u_blv))
 
 /* Forwarding object types.  */
 
@@ -1342,6 +1344,59 @@
     Lisp_Object plist;
   };
 
+/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
+   the symbol has buffer-local or frame-local bindings.  (Exception:
+   some buffer-local variables are built-in, with their values stored
+   in the buffer structure itself.  They are handled differently,
+   using struct Lisp_Buffer_Objfwd.)
+
+   The `realvalue' slot holds the variable's current value, or a
+   forwarding pointer to where that value is kept.  This value is the
+   one that corresponds to the loaded binding.  To read or set the
+   variable, you must first make sure the right binding is loaded;
+   then you can access the value in (or through) `realvalue'.
+
+   `buffer' and `frame' are the buffer and frame for which the loaded
+   binding was found.  If those have changed, to make sure the right
+   binding is loaded it is necessary to find which binding goes with
+   the current buffer and selected frame, then load it.  To load it,
+   first unload the previous binding, then copy the value of the new
+   binding into `realvalue' (or through it).  Also update
+   LOADED-BINDING to point to the newly loaded binding.
+
+   `local_if_set' indicates that merely setting the variable creates a
+   local binding for the current buffer.  Otherwise the latter, setting
+   the variable does not do that; only make-local-variable does that.  */
+
+struct Lisp_Buffer_Local_Value
+  {
+    ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Buffer_Local_Value */
+    unsigned gcmarkbit : 1;
+    int spacer : 12;
+    /* 1 means that merely setting the variable creates a local
+       binding for the current buffer.  */
+    unsigned int local_if_set : 1;
+    /* 1 means this variable can have frame-local bindings, otherwise, it is
+       can have buffer-local bindings.  The two cannot be combined.  */
+    unsigned int frame_local : 1;
+    /* 1 means that the binding now loaded was found.
+       Presumably equivalent to (defcell!=valcell).  */
+    unsigned int found : 1;
+    /* If non-NULL, a forwarding to the C var where it should also be set.  */
+    union Lisp_Fwd *fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
+    /* The buffer or frame for which the loaded binding was found.  */
+    Lisp_Object where;
+    /* A cons cell that holds the default value.  It has the form
+       (SYMBOL . DEFAULT-VALUE).  */
+    Lisp_Object defcell;
+    /* The cons cell from `where's parameter alist.
+       It always has the form (SYMBOL . VALUE)
+       Note that if `forward' is non-nil, VALUE may be out of date.
+       Also if the currently loaded binding is the default binding, then
+       this is `eq'ual to defcell.  */
+    Lisp_Object valcell;
+  };
+
 /* Hold a C pointer for later use.
    This type of object is used in the arg to record_unwind_protect.  */
 struct Lisp_Save_Value
@@ -1375,6 +1430,7 @@
     struct Lisp_Free u_free;
     struct Lisp_Marker u_marker;
     struct Lisp_Overlay u_overlay;
+    struct Lisp_Buffer_Local_Value u_blv;
     struct Lisp_Save_Value u_save_value;
   };
 
@@ -1417,64 +1473,6 @@
     Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String.  */
   };
 
-/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
-   the symbol has buffer-local or frame-local bindings.  (Exception:
-   some buffer-local variables are built-in, with their values stored
-   in the buffer structure itself.  They are handled differently,
-   using struct Lisp_Buffer_Objfwd.)
-
-   The `realvalue' slot holds the variable's current value, or a
-   forwarding pointer to where that value is kept.  This value is the
-   one that corresponds to the loaded binding.  To read or set the
-   variable, you must first make sure the right binding is loaded;
-   then you can access the value in (or through) `realvalue'.
-
-   `buffer' and `frame' are the buffer and frame for which the loaded
-   binding was found.  If those have changed, to make sure the right
-   binding is loaded it is necessary to find which binding goes with
-   the current buffer and selected frame, then load it.  To load it,
-   first unload the previous binding, then copy the value of the new
-   binding into `realvalue' (or through it).  Also update
-   LOADED-BINDING to point to the newly loaded binding.
-
-   `local_if_set' indicates that merely setting the variable creates a
-   local binding for the current buffer.  Otherwise the latter, setting
-   the variable does not do that; only make-local-variable does that.  */
-
-struct Lisp_Buffer_Local_Value
-  {
-    /* 1 means that merely setting the variable creates a local
-       binding for the current buffer.  */
-    unsigned int local_if_set : 1;
-    /* 1 means this variable can have frame-local bindings, otherwise, it is
-       can have buffer-local bindings.  The two cannot be combined.  */
-    unsigned int frame_local : 1;
-    /* 1 means that the binding now loaded was found.
-       Presumably equivalent to (defcell!=valcell).  */
-    unsigned int found : 1;
-    /* If non-NULL, a forwarding to the C var where it should also be set.  */
-    union Lisp_Fwd *fwd;	/* Should never be (Buffer|Kboard)_Objfwd.  */
-    /* The buffer or frame for which the loaded binding was found.  */
-    Lisp_Object where;
-    /* A cons cell that holds the default value.  It has the form
-       (SYMBOL . DEFAULT-VALUE).  */
-    Lisp_Object defcell;
-    /* The cons cell from `where's parameter alist.
-       It always has the form (SYMBOL . VALUE)
-       Note that if `forward' is non-nil, VALUE may be out of date.
-       Also if the currently loaded binding is the default binding, then
-       this is `eq'ual to defcell.  */
-    Lisp_Object valcell;
-  };
-
-#define BLV_FOUND(blv) \
-  (eassert ((blv)->found == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found)
-#define SET_BLV_FOUND(blv, v) \
-  (eassert ((v) == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found = (v))
-
-#define BLV_VALUE(blv) (XCDR ((blv)->valcell))
-#define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v))
-
 /* Like Lisp_Objfwd except that value lives in a slot in the
    current kboard.  */
 struct Lisp_Kboard_Objfwd
@@ -1664,6 +1662,7 @@
 #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
 #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
 #define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
+#define BLVP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Buffer_Local_Value)
 
 #define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int)
 #define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool)
@@ -2407,6 +2406,53 @@
   XSYMBOL (sym)->next = next;
 }
 
+/* Use these functions to get and set Lisp_Object
+   slots of struct Lisp_Buffer_Local_Value.  */
+
+LISP_INLINE int
+get_blv_found (struct Lisp_Buffer_Local_Value *blv)
+{
+  eassert (blv->found == !EQ (blv->defcell, blv->valcell));
+  return blv->found;
+}
+
+LISP_INLINE void
+set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found)
+{
+  eassert (found == !EQ (blv->defcell, blv->valcell));
+  blv->found = found;
+}
+
+LISP_INLINE Lisp_Object
+get_blv_value (struct Lisp_Buffer_Local_Value *blv)
+{
+  return XCDR (blv->valcell);
+}
+
+LISP_INLINE void
+set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
+{
+  XSETCDR (blv->valcell, val);
+}
+
+LISP_INLINE void
+set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
+{
+  blv->where = val;
+}
+
+LISP_INLINE void
+set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
+{
+  blv->defcell = val;
+}
+
+LISP_INLINE void
+set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
+{
+  blv->valcell = val;
+}
+
 /* Set overlay's property list.  */
 
 LISP_INLINE void
@@ -2802,6 +2848,7 @@
 extern void display_malloc_warning (void);
 extern ptrdiff_t inhibit_garbage_collection (void);
 extern Lisp_Object make_save_value (void *, ptrdiff_t);
+extern struct Lisp_Buffer_Local_Value * make_buffer_local_value (void);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
 extern void free_marker (Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-08-21 17:35 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-15 10:50 Make buffer- and frame-locals a misc object Dmitry Antipov
2012-08-15 14:20 ` Stefan Monnier
2012-08-15 14:33   ` Dmitry Antipov
2012-08-15 16:02     ` Stefan Monnier
2012-08-16  4:10       ` Buffer-/frame-local variables [Was: Re: Make buffer- and frame-locals a misc object] Dmitry Antipov
2012-08-17 13:20         ` Stefan Monnier
2012-08-17 14:29           ` Dmitry Antipov
2012-08-21 17:35             ` Stefan Monnier
2012-08-17 17:11           ` Paul Eggert

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.