Now on revision 109224. ------------------------------------------------------------ revno: 109224 fixes bug(s): http://debbugs.gnu.org/12036 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 23:18:36 -0700 message: Improve GDB symbol export. * .gdbinit (xgetptr, xgetint, xgettype): Set $bugfix in different arms of an 'if', not using conditional expressions; otherwise GDB complains about the types in the unevaluated arm when the argument is an integer literal. (xgetint): Simplify expression. * alloc.c (gdb_make_enums_visible): New constant. This ports to GCC 3.4.2 the export of symbols to GDB. Problem reported by Eli Zaretskii in . * lisp.h (PUBLISH_TO_GDB): Remove. All uses removed. No longer needed now that we have gdb_make_enums_visible. (enum CHECK_LISP_OBJECT_TYPE, enum Lisp_Bits, enum More_Lisp_Bits) (enum enum_USE_LSB_TAG): New enum types, packaging up enums that need to be exported to GDB. diff: === modified file 'src/.gdbinit' --- src/.gdbinit 2012-07-26 08:12:03 +0000 +++ src/.gdbinit 2012-07-27 06:18:36 +0000 @@ -46,17 +46,29 @@ # Use $bugfix so that the value isn't a constant. # Using a constant runs into GDB bugs sometimes. define xgetptr - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end set $ptr = ($bugfix & VALMASK) | DATA_SEG_BITS end define xgetint - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 - set $int = USE_LSB_TAG ? $bugfix >> INTTYPEBITS : $bugfix << INTTYPEBITS >> INTTYPEBITS + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end + set $int = $bugfix << (USE_LSB_TAG ? 0 : INTTYPEBITS) >> INTTYPEBITS end define xgettype - set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + if (CHECK_LISP_OBJECT_TYPE) + set $bugfix = $arg0.i + else + set $bugfix = $arg0 + end set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : $bugfix >> VALBITS) end === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-27 06:04:35 +0000 +++ src/ChangeLog 2012-07-27 06:18:36 +0000 @@ -1,3 +1,20 @@ +2012-07-27 Paul Eggert + + Improve GDB symbol export (Bug#12036). + * .gdbinit (xgetptr, xgetint, xgettype): Set $bugfix in different + arms of an 'if', not using conditional expressions; otherwise GDB + complains about the types in the unevaluated arm when the argument + is an integer literal. + (xgetint): Simplify expression. + * alloc.c (gdb_make_enums_visible): New constant. This ports to + GCC 3.4.2 the export of symbols to GDB. Problem reported by Eli + Zaretskii in . + * lisp.h (PUBLISH_TO_GDB): Remove. All uses removed. No longer + needed now that we have gdb_make_enums_visible. + (enum CHECK_LISP_OBJECT_TYPE, enum Lisp_Bits, enum More_Lisp_Bits) + (enum enum_USE_LSB_TAG): + New enum types, packaging up enums that need to be exported to GDB. + 2012-07-27 Dmitry Antipov Utility function to make a list from specified amount of objects. === modified file 'src/alloc.c' --- src/alloc.c 2012-07-27 06:04:35 +0000 +++ src/alloc.c 2012-07-27 06:18:36 +0000 @@ -6910,12 +6910,25 @@ #endif } -/* Make some symbols visible to GDB. These cannot be done as enums, like - GCTYPEBITS or USE_LSB_TAG, since values might not be in 'int' range. - Each symbol X has a corresponding X_VAL symbol, verified to have - the correct value. - - This is last, so that the #undef lines don't mess up later code. */ +/* Make some symbols visible to GDB. This section is last, so that + the #undef lines don't mess up later code. */ + +/* When compiled with GCC, GDB might say "No enum type named + pvec_type" if we don't have at least one symbol with that type, and + then xbacktrace could fail. Similarly for the other enums and + their values. */ +union +{ + enum CHECK_LISP_OBJECT_TYPE CHECK_LISP_OBJECT_TYPE; + enum enum_USE_LSB_TAG enum_USE_LSB_TAG; + enum Lisp_Bits Lisp_Bits; + enum More_Lisp_Bits More_Lisp_Bits; + enum pvec_type pvec_type; +} const EXTERNALLY_VISIBLE gdb_make_enums_visible = {0}; + +/* These symbols cannot be done as enums, since values might not be + in 'int' range. Each symbol X has a corresponding X_VAL symbol, + verified to have the correct value. */ #define ARRAY_MARK_FLAG_VAL PTRDIFF_MIN #define PSEUDOVECTOR_FLAG_VAL (PTRDIFF_MAX - PTRDIFF_MAX / 2) === modified file 'src/lisp.h' --- src/lisp.h 2012-07-27 06:04:35 +0000 +++ src/lisp.h 2012-07-27 06:18:36 +0000 @@ -64,12 +64,6 @@ # endif #endif -/* If an enum type is not used, the enum symbols are not put into the - executable so the debugger cannot see them on many systems, e.g., - GCC 4.7.1 + GDB 7.4.1 + GNU/Linux. Work around this problem by - explicitly using the names in the integer constant expression EXPR. */ -#define PUBLISH_TO_GDB(expr) extern int (*gdb_dummy (int))[(expr) || 1] - /* Number of bits in some machine integer types. */ enum { @@ -161,14 +155,23 @@ variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ -/* Number of bits in a Lisp_Object tag. This can be used in #if, - and for GDB's sake also as a regular symbol. */ -enum { GCTYPEBITS = 3 }; -PUBLISH_TO_GDB (GCTYPEBITS); +enum Lisp_Bits + { + /* Number of bits in a Lisp_Object tag. This can be used in #if, + and for GDB's sake also as a regular symbol. */ + GCTYPEBITS = #define GCTYPEBITS 3 - -/* Number of bits in a Lisp_Object value, not counting the tag. */ -enum { VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS }; + GCTYPEBITS, + + /* Number of bits in a Lisp_Object value, not counting the tag. */ + VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, + + /* Number of bits in a Lisp fixnum tag. */ + INTTYPEBITS = GCTYPEBITS - 1, + + /* Number of bits in a Lisp fixnum value, not counting the tag. */ + FIXNUM_BITS = VALBITS + 1 + }; /* The maximum value that can be stored in a EMACS_INT, assuming all bits other than the type bits contribute to a nonnegative signed value. @@ -211,16 +214,12 @@ # endif # endif #endif -/* USE_LSB_TAG can be used in #if; default it to 0 and make it visible - to GDB. */ #ifdef USE_LSB_TAG # undef USE_LSB_TAG -enum { USE_LSB_TAG = 1 }; -PUBLISH_TO_GDB (USE_LSB_TAG); +enum enum_USE_LSB_TAG { USE_LSB_TAG = 1 }; # define USE_LSB_TAG 1 #else -enum { USE_LSB_TAG = 0 }; -PUBLISH_TO_GDB (USE_LSB_TAG); +enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; # define USE_LSB_TAG 0 #endif @@ -239,8 +238,6 @@ /* Lisp integers use 2 tags, to give them one extra bit, thus extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ -enum { INTTYPEBITS = GCTYPEBITS - 1 }; -enum { FIXNUM_BITS = VALBITS + 1 }; #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) #define LISP_INT_TAG Lisp_Int0 #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 @@ -335,9 +332,9 @@ } #define LISP_INITIALLY_ZERO {0} + #undef CHECK_LISP_OBJECT_TYPE -enum { CHECK_LISP_OBJECT_TYPE = 1 }; - +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 }; #else /* CHECK_LISP_OBJECT_TYPE */ /* If a struct type is not wanted, define Lisp_Object as just a number. */ @@ -347,9 +344,8 @@ #define XIL(i) (i) #define LISP_MAKE_RVALUE(o) (0+(o)) #define LISP_INITIALLY_ZERO 0 -enum { CHECK_LISP_OBJECT_TYPE = 0 }; +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; #endif /* CHECK_LISP_OBJECT_TYPE */ -PUBLISH_TO_GDB (CHECK_LISP_OBJECT_TYPE); /* In the size word of a vector, this bit means the vector has been marked. */ @@ -390,35 +386,32 @@ PVEC_SUB_CHAR_TABLE = 0x30, PVEC_FONT = 0x40 }; -PUBLISH_TO_GDB ((enum pvec_type) 0); /* This also publishes PVEC_*. */ - -/* For convenience, we also store the number of elements in these bits. - Note that this size is not necessarily the memory-footprint size, but - only the number of Lisp_Object fields (that need to be traced by the GC). - The distinction is used e.g. by Lisp_Process which places extra - non-Lisp_Object fields at the end of the structure. */ -enum + +/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers + which were stored in a Lisp_Object. */ +#ifndef DATA_SEG_BITS +# define DATA_SEG_BITS 0 +#endif +enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; +#undef DATA_SEG_BITS + +enum More_Lisp_Bits { + DATA_SEG_BITS = gdb_DATA_SEG_BITS, + + /* For convenience, we also store the number of elements in these bits. + Note that this size is not necessarily the memory-footprint size, but + only the number of Lisp_Object fields (that need to be traced by GC). + The distinction is used, e.g., by Lisp_Process, which places extra + non-Lisp_Object fields at the end of the structure. */ PSEUDOVECTOR_SIZE_BITS = 16, PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, - PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS + PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS, + + /* Number of bits to put in each character in the internal representation + of bool vectors. This should not vary across implementations. */ + BOOL_VECTOR_BITS_PER_CHAR = 8 }; - -/* Number of bits to put in each character in the internal representation - of bool vectors. This should not vary across implementations. */ -enum { BOOL_VECTOR_BITS_PER_CHAR = 8 }; - -/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object. It is not needed in #if, so - for GDB's sake change it from a macro to a regular symbol. */ -#ifdef DATA_SEG_BITS -enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; -# undef DATA_SEG_BITS -enum { DATA_SEG_BITS = gdb_DATA_SEG_BITS }; -#else -enum { DATA_SEG_BITS = 0 }; -#endif -PUBLISH_TO_GDB (DATA_SEG_BITS); /* These macros extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons, ------------------------------------------------------------ revno: 109223 committer: Dmitry Antipov branch nick: trunk timestamp: Fri 2012-07-27 10:04:35 +0400 message: Utility function to make a list from specified amount of objects. * lisp.h (enum constype): New datatype. (listn): New prototype. * alloc.c (listn): New function. (Fmemory_use_count, syms_of_alloc): Use it. * buffer.c (syms_of_buffer): Likewise. * callint.c (syms_of_callint): Likewise. * charset.c (define_charset_internal): Likewise. * coding.c (syms_of_coding): Likewise. * keymap.c (syms_of_keymap): Likewise. * search.c (syms_of_search): Likewise. * syntax.c (syms_of_syntax): Likewise. * w32.c (init_environment): Likewise. * w32fns.c (Fw32_battery_status, syms_of_w32fns): Likewise. * xdisp.c (syms_of_xdisp): Likewise. * xfns.c (syms_of_xfns): Likewise. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-27 02:47:07 +0000 +++ src/ChangeLog 2012-07-27 06:04:35 +0000 @@ -1,5 +1,24 @@ 2012-07-27 Dmitry Antipov + Utility function to make a list from specified amount of objects. + * lisp.h (enum constype): New datatype. + (listn): New prototype. + * alloc.c (listn): New function. + (Fmemory_use_count, syms_of_alloc): Use it. + * buffer.c (syms_of_buffer): Likewise. + * callint.c (syms_of_callint): Likewise. + * charset.c (define_charset_internal): Likewise. + * coding.c (syms_of_coding): Likewise. + * keymap.c (syms_of_keymap): Likewise. + * search.c (syms_of_search): Likewise. + * syntax.c (syms_of_syntax): Likewise. + * w32.c (init_environment): Likewise. + * w32fns.c (Fw32_battery_status, syms_of_w32fns): Likewise. + * xdisp.c (syms_of_xdisp): Likewise. + * xfns.c (syms_of_xfns): Likewise. + +2012-07-27 Dmitry Antipov + Fast save_excursion_save and save_excursion_restore. * lisp.h (struct Lisp_Excursion): New data type. (PVEC_EXCURSION): New pseudovector type. === modified file 'src/alloc.c' --- src/alloc.c 2012-07-27 02:47:07 +0000 +++ src/alloc.c 2012-07-27 06:04:35 +0000 @@ -2811,6 +2811,38 @@ Fcons (arg5, Qnil))))); } +/* Make a list of COUNT Lisp_Objects, where ARG is the + first one. Allocate conses from pure space if TYPE + is PURE, or allocate as usual if type is HEAP. */ + +Lisp_Object +listn (enum constype type, ptrdiff_t count, Lisp_Object arg, ...) +{ + va_list ap; + ptrdiff_t i; + Lisp_Object val, *objp; + + /* Change to SAFE_ALLOCA if you hit this eassert. */ + eassert (count <= MAX_ALLOCA / sizeof (Lisp_Object)); + + objp = alloca (count * sizeof (Lisp_Object)); + objp[0] = arg; + va_start (ap, arg); + for (i = 1; i < count; i++) + objp[i] = va_arg (ap, Lisp_Object); + va_end (ap); + + for (i = 0, val = Qnil; i < count; i++) + { + if (type == PURE) + val = pure_cons (objp[i], val); + else if (type == HEAP) + val = Fcons (objp[i], val); + else + abort (); + } + return val; +} DEFUN ("list", Flist, Slist, 0, MANY, 0, doc: /* Return a newly created list with specified arguments as elements. @@ -6649,18 +6681,15 @@ (but the contents of a buffer's text do not count here). */) (void) { - Lisp_Object consed[8]; - - consed[0] = bounded_number (cons_cells_consed); - consed[1] = bounded_number (floats_consed); - consed[2] = bounded_number (vector_cells_consed); - consed[3] = bounded_number (symbols_consed); - consed[4] = bounded_number (string_chars_consed); - consed[5] = bounded_number (misc_objects_consed); - consed[6] = bounded_number (intervals_consed); - consed[7] = bounded_number (strings_consed); - - return Flist (8, consed); + return listn (HEAP, 8, + bounded_number (cons_cells_consed), + bounded_number (floats_consed), + bounded_number (vector_cells_consed), + bounded_number (symbols_consed), + bounded_number (string_chars_consed), + bounded_number (misc_objects_consed), + bounded_number (intervals_consed), + bounded_number (strings_consed)); } /* Find at most FIND_MAX symbols which have OBJ as their value or @@ -6841,8 +6870,8 @@ /* We build this in advance because if we wait until we need it, we might not be able to allocate the memory to hold it. */ Vmemory_signal_data - = pure_cons (Qerror, - pure_cons (build_pure_c_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs"), Qnil)); + = listn (PURE, 2, Qerror, + build_pure_c_string ("Memory exhausted--use M-x save-some-buffers then exit and restart Emacs")); DEFVAR_LISP ("memory-full", Vmemory_full, doc: /* Non-nil means Emacs cannot get much more Lisp memory. */); === modified file 'src/buffer.c' --- src/buffer.c 2012-07-25 05:09:02 +0000 +++ src/buffer.c 2012-07-27 06:04:35 +0000 @@ -5212,7 +5212,7 @@ DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions"); Fput (Qprotected_field, Qerror_conditions, - pure_cons (Qprotected_field, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qprotected_field, Qerror)); Fput (Qprotected_field, Qerror_message, build_pure_c_string ("Attempt to modify a protected field")); === modified file 'src/callint.c' --- src/callint.c 2012-07-10 16:53:26 +0000 +++ src/callint.c 2012-07-27 06:04:35 +0000 @@ -888,10 +888,11 @@ callint_message = Qnil; staticpro (&callint_message); - preserved_fns = pure_cons (intern_c_string ("region-beginning"), - pure_cons (intern_c_string ("region-end"), - pure_cons (intern_c_string ("point"), - pure_cons (intern_c_string ("mark"), Qnil)))); + preserved_fns = listn (PURE, 4, + intern_c_string ("region-beginning"), + intern_c_string ("region-end"), + intern_c_string ("point"), + intern_c_string ("mark")); DEFSYM (Qlist, "list"); DEFSYM (Qlet, "let"); === modified file 'src/charset.c' --- src/charset.c 2012-07-05 18:35:48 +0000 +++ src/charset.c 2012-07-27 06:04:35 +0000 @@ -1257,7 +1257,6 @@ { const unsigned char *code_space = (const unsigned char *) code_space_chars; Lisp_Object args[charset_arg_max]; - Lisp_Object plist[14]; Lisp_Object val; int i; @@ -1283,22 +1282,22 @@ args[charset_arg_superset] = Qnil; args[charset_arg_unify_map] = Qnil; - plist[0] = intern_c_string (":name"); - plist[1] = args[charset_arg_name]; - plist[2] = intern_c_string (":dimension"); - plist[3] = args[charset_arg_dimension]; - plist[4] = intern_c_string (":code-space"); - plist[5] = args[charset_arg_code_space]; - plist[6] = intern_c_string (":iso-final-char"); - plist[7] = args[charset_arg_iso_final]; - plist[8] = intern_c_string (":emacs-mule-id"); - plist[9] = args[charset_arg_emacs_mule_id]; - plist[10] = intern_c_string (":ascii-compatible-p"); - plist[11] = args[charset_arg_ascii_compatible_p]; - plist[12] = intern_c_string (":code-offset"); - plist[13] = args[charset_arg_code_offset]; - - args[charset_arg_plist] = Flist (14, plist); + args[charset_arg_plist] = + listn (HEAP, 14, + intern_c_string (":name"), + args[charset_arg_name], + intern_c_string (":dimension"), + args[charset_arg_dimension], + intern_c_string (":code-space"), + args[charset_arg_code_space], + intern_c_string (":iso-final-char"), + args[charset_arg_iso_final], + intern_c_string (":emacs-mule-id"), + args[charset_arg_emacs_mule_id], + intern_c_string (":ascii-compatible-p"), + args[charset_arg_ascii_compatible_p], + intern_c_string (":code-offset"), + args[charset_arg_code_offset]); Fdefine_charset_internal (charset_arg_max, args); return XINT (CHARSET_SYMBOL_ID (name)); === modified file 'src/coding.c' --- src/coding.c 2012-07-19 03:55:59 +0000 +++ src/coding.c 2012-07-27 06:04:35 +0000 @@ -10411,7 +10411,7 @@ DEFSYM (Qcoding_system_error, "coding-system-error"); Fput (Qcoding_system_error, Qerror_conditions, - pure_cons (Qcoding_system_error, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qcoding_system_error, Qerror)); Fput (Qcoding_system_error, Qerror_message, build_pure_c_string ("Invalid coding system")); === modified file 'src/keymap.c' --- src/keymap.c 2012-07-26 01:27:33 +0000 +++ src/keymap.c 2012-07-27 06:04:35 +0000 @@ -3702,13 +3702,12 @@ Fset (intern_c_string ("ctl-x-map"), control_x_map); Ffset (intern_c_string ("Control-X-prefix"), control_x_map); - exclude_keys - = pure_cons (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")), - pure_cons (pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")), - pure_cons (pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")), - pure_cons (pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")), - pure_cons (pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" ")), - Qnil))))); + exclude_keys = listn (PURE, 5, + pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")), + pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")), + pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")), + pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")), + pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" "))); staticpro (&exclude_keys); DEFVAR_LISP ("define-key-rebound-commands", Vdefine_key_rebound_commands, @@ -3761,16 +3760,16 @@ where_is_preferred_modifier = 0; staticpro (&Vmouse_events); - Vmouse_events = pure_cons (intern_c_string ("menu-bar"), - pure_cons (intern_c_string ("tool-bar"), - pure_cons (intern_c_string ("header-line"), - pure_cons (intern_c_string ("mode-line"), - pure_cons (intern_c_string ("mouse-1"), - pure_cons (intern_c_string ("mouse-2"), - pure_cons (intern_c_string ("mouse-3"), - pure_cons (intern_c_string ("mouse-4"), - pure_cons (intern_c_string ("mouse-5"), - Qnil))))))))); + Vmouse_events = listn (PURE, 9, + intern_c_string ("menu-bar"), + intern_c_string ("tool-bar"), + intern_c_string ("header-line"), + intern_c_string ("mode-line"), + intern_c_string ("mouse-1"), + intern_c_string ("mouse-2"), + intern_c_string ("mouse-3"), + intern_c_string ("mouse-4"), + intern_c_string ("mouse-5")); DEFSYM (Qsingle_key_description, "single-key-description"); DEFSYM (Qkey_description, "key-description"); === modified file 'src/lisp.h' --- src/lisp.h 2012-07-27 02:47:07 +0000 +++ src/lisp.h 2012-07-27 06:04:35 +0000 @@ -2685,6 +2685,8 @@ extern Lisp_Object list4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object list5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); +enum constype {HEAP, PURE}; +extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...); extern _Noreturn void string_overflow (void); extern Lisp_Object make_string (const char *, ptrdiff_t); extern Lisp_Object make_formatted_string (char *, const char *, ...) === modified file 'src/search.c' --- src/search.c 2012-07-11 06:14:19 +0000 +++ src/search.c 2012-07-27 06:04:35 +0000 @@ -3054,12 +3054,12 @@ DEFSYM (Qinvalid_regexp, "invalid-regexp"); Fput (Qsearch_failed, Qerror_conditions, - pure_cons (Qsearch_failed, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qsearch_failed, Qerror)); Fput (Qsearch_failed, Qerror_message, build_pure_c_string ("Search failed")); Fput (Qinvalid_regexp, Qerror_conditions, - pure_cons (Qinvalid_regexp, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qinvalid_regexp, Qerror)); Fput (Qinvalid_regexp, Qerror_message, build_pure_c_string ("Invalid regexp")); === modified file 'src/syntax.c' --- src/syntax.c 2012-07-10 08:43:46 +0000 +++ src/syntax.c 2012-07-27 06:04:35 +0000 @@ -3473,7 +3473,7 @@ DEFSYM (Qscan_error, "scan-error"); Fput (Qscan_error, Qerror_conditions, - pure_cons (Qscan_error, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qscan_error, Qerror)); Fput (Qscan_error, Qerror_message, build_pure_c_string ("Scan error")); === modified file 'src/w32.c' --- src/w32.c 2012-07-10 23:24:36 +0000 +++ src/w32.c 2012-07-27 06:04:35 +0000 @@ -1722,13 +1722,11 @@ dwType = REG_EXPAND_SZ; dont_free = 1; if (!strcmp (env_vars[i].name, "HOME") && !appdata) - { - Lisp_Object warning[2]; - warning[0] = intern ("initialization"); - warning[1] = build_string ("Setting HOME to C:\\ by default is deprecated"); - Vdelayed_warnings_list = Fcons (Flist (2, warning), - Vdelayed_warnings_list); - } + Vdelayed_warnings_list + = Fcons (listn (HEAP, 2, + intern ("initialization"); + build_string ("Setting HOME to C:\\ by default is deprecated")), + Vdelayed_warnings_list); } if (lpval) === modified file 'src/w32fns.c' --- src/w32fns.c 2012-07-20 07:29:04 +0000 +++ src/w32fns.c 2012-07-27 06:04:35 +0000 @@ -6470,7 +6470,6 @@ { Lisp_Object line_status, battery_status, battery_status_symbol; Lisp_Object load_percentage, seconds, minutes, hours, remain; - Lisp_Object sequences[8]; long seconds_left = (long) system_status.BatteryLifeTime; @@ -6544,16 +6543,16 @@ _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60); remain = build_string (buffer); } - sequences[0] = Fcons (make_number ('L'), line_status); - sequences[1] = Fcons (make_number ('B'), battery_status); - sequences[2] = Fcons (make_number ('b'), battery_status_symbol); - sequences[3] = Fcons (make_number ('p'), load_percentage); - sequences[4] = Fcons (make_number ('s'), seconds); - sequences[5] = Fcons (make_number ('m'), minutes); - sequences[6] = Fcons (make_number ('h'), hours); - sequences[7] = Fcons (make_number ('t'), remain); - status = Flist (8, sequences); + status = listn (HEAP, 8, + Fcons (make_number ('L'), line_status), + Fcons (make_number ('B'), battery_status), + Fcons (make_number ('b'), battery_status_symbol), + Fcons (make_number ('p'), load_percentage), + Fcons (make_number ('s'), seconds), + Fcons (make_number ('m'), minutes), + Fcons (make_number ('h'), hours), + Fcons (make_number ('t'), remain)); } return status; } @@ -6795,7 +6794,7 @@ Fput (Qundefined_color, Qerror_conditions, - pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qundefined_color, Qerror); Fput (Qundefined_color, Qerror_message, build_pure_c_string ("Undefined color")); === modified file 'src/xdisp.c' --- src/xdisp.c 2012-07-24 16:34:15 +0000 +++ src/xdisp.c 2012-07-27 06:04:35 +0000 @@ -28932,14 +28932,14 @@ \(see `modify-frame-parameters'). */); Vicon_title_format = Vframe_title_format - = pure_cons (intern_c_string ("multiple-frames"), - pure_cons (build_pure_c_string ("%b"), - pure_cons (pure_cons (empty_unibyte_string, - pure_cons (intern_c_string ("invocation-name"), - pure_cons (build_pure_c_string ("@"), - pure_cons (intern_c_string ("system-name"), - Qnil)))), - Qnil))); + = listn (PURE, 3, + intern_c_string ("multiple-frames"), + build_pure_c_string ("%b"), + listn (PURE, 4, + empty_unibyte_string, + intern_c_string ("invocation-name"), + build_pure_c_string ("@"), + intern_c_string ("system-name"))); DEFVAR_LISP ("message-log-max", Vmessage_log_max, doc: /* Maximum number of lines to keep in the message log buffer. === modified file 'src/xfns.c' --- src/xfns.c 2012-07-20 07:29:04 +0000 +++ src/xfns.c 2012-07-27 06:04:35 +0000 @@ -5822,7 +5822,7 @@ /* This is the end of symbol initialization. */ Fput (Qundefined_color, Qerror_conditions, - pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); + listn (PURE, 2, Qundefined_color, Qerror)); Fput (Qundefined_color, Qerror_message, build_pure_c_string ("Undefined color")); ------------------------------------------------------------ revno: 109222 committer: Jay Belanger branch nick: trunk timestamp: Thu 2012-07-26 22:48:40 -0500 message: calccomp.el (math-compose-expr): Use parentheses when there is a product in the denominator of a fraction. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-07-26 17:10:21 +0000 +++ lisp/ChangeLog 2012-07-27 03:48:40 +0000 @@ -1,3 +1,8 @@ +2012-07-27 Jay Belanger + + * calc/calccomp.el (math-compose-expr): Use parentheses when + there is a product in the denominator of a fraction. + 2012-07-26 Eli Zaretskii * makefile.w32-in ($(lisp)/calendar/cal-loaddefs.el) === modified file 'lisp/calc/calccomp.el' --- lisp/calc/calccomp.el 2012-01-19 07:21:25 +0000 +++ lisp/calc/calccomp.el 2012-07-27 03:48:40 +0000 @@ -87,7 +87,8 @@ sn))) (defun math-compose-expr (a prec) - (let ((math-compose-level (1+ math-compose-level)) + (let ((calc-multiplication-has-precedence nil) + (math-compose-level (1+ math-compose-level)) (math-expr-opers (math-expr-ops)) spfn) (cond ------------------------------------------------------------ revno: 109221 committer: Dmitry Antipov branch nick: trunk timestamp: Fri 2012-07-27 06:47:07 +0400 message: Fast save_excursion_save and save_excursion_restore. * lisp.h (struct Lisp_Excursion): New data type. (PVEC_EXCURSION): New pseudovector type. (XEXCURSION, XSETEXCURSION, EXCURSIONP): Convenient macros to deal with it. Adjust comments. (init_marker, attach_marker): New prototype. (unchain_marker): Adjust prototype. * marker.c (attach_marker): Change to global. (init_marker): New function. * alloc.c (Fmake_marker, build_marker): Use it. (build_marker): More easserts. (mark_object): Handle struct Lisp_Excursion. * editfns.c (save_excursion_save, save_excursion_restore): Reimplement to use struct Lisp_Excursion. Add comments. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 19:58:48 +0000 +++ src/ChangeLog 2012-07-27 02:47:07 +0000 @@ -1,3 +1,20 @@ +2012-07-27 Dmitry Antipov + + Fast save_excursion_save and save_excursion_restore. + * lisp.h (struct Lisp_Excursion): New data type. + (PVEC_EXCURSION): New pseudovector type. + (XEXCURSION, XSETEXCURSION, EXCURSIONP): Convenient macros + to deal with it. Adjust comments. + (init_marker, attach_marker): New prototype. + (unchain_marker): Adjust prototype. + * marker.c (attach_marker): Change to global. + (init_marker): New function. + * alloc.c (Fmake_marker, build_marker): Use it. + (build_marker): More easserts. + (mark_object): Handle struct Lisp_Excursion. + * editfns.c (save_excursion_save, save_excursion_restore): + Reimplement to use struct Lisp_Excursion. Add comments. + 2012-07-26 Paul Eggert Fix export of symbols to GDB (Bug#12036). === modified file 'src/alloc.c' --- src/alloc.c 2012-07-26 18:35:50 +0000 +++ src/alloc.c 2012-07-27 02:47:07 +0000 @@ -3653,17 +3653,10 @@ doc: /* Return a newly allocated marker which does not point at any place. */) (void) { - register Lisp_Object val; - register struct Lisp_Marker *p; + register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); - val = allocate_misc (Lisp_Misc_Marker); - p = XMARKER (val); - p->buffer = 0; - p->bytepos = 0; - p->charpos = 0; - p->next = NULL; - p->insertion_type = 0; - return val; + init_marker (XMARKER (marker), NULL, 0, 0, 0); + return marker; } /* Return a newly allocated marker which points into BUF @@ -3672,24 +3665,23 @@ Lisp_Object build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) { - Lisp_Object obj; - struct Lisp_Marker *m; + register Lisp_Object marker = allocate_misc (Lisp_Misc_Marker); + + /* Use Fmake_marker to create marker points to nowhere. */ + eassert (buf != NULL); /* No dead buffers here. */ eassert (!NILP (BVAR (buf, name))); - /* Every character is at least one byte. */ - eassert (charpos <= bytepos); + /* In a single-byte buffer, two positions must be equal. + Otherwise, every character is at least one byte. */ + if (BUF_Z (buf) == BUF_Z_BYTE (buf)) + eassert (charpos == bytepos); + else + eassert (charpos <= bytepos); - obj = allocate_misc (Lisp_Misc_Marker); - m = XMARKER (obj); - m->buffer = buf; - m->charpos = charpos; - m->bytepos = bytepos; - m->insertion_type = 0; - m->next = BUF_MARKERS (buf); - BUF_MARKERS (buf) = m; - return obj; + init_marker (XMARKER (marker), buf, charpos, bytepos, 0); + return marker; } /* Put MARKER back on the free list after using it temporarily. */ @@ -6057,6 +6049,19 @@ case PVEC_SUBR: break; + case PVEC_EXCURSION: + { + struct Lisp_Excursion *e = (struct Lisp_Excursion *) ptr; + /* No Lisp_Objects but two special pointers to mark here. */ + eassert (e->buffer != NULL); + eassert (e->window != NULL); + if (!VECTOR_MARKED_P (e->buffer)) + mark_buffer (e->buffer); + if (!VECTOR_MARKED_P (e->window)) + mark_vectorlike ((struct Lisp_Vector *) e->window); + } + break; + case PVEC_FREE: abort (); === modified file 'src/editfns.c' --- src/editfns.c 2012-07-26 05:23:25 +0000 +++ src/editfns.c 2012-07-27 02:47:07 +0000 @@ -821,104 +821,104 @@ Qnil, Qt, Qnil); } - +/* Record buffer state before entering Fsave_excursion. */ + Lisp_Object save_excursion_save (void) { - int visible = (XBUFFER (XWINDOW (selected_window)->buffer) - == current_buffer); - - return Fcons (Fpoint_marker (), - Fcons (Fcopy_marker (BVAR (current_buffer, mark), Qnil), - Fcons (visible ? Qt : Qnil, - Fcons (BVAR (current_buffer, mark_active), - selected_window)))); + Lisp_Object excursion; + struct buffer *b = current_buffer; + struct window *w = XWINDOW (selected_window); + struct Lisp_Excursion *ex = xmalloc (sizeof *ex); + struct Lisp_Marker *m = XMARKER (BVAR (b, mark)); + + ex->size = 0; + ex->buffer = b; + ex->window = w; + ex->visible = (XBUFFER (w->buffer) == b); + ex->active = !NILP (BVAR (b, mark_active)); + + /* We do not initialize type and gcmarkbit since this marker + is never referenced via Lisp_Object and invisible for GC. */ + init_marker (&ex->point, b, PT, PT_BYTE, 0); + + /* Likewise. Note that charpos and bytepos may be zero. */ + init_marker (&ex->mark, m->buffer, m->charpos, + m->bytepos, m->insertion_type); + + /* Make it a pseudovector and return excursion object. */ + XSETTYPED_PVECTYPE (ex, size, PVEC_EXCURSION); + XSETEXCURSION (excursion, ex); + return excursion; } +/* Restore buffer state before leaving Fsave_excursion. */ + Lisp_Object -save_excursion_restore (Lisp_Object info) +save_excursion_restore (Lisp_Object obj) { - Lisp_Object tem, tem1, omark, nmark; - struct gcpro gcpro1, gcpro2, gcpro3; - int visible_p; - - tem = Fmarker_buffer (XCAR (info)); - /* If buffer being returned to is now deleted, avoid error */ - /* Otherwise could get error here while unwinding to top level - and crash */ - /* In that case, Fmarker_buffer returns nil now. */ - if (NILP (tem)) - return Qnil; - - omark = nmark = Qnil; - GCPRO3 (info, omark, nmark); - - Fset_buffer (tem); - - /* Point marker. */ - tem = XCAR (info); - Fgoto_char (tem); - unchain_marker (XMARKER (tem)); - - /* Mark marker. */ - info = XCDR (info); - tem = XCAR (info); - omark = Fmarker_position (BVAR (current_buffer, mark)); - Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ()); - nmark = Fmarker_position (tem); - unchain_marker (XMARKER (tem)); - - /* visible */ - info = XCDR (info); - visible_p = !NILP (XCAR (info)); - -#if 0 /* We used to make the current buffer visible in the selected window - if that was true previously. That avoids some anomalies. - But it creates others, and it wasn't documented, and it is simpler - and cleaner never to alter the window/buffer connections. */ - tem1 = Fcar (tem); - if (!NILP (tem1) - && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) - Fswitch_to_buffer (Fcurrent_buffer (), Qnil); -#endif /* 0 */ - - /* Mark active */ - info = XCDR (info); - tem = XCAR (info); - tem1 = BVAR (current_buffer, mark_active); - BVAR (current_buffer, mark_active) = tem; - - /* If mark is active now, and either was not active - or was at a different place, run the activate hook. */ - if (! NILP (tem)) - { - if (! EQ (omark, nmark)) - { - tem = intern ("activate-mark-hook"); - Frun_hooks (1, &tem); - } - } - /* If mark has ceased to be active, run deactivate hook. */ - else if (! NILP (tem1)) - { - tem = intern ("deactivate-mark-hook"); - Frun_hooks (1, &tem); - } - - /* If buffer was visible in a window, and a different window was - selected, and the old selected window is still showing this - buffer, restore point in that window. */ - tem = XCDR (info); - if (visible_p - && !EQ (tem, selected_window) - && (tem1 = XWINDOW (tem)->buffer, - (/* Window is live... */ - BUFFERP (tem1) - /* ...and it shows the current buffer. */ - && XBUFFER (tem1) == current_buffer))) - Fset_window_point (tem, make_number (PT)); - - UNGCPRO; + struct Lisp_Excursion *ex = XEXCURSION (obj); + struct buffer *b = ex->buffer; + + eassert (b != NULL); + eassert (ex->window != NULL); + + /* Restore buffer state only if the buffer is live. + Otherwise, just cancel an excursion state. */ + + if (!NILP (BVAR (b, name))) + { + int active; + struct Lisp_Marker *m; + ptrdiff_t oldpos, newpos; + + /* Restore current buffer. */ + set_buffer_internal (b); + + /* Restore buffer position. */ + SET_PT_BOTH (clip_to_bounds (BEGV, ex->point.charpos, ZV), + clip_to_bounds (BEGV_BYTE, ex->point.bytepos, ZV_BYTE)); + unchain_marker (&ex->point); + + /* Restore mark if it was non-zero. */ + m = XMARKER (BVAR (b, mark)); + oldpos = m->charpos; + if (BEGV <= ex->mark.charpos) + attach_marker (m, b, ex->mark.charpos, ex->mark.bytepos); + newpos = ex->mark.charpos; + unchain_marker (&ex->mark); + + /* If mark and region was active, restore them. */ + active = !NILP (BVAR (b, mark_active)); + BVAR (b, mark_active) = ex->active ? Qt : Qnil; + + /* If mark is active now, and either was not active + or was at a different place, run the activate hook. */ + if (ex->active && oldpos != newpos) + { + obj = intern ("activate-mark-hook"); + Frun_hooks (1, &obj); + } + /* If mark has ceased to be active, run deactivate hook. */ + else if (active) + { + obj = intern ("deactivate-mark-hook"); + Frun_hooks (1, &obj); + } + + /* If buffer was visible in a window, and a different window + was selected, and the old selected window is still showing + this buffer, restore point in that window. */ + if (ex->visible) + { + struct window *w = ex->window; + + if (w != XWINDOW (selected_window) && XBUFFER (w->buffer) == b) + attach_marker (XMARKER (w->pointm), b, PT, PT_BYTE); + } + } + + xfree (ex); return Qnil; } === modified file 'src/lisp.h' --- src/lisp.h 2012-07-26 18:35:50 +0000 +++ src/lisp.h 2012-07-27 02:47:07 +0000 @@ -379,6 +379,7 @@ PVEC_TERMINAL, PVEC_WINDOW_CONFIGURATION, PVEC_SUBR, + PVEC_EXCURSION, PVEC_OTHER, /* These last 4 are special because we OR them in fns.c:internal_equal, so they have to use a disjoint bit pattern: @@ -551,6 +552,8 @@ (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) #define XSUBR(a) (eassert (SUBRP (a)), \ (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) +#define XEXCURSION(a) (eassert (EXCURSIONP (a)), \ + (struct Lisp_Excursion *) XUNTAG (a, Lisp_Vectorlike)) #define XBUFFER(a) (eassert (BUFFERP (a)), \ (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) #define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ @@ -603,9 +606,12 @@ #define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) #define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) #define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) -/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ +/* These are special because both Lisp_Subr and Lisp_Excursion lacks + struct vectorlike_header. */ #define XSETSUBR(a, b) \ XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) +#define XSETEXCURSION(a, b) \ + XSETTYPED_PSEUDOVECTOR (a, b, XEXCURSION (a)->size, PVEC_EXCURSION) #define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) @@ -1522,6 +1528,33 @@ #define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) #endif +/* This structure is used to record buffer state for Fsave_excursion. + It's mostly treated as Lisp_Vector but allocated and freed explicitly + with xmalloc and xfree, so there is no vectorlike_header here. */ + +struct Lisp_Excursion +{ + ptrdiff_t size; + + /* Saved value of XWINDOW (selected_window). */ + struct window *window; + + /* Buffer where this excursion is in effect. */ + struct buffer *buffer; + + /* Non-zero if the window above has displayed the buffer. */ + unsigned visible : 1; + + /* Non-zero if this buffer has the mark active. */ + unsigned active : 1; + + /* Saved point. */ + struct Lisp_Marker point; + + /* Saved mark. May point to nowhere. */ + struct Lisp_Marker mark; +}; + /* A character, declared with the following typedef, is a member of some character set associated with the current buffer. */ #ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */ @@ -1704,8 +1737,10 @@ #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) -/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ +/* These are special because both Lisp_Subr and Lisp_Excursion lacks + struct vectorlike_header. */ #define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) +#define EXCURSIONP(x) TYPED_PSEUDOVECTORP (x, Lisp_Excursion, PVEC_EXCURSION) #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) @@ -2919,11 +2954,15 @@ extern ptrdiff_t charpos_to_bytepos (ptrdiff_t); extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); -extern void unchain_marker (struct Lisp_Marker *marker); +extern void unchain_marker (struct Lisp_Marker *); extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, - ptrdiff_t, ptrdiff_t); + ptrdiff_t, ptrdiff_t); +extern void init_marker (struct Lisp_Marker *, struct buffer *, + ptrdiff_t, ptrdiff_t, int); +extern void attach_marker (struct Lisp_Marker *, struct buffer *, + ptrdiff_t, ptrdiff_t); extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); extern void syms_of_marker (void); === modified file 'src/marker.c' --- src/marker.c 2012-07-22 05:37:24 +0000 +++ src/marker.c 2012-07-27 02:47:07 +0000 @@ -425,9 +425,28 @@ return Qnil; } +/* Initialize just allocated Lisp_Marker. */ + +void +init_marker (struct Lisp_Marker *m, struct buffer *b, + ptrdiff_t charpos, ptrdiff_t bytepos, int type) +{ + m->buffer = b; + m->charpos = charpos; + m->bytepos = bytepos; + m->insertion_type = type; + if (b) + { + m->next = BUF_MARKERS (b); + BUF_MARKERS (b) = m; + } + else + m->next = NULL; +} + /* Change M so it points to B at CHARPOS and BYTEPOS. */ -static inline void +void attach_marker (struct Lisp_Marker *m, struct buffer *b, ptrdiff_t charpos, ptrdiff_t bytepos) { ------------------------------------------------------------ revno: 109220 fixes bug(s): http://debbugs.gnu.org/12036 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 12:58:48 -0700 message: * emacs.c: Do not include ; no longer needed. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 18:35:50 +0000 +++ src/ChangeLog 2012-07-26 19:58:48 +0000 @@ -7,7 +7,8 @@ the fix for 12036 would have avoided some of the problems noted in by Eli Zaretskii, as the scope problems would have been more obvious. - * emacs.c (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS) + * emacs.c: Do not include ; no longer needed. + (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS) (gdb_GCTYPEBITS, gdb_USE_LSB_TAG) (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS, GCTYPEBITS, USE_LSB_TAG): Remove; now done in lisp.h. === modified file 'src/emacs.c' --- src/emacs.c 2012-07-26 18:35:50 +0000 +++ src/emacs.c 2012-07-26 19:58:48 +0000 @@ -29,8 +29,6 @@ #include #include -#include - #include "lisp.h" #ifdef WINDOWSNT ------------------------------------------------------------ revno: 109219 fixes bug(s): http://debbugs.gnu.org/12036 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 11:35:50 -0700 message: Fix export of symbols to GDB. * alloc.c (ARRAY_MARK_FLAG_VAL, PSEUDOVECTOR_FLAG_VAL, VALMASK_VAL) (ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK): Move these here from emacs.c, as this is a more-suitable home. Had this been done earlier the fix for 12036 would have avoided some of the problems noted in by Eli Zaretskii, as the scope problems would have been more obvious. * emacs.c (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS) (gdb_GCTYPEBITS, gdb_USE_LSB_TAG) (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS, GCTYPEBITS, USE_LSB_TAG): Remove; now done in lisp.h. * lisp.h (PUBLISH_TO_GDB): New macro. (GCTYPEBITS, USE_LSB_TAG, CHECK_LISP_OBJECT_TYPE, enum pvec_type) (DATA_SEG_BITS): Use it. (GCTYPEBITS, USE_LSB_TAG): Now also an enum, for GDB. (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS): Now just an enum, for GDB. * mem-limits.h (EXCEEDS_LISP_PTR): Redo so that DATA_SEG_BITS need not be usable in #if. This simplifies things. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 13:59:01 +0000 +++ src/ChangeLog 2012-07-26 18:35:50 +0000 @@ -1,3 +1,24 @@ +2012-07-26 Paul Eggert + + Fix export of symbols to GDB (Bug#12036). + * alloc.c (ARRAY_MARK_FLAG_VAL, PSEUDOVECTOR_FLAG_VAL, VALMASK_VAL) + (ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK): Move these here from + emacs.c, as this is a more-suitable home. Had this been done earlier + the fix for 12036 would have avoided some of the problems noted in + by Eli Zaretskii, as the scope problems + would have been more obvious. + * emacs.c (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS) + (gdb_GCTYPEBITS, gdb_USE_LSB_TAG) + (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS, GCTYPEBITS, USE_LSB_TAG): + Remove; now done in lisp.h. + * lisp.h (PUBLISH_TO_GDB): New macro. + (GCTYPEBITS, USE_LSB_TAG, CHECK_LISP_OBJECT_TYPE, enum pvec_type) + (DATA_SEG_BITS): Use it. + (GCTYPEBITS, USE_LSB_TAG): Now also an enum, for GDB. + (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS): Now just an enum, for GDB. + * mem-limits.h (EXCEEDS_LISP_PTR): Redo so that DATA_SEG_BITS need + not be usable in #if. This simplifies things. + 2012-07-26 Juanma Barranquero * makefile.w32-in ($(BLD)/emacs.$(O)): Update dependencies. === modified file 'src/alloc.c' --- src/alloc.c 2012-07-23 11:15:43 +0000 +++ src/alloc.c 2012-07-26 18:35:50 +0000 @@ -6875,3 +6875,29 @@ defsubr (&Sgc_status); #endif } + +/* Make some symbols visible to GDB. These cannot be done as enums, like + GCTYPEBITS or USE_LSB_TAG, since values might not be in 'int' range. + Each symbol X has a corresponding X_VAL symbol, verified to have + the correct value. + + This is last, so that the #undef lines don't mess up later code. */ + +#define ARRAY_MARK_FLAG_VAL PTRDIFF_MIN +#define PSEUDOVECTOR_FLAG_VAL (PTRDIFF_MAX - PTRDIFF_MAX / 2) +#define VALMASK_VAL (USE_LSB_TAG ? -1 << GCTYPEBITS : VAL_MAX) + +verify (ARRAY_MARK_FLAG_VAL == ARRAY_MARK_FLAG); +verify (PSEUDOVECTOR_FLAG_VAL == PSEUDOVECTOR_FLAG); +verify (VALMASK_VAL == VALMASK); + +#undef ARRAY_MARK_FLAG +#undef PSEUDOVECTOR_FLAG +#undef VALMASK + +ptrdiff_t const EXTERNALLY_VISIBLE + ARRAY_MARK_FLAG = ARRAY_MARK_FLAG_VAL, + PSEUDOVECTOR_FLAG = PSEUDOVECTOR_FLAG_VAL; + +EMACS_INT const EXTERNALLY_VISIBLE + VALMASK = VALMASK_VAL; === modified file 'src/emacs.c' --- src/emacs.c 2012-07-26 08:12:03 +0000 +++ src/emacs.c 2012-07-26 18:35:50 +0000 @@ -2490,50 +2490,3 @@ /* Make sure IS_DAEMON starts up as false. */ daemon_pipe[1] = 0; } - -/* Make these values available in GDB, which doesn't see macros. - This is last, so that the #undef lines don't mess up later code. */ - -enum - { - gdb_CHECK_LISP_OBJECT_TYPE = CHECK_LISP_OBJECT_TYPE, - gdb_DATA_SEG_BITS = DATA_SEG_BITS, - gdb_GCTYPEBITS = GCTYPEBITS, - gdb_USE_LSB_TAG = USE_LSB_TAG - }; - -#undef CHECK_LISP_OBJECT_TYPE -#undef DATA_SEG_BITS -#undef GCTYPEBITS -#undef USE_LSB_TAG - -enum - { - CHECK_LISP_OBJECT_TYPE = gdb_CHECK_LISP_OBJECT_TYPE, - DATA_SEG_BITS = gdb_DATA_SEG_BITS, - GCTYPEBITS = gdb_GCTYPEBITS, - USE_LSB_TAG = gdb_USE_LSB_TAG - }; - -/* These are trickier since they might fall out of int range. Each - symbol X has a corresponding X_VAL symbol, verified to have the - correct value. */ - -#define ARRAY_MARK_FLAG_VAL PTRDIFF_MIN -#define PSEUDOVECTOR_FLAG_VAL (PTRDIFF_MAX - PTRDIFF_MAX / 2) -#define VALMASK_VAL (USE_LSB_TAG ? -1 << GCTYPEBITS : VAL_MAX) - -verify (ARRAY_MARK_FLAG_VAL == ARRAY_MARK_FLAG); -verify (PSEUDOVECTOR_FLAG_VAL == PSEUDOVECTOR_FLAG); -verify (VALMASK_VAL == VALMASK); - -#undef ARRAY_MARK_FLAG -#undef PSEUDOVECTOR_FLAG -#undef VALMASK - -ptrdiff_t const EXTERNALLY_VISIBLE - ARRAY_MARK_FLAG = ARRAY_MARK_FLAG_VAL, - PSEUDOVECTOR_FLAG = PSEUDOVECTOR_FLAG_VAL; - -EMACS_INT const EXTERNALLY_VISIBLE - VALMASK = VALMASK_VAL; === modified file 'src/lisp.h' --- src/lisp.h 2012-07-26 08:51:23 +0000 +++ src/lisp.h 2012-07-26 18:35:50 +0000 @@ -64,6 +64,12 @@ # endif #endif +/* If an enum type is not used, the enum symbols are not put into the + executable so the debugger cannot see them on many systems, e.g., + GCC 4.7.1 + GDB 7.4.1 + GNU/Linux. Work around this problem by + explicitly using the names in the integer constant expression EXPR. */ +#define PUBLISH_TO_GDB(expr) extern int (*gdb_dummy (int))[(expr) || 1] + /* Number of bits in some machine integer types. */ enum { @@ -155,7 +161,10 @@ variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ -/* Number of bits in a Lisp_Object tag. This can be used in #if. */ +/* Number of bits in a Lisp_Object tag. This can be used in #if, + and for GDB's sake also as a regular symbol. */ +enum { GCTYPEBITS = 3 }; +PUBLISH_TO_GDB (GCTYPEBITS); #define GCTYPEBITS 3 /* Number of bits in a Lisp_Object value, not counting the tag. */ @@ -202,7 +211,16 @@ # endif # endif #endif -#ifndef USE_LSB_TAG +/* USE_LSB_TAG can be used in #if; default it to 0 and make it visible + to GDB. */ +#ifdef USE_LSB_TAG +# undef USE_LSB_TAG +enum { USE_LSB_TAG = 1 }; +PUBLISH_TO_GDB (USE_LSB_TAG); +# define USE_LSB_TAG 1 +#else +enum { USE_LSB_TAG = 0 }; +PUBLISH_TO_GDB (USE_LSB_TAG); # define USE_LSB_TAG 0 #endif @@ -317,6 +335,8 @@ } #define LISP_INITIALLY_ZERO {0} +#undef CHECK_LISP_OBJECT_TYPE +enum { CHECK_LISP_OBJECT_TYPE = 1 }; #else /* CHECK_LISP_OBJECT_TYPE */ @@ -327,8 +347,9 @@ #define XIL(i) (i) #define LISP_MAKE_RVALUE(o) (0+(o)) #define LISP_INITIALLY_ZERO 0 -#define CHECK_LISP_OBJECT_TYPE 0 +enum { CHECK_LISP_OBJECT_TYPE = 0 }; #endif /* CHECK_LISP_OBJECT_TYPE */ +PUBLISH_TO_GDB (CHECK_LISP_OBJECT_TYPE); /* In the size word of a vector, this bit means the vector has been marked. */ @@ -368,6 +389,7 @@ PVEC_SUB_CHAR_TABLE = 0x30, PVEC_FONT = 0x40 }; +PUBLISH_TO_GDB ((enum pvec_type) 0); /* This also publishes PVEC_*. */ /* For convenience, we also store the number of elements in these bits. Note that this size is not necessarily the memory-footprint size, but @@ -386,10 +408,16 @@ enum { BOOL_VECTOR_BITS_PER_CHAR = 8 }; /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object */ -#ifndef DATA_SEG_BITS -# define DATA_SEG_BITS 0 + which were stored in a Lisp_Object. It is not needed in #if, so + for GDB's sake change it from a macro to a regular symbol. */ +#ifdef DATA_SEG_BITS +enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; +# undef DATA_SEG_BITS +enum { DATA_SEG_BITS = gdb_DATA_SEG_BITS }; +#else +enum { DATA_SEG_BITS = 0 }; #endif +PUBLISH_TO_GDB (DATA_SEG_BITS); /* These macros extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons, === modified file 'src/mem-limits.h' --- src/mem-limits.h 2012-07-26 08:12:03 +0000 +++ src/mem-limits.h 2012-07-26 18:35:50 +0000 @@ -36,9 +36,7 @@ extern char *start_of_data (void) ATTRIBUTE_CONST; #if USE_LSB_TAG || UINTPTR_MAX <= VAL_MAX #define EXCEEDS_LISP_PTR(ptr) 0 -#elif DATA_SEG_BITS +#else #define EXCEEDS_LISP_PTR(ptr) \ (((uintptr_t) (ptr) & ~DATA_SEG_BITS) >> VALBITS) -#else -#define EXCEEDS_LISP_PTR(ptr) ((uintptr_t) (ptr) >> VALBITS) #endif ------------------------------------------------------------ revno: 109218 committer: Eli Zaretskii branch nick: trunk timestamp: Thu 2012-07-26 20:10:21 +0300 message: Fix parallel bootstrap in lisp/ on MS-Windows. lisp/makefile.w32-in ($(lisp)/calendar/cal-loaddefs.el) ($(lisp)/calendar/diary-loaddefs.el) ($(lisp)/calendar/hol-loaddefs.el, $(lisp)/mh-e/mh-loaddefs.el) ($(lisp)/net/tramp-loaddefs.el): Depend on update-subdirs. Fixes failures in parallel bootstrap because subdirs.el is being rewritten while the autoload files are built at the same time, which needs to load subdirs.el. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-07-26 08:32:25 +0000 +++ lisp/ChangeLog 2012-07-26 17:10:21 +0000 @@ -1,3 +1,13 @@ +2012-07-26 Eli Zaretskii + + * makefile.w32-in ($(lisp)/calendar/cal-loaddefs.el) + ($(lisp)/calendar/diary-loaddefs.el) + ($(lisp)/calendar/hol-loaddefs.el, $(lisp)/mh-e/mh-loaddefs.el) + ($(lisp)/net/tramp-loaddefs.el): Depend on update-subdirs. Fixes + failures in parallel bootstrap because subdirs.el is being + rewritten while the autoload files are built at the same time, + which needs to load subdirs.el. + 2012-07-26 Martin Rudalics * mouse.el (popup-menu): Fix doc-string and re-indent code. === modified file 'lisp/makefile.w32-in' --- lisp/makefile.w32-in 2012-06-26 16:57:54 +0000 +++ lisp/makefile.w32-in 2012-07-26 17:10:21 +0000 @@ -393,7 +393,7 @@ recompile: compile-first autoloads doit $(lisp)/progmodes/cc-mode.elc $(emacs) --eval $(ARGQUOTE)(batch-byte-recompile-directory 0)$(ARGQUOTE) $(lisp) -$(lisp)/calendar/cal-loaddefs.el: +$(lisp)/calendar/cal-loaddefs.el: update-subdirs "$(EMACS)" $(EMACSOPT) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###cal-autoload\")" \ --eval "(setq find-file-suppress-same-file-warnings t)" \ @@ -401,7 +401,7 @@ -f w32-batch-update-autoloads "$(lisp)/calendar/cal-loaddefs.el" \ $(MAKE) ./calendar -$(lisp)/calendar/diary-loaddefs.el: +$(lisp)/calendar/diary-loaddefs.el: update-subdirs "$(EMACS)" $(EMACSOPT) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###diary-autoload\")" \ --eval "(setq find-file-suppress-same-file-warnings t)" \ @@ -409,7 +409,7 @@ -f w32-batch-update-autoloads $(lisp)/calendar/diary-loaddefs.el \ $(MAKE) ./calendar -$(lisp)/calendar/hol-loaddefs.el: +$(lisp)/calendar/hol-loaddefs.el: update-subdirs "$(EMACS)" $(EMACSOPT) -l autoload \ --eval "(setq generate-autoload-cookie \";;;###holiday-autoload\")" \ --eval "(setq find-file-suppress-same-file-warnings t)" \ @@ -437,7 +437,7 @@ # See the commentary for autoloads above for why we use ./mh-e below # instead of $(lisp)/mh-e. mh-autoloads: $(lisp)/mh-e/mh-loaddefs.el -$(lisp)/mh-e/mh-loaddefs.el: $(MH_E_SRC) +$(lisp)/mh-e/mh-loaddefs.el: $(MH_E_SRC) update-subdirs "$(EMACS)" $(EMACSOPT) \ -l autoload \ --eval $(ARGQUOTE)(setq generate-autoload-cookie $(DQUOTE);;;###mh-autoload$(DQUOTE))$(ARGQUOTE) \ @@ -456,7 +456,7 @@ $(lisp)/net/tramp-smb.el $(lisp)/net/tramp-uu.el \ $(lisp)/net/trampver.el -$(lisp)/net/tramp-loaddefs.el: $(TRAMP_SRC) +$(lisp)/net/tramp-loaddefs.el: $(TRAMP_SRC) update-subdirs "$(EMACS)" $(EMACSOPT) \ -l autoload \ --eval $(ARGQUOTE)(setq generate-autoload-cookie $(DQUOTE);;;###tramp-autoload$(DQUOTE))$(ARGQUOTE) \ ------------------------------------------------------------ revno: 109217 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2012-07-26 15:59:01 +0200 message: src/makefile.w32-in ($(BLD)/emacs.$(O)): Update dependencies. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 09:14:40 +0000 +++ src/ChangeLog 2012-07-26 13:59:01 +0000 @@ -1,3 +1,7 @@ +2012-07-26 Juanma Barranquero + + * makefile.w32-in ($(BLD)/emacs.$(O)): Update dependencies. + 2012-07-26 Paul Eggert Simplify export of symbols to GDB (Bug#12036). === modified file 'src/makefile.w32-in' --- src/makefile.w32-in 2012-07-10 23:24:36 +0000 +++ src/makefile.w32-in 2012-07-26 13:59:01 +0000 @@ -783,6 +783,7 @@ $(SRC)/w32heap.h \ $(NT_INC)/sys/file.h \ $(NT_INC)/unistd.h \ + $(GNU_LIB)/verify.h \ $(BLOCKINPUT_H) \ $(BUFFER_H) \ $(CHARACTER_H) \ ------------------------------------------------------------ revno: 109216 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 02:14:40 -0700 message: Add Bug#12036 to latest ChangeLog entry. (I found this bug report after installing the change.) diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 08:12:03 +0000 +++ src/ChangeLog 2012-07-26 09:14:40 +0000 @@ -1,6 +1,6 @@ 2012-07-26 Paul Eggert - Simplify export of symbols to GDB; fix related .gdbinit bugs. + Simplify export of symbols to GDB (Bug#12036). * .gdbinit (xgetptr, xgetint, xgettype): Don't use "set $bugfix = $bugfix.i", as this doesn't work (with GDB 7.4.1, anyway). (xgetptr, xgetint, xgettype, xcoding, xcharset, xprintbytestr): ------------------------------------------------------------ revno: 109215 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 01:51:23 -0700 message: Spelling fix in comment. diff: === modified file 'src/lisp.h' --- src/lisp.h 2012-07-26 08:12:03 +0000 +++ src/lisp.h 2012-07-26 08:51:23 +0000 @@ -155,7 +155,7 @@ variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ -/* Number of bits in a Lisp_Obect tag. This can be used in #if. */ +/* Number of bits in a Lisp_Object tag. This can be used in #if. */ #define GCTYPEBITS 3 /* Number of bits in a Lisp_Object value, not counting the tag. */ ------------------------------------------------------------ revno: 109214 committer: martin rudalics branch nick: trunk timestamp: Thu 2012-07-26 10:32:25 +0200 message: In mouse-drag-line don't exit tracking prematurely (Bug#12006). * mouse.el (popup-menu): Fix doc-string and re-indent code. (mouse-drag-line): Don't exit tracking when a switch-frame or switch-window event occurs (Bug#12006). diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-07-26 01:29:24 +0000 +++ lisp/ChangeLog 2012-07-26 08:32:25 +0000 @@ -1,3 +1,9 @@ +2012-07-26 Martin Rudalics + + * mouse.el (popup-menu): Fix doc-string and re-indent code. + (mouse-drag-line): Don't exit tracking when a switch-frame or + switch-window event occurs (Bug#12006). + 2012-07-26 Stefan Monnier * mouse.el (popup-menu): Fix last change. === modified file 'lisp/mouse.el' --- lisp/mouse.el 2012-07-26 01:29:24 +0000 +++ lisp/mouse.el 2012-07-26 08:32:25 +0000 @@ -101,9 +101,11 @@ "Popup the given menu and call the selected option. MENU can be a keymap, an easymenu-style menu or a list of keymaps as for `x-popup-menu'. -POSITION can be a click event or ((XOFFSET YOFFSET) WINDOW) and defaults to - the current mouse position. If POSITION is a symbol, `point' the current point -position is used. + +POSITION can be a click event or ((XOFFSET YOFFSET) WINDOW) and +defaults to the current mouse position. If POSITION is the +symbol `point', the current point position is used. + PREFIX is the prefix argument (if any) to pass to the command." (let* ((map (cond ((keymapp menu) menu) @@ -113,17 +115,17 @@ (plist-get (get map 'menu-prop) :filter)))) (if filter (funcall filter (symbol-function map)) map))))) event cmd) - (setq position - (cond - ((eq position 'point) - (let* ((pp (posn-at-point)) - (xy (posn-x-y pp))) - (list (list (car xy) (cdr xy)) (posn-window pp)))) - ((not position) - (let ((mp (mouse-pixel-position))) - (list (list (cadr mp) (cddr mp)) (car mp)))) - (t - position))) + (setq position + (cond + ((eq position 'point) + (let* ((pp (posn-at-point)) + (xy (posn-x-y pp))) + (list (list (car xy) (cdr xy)) (posn-window pp)))) + ((not position) + (let ((mp (mouse-pixel-position))) + (list (list (cadr mp) (cddr mp)) (car mp)))) + (t + position))) ;; The looping behavior was taken from lmenu's popup-menu-popup (while (and map (setq event ;; map could be a prefix key, in which case @@ -141,7 +143,7 @@ binding) (while (and map (null binding)) (setq binding (lookup-key (car map) mouse-click)) - (if (numberp binding) ; `too long' + (if (numberp binding) ; `too long' (setq binding nil)) (setq map (cdr map))) binding) @@ -447,17 +449,39 @@ ;; Start tracking. (track-mouse - ;; Loop reading events and sampling the position of the mouse, - ;; until there is a non-mouse-movement event. Also, - ;; scroll-bar-movement events are the same as mouse movement for - ;; our purposes. (Why? -- cyd) - (while (progn - (setq event (read-event)) - (memq (car-safe event) '(mouse-movement scroll-bar-movement))) + ;; Loop reading events and sampling the position of the mouse. + (while draggable + (setq event (read-event)) (setq position (mouse-position)) + ;; Do nothing if + ;; - there is a switch-frame event. + ;; - the mouse isn't in the frame that we started in + ;; - the mouse isn't in any Emacs frame + ;; Drag if + ;; - there is a mouse-movement event + ;; - there is a scroll-bar-movement event (Why? -- cyd) + ;; (same as mouse movement for our purposes) + ;; Quit if + ;; - there is a keyboard event or some other unknown event. (cond + ((not (consp event)) + (setq draggable nil)) + ((memq (car event) '(switch-frame select-window)) + nil) + ((not (memq (car event) '(mouse-movement scroll-bar-movement))) + (when (consp event) + ;; Do not unread a drag-mouse-1 event to avoid selecting + ;; some other window. For vertical line dragging do not + ;; unread mouse-1 events either (but only if we dragged at + ;; least once to allow mouse-1 clicks get through. + (unless (and dragged + (if (eq line 'vertical) + (memq (car event) '(drag-mouse-1 mouse-1)) + (eq (car event) 'drag-mouse-1))) + (push event unread-command-events))) + (setq draggable nil)) ((or (not (eq (car position) frame)) - (null (cadr position))) + (null (car (cdr position)))) nil) ((eq line 'vertical) ;; Drag vertical divider. @@ -489,7 +513,6 @@ (setcar event 'mouse-2)) (push event unread-command-events))) - (defun mouse-drag-mode-line (start-event) "Change the height of a window by dragging on the mode line." (interactive "e") ------------------------------------------------------------ revno: 109213 committer: Paul Eggert branch nick: trunk timestamp: Thu 2012-07-26 01:12:03 -0700 message: Simplify export of symbols to GDB; fix related .gdbinit bugs. * etc/emacs-buffer.gdb ($tagmask, $valmask): Remove. (ygetptr): Adjust to recent changes in lisp.h and emacs.c, by using VALMASK instead of $valmask, CHECK_LISP_OBJECT_TYPE instead of gdb_use_union, and DATA_SEG_BITS instead of gdb_data_seg_bits. Also, use $ptr.i rather than $ptr.u.val. * src/.gdbinit (xgetptr, xgetint, xgettype): Don't use "set $bugfix = $bugfix.i", as this doesn't work (with GDB 7.4.1, anyway). (xgetptr, xgetint, xgettype, xcoding, xcharset, xprintbytestr): Adjust to changes in lisp.h and emacs.c, by using CHECK_LISP_OBJECT_TYPE rather than gdb_use_struct, VALMASK instead of $valmask, DATA_SEG_BITS instead of gdb_data_seg_bits, INTTYPEBITS instead of gdb_gctypebits - 1, USE_LSB_TAG instead of gdb_use_lsb, (1 << GCTYPEBITS) - 1 instead of $tagmask, VALBITS instead of gdb_valbits. (xvectype, xvector, xpr, xprintstr, xbacktrace): Similarly, use PSEUDOVECTOR_FLAG instead of PVEC_FLAG, and ARRAY_MARK_FLAG instead of gdb_array_mark_flag. (xboolvector): Get size from $->size, not $->header.size. Use BOOL_VECTOR_BITS_PER_CHAR rather than mystery constants. (xreload, hook-run, hookpost-run): Remove. * src/emacs.c: Include . (gdb_use_lsb, gdb_use_struct, gdb_valbits, gdb_gctypebits) (gdb_data_seg_bits, PVEC_FLAG, gdb_array_mark_flag, gdb_pvec_type): Remove. (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS, gdb_GCTYPEBITS) (gdb_USE_LSB_TAG): New enum constants. (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS, GCTYPEBITS, USE_LSB_TAG): Also define these as enum constants, so they're visible to GDB. (ARRAY_MARK_FLAG_VAL, PSEUDOVECTOR_FLAG_VAL, VALMASK_VAL): New macros. (ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK): Also define these as constants, so they're visible to GDB. * src/lisp.h (VALBITS, INTTYPEBITS, FIXNUM_BITS, PSEUDOVECTOR_SIZE_BITS) (PSEUDOVECTOR_SIZE_MASK, PVEC_TYPE_MASK, BOOL_VECTOR_BITS_PER_CHAR): Now enum constants, not macros, so they're visible to GDB. (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS): Default to 0, as this is more convenient now. All uses changed. (VALMASK) [USE_LSB_TAG]: Also define in this case. * src/mem-limits.h (EXCEEDS_LISP_PTR): Adjust to DATA_SEG_BITS change. diff: === modified file 'etc/ChangeLog' --- etc/ChangeLog 2012-07-20 10:29:32 +0000 +++ etc/ChangeLog 2012-07-26 08:12:03 +0000 @@ -1,3 +1,12 @@ +2012-07-26 Paul Eggert + + Simplify export of symbols to GDB. + * emacs-buffer.gdb ($tagmask, $valmask): Remove. + (ygetptr): Adjust to recent changes in lisp.h and emacs.c, + by using VALMASK instead of $valmask, CHECK_LISP_OBJECT_TYPE + instead of gdb_use_union, and DATA_SEG_BITS instead of + gdb_data_seg_bits. Also, use $ptr.i rather than $ptr.u.val. + 2012-07-20 Eli Zaretskii * tutorials/TUTORIAL.he: Make the first sentence display correctly === modified file 'etc/emacs-buffer.gdb' --- etc/emacs-buffer.gdb 2012-02-21 00:07:53 +0000 +++ etc/emacs-buffer.gdb 2012-07-26 08:12:03 +0000 @@ -70,21 +70,16 @@ # Code: -# Force loading of symbols, enough to give us gdb_valbits etc. +# Force loading of symbols, enough to give us VALMASK etc. set main # When nonzero, display some extra diagnostics in various commands set $yverbose = 1 set $yfile_buffers_only = 0 -set $tagmask = (((long)1 << gdb_gctypebits) - 1) -# The consing_since_gc business widens the 1 to EMACS_INT, -# a symbol not directly visible to GDB. -set $valmask = gdb_use_lsb ? ~($tagmask) : ((consing_since_gc - consing_since_gc + 1) << gdb_valbits) - 1 - define ygetptr set $ptr = $arg0 - set $ptr = (gdb_use_union ? $ptr.u.val : $ptr & $valmask) | gdb_data_seg_bits + set $ptr = ((CHECK_LISP_OBJECT_TYPE ? $ptr.i : $ptr) & VALMASK) | DATA_SEG_BITS end define ybuffer-list === modified file 'src/.gdbinit' --- src/.gdbinit 2012-07-25 22:47:42 +0000 +++ src/.gdbinit 2012-07-26 08:12:03 +0000 @@ -17,7 +17,7 @@ # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. -# Force loading of symbols, enough to give us gdb_valbits etc. +# Force loading of symbols, enough to give us VALBITS etc. set main # With some compilers, we need this to give us struct Lisp_Symbol etc.: set Fmake_symbol @@ -43,32 +43,21 @@ # debugging. handle SIGALRM ignore -# $valmask and $tagmask are mask values set up by the xreload macro below. - # Use $bugfix so that the value isn't a constant. # Using a constant runs into GDB bugs sometimes. define xgetptr - set $bugfix = $arg0 - if gdb_use_struct - set $bugfix = $bugfix.i - end - set $ptr = $bugfix & $valmask | gdb_data_seg_bits + set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + set $ptr = ($bugfix & VALMASK) | DATA_SEG_BITS end define xgetint - set $bugfix = $arg0 - if gdb_use_struct - set $bugfix = $bugfix.i - end - set $int = gdb_use_lsb ? $bugfix >> (gdb_gctypebits - 1) : $bugfix << (gdb_gctypebits - 1) >> (gdb_gctypebits - 1) + set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + set $int = USE_LSB_TAG ? $bugfix >> INTTYPEBITS : $bugfix << INTTYPEBITS >> INTTYPEBITS end define xgettype - set $bugfix = $arg0 - if gdb_use_struct - set $bugfix = $bugfix.i - end - set $type = (enum Lisp_Type) (gdb_use_lsb ? $bugfix & $tagmask : $bugfix >> gdb_valbits) + set $bugfix = CHECK_LISP_OBJECT_TYPE ? $arg0.i : $arg0 + set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : $bugfix >> VALBITS) end # Set up something to print out s-expressions. @@ -652,7 +641,7 @@ define xvectype xgetptr $ set $size = ((struct Lisp_Vector *) $ptr)->header.size - output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag + output ($size & PSEUDOVECTOR_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~ARRAY_MARK_FLAG echo \n end document xvectype @@ -738,7 +727,7 @@ define xvector xgetptr $ print (struct Lisp_Vector *) $ptr - output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~gdb_array_mark_flag) + output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~ARRAY_MARK_FLAG) echo \n end document xvector @@ -847,7 +836,7 @@ define xboolvector xgetptr $ print (struct Lisp_Bool_Vector *) $ptr - output ($->header.size > 256) ? 0 : ($->data[0])@((($->header.size & ~gdb_array_mark_flag) + 7)/ 8) + output ($->size > 256) ? 0 : ($->data[0])@(($->size + BOOL_VECTOR_BITS_PER_CHAR - 1)/ BOOL_VECTOR_BITS_PER_CHAR) echo \n end document xboolvector @@ -990,7 +979,7 @@ end if $type == Lisp_Vectorlike set $size = ((struct Lisp_Vector *) $ptr)->header.size - if ($size & PVEC_FLAG) + if ($size & PSEUDOVECTOR_FLAG) set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK) if $vec == PVEC_NORMAL_VECTOR xvector @@ -1036,7 +1025,7 @@ define xprintstr set $data = (char *) $arg0->data - output ($arg0->size > 1000) ? 0 : ($data[0])@($arg0->size_byte < 0 ? $arg0->size & ~gdb_array_mark_flag : $arg0->size_byte) + output ($arg0->size > 1000) ? 0 : ($data[0])@($arg0->size_byte < 0 ? $arg0->size & ~ARRAY_MARK_FLAG : $arg0->size_byte) end define xprintsym @@ -1051,8 +1040,8 @@ end define xcoding - set $tmp = (struct Lisp_Hash_Table *) ((Vcoding_system_hash_table & $valmask) | gdb_data_seg_bits) - set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & $valmask) | gdb_data_seg_bits) + set $tmp = (struct Lisp_Hash_Table *) ((Vcoding_system_hash_table & VALMASK) | DATA_SEG_BITS) + set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & VALMASK) | DATA_SEG_BITS) set $name = $tmp->contents[$arg0 * 2] print $name pr @@ -1064,8 +1053,8 @@ end define xcharset - set $tmp = (struct Lisp_Hash_Table *) ((Vcharset_hash_table & $valmask) | gdb_data_seg_bits) - set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & $valmask) | gdb_data_seg_bits) + set $tmp = (struct Lisp_Hash_Table *) ((Vcharset_hash_table & VALMASK) | DATA_SEG_BITS) + set $tmp = (struct Lisp_Vector *) (($tmp->key_and_value & VALMASK) | DATA_SEG_BITS) p $tmp->contents[charset_table[$arg0].hash_index * 2] pr end @@ -1126,7 +1115,7 @@ if $type == Lisp_Vectorlike xgetptr (*$bt->function) set $size = ((struct Lisp_Vector *) $ptr)->header.size - output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag + output ($size & PSEUDOVECTOR_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~ARRAY_MARK_FLAG else printf "Lisp type %d", $type end @@ -1144,7 +1133,7 @@ define xprintbytestr set $data = (char *) $arg0->data printf "Bytecode: " - output/u ($arg0->size > 1000) ? 0 : ($data[0])@($arg0->size_byte < 0 ? $arg0->size & ~gdb_array_mark_flag : $arg0->size_byte) + output/u ($arg0->size > 1000) ? 0 : ($data[0])@($arg0->size_byte < 0 ? $arg0->size & ~ARRAY_MARK_FLAG : $arg0->size_byte) end document xprintbytestr Print a string of byte code. @@ -1188,19 +1177,6 @@ end end -define xreload - set $tagmask = ((1 << gdb_gctypebits) - 1) - set $valmask = gdb_use_lsb ? ~($tagmask) : ((EMACS_INT) 1 << gdb_valbits) - 1 -end -document xreload - When starting Emacs a second time in the same gdb session under - FreeBSD 2.2.5, gdb 4.13, $valmask have lost - their values. (The same happens on current (2000) versions of GNU/Linux - with gdb 5.0.) - This function reloads them. -end -xreload - # Flush display (X only) define ff set x_flush (0) @@ -1211,15 +1187,6 @@ end -define hook-run - xreload -end - -# Call xreload if a new Emacs executable is loaded. -define hookpost-run - xreload -end - set print pretty on set print sevenbit-strings === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 05:23:25 +0000 +++ src/ChangeLog 2012-07-26 08:12:03 +0000 @@ -1,3 +1,40 @@ +2012-07-26 Paul Eggert + + Simplify export of symbols to GDB; fix related .gdbinit bugs. + * .gdbinit (xgetptr, xgetint, xgettype): Don't use "set $bugfix = + $bugfix.i", as this doesn't work (with GDB 7.4.1, anyway). + (xgetptr, xgetint, xgettype, xcoding, xcharset, xprintbytestr): + Adjust to changes in lisp.h and emacs.c, by using + CHECK_LISP_OBJECT_TYPE rather than gdb_use_struct, VALMASK instead + of $valmask, DATA_SEG_BITS instead of gdb_data_seg_bits, + INTTYPEBITS instead of gdb_gctypebits - 1, USE_LSB_TAG instead of + gdb_use_lsb, (1 << GCTYPEBITS) - 1 instead of $tagmask, VALBITS + instead of gdb_valbits. + (xvectype, xvector, xpr, xprintstr, xbacktrace): Similarly, use + PSEUDOVECTOR_FLAG instead of PVEC_FLAG, and ARRAY_MARK_FLAG + instead of gdb_array_mark_flag. + (xboolvector): Get size from $->size, not $->header.size. + Use BOOL_VECTOR_BITS_PER_CHAR rather than mystery constants. + (xreload, hook-run, hookpost-run): Remove. + * emacs.c: Include . + (gdb_use_lsb, gdb_use_struct, gdb_valbits, gdb_gctypebits) + (gdb_data_seg_bits, PVEC_FLAG, gdb_array_mark_flag, gdb_pvec_type): + Remove. + (gdb_CHECK_LISP_OBJECT_TYPE, gdb_DATA_SEG_BITS, gdb_GCTYPEBITS) + (gdb_USE_LSB_TAG): New enum constants. + (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS, GCTYPEBITS, USE_LSB_TAG): + Also define these as enum constants, so they're visible to GDB. + (ARRAY_MARK_FLAG_VAL, PSEUDOVECTOR_FLAG_VAL, VALMASK_VAL): New macros. + (ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG, VALMASK): Also define these + as constants, so they're visible to GDB. + * lisp.h (VALBITS, INTTYPEBITS, FIXNUM_BITS, PSEUDOVECTOR_SIZE_BITS) + (PSEUDOVECTOR_SIZE_MASK, PVEC_TYPE_MASK, BOOL_VECTOR_BITS_PER_CHAR): + Now enum constants, not macros, so they're visible to GDB. + (CHECK_LISP_OBJECT_TYPE, DATA_SEG_BITS): Default to 0, as this is + more convenient now. All uses changed. + (VALMASK) [USE_LSB_TAG]: Also define in this case. + * mem-limits.h (EXCEEDS_LISP_PTR): Adjust to DATA_SEG_BITS change. + 2012-07-26 Dmitry Antipov Explicitly free restriction data that are not needed anymore. === modified file 'src/emacs.c' --- src/emacs.c 2012-07-16 04:47:31 +0000 +++ src/emacs.c 2012-07-26 08:12:03 +0000 @@ -29,6 +29,8 @@ #include #include +#include + #include "lisp.h" #ifdef WINDOWSNT @@ -96,31 +98,6 @@ static const char emacs_version[] = VERSION; static const char emacs_copyright[] = "Copyright (C) 2012 Free Software Foundation, Inc."; -/* Make these values available in GDB, which doesn't see macros. */ - -#if USE_LSB_TAG -int gdb_use_lsb EXTERNALLY_VISIBLE = 1; -#else -int gdb_use_lsb EXTERNALLY_VISIBLE = 0; -#endif -#ifndef CHECK_LISP_OBJECT_TYPE -int gdb_use_struct EXTERNALLY_VISIBLE = 0; -#else -int gdb_use_struct EXTERNALLY_VISIBLE = 1; -#endif -int gdb_valbits EXTERNALLY_VISIBLE = VALBITS; -int gdb_gctypebits EXTERNALLY_VISIBLE = GCTYPEBITS; -#if defined DATA_SEG_BITS && !USE_LSB_TAG -uintptr_t gdb_data_seg_bits EXTERNALLY_VISIBLE = DATA_SEG_BITS; -#else -uintptr_t gdb_data_seg_bits EXTERNALLY_VISIBLE = 0; -#endif -ptrdiff_t PVEC_FLAG EXTERNALLY_VISIBLE = PSEUDOVECTOR_FLAG; -ptrdiff_t gdb_array_mark_flag EXTERNALLY_VISIBLE = ARRAY_MARK_FLAG; -/* GDB might say "No enum type named pvec_type" if we don't have at - least one symbol with that type, and then xbacktrace could fail. */ -enum pvec_type const gdb_pvec_type EXTERNALLY_VISIBLE = 0; - /* Empty lisp strings. To avoid having to build any others. */ Lisp_Object empty_unibyte_string, empty_multibyte_string; @@ -2513,3 +2490,50 @@ /* Make sure IS_DAEMON starts up as false. */ daemon_pipe[1] = 0; } + +/* Make these values available in GDB, which doesn't see macros. + This is last, so that the #undef lines don't mess up later code. */ + +enum + { + gdb_CHECK_LISP_OBJECT_TYPE = CHECK_LISP_OBJECT_TYPE, + gdb_DATA_SEG_BITS = DATA_SEG_BITS, + gdb_GCTYPEBITS = GCTYPEBITS, + gdb_USE_LSB_TAG = USE_LSB_TAG + }; + +#undef CHECK_LISP_OBJECT_TYPE +#undef DATA_SEG_BITS +#undef GCTYPEBITS +#undef USE_LSB_TAG + +enum + { + CHECK_LISP_OBJECT_TYPE = gdb_CHECK_LISP_OBJECT_TYPE, + DATA_SEG_BITS = gdb_DATA_SEG_BITS, + GCTYPEBITS = gdb_GCTYPEBITS, + USE_LSB_TAG = gdb_USE_LSB_TAG + }; + +/* These are trickier since they might fall out of int range. Each + symbol X has a corresponding X_VAL symbol, verified to have the + correct value. */ + +#define ARRAY_MARK_FLAG_VAL PTRDIFF_MIN +#define PSEUDOVECTOR_FLAG_VAL (PTRDIFF_MAX - PTRDIFF_MAX / 2) +#define VALMASK_VAL (USE_LSB_TAG ? -1 << GCTYPEBITS : VAL_MAX) + +verify (ARRAY_MARK_FLAG_VAL == ARRAY_MARK_FLAG); +verify (PSEUDOVECTOR_FLAG_VAL == PSEUDOVECTOR_FLAG); +verify (VALMASK_VAL == VALMASK); + +#undef ARRAY_MARK_FLAG +#undef PSEUDOVECTOR_FLAG +#undef VALMASK + +ptrdiff_t const EXTERNALLY_VISIBLE + ARRAY_MARK_FLAG = ARRAY_MARK_FLAG_VAL, + PSEUDOVECTOR_FLAG = PSEUDOVECTOR_FLAG_VAL; + +EMACS_INT const EXTERNALLY_VISIBLE + VALMASK = VALMASK_VAL; === modified file 'src/lisp.h' --- src/lisp.h 2012-07-26 01:27:33 +0000 +++ src/lisp.h 2012-07-26 08:12:03 +0000 @@ -155,8 +155,11 @@ variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ +/* Number of bits in a Lisp_Obect tag. This can be used in #if. */ #define GCTYPEBITS 3 -#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS) + +/* Number of bits in a Lisp_Object value, not counting the tag. */ +enum { VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS }; /* The maximum value that can be stored in a EMACS_INT, assuming all bits other than the type bits contribute to a nonnegative signed value. @@ -218,8 +221,8 @@ /* Lisp integers use 2 tags, to give them one extra bit, thus extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ -#define INTTYPEBITS (GCTYPEBITS - 1) -#define FIXNUM_BITS (VALBITS + 1) +enum { INTTYPEBITS = GCTYPEBITS - 1 }; +enum { FIXNUM_BITS = VALBITS + 1 }; #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) #define LISP_INT_TAG Lisp_Int0 #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 @@ -324,6 +327,7 @@ #define XIL(i) (i) #define LISP_MAKE_RVALUE(o) (0+(o)) #define LISP_INITIALLY_ZERO 0 +#define CHECK_LISP_OBJECT_TYPE 0 #endif /* CHECK_LISP_OBJECT_TYPE */ /* In the size word of a vector, this bit means the vector has been marked. */ @@ -370,13 +374,22 @@ only the number of Lisp_Object fields (that need to be traced by the GC). The distinction is used e.g. by Lisp_Process which places extra non-Lisp_Object fields at the end of the structure. */ -#define PSEUDOVECTOR_SIZE_BITS 16 -#define PSEUDOVECTOR_SIZE_MASK ((1 << PSEUDOVECTOR_SIZE_BITS) - 1) -#define PVEC_TYPE_MASK (0x0fff << PSEUDOVECTOR_SIZE_BITS) +enum + { + PSEUDOVECTOR_SIZE_BITS = 16, + PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, + PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS + }; /* Number of bits to put in each character in the internal representation of bool vectors. This should not vary across implementations. */ -#define BOOL_VECTOR_BITS_PER_CHAR 8 +enum { BOOL_VECTOR_BITS_PER_CHAR = 8 }; + +/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers + which were stored in a Lisp_Object */ +#ifndef DATA_SEG_BITS +# define DATA_SEG_BITS 0 +#endif /* These macros extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons, @@ -387,6 +400,7 @@ #if USE_LSB_TAG +#define VALMASK (-1 << GCTYPEBITS) #define TYPEMASK ((1 << GCTYPEBITS) - 1) #define XTYPE(a) ((enum Lisp_Type) (XLI (a) & TYPEMASK)) #define XINT(a) (XLI (a) >> INTTYPEBITS) @@ -421,7 +435,7 @@ ((var) = XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ + ((intptr_t) (ptr) & VALMASK))) -#ifdef DATA_SEG_BITS +#if DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) === modified file 'src/mem-limits.h' --- src/mem-limits.h 2012-07-09 16:38:45 +0000 +++ src/mem-limits.h 2012-07-26 08:12:03 +0000 @@ -36,7 +36,7 @@ extern char *start_of_data (void) ATTRIBUTE_CONST; #if USE_LSB_TAG || UINTPTR_MAX <= VAL_MAX #define EXCEEDS_LISP_PTR(ptr) 0 -#elif defined DATA_SEG_BITS +#elif DATA_SEG_BITS #define EXCEEDS_LISP_PTR(ptr) \ (((uintptr_t) (ptr) & ~DATA_SEG_BITS) >> VALBITS) #else ------------------------------------------------------------ revno: 109212 committer: Dmitry Antipov branch nick: trunk timestamp: Thu 2012-07-26 09:23:25 +0400 message: Explicitly free restriction data that are not needed anymore. * editfns.c (save_restriction_restore): Free restriction data. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-26 01:27:33 +0000 +++ src/ChangeLog 2012-07-26 05:23:25 +0000 @@ -1,3 +1,8 @@ +2012-07-26 Dmitry Antipov + + Explicitly free restriction data that are not needed anymore. + * editfns.c (save_restriction_restore): Free restriction data. + 2012-07-26 Stefan Monnier * eval.c (Fautoload_do_load): Rename from do_autoload, export to Lisp, === modified file 'src/editfns.c' --- src/editfns.c 2012-07-17 07:43:01 +0000 +++ src/editfns.c 2012-07-26 05:23:25 +0000 @@ -3379,6 +3379,10 @@ buf->clip_changed = 1; /* Remember that the narrowing changed. */ } + /* These aren't needed anymore, so don't wait for GC. */ + free_marker (XCAR (data)); + free_marker (XCDR (data)); + free_cons (XCONS (data)); } else /* A buffer, which means that there was no old restriction. */