aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoakim Verona2012-11-13 03:01:33 +0100
committerJoakim Verona2012-11-13 03:01:33 +0100
commit74fa27af7f4b50a6f5e2a378802b4c5edc11d044 (patch)
tree7030d55ecc2e06df59c08047b6f89e5b11a329dc /src
parent2a4942ed0e4cca22145a0d973112454c410c3dd7 (diff)
parentb95a9c0cba301ef8f1920a1d123ccd6873c14a63 (diff)
downloademacs-74fa27af7f4b50a6f5e2a378802b4c5edc11d044.tar.gz
emacs-74fa27af7f4b50a6f5e2a378802b4c5edc11d044.zip
upstream
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit49
-rw-r--r--src/ChangeLog258
-rw-r--r--src/alloc.c193
-rw-r--r--src/buffer.c13
-rw-r--r--src/buffer.h31
-rw-r--r--src/category.c4
-rw-r--r--src/composite.c4
-rw-r--r--src/data.c70
-rw-r--r--src/doc.c35
-rw-r--r--src/emacs.c4
-rw-r--r--src/eval.c21
-rw-r--r--src/fileio.c10
-rw-r--r--src/fns.c178
-rw-r--r--src/frame.c108
-rw-r--r--src/frame.h2
-rw-r--r--src/image.c4
-rw-r--r--src/keyboard.c21
-rw-r--r--src/lisp.h181
-rw-r--r--src/lread.c2
-rw-r--r--src/nsfont.m15
-rw-r--r--src/print.c8
-rw-r--r--src/profiler.c91
-rw-r--r--src/ralloc.c34
-rw-r--r--src/regex.c2
-rw-r--r--src/termhooks.h18
-rw-r--r--src/w32fns.c23
-rw-r--r--src/w32term.c13
-rw-r--r--src/w32term.h11
-rw-r--r--src/window.c112
-rw-r--r--src/xdisp.c52
-rw-r--r--src/xfaces.c32
-rw-r--r--src/xfns.c38
-rw-r--r--src/xmenu.c5
-rw-r--r--src/xselect.c21
-rw-r--r--src/xterm.c55
-rw-r--r--src/xterm.h6
36 files changed, 1000 insertions, 724 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 952d7392a4c..fa580cc99bf 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -650,19 +650,52 @@ If the first type printed is Lisp_Vector or Lisp_Misc,
650a second line gives the more precise type. 650a second line gives the more precise type.
651end 651end
652 652
653define pvectype
654 set $size = ((struct Lisp_Vector *) $arg0)->header.size
655 if ($size & PSEUDOVECTOR_FLAG)
656 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
657 else
658 output PVEC_NORMAL_VECTOR
659 end
660 echo \n
661end
662document pvectype
663Print the subtype of vectorlike object.
664Takes one argument, a pointer to an object.
665end
666
653define xvectype 667define xvectype
654 xgetptr $ 668 xgetptr $
655 set $size = ((struct Lisp_Vector *) $ptr)->header.size 669 pvectype $ptr
670end
671document xvectype
672Print the subtype of vectorlike object.
673This command assumes that $ is a Lisp_Object.
674end
675
676define pvecsize
677 set $size = ((struct Lisp_Vector *) $arg0)->header.size
656 if ($size & PSEUDOVECTOR_FLAG) 678 if ($size & PSEUDOVECTOR_FLAG)
657 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 679 output ($size & PSEUDOVECTOR_SIZE_MASK)
680 echo \n
681 output (($size & PSEUDOVECTOR_REST_MASK) >> PSEUDOVECTOR_SIZE_BITS)
658 else 682 else
659 output $size & ~ARRAY_MARK_FLAG 683 output ($size & ~ARRAY_MARK_FLAG)
660 end 684 end
661 echo \n 685 echo \n
662end 686end
663document xvectype 687document pvecsize
664Print the size or vector subtype of $. 688Print the size of vectorlike object.
665This command assumes that $ is a vector or pseudovector. 689Takes one argument, a pointer to an object.
690end
691
692define xvecsize
693 xgetptr $
694 pvecsize $ptr
695end
696document xvecsize
697Print the size of $
698This command assumes that $ is a Lisp_Object.
666end 699end
667 700
668define xmisctype 701define xmisctype
@@ -996,7 +1029,7 @@ define xpr
996 if $type == Lisp_Vectorlike 1029 if $type == Lisp_Vectorlike
997 set $size = ((struct Lisp_Vector *) $ptr)->header.size 1030 set $size = ((struct Lisp_Vector *) $ptr)->header.size
998 if ($size & PSEUDOVECTOR_FLAG) 1031 if ($size & PSEUDOVECTOR_FLAG)
999 set $vec = (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 1032 set $vec = (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
1000 if $vec == PVEC_NORMAL_VECTOR 1033 if $vec == PVEC_NORMAL_VECTOR
1001 xvector 1034 xvector
1002 end 1035 end
@@ -1132,7 +1165,7 @@ define xbacktrace
1132 xgetptr ($bt->function) 1165 xgetptr ($bt->function)
1133 set $size = ((struct Lisp_Vector *) $ptr)->header.size 1166 set $size = ((struct Lisp_Vector *) $ptr)->header.size
1134 if ($size & PSEUDOVECTOR_FLAG) 1167 if ($size & PSEUDOVECTOR_FLAG)
1135 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_SIZE_BITS) 1168 output (enum pvec_type) (($size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
1136 else 1169 else
1137 output $size & ~ARRAY_MARK_FLAG 1170 output $size & ~ARRAY_MARK_FLAG
1138 end 1171 end
diff --git a/src/ChangeLog b/src/ChangeLog
index 0eb69f59efe..5905c667852 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,249 @@
12012-11-13 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix a race with verify-visited-file-modtime (Bug#12863).
4 Since at least 1991 Emacs has ignored an mtime difference of no
5 more than one second, but my guess is that this was to work around
6 file system bugs that were fixed long ago. Since the race is
7 causing problems now, let's remove that code.
8 * fileio.c (Fverify_visited_file_modtime): Do not accept a file
9 whose time stamp is off by no more than a second. Insist that the
10 file time stamps match exactly.
11
122012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
13
14 * frame.h (struct frame): Convert external_tool_bar member to
15 1-bit unsigned bitfield.
16 * termhooks.h (struct terminal): Remove mouse_moved member since
17 all users are long dead. Adjust comment on mouse_position_hook.
18
192012-11-12 Dmitry Antipov <dmantipov@yandex.ru>
20
21 Simplify by using FOR_EACH_FRAME here and there.
22 * frame.c (next_frame, prev_frame, other_visible_frames)
23 (delete_frame, visible-frame-list): Use FOR_EACH_FRAME.
24 * w32term.c (x_window_to_scroll_bar): Likewise.
25 * window.c (window_list): Likewise.
26 * xdisp.c (x_consider_frame_title): Likewise.
27 * xfaces.c ( Fdisplay_supports_face_attributes_p): Likewise.
28 * xfns.c (x_window_to_frame, x_any_window_to_frame)
29 (x_menubar_window_to_frame, x_top_window_to_frame): Likewise.
30 * xmenu.c (menubar_id_to_frame): Likewise.
31 * xselect.c (frame_for_x_selection): Likewise.
32 * xterm.c (x_frame_of_widget, x_window_to_scroll_bar)
33 (x_window_to_menu_bar): Likewise.
34 * w32fns.c (x_window_to_frame): Likewise. Adjust comment.
35
362012-11-12 Paul Eggert <eggert@cs.ucla.edu>
37
38 * data.c (Qdefalias_fset_function): Now static.
39
40 Another tweak to vectorlike_header change.
41 * alloc.c (struct Lisp_Vectorlike_Free, NEXT_IN_FREE_LIST):
42 Remove, and replace all uses with ...
43 (next_in_free_list, set_next_in_free_list):
44 New functions, which respect C's aliasing rules better.
45
462012-11-11 Paul Eggert <eggert@cs.ucla.edu>
47
48 * window.c (list4i): Rename from 'quad'. All uses changed.
49 Needed because <sys/types.h> defines 'quad' on Solaris 10.
50
512012-11-11 Juanma Barranquero <lekktu@gmail.com>
52
53 * xdisp.c (start_hourglass) [HAVE_NTGUI]: Add block to silence
54 warning about mixing declarations and code in ISO C90.
55
562012-11-10 Martin Rudalics <rudalics@gmx.at>
57
58 * window.c (Fsplit_window_internal): Set combination limit of
59 new parent window to t iff Vwindow_combination_limit is t;
60 fixing a regression introduced with the change from 2012-09-22.
61 (Fset_window_combination_limit): Fix doc-string.
62
632012-11-10 Eli Zaretskii <eliz@gnu.org>
64
65 * xdisp.c (try_scrolling): Fix correction of aggressive-scroll
66 amount when the scroll margins are too large. When scrolling
67 backwards in the buffer, give up if cannot reach point or the
68 scroll margin within a reasonable number of screen lines. Fixes
69 point position in window under scroll-up/down-aggressively when
70 point is positioned many lines beyond the window top/bottom.
71 (Bug#12811)
72
73 * ralloc.c (relinquish): If real_morecore fails to return memory
74 to the system, don't crash; instead, leave the last heap
75 unchanged and return. (Bug#12774)
76
772012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
78
79 * lisp.h (AUTOLOADP): New macro.
80 * eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead.
81 * data.c (Ffset): Remove special ad-advice-info handling.
82 (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function.
83 (Fsubr_arity): CSE.
84 (Finteractive_form): Simplify.
85 (Fquo): Don't insist on having at least 2 arguments.
86 (Qdefalias_fset_function): New var.
87
882012-11-09 Jan Djärv <jan.h.d@swipnet.se>
89
90 * image.c (xpm_make_color_table_h): Change to hashtest_equal.
91
92 * nsfont.m (Qcondensed, Qexpanded): New variables.
93 (ns_descriptor_to_entity): Restore Qcondensed, Qexpanded setting.
94 (syms_of_nsfont): Defsym Qcondensed, Qexpanded.
95
962012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
97
98 Fix recently introduced crash on MS-Windows (Bug#12839).
99 * w32term.h (struct scroll_bar): Use convenient header.
100 (SCROLL_BAR_VEC_SIZE): Remove.
101 * w32term.c (x_scroll_bar_create): Use VECSIZE.
102
1032012-11-09 Dmitry Antipov <dmantipov@yandex.ru>
104
105 Tweak last vectorlike_header change.
106 * alloc.c (struct Lisp_Vectorlike_Free): Special type to represent
107 vectorlike object on the free list. This is introduced to avoid
108 some (but not all) pointer casting and aliasing problems, see
109 http://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00105.html.
110 * .gdbinit (pvectype, pvecsize): New commands to examine vectorlike
111 objects.
112 (xvectype, xvecsize): Use them to examine Lisp_Object values.
113
1142012-11-09 Jan Djärv <jan.h.d@swipnet.se>
115
116 * nsfont.m (ns_descriptor_to_entity): Qcondensed and Qexpanded has
117 been removed, so remove them here also.
118
1192012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
120
121 * doc.c (Fdocumentation): Handle new property
122 dynamic-docstring-function to replace the old ad-advice-info.
123
1242012-11-09 Paul Eggert <eggert@cs.ucla.edu>
125
126 * fns.c (Qeql, hashtest_eq): Now static.
127
1282012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
129
130 * lisp.h (XHASH): Redefine to be imperfect and fit in a Lisp int.
131 * fns.c (hashfn_eq, hashfn_eql, sxhash):
132 * profiler.c (hashfn_profiler): Don't use XUINT on non-integers.
133 * buffer.c (compare_overlays): Use XLI rather than XHASH.
134
1352012-11-08 Paul Eggert <eggert@cs.ucla.edu>
136
137 Use same hash function for hashfn_profiler as for hash_string etc.
138 * fns.c (SXHASH_COMBINE): Remove. All uses replaced by sxhash_combine.
139 * lisp.h (sxhash_combine): New inline function, with the contents
140 of the old SXHASH_COMBINE.
141 * profiler.c (hashfn_profiler): Use it, instead of having a
142 special hash function containing a comparison that always yields 1.
143
1442012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
145
146 * xfaces.c (Qultra_light, Qreverse_oblique, Qreverse_italic)
147 (Qultra_condensed, Qextra_condensed, Qcondensed, Qsemi_condensed)
148 (Qsemi_expanded, Qextra_expanded, Qexpanded, Qultra_expanded):
149 Remove unused vars.
150
1512012-11-08 Jan Djärv <jan.h.d@swipnet.se>
152
153 * image.c (xpm_make_color_table_h): Fix compiler error because
154 make_hash_table changed.
155
1562012-11-08 Thomas Kappler <tkappler@gmail.com> (tiny change)
157
158 * nsfont.m (ns_findfonts): Handle empty matchingDescs (Bug#11541).
159
1602012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
161
162 Use ad-hoc comparison function for the profiler's hash-tables.
163 * profiler.c (Qprofiler_backtrace_equal, hashtest_profiler): New vars.
164 (make_log): Use them.
165 (handle_profiler_signal): Don't inhibit quit any longer since we don't
166 call Fequal any more.
167 (Ffunction_equal): New function.
168 (cmpfn_profiler, hashfn_profiler): New functions.
169 (syms_of_profiler): Initialize them.
170 * lisp.h (struct hash_table_test): New struct.
171 (struct Lisp_Hash_Table): Use it.
172 * alloc.c (mark_object): Mark hash_table_test fields of hash tables.
173 * fns.c (make_hash_table): Take a struct to describe the test.
174 (cmpfn_eql, cmpfn_equal, cmpfn_user_defined, hashfn_eq, hashfn_eql)
175 (hashfn_equal, hashfn_user_defined): Adjust to new calling convention.
176 (hash_lookup, hash_remove_from_table): Move assertion checking of
177 hashfn result here. Check hash-equality before calling cmpfn.
178 (Fmake_hash_table): Adjust call to make_hash_table.
179 (hashtest_eq, hashtest_eql, hashtest_equal): New structs.
180 (syms_of_fns): Initialize them.
181 * emacs.c (main): Move syms_of_fns earlier.
182 * xterm.c (syms_of_xterm):
183 * category.c (hash_get_category_set): Adjust call to make_hash_table.
184 * print.c (print_object): Adjust to new hash-table struct.
185 * composite.c (composition_gstring_put_cache): Adjust to new hashfn.
186
1872012-11-08 Eli Zaretskii <eliz@gnu.org>
188
189 * w32fns.c (modifier_set): Fix handling of Scroll Lock when the
190 value of w32-scroll-lock-modifier is neither nil nor one of the
191 known key modifiers. (Bug#12806)
192
1932012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
194
195 Shrink struct vectorlike_header to the only size field.
196 * lisp.h (enum pvec_type): Avoid explicit enum member values.
197 Adjust comment.
198 (enum More_Lisp_Bits): Change PSEUDOVECTOR_SIZE_BITS and
199 PVEC_TYPE_MASK to arrange new bitfield in the vector header.
200 (PSEUDOVECTOR_REST_BITS, PSEUDOVECTOR_REST_MASK): New members.
201 (PSEUDOVECTOR_AREA_BITS): New member used to extract subtype
202 information from the vector header. Adjust comment.
203 (XSETPVECTYPE, XSETPVECTYPESIZE, XSETTYPED_PSEUDOVECTOR)
204 (PSEUDOVECTOR_TYPEP, DEFUN): Adjust to match new vector header
205 layout.
206 (XSETSUBR, SUBRP): Adjust to match new Lisp_Subr layout.
207 (struct vectorlike_header): Remove next member. Adjust comment.
208 (struct Lisp_Subr): Add convenient header. Adjust comment.
209 (allocate_pseudovector): Adjust prototype.
210 * alloc.c (mark_glyph_matrix, mark_face_cache, allocate_string)
211 (sweep_string, lisp_malloc): Remove useless prototypes.
212 (enum mem_type): Adjust comment.
213 (NEXT_IN_FREE_LIST): New macro.
214 (SETUP_ON_FREE_LIST): Adjust XSETPVECTYPESIZE usage.
215 (Fmake_bool_vector): Likewise.
216 (struct large_vector): New type to represent allocation unit for
217 the vectors with the memory footprint more than VBLOOCK_BYTES_MAX.
218 (large_vectors): Change type to struct large_vector.
219 (allocate_vector_from_block): Simplify.
220 (PSEUDOVECTOR_NBYTES): Replace with...
221 (vector_nbytes): ...new function. Adjust users.
222 (sweep_vectors): Adjust processing of large vectors.
223 (allocate_vectorlike): Likewise.
224 (allocate_pseudovector): Change type of 3rd arg to enum pvec_type.
225 Add easserts. Adjust XSETPVECTYPESIZE usage.
226 (allocate_buffer): Use BUFFER_PVEC_INIT.
227 (live_vector_p): Adjust to match large vector.
228 * buffer.c (init_buffer_once): Use BUFFER_PVEC_INIT.
229 * buffer.h (struct buffer): Add next member.
230 (BUFFER_LISP_SIZE, BUFFER_REST_SIZE, BUFFER_PVEC_INIT):
231 New macros.
232 (FOR_EACH_BUFFER): Adjust to match struct buffer change.
233 * fns.c (internal_equal): Adjust to match enum pvec_type change.
234 (copy_hash_table): Adjust to match vector header change.
235 * lread.c (defsubr): Use XSETPVECTYPE.
236 * .gdbinit (xpr, xbacktrace): Adjust to match vector header change.
237 (xvectype): Likewise. Print PVEC_NORMAL_VECTOR for regular vectors.
238 (xvecsize): New command.
239
2402012-11-08 Dmitry Antipov <dmantipov@yandex.ru>
241
242 * keyboard.c (event_to_kboard): Do not dereference
243 frame_or_window field of SELECTION_REQUEST_EVENT
244 and SELECTION_CLEAR_EVENT events (Bug#12814).
245 * xterm.h (struct selection_input_event): Adjust comment.
246
12012-11-07 Eli Zaretskii <eliz@gnu.org> 2472012-11-07 Eli Zaretskii <eliz@gnu.org>
2 248
3 * w32fns.c (modifier_set): Don't report modifiers from toggle key, 249 * w32fns.c (modifier_set): Don't report modifiers from toggle key,
@@ -129,8 +375,8 @@
129 375
130 Remove EMACS_OUTQSIZE+sleep hack. 376 Remove EMACS_OUTQSIZE+sleep hack.
131 * dispnew.c (update_frame_1): Remove hack for terminals slower 377 * dispnew.c (update_frame_1): Remove hack for terminals slower
132 than 2400 bps, which throttled Emacs by having it sleep. This 378 than 2400 bps, which throttled Emacs by having it sleep.
133 code hasn't worked since at least 2007, when the multi-tty stuff 379 This code hasn't worked since at least 2007, when the multi-tty stuff
134 was added, and anyway those old terminals are long dead. 380 was added, and anyway those old terminals are long dead.
135 * systty.h (EMACS_OUTQSIZE): Remove; unused. The macro isn't used even 381 * systty.h (EMACS_OUTQSIZE): Remove; unused. The macro isn't used even
136 without the dispnew.c change, as dispnew.c doesn't include systty.h. 382 without the dispnew.c change, as dispnew.c doesn't include systty.h.
@@ -169,8 +415,8 @@
169 waitpid only on subprocesses that Emacs itself creates. 415 waitpid only on subprocesses that Emacs itself creates.
170 * process.c (create_process, record_child_status_change): 416 * process.c (create_process, record_child_status_change):
171 Don't use special value -1 in pid field, as the caller now must 417 Don't use special value -1 in pid field, as the caller now must
172 know the pid rather than having the callee infer it. The 418 know the pid rather than having the callee infer it.
173 inference was sometimes incorrect anyway, due to another race. 419 The inference was sometimes incorrect anyway, due to another race.
174 (create_process): Set new 'alive' member if child is created. 420 (create_process): Set new 'alive' member if child is created.
175 (process_status_retrieved): New function. 421 (process_status_retrieved): New function.
176 (record_child_status_change): Use it. 422 (record_child_status_change): Use it.
@@ -331,8 +577,8 @@
331 577
3322012-10-29 Daniel Colascione <dancol@dancol.org> 5782012-10-29 Daniel Colascione <dancol@dancol.org>
333 579
334 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode): In 580 * cygw32.h, cygw32.c (Qutf_16le, from_unicode, to_unicode):
335 preparation for fixing bug#12739, move these functions from 581 In preparation for fixing bug#12739, move these functions from
336 here... 582 here...
337 583
338 * coding.h, coding.c: ... to here, and compile them only when 584 * coding.h, coding.c: ... to here, and compile them only when
diff --git a/src/alloc.c b/src/alloc.c
index 5bb528c64ab..a66a752f5dc 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -216,23 +216,19 @@ static Lisp_Object Qpost_gc_hook;
216static void mark_terminals (void); 216static void mark_terminals (void);
217static void gc_sweep (void); 217static void gc_sweep (void);
218static Lisp_Object make_pure_vector (ptrdiff_t); 218static Lisp_Object make_pure_vector (ptrdiff_t);
219static void mark_glyph_matrix (struct glyph_matrix *);
220static void mark_face_cache (struct face_cache *);
221static void mark_buffer (struct buffer *); 219static void mark_buffer (struct buffer *);
222 220
223#if !defined REL_ALLOC || defined SYSTEM_MALLOC 221#if !defined REL_ALLOC || defined SYSTEM_MALLOC
224static void refill_memory_reserve (void); 222static void refill_memory_reserve (void);
225#endif 223#endif
226static struct Lisp_String *allocate_string (void);
227static void compact_small_strings (void); 224static void compact_small_strings (void);
228static void free_large_strings (void); 225static void free_large_strings (void);
229static void sweep_strings (void);
230static void free_misc (Lisp_Object); 226static void free_misc (Lisp_Object);
231extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE; 227extern Lisp_Object which_symbols (Lisp_Object, EMACS_INT) EXTERNALLY_VISIBLE;
232 228
233/* When scanning the C stack for live Lisp objects, Emacs keeps track 229/* When scanning the C stack for live Lisp objects, Emacs keeps track of
234 of what memory allocated via lisp_malloc is intended for what 230 what memory allocated via lisp_malloc and lisp_align_malloc is intended
235 purpose. This enumeration specifies the type of memory. */ 231 for what purpose. This enumeration specifies the type of memory. */
236 232
237enum mem_type 233enum mem_type
238{ 234{
@@ -243,10 +239,9 @@ enum mem_type
243 MEM_TYPE_MISC, 239 MEM_TYPE_MISC,
244 MEM_TYPE_SYMBOL, 240 MEM_TYPE_SYMBOL,
245 MEM_TYPE_FLOAT, 241 MEM_TYPE_FLOAT,
246 /* We used to keep separate mem_types for subtypes of vectors such as 242 /* Since all non-bool pseudovectors are small enough to be
247 process, hash_table, frame, terminal, and window, but we never made 243 allocated from vector blocks, this memory type denotes
248 use of the distinction, so it only caused source-code complexity 244 large regular vectors and large bool pseudovectors. */
249 and runtime slowdown. Minor but pointless. */
250 MEM_TYPE_VECTORLIKE, 245 MEM_TYPE_VECTORLIKE,
251 /* Special type to denote vector blocks. */ 246 /* Special type to denote vector blocks. */
252 MEM_TYPE_VECTOR_BLOCK, 247 MEM_TYPE_VECTOR_BLOCK,
@@ -254,9 +249,6 @@ enum mem_type
254 MEM_TYPE_SPARE 249 MEM_TYPE_SPARE
255}; 250};
256 251
257static void *lisp_malloc (size_t, enum mem_type);
258
259
260#if GC_MARK_STACK || defined GC_MALLOC_CHECK 252#if GC_MARK_STACK || defined GC_MALLOC_CHECK
261 253
262#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES 254#if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
@@ -2040,7 +2032,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2040 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil); 2032 val = Fmake_vector (make_number (length_in_elts + extra_bool_elts), Qnil);
2041 2033
2042 /* No Lisp_Object to trace in there. */ 2034 /* No Lisp_Object to trace in there. */
2043 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0); 2035 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2044 2036
2045 p = XBOOL_VECTOR (val); 2037 p = XBOOL_VECTOR (val);
2046 p->size = XFASTINT (length); 2038 p->size = XFASTINT (length);
@@ -2619,19 +2611,54 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2619 2611
2620#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) 2612#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2621 2613
2614/* Get and set the next field in block-allocated vectorlike objects on
2615 the free list. Doing it this way respects C's aliasing rules.
2616 We could instead make 'contents' a union, but that would mean
2617 changes everywhere that the code uses 'contents'. */
2618static struct Lisp_Vector *
2619next_in_free_list (struct Lisp_Vector *v)
2620{
2621 intptr_t i = XLI (v->contents[0]);
2622 return (struct Lisp_Vector *) i;
2623}
2624static void
2625set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2626{
2627 v->contents[0] = XIL ((intptr_t) next);
2628}
2629
2622/* Common shortcut to setup vector on a free list. */ 2630/* Common shortcut to setup vector on a free list. */
2623 2631
2624#define SETUP_ON_FREE_LIST(v, nbytes, index) \ 2632#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
2625 do { \ 2633 do { \
2626 XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ 2634 (tmp) = ((nbytes - header_size) / word_size); \
2627 eassert ((nbytes) % roundup_size == 0); \ 2635 XSETPVECTYPESIZE (v, PVEC_FREE, 0, (tmp)); \
2628 (index) = VINDEX (nbytes); \ 2636 eassert ((nbytes) % roundup_size == 0); \
2629 eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ 2637 (tmp) = VINDEX (nbytes); \
2630 (v)->header.next.vector = vector_free_lists[index]; \ 2638 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2631 vector_free_lists[index] = (v); \ 2639 set_next_in_free_list (v, vector_free_lists[tmp]); \
2632 total_free_vector_slots += (nbytes) / word_size; \ 2640 vector_free_lists[tmp] = (v); \
2641 total_free_vector_slots += (nbytes) / word_size; \
2633 } while (0) 2642 } while (0)
2634 2643
2644/* This internal type is used to maintain the list of large vectors
2645 which are allocated at their own, e.g. outside of vector blocks. */
2646
2647struct large_vector
2648{
2649 union {
2650 struct large_vector *vector;
2651#if USE_LSB_TAG
2652 /* We need to maintain ROUNDUP_SIZE alignment for the vector member. */
2653 unsigned char c[vroundup (sizeof (struct large_vector *))];
2654#endif
2655 } next;
2656 struct Lisp_Vector v;
2657};
2658
2659/* This internal type is used to maintain an underlying storage
2660 for small vectors. */
2661
2635struct vector_block 2662struct vector_block
2636{ 2663{
2637 char data[VECTOR_BLOCK_BYTES]; 2664 char data[VECTOR_BLOCK_BYTES];
@@ -2649,7 +2676,7 @@ static struct Lisp_Vector *vector_free_lists[VECTOR_MAX_FREE_LIST_INDEX];
2649 2676
2650/* Singly-linked list of large vectors. */ 2677/* Singly-linked list of large vectors. */
2651 2678
2652static struct Lisp_Vector *large_vectors; 2679static struct large_vector *large_vectors;
2653 2680
2654/* The only vector with 0 slots, allocated from pure space. */ 2681/* The only vector with 0 slots, allocated from pure space. */
2655 2682
@@ -2693,7 +2720,7 @@ init_vectors (void)
2693static struct Lisp_Vector * 2720static struct Lisp_Vector *
2694allocate_vector_from_block (size_t nbytes) 2721allocate_vector_from_block (size_t nbytes)
2695{ 2722{
2696 struct Lisp_Vector *vector, *rest; 2723 struct Lisp_Vector *vector;
2697 struct vector_block *block; 2724 struct vector_block *block;
2698 size_t index, restbytes; 2725 size_t index, restbytes;
2699 2726
@@ -2706,8 +2733,7 @@ allocate_vector_from_block (size_t nbytes)
2706 if (vector_free_lists[index]) 2733 if (vector_free_lists[index])
2707 { 2734 {
2708 vector = vector_free_lists[index]; 2735 vector = vector_free_lists[index];
2709 vector_free_lists[index] = vector->header.next.vector; 2736 vector_free_lists[index] = next_in_free_list (vector);
2710 vector->header.next.nbytes = nbytes;
2711 total_free_vector_slots -= nbytes / word_size; 2737 total_free_vector_slots -= nbytes / word_size;
2712 return vector; 2738 return vector;
2713 } 2739 }
@@ -2721,16 +2747,14 @@ allocate_vector_from_block (size_t nbytes)
2721 { 2747 {
2722 /* This vector is larger than requested. */ 2748 /* This vector is larger than requested. */
2723 vector = vector_free_lists[index]; 2749 vector = vector_free_lists[index];
2724 vector_free_lists[index] = vector->header.next.vector; 2750 vector_free_lists[index] = next_in_free_list (vector);
2725 vector->header.next.nbytes = nbytes;
2726 total_free_vector_slots -= nbytes / word_size; 2751 total_free_vector_slots -= nbytes / word_size;
2727 2752
2728 /* Excess bytes are used for the smaller vector, 2753 /* Excess bytes are used for the smaller vector,
2729 which should be set on an appropriate free list. */ 2754 which should be set on an appropriate free list. */
2730 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; 2755 restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes;
2731 eassert (restbytes % roundup_size == 0); 2756 eassert (restbytes % roundup_size == 0);
2732 rest = ADVANCE (vector, nbytes); 2757 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2733 SETUP_ON_FREE_LIST (rest, restbytes, index);
2734 return vector; 2758 return vector;
2735 } 2759 }
2736 2760
@@ -2739,7 +2763,6 @@ allocate_vector_from_block (size_t nbytes)
2739 2763
2740 /* New vector will be at the beginning of this block. */ 2764 /* New vector will be at the beginning of this block. */
2741 vector = (struct Lisp_Vector *) block->data; 2765 vector = (struct Lisp_Vector *) block->data;
2742 vector->header.next.nbytes = nbytes;
2743 2766
2744 /* If the rest of space from this block is large enough 2767 /* If the rest of space from this block is large enough
2745 for one-slot vector at least, set up it on a free list. */ 2768 for one-slot vector at least, set up it on a free list. */
@@ -2747,11 +2770,10 @@ allocate_vector_from_block (size_t nbytes)
2747 if (restbytes >= VBLOCK_BYTES_MIN) 2770 if (restbytes >= VBLOCK_BYTES_MIN)
2748 { 2771 {
2749 eassert (restbytes % roundup_size == 0); 2772 eassert (restbytes % roundup_size == 0);
2750 rest = ADVANCE (vector, nbytes); 2773 SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index);
2751 SETUP_ON_FREE_LIST (rest, restbytes, index);
2752 } 2774 }
2753 return vector; 2775 return vector;
2754 } 2776}
2755 2777
2756/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */ 2778/* Nonzero if VECTOR pointer is valid pointer inside BLOCK. */
2757 2779
@@ -2759,15 +2781,30 @@ allocate_vector_from_block (size_t nbytes)
2759 ((char *) (vector) <= (block)->data \ 2781 ((char *) (vector) <= (block)->data \
2760 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) 2782 + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN)
2761 2783
2762/* Number of bytes used by vector-block-allocated object. This is the only 2784/* Return the memory footprint of V in bytes. */
2763 place where we actually use the `nbytes' field of the vector-header.
2764 I.e. we could get rid of the `nbytes' field by computing it based on the
2765 vector-type. */
2766 2785
2767#define PSEUDOVECTOR_NBYTES(vector) \ 2786static ptrdiff_t
2768 (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ 2787vector_nbytes (struct Lisp_Vector *v)
2769 ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ 2788{
2770 : vector->header.next.nbytes) 2789 ptrdiff_t size = v->header.size & ~ARRAY_MARK_FLAG;
2790
2791 if (size & PSEUDOVECTOR_FLAG)
2792 {
2793 if (PSEUDOVECTOR_TYPEP (&v->header, PVEC_BOOL_VECTOR))
2794 size = (bool_header_size
2795 + (((struct Lisp_Bool_Vector *) v)->size
2796 + BOOL_VECTOR_BITS_PER_CHAR - 1)
2797 / BOOL_VECTOR_BITS_PER_CHAR);
2798 else
2799 size = (header_size
2800 + ((size & PSEUDOVECTOR_SIZE_MASK)
2801 + ((size & PSEUDOVECTOR_REST_MASK)
2802 >> PSEUDOVECTOR_SIZE_BITS)) * word_size);
2803 }
2804 else
2805 size = header_size + size * word_size;
2806 return vroundup (size);
2807}
2771 2808
2772/* Reclaim space used by unmarked vectors. */ 2809/* Reclaim space used by unmarked vectors. */
2773 2810
@@ -2775,7 +2812,8 @@ static void
2775sweep_vectors (void) 2812sweep_vectors (void)
2776{ 2813{
2777 struct vector_block *block = vector_blocks, **bprev = &vector_blocks; 2814 struct vector_block *block = vector_blocks, **bprev = &vector_blocks;
2778 struct Lisp_Vector *vector, *next, **vprev = &large_vectors; 2815 struct large_vector *lv, **lvprev = &large_vectors;
2816 struct Lisp_Vector *vector, *next;
2779 2817
2780 total_vectors = total_vector_slots = total_free_vector_slots = 0; 2818 total_vectors = total_vector_slots = total_free_vector_slots = 0;
2781 memset (vector_free_lists, 0, sizeof (vector_free_lists)); 2819 memset (vector_free_lists, 0, sizeof (vector_free_lists));
@@ -2785,6 +2823,7 @@ sweep_vectors (void)
2785 for (block = vector_blocks; block; block = *bprev) 2823 for (block = vector_blocks; block; block = *bprev)
2786 { 2824 {
2787 bool free_this_block = 0; 2825 bool free_this_block = 0;
2826 ptrdiff_t nbytes;
2788 2827
2789 for (vector = (struct Lisp_Vector *) block->data; 2828 for (vector = (struct Lisp_Vector *) block->data;
2790 VECTOR_IN_BLOCK (vector, block); vector = next) 2829 VECTOR_IN_BLOCK (vector, block); vector = next)
@@ -2793,14 +2832,16 @@ sweep_vectors (void)
2793 { 2832 {
2794 VECTOR_UNMARK (vector); 2833 VECTOR_UNMARK (vector);
2795 total_vectors++; 2834 total_vectors++;
2796 total_vector_slots += vector->header.next.nbytes / word_size; 2835 nbytes = vector_nbytes (vector);
2797 next = ADVANCE (vector, vector->header.next.nbytes); 2836 total_vector_slots += nbytes / word_size;
2837 next = ADVANCE (vector, nbytes);
2798 } 2838 }
2799 else 2839 else
2800 { 2840 {
2801 ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); 2841 ptrdiff_t total_bytes;
2802 ptrdiff_t total_bytes = nbytes;
2803 2842
2843 nbytes = vector_nbytes (vector);
2844 total_bytes = nbytes;
2804 next = ADVANCE (vector, nbytes); 2845 next = ADVANCE (vector, nbytes);
2805 2846
2806 /* While NEXT is not marked, try to coalesce with VECTOR, 2847 /* While NEXT is not marked, try to coalesce with VECTOR,
@@ -2810,7 +2851,7 @@ sweep_vectors (void)
2810 { 2851 {
2811 if (VECTOR_MARKED_P (next)) 2852 if (VECTOR_MARKED_P (next))
2812 break; 2853 break;
2813 nbytes = PSEUDOVECTOR_NBYTES (next); 2854 nbytes = vector_nbytes (next);
2814 total_bytes += nbytes; 2855 total_bytes += nbytes;
2815 next = ADVANCE (next, nbytes); 2856 next = ADVANCE (next, nbytes);
2816 } 2857 }
@@ -2844,8 +2885,9 @@ sweep_vectors (void)
2844 2885
2845 /* Sweep large vectors. */ 2886 /* Sweep large vectors. */
2846 2887
2847 for (vector = large_vectors; vector; vector = *vprev) 2888 for (lv = large_vectors; lv; lv = *lvprev)
2848 { 2889 {
2890 vector = &lv->v;
2849 if (VECTOR_MARKED_P (vector)) 2891 if (VECTOR_MARKED_P (vector))
2850 { 2892 {
2851 VECTOR_UNMARK (vector); 2893 VECTOR_UNMARK (vector);
@@ -2867,12 +2909,12 @@ sweep_vectors (void)
2867 else 2909 else
2868 total_vector_slots 2910 total_vector_slots
2869 += header_size / word_size + vector->header.size; 2911 += header_size / word_size + vector->header.size;
2870 vprev = &vector->header.next.vector; 2912 lvprev = &lv->next.vector;
2871 } 2913 }
2872 else 2914 else
2873 { 2915 {
2874 *vprev = vector->header.next.vector; 2916 *lvprev = lv->next.vector;
2875 lisp_free (vector); 2917 lisp_free (lv);
2876 } 2918 }
2877 } 2919 }
2878} 2920}
@@ -2904,9 +2946,12 @@ allocate_vectorlike (ptrdiff_t len)
2904 p = allocate_vector_from_block (vroundup (nbytes)); 2946 p = allocate_vector_from_block (vroundup (nbytes));
2905 else 2947 else
2906 { 2948 {
2907 p = lisp_malloc (nbytes, MEM_TYPE_VECTORLIKE); 2949 struct large_vector *lv
2908 p->header.next.vector = large_vectors; 2950 = lisp_malloc (sizeof (*lv) + (len - 1) * word_size,
2909 large_vectors = p; 2951 MEM_TYPE_VECTORLIKE);
2952 lv->next.vector = large_vectors;
2953 large_vectors = lv;
2954 p = &lv->v;
2910 } 2955 }
2911 2956
2912#ifdef DOUG_LEA_MALLOC 2957#ifdef DOUG_LEA_MALLOC
@@ -2943,16 +2988,21 @@ allocate_vector (EMACS_INT len)
2943/* Allocate other vector-like structures. */ 2988/* Allocate other vector-like structures. */
2944 2989
2945struct Lisp_Vector * 2990struct Lisp_Vector *
2946allocate_pseudovector (int memlen, int lisplen, int tag) 2991allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
2947{ 2992{
2948 struct Lisp_Vector *v = allocate_vectorlike (memlen); 2993 struct Lisp_Vector *v = allocate_vectorlike (memlen);
2949 int i; 2994 int i;
2950 2995
2996 /* Catch bogus values. */
2997 eassert (tag <= PVEC_FONT);
2998 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
2999 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3000
2951 /* Only the first lisplen slots will be traced normally by the GC. */ 3001 /* Only the first lisplen slots will be traced normally by the GC. */
2952 for (i = 0; i < lisplen; ++i) 3002 for (i = 0; i < lisplen; ++i)
2953 v->contents[i] = Qnil; 3003 v->contents[i] = Qnil;
2954 3004
2955 XSETPVECTYPESIZE (v, tag, lisplen); 3005 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
2956 return v; 3006 return v;
2957} 3007}
2958 3008
@@ -2961,10 +3011,9 @@ allocate_buffer (void)
2961{ 3011{
2962 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER); 3012 struct buffer *b = lisp_malloc (sizeof *b, MEM_TYPE_BUFFER);
2963 3013
2964 XSETPVECTYPESIZE (b, PVEC_BUFFER, (offsetof (struct buffer, own_text) 3014 BUFFER_PVEC_INIT (b);
2965 - header_size) / word_size);
2966 /* Put B on the chain of all buffers including killed ones. */ 3015 /* Put B on the chain of all buffers including killed ones. */
2967 b->header.next.buffer = all_buffers; 3016 b->next = all_buffers;
2968 all_buffers = b; 3017 all_buffers = b;
2969 /* Note that the rest fields of B are not initialized. */ 3018 /* Note that the rest fields of B are not initialized. */
2970 return b; 3019 return b;
@@ -4068,16 +4117,15 @@ live_vector_p (struct mem_node *m, void *p)
4068 while (VECTOR_IN_BLOCK (vector, block) 4117 while (VECTOR_IN_BLOCK (vector, block)
4069 && vector <= (struct Lisp_Vector *) p) 4118 && vector <= (struct Lisp_Vector *) p)
4070 { 4119 {
4071 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) 4120 if (!PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) && vector == p)
4072 vector = ADVANCE (vector, (vector->header.size
4073 & PSEUDOVECTOR_SIZE_MASK));
4074 else if (vector == p)
4075 return 1; 4121 return 1;
4076 else 4122 else
4077 vector = ADVANCE (vector, vector->header.next.nbytes); 4123 vector = ADVANCE (vector, vector_nbytes (vector));
4078 } 4124 }
4079 } 4125 }
4080 else if (m->type == MEM_TYPE_VECTORLIKE && p == m->start) 4126 else if (m->type == MEM_TYPE_VECTORLIKE
4127 && (char *) p == ((char *) m->start
4128 + offsetof (struct large_vector, v)))
4081 /* This memory node corresponds to a large vector. */ 4129 /* This memory node corresponds to a large vector. */
4082 return 1; 4130 return 1;
4083 return 0; 4131 return 0;
@@ -5687,7 +5735,7 @@ mark_object (Lisp_Object arg)
5687 5735
5688 if (ptr->header.size & PSEUDOVECTOR_FLAG) 5736 if (ptr->header.size & PSEUDOVECTOR_FLAG)
5689 pvectype = ((ptr->header.size & PVEC_TYPE_MASK) 5737 pvectype = ((ptr->header.size & PVEC_TYPE_MASK)
5690 >> PSEUDOVECTOR_SIZE_BITS); 5738 >> PSEUDOVECTOR_AREA_BITS);
5691 else 5739 else
5692 pvectype = PVEC_NORMAL_VECTOR; 5740 pvectype = PVEC_NORMAL_VECTOR;
5693 5741
@@ -5766,6 +5814,9 @@ mark_object (Lisp_Object arg)
5766 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; 5814 struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr;
5767 5815
5768 mark_vectorlike (ptr); 5816 mark_vectorlike (ptr);
5817 mark_object (h->test.name);
5818 mark_object (h->test.user_hash_function);
5819 mark_object (h->test.user_cmp_function);
5769 /* If hash table is not weak, mark all keys and values. 5820 /* If hash table is not weak, mark all keys and values.
5770 For weak tables, mark only the vector. */ 5821 For weak tables, mark only the vector. */
5771 if (NILP (h->weak)) 5822 if (NILP (h->weak))
@@ -6317,7 +6368,7 @@ gc_sweep (void)
6317 for (buffer = all_buffers; buffer; buffer = *bprev) 6368 for (buffer = all_buffers; buffer; buffer = *bprev)
6318 if (!VECTOR_MARKED_P (buffer)) 6369 if (!VECTOR_MARKED_P (buffer))
6319 { 6370 {
6320 *bprev = buffer->header.next.buffer; 6371 *bprev = buffer->next;
6321 lisp_free (buffer); 6372 lisp_free (buffer);
6322 } 6373 }
6323 else 6374 else
@@ -6326,7 +6377,7 @@ gc_sweep (void)
6326 /* Do not use buffer_(set|get)_intervals here. */ 6377 /* Do not use buffer_(set|get)_intervals here. */
6327 buffer->text->intervals = balance_intervals (buffer->text->intervals); 6378 buffer->text->intervals = balance_intervals (buffer->text->intervals);
6328 total_buffers++; 6379 total_buffers++;
6329 bprev = &buffer->header.next.buffer; 6380 bprev = &buffer->next;
6330 } 6381 }
6331 } 6382 }
6332 6383
diff --git a/src/buffer.c b/src/buffer.c
index bb69675346a..619a729a859 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3132,8 +3132,8 @@ compare_overlays (const void *v1, const void *v2)
3132 between "equal" overlays. The result can still change between 3132 between "equal" overlays. The result can still change between
3133 invocations of Emacs, but it won't change in the middle of 3133 invocations of Emacs, but it won't change in the middle of
3134 `find_field' (bug#6830). */ 3134 `find_field' (bug#6830). */
3135 if (XHASH (s1->overlay) != XHASH (s2->overlay)) 3135 if (!EQ (s1->overlay, s2->overlay))
3136 return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1; 3136 return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
3137 return 0; 3137 return 0;
3138} 3138}
3139 3139
@@ -5105,11 +5105,6 @@ void
5105init_buffer_once (void) 5105init_buffer_once (void)
5106{ 5106{
5107 int idx; 5107 int idx;
5108 /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
5109 sure that this is still correct. Otherwise, mark_vectorlike may not
5110 trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */
5111 const int pvecsize
5112 = (offsetof (struct buffer, own_text) - header_size) / word_size;
5113 5108
5114 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags); 5109 memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
5115 5110
@@ -5132,8 +5127,8 @@ init_buffer_once (void)
5132 /* This is not strictly necessary, but let's make them initialized. */ 5127 /* This is not strictly necessary, but let's make them initialized. */
5133 bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*")); 5128 bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
5134 bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*")); 5129 bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
5135 XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize); 5130 BUFFER_PVEC_INIT (&buffer_defaults);
5136 XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize); 5131 BUFFER_PVEC_INIT (&buffer_local_symbols);
5137 5132
5138 /* Set up the default values of various buffer slots. */ 5133 /* Set up the default values of various buffer slots. */
5139 /* Must do these before making the first buffer! */ 5134 /* Must do these before making the first buffer! */
diff --git a/src/buffer.h b/src/buffer.h
index 9e0e9eef0b1..fbbbf1b8434 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -482,11 +482,6 @@ struct buffer_text
482 482
483struct buffer 483struct buffer
484{ 484{
485 /* HEADER.NEXT is the next buffer, in chain of all buffers, including killed
486 buffers. This chain, starting from all_buffers, is used only for garbage
487 collection, in order to collect killed buffers properly. Note that large
488 vectors and large pseudo-vector objects are all on another chain starting
489 from large_vectors. */
490 struct vectorlike_header header; 485 struct vectorlike_header header;
491 486
492 /* The name of this buffer. */ 487 /* The name of this buffer. */
@@ -750,6 +745,9 @@ struct buffer
750 In an indirect buffer, this is the own_text field of another buffer. */ 745 In an indirect buffer, this is the own_text field of another buffer. */
751 struct buffer_text *text; 746 struct buffer_text *text;
752 747
748 /* Next buffer, in chain of all buffers, including killed ones. */
749 struct buffer *next;
750
753 /* Char position of point in buffer. */ 751 /* Char position of point in buffer. */
754 ptrdiff_t pt; 752 ptrdiff_t pt;
755 753
@@ -959,6 +957,27 @@ bset_width_table (struct buffer *b, Lisp_Object val)
959 b->INTERNAL_FIELD (width_table) = val; 957 b->INTERNAL_FIELD (width_table) = val;
960} 958}
961 959
960/* Number of Lisp_Objects at the beginning of struct buffer.
961 If you add, remove, or reorder Lisp_Objects within buffer
962 structure, make sure that this is still correct. */
963
964#define BUFFER_LISP_SIZE \
965 ((offsetof (struct buffer, own_text) - header_size) / word_size)
966
967/* Size of the struct buffer part beyond leading Lisp_Objects, in word_size
968 units. Rounding is needed for --with-wide-int configuration. */
969
970#define BUFFER_REST_SIZE \
971 ((((sizeof (struct buffer) - offsetof (struct buffer, own_text)) \
972 + (word_size - 1)) & ~(word_size - 1)) / word_size)
973
974/* Initialize the pseudovector header of buffer object. BUFFER_LISP_SIZE
975 is required for GC, but BUFFER_REST_SIZE is set up just to be consistent
976 with other pseudovectors. */
977
978#define BUFFER_PVEC_INIT(b) \
979 XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE)
980
962/* Convenient check whether buffer B is live. */ 981/* Convenient check whether buffer B is live. */
963 982
964#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) 983#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name)))
@@ -986,7 +1005,7 @@ extern struct buffer *all_buffers;
986/* Used to iterate over the chain above. */ 1005/* Used to iterate over the chain above. */
987 1006
988#define FOR_EACH_BUFFER(b) \ 1007#define FOR_EACH_BUFFER(b) \
989 for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer) 1008 for ((b) = all_buffers; (b); (b) = (b)->next)
990 1009
991/* This points to the current buffer. */ 1010/* This points to the current buffer. */
992 1011
diff --git a/src/category.c b/src/category.c
index fe02303f679..31cc90bca68 100644
--- a/src/category.c
+++ b/src/category.c
@@ -78,10 +78,10 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
78 if (NILP (XCHAR_TABLE (table)->extras[1])) 78 if (NILP (XCHAR_TABLE (table)->extras[1]))
79 set_char_table_extras 79 set_char_table_extras
80 (table, 1, 80 (table, 1,
81 make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), 81 make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
82 make_float (DEFAULT_REHASH_SIZE), 82 make_float (DEFAULT_REHASH_SIZE),
83 make_float (DEFAULT_REHASH_THRESHOLD), 83 make_float (DEFAULT_REHASH_THRESHOLD),
84 Qnil, Qnil, Qnil)); 84 Qnil));
85 h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]); 85 h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
86 i = hash_lookup (h, category_set, &hash); 86 i = hash_lookup (h, category_set, &hash);
87 if (i >= 0) 87 if (i >= 0)
diff --git a/src/composite.c b/src/composite.c
index 6c603fab3fc..bcde0a4c9e6 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -676,7 +676,7 @@ composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len)
676 ptrdiff_t i; 676 ptrdiff_t i;
677 677
678 header = LGSTRING_HEADER (gstring); 678 header = LGSTRING_HEADER (gstring);
679 hash = h->hashfn (h, header); 679 hash = h->test.hashfn (&h->test, header);
680 if (len < 0) 680 if (len < 0)
681 { 681 {
682 ptrdiff_t j, glyph_len = LGSTRING_GLYPH_LEN (gstring); 682 ptrdiff_t j, glyph_len = LGSTRING_GLYPH_LEN (gstring);
@@ -1382,7 +1382,7 @@ composition_update_it (struct composition_it *cmp_it, ptrdiff_t charpos, ptrdiff
1382 } 1382 }
1383 else 1383 else
1384 { 1384 {
1385 /* automatic composition */ 1385 /* Automatic composition. */
1386 Lisp_Object gstring = composition_gstring_from_id (cmp_it->id); 1386 Lisp_Object gstring = composition_gstring_from_id (cmp_it->id);
1387 Lisp_Object glyph; 1387 Lisp_Object glyph;
1388 ptrdiff_t from; 1388 ptrdiff_t from;
diff --git a/src/data.c b/src/data.c
index abcdd4dca0d..09899400b68 100644
--- a/src/data.c
+++ b/src/data.c
@@ -81,6 +81,7 @@ Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
81static Lisp_Object Qdefun; 81static Lisp_Object Qdefun;
82 82
83Lisp_Object Qinteractive_form; 83Lisp_Object Qinteractive_form;
84static Lisp_Object Qdefalias_fset_function;
84 85
85static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); 86static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *);
86 87
@@ -444,7 +445,7 @@ DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
444} 445}
445 446
446 447
447/* Extract and set components of lists */ 448/* Extract and set components of lists. */
448 449
449DEFUN ("car", Fcar, Scar, 1, 1, 0, 450DEFUN ("car", Fcar, Scar, 1, 1, 0,
450 doc: /* Return the car of LIST. If arg is nil, return nil. 451 doc: /* Return the car of LIST. If arg is nil, return nil.
@@ -608,27 +609,18 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
608 (register Lisp_Object symbol, Lisp_Object definition) 609 (register Lisp_Object symbol, Lisp_Object definition)
609{ 610{
610 register Lisp_Object function; 611 register Lisp_Object function;
611
612 CHECK_SYMBOL (symbol); 612 CHECK_SYMBOL (symbol);
613 if (NILP (symbol) || EQ (symbol, Qt))
614 xsignal1 (Qsetting_constant, symbol);
615 613
616 function = XSYMBOL (symbol)->function; 614 function = XSYMBOL (symbol)->function;
617 615
618 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) 616 if (!NILP (Vautoload_queue) && !EQ (function, Qunbound))
619 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); 617 Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue);
620 618
621 if (CONSP (function) && EQ (XCAR (function), Qautoload)) 619 if (AUTOLOADP (function))
622 Fput (symbol, Qautoload, XCDR (function)); 620 Fput (symbol, Qautoload, XCDR (function));
623 621
624 set_symbol_function (symbol, definition); 622 set_symbol_function (symbol, definition);
625 /* Handle automatic advice activation. */ 623
626 if (CONSP (XSYMBOL (symbol)->plist)
627 && !NILP (Fget (symbol, Qad_advice_info)))
628 {
629 call2 (Qad_activate_internal, symbol, Qnil);
630 definition = XSYMBOL (symbol)->function;
631 }
632 return definition; 624 return definition;
633} 625}
634 626
@@ -642,15 +634,32 @@ The return value is undefined. */)
642 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) 634 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
643{ 635{
644 CHECK_SYMBOL (symbol); 636 CHECK_SYMBOL (symbol);
645 if (CONSP (XSYMBOL (symbol)->function)
646 && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload))
647 LOADHIST_ATTACH (Fcons (Qt, symbol));
648 if (!NILP (Vpurify_flag) 637 if (!NILP (Vpurify_flag)
649 /* If `definition' is a keymap, immutable (and copying) is wrong. */ 638 /* If `definition' is a keymap, immutable (and copying) is wrong. */
650 && !KEYMAPP (definition)) 639 && !KEYMAPP (definition))
651 definition = Fpurecopy (definition); 640 definition = Fpurecopy (definition);
652 definition = Ffset (symbol, definition); 641
653 LOADHIST_ATTACH (Fcons (Qdefun, symbol)); 642 {
643 bool autoload = AUTOLOADP (definition);
644 if (NILP (Vpurify_flag) || !autoload)
645 { /* Only add autoload entries after dumping, because the ones before are
646 not useful and else we get loads of them from the loaddefs.el. */
647
648 if (AUTOLOADP (XSYMBOL (symbol)->function))
649 /* Remember that the function was already an autoload. */
650 LOADHIST_ATTACH (Fcons (Qt, symbol));
651 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
652 }
653 }
654
655 { /* Handle automatic advice activation. */
656 Lisp_Object hook = Fget (symbol, Qdefalias_fset_function);
657 if (!NILP (hook))
658 call2 (hook, symbol, definition);
659 else
660 Ffset (symbol, definition);
661 }
662
654 if (!NILP (docstring)) 663 if (!NILP (docstring))
655 Fput (symbol, Qfunction_documentation, docstring); 664 Fput (symbol, Qfunction_documentation, docstring);
656 /* We used to return `definition', but now that `defun' and `defmacro' expand 665 /* We used to return `definition', but now that `defun' and `defmacro' expand
@@ -680,12 +689,10 @@ function with `&rest' args, or `unevalled' for a special form. */)
680 CHECK_SUBR (subr); 689 CHECK_SUBR (subr);
681 minargs = XSUBR (subr)->min_args; 690 minargs = XSUBR (subr)->min_args;
682 maxargs = XSUBR (subr)->max_args; 691 maxargs = XSUBR (subr)->max_args;
683 if (maxargs == MANY) 692 return Fcons (make_number (minargs),
684 return Fcons (make_number (minargs), Qmany); 693 maxargs == MANY ? Qmany
685 else if (maxargs == UNEVALLED) 694 : maxargs == UNEVALLED ? Qunevalled
686 return Fcons (make_number (minargs), Qunevalled); 695 : make_number (maxargs));
687 else
688 return Fcons (make_number (minargs), make_number (maxargs));
689} 696}
690 697
691DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, 698DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
@@ -711,7 +718,7 @@ Value, if non-nil, is a list \(interactive SPEC). */)
711 return Qnil; 718 return Qnil;
712 719
713 /* Use an `interactive-form' property if present, analogous to the 720 /* Use an `interactive-form' property if present, analogous to the
714 function-documentation property. */ 721 function-documentation property. */
715 fun = cmd; 722 fun = cmd;
716 while (SYMBOLP (fun)) 723 while (SYMBOLP (fun))
717 { 724 {
@@ -735,6 +742,8 @@ Value, if non-nil, is a list \(interactive SPEC). */)
735 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE) 742 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE)
736 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); 743 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE));
737 } 744 }
745 else if (AUTOLOADP (fun))
746 return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil));
738 else if (CONSP (fun)) 747 else if (CONSP (fun))
739 { 748 {
740 Lisp_Object funcar = XCAR (fun); 749 Lisp_Object funcar = XCAR (fun);
@@ -742,14 +751,6 @@ Value, if non-nil, is a list \(interactive SPEC). */)
742 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); 751 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun))));
743 else if (EQ (funcar, Qlambda)) 752 else if (EQ (funcar, Qlambda))
744 return Fassq (Qinteractive, Fcdr (XCDR (fun))); 753 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
745 else if (EQ (funcar, Qautoload))
746 {
747 struct gcpro gcpro1;
748 GCPRO1 (cmd);
749 Fautoload_do_load (fun, cmd, Qnil);
750 UNGCPRO;
751 return Finteractive_form (cmd);
752 }
753 } 754 }
754 return Qnil; 755 return Qnil;
755} 756}
@@ -2695,10 +2696,10 @@ usage: (* &rest NUMBERS-OR-MARKERS) */)
2695 return arith_driver (Amult, nargs, args); 2696 return arith_driver (Amult, nargs, args);
2696} 2697}
2697 2698
2698DEFUN ("/", Fquo, Squo, 2, MANY, 0, 2699DEFUN ("/", Fquo, Squo, 1, MANY, 0,
2699 doc: /* Return first argument divided by all the remaining arguments. 2700 doc: /* Return first argument divided by all the remaining arguments.
2700The arguments must be numbers or markers. 2701The arguments must be numbers or markers.
2701usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) 2702usage: (/ DIVIDEND &rest DIVISORS) */)
2702 (ptrdiff_t nargs, Lisp_Object *args) 2703 (ptrdiff_t nargs, Lisp_Object *args)
2703{ 2704{
2704 ptrdiff_t argnum; 2705 ptrdiff_t argnum;
@@ -3063,6 +3064,7 @@ syms_of_data (void)
3063 DEFSYM (Qfont_object, "font-object"); 3064 DEFSYM (Qfont_object, "font-object");
3064 3065
3065 DEFSYM (Qinteractive_form, "interactive-form"); 3066 DEFSYM (Qinteractive_form, "interactive-form");
3067 DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
3066 3068
3067 defsubr (&Sindirect_variable); 3069 defsubr (&Sindirect_variable);
3068 defsubr (&Sinteractive_form); 3070 defsubr (&Sinteractive_form);
diff --git a/src/doc.c b/src/doc.c
index 9ead1addfba..1d3d1e64442 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -21,7 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21#include <config.h> 21#include <config.h>
22 22
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/file.h> /* Must be after sys/types.h for USG*/ 24#include <sys/file.h> /* Must be after sys/types.h for USG. */
25#include <fcntl.h> 25#include <fcntl.h>
26#include <unistd.h> 26#include <unistd.h>
27 27
@@ -42,7 +42,7 @@ static ptrdiff_t get_doc_string_buffer_size;
42 42
43static unsigned char *read_bytecode_pointer; 43static unsigned char *read_bytecode_pointer;
44 44
45/* readchar in lread.c calls back here to fetch the next byte. 45/* `readchar' in lread.c calls back here to fetch the next byte.
46 If UNREADFLAG is 1, we unread a byte. */ 46 If UNREADFLAG is 1, we unread a byte. */
47 47
48int 48int
@@ -338,15 +338,9 @@ string is passed through `substitute-command-keys'. */)
338 338
339 doc = Qnil; 339 doc = Qnil;
340 340
341 if (SYMBOLP (function))
342 {
343 Lisp_Object tem = Fget (function, Qfunction_documentation);
344 if (!NILP (tem))
345 return Fdocumentation_property (function, Qfunction_documentation,
346 raw);
347 }
348
349 fun = Findirect_function (function, Qnil); 341 fun = Findirect_function (function, Qnil);
342 if (CONSP (fun) && EQ (XCAR (fun), Qmacro))
343 fun = XCDR (fun);
350 if (SUBRP (fun)) 344 if (SUBRP (fun))
351 { 345 {
352 if (XSUBR (fun)->doc == 0) 346 if (XSUBR (fun)->doc == 0)
@@ -400,8 +394,6 @@ string is passed through `substitute-command-keys'. */)
400 else 394 else
401 return Qnil; 395 return Qnil;
402 } 396 }
403 else if (EQ (funcar, Qmacro))
404 return Fdocumentation (Fcdr (fun), raw);
405 else 397 else
406 goto oops; 398 goto oops;
407 } 399 }
@@ -411,16 +403,19 @@ string is passed through `substitute-command-keys'. */)
411 xsignal1 (Qinvalid_function, fun); 403 xsignal1 (Qinvalid_function, fun);
412 } 404 }
413 405
414 /* Check for an advised function. Its doc string 406 /* Check for a dynamic docstring. These come with
415 has an `ad-advice-info' text property. */ 407 a dynamic-docstring-function text property. */
416 if (STRINGP (doc)) 408 if (STRINGP (doc))
417 { 409 {
418 Lisp_Object innerfunc; 410 Lisp_Object func
419 innerfunc = Fget_text_property (make_number (0), 411 = Fget_text_property (make_number (0),
420 intern ("ad-advice-info"), 412 intern ("dynamic-docstring-function"),
421 doc); 413 doc);
422 if (! NILP (innerfunc)) 414 if (!NILP (func))
423 doc = call1 (intern ("ad-make-advised-docstring"), innerfunc); 415 /* Pass both `doc' and `function' since `function' can be needed, and
416 finding `doc' can be annoying: calling `documentation' is not an
417 option because it would infloop. */
418 doc = call2 (func, doc, function);
424 } 419 }
425 420
426 /* If DOC is 0, it's typically because of a dumped file missing 421 /* If DOC is 0, it's typically because of a dumped file missing
@@ -528,6 +523,8 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset)
528 { 523 {
529 tem = Fcdr (Fcdr (fun)); 524 tem = Fcdr (Fcdr (fun));
530 if (CONSP (tem) && INTEGERP (XCAR (tem))) 525 if (CONSP (tem) && INTEGERP (XCAR (tem)))
526 /* FIXME: This modifies typically pure hash-cons'd data, so its
527 correctness is quite delicate. */
531 XSETCAR (tem, make_number (offset)); 528 XSETCAR (tem, make_number (offset));
532 } 529 }
533 else if (EQ (tem, Qmacro)) 530 else if (EQ (tem, Qmacro))
diff --git a/src/emacs.c b/src/emacs.c
index 894e4d3cb30..aece6069230 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1157,6 +1157,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1157 1157
1158 /* Called before syms_of_fileio, because it sets up Qerror_condition. */ 1158 /* Called before syms_of_fileio, because it sets up Qerror_condition. */
1159 syms_of_data (); 1159 syms_of_data ();
1160 syms_of_fns (); /* Before syms_of_charset which uses hashtables. */
1160 syms_of_fileio (); 1161 syms_of_fileio ();
1161 /* Before syms_of_coding to initialize Vgc_cons_threshold. */ 1162 /* Before syms_of_coding to initialize Vgc_cons_threshold. */
1162 syms_of_alloc (); 1163 syms_of_alloc ();
@@ -1168,7 +1169,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1168 1169
1169 init_window_once (); /* Init the window system. */ 1170 init_window_once (); /* Init the window system. */
1170#ifdef HAVE_WINDOW_SYSTEM 1171#ifdef HAVE_WINDOW_SYSTEM
1171 init_fringe_once (); /* Swap bitmaps if necessary. */ 1172 init_fringe_once (); /* Swap bitmaps if necessary. */
1172#endif /* HAVE_WINDOW_SYSTEM */ 1173#endif /* HAVE_WINDOW_SYSTEM */
1173 } 1174 }
1174 1175
@@ -1351,7 +1352,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1351 syms_of_lread (); 1352 syms_of_lread ();
1352 syms_of_print (); 1353 syms_of_print ();
1353 syms_of_eval (); 1354 syms_of_eval ();
1354 syms_of_fns ();
1355 syms_of_floatfns (); 1355 syms_of_floatfns ();
1356 1356
1357 syms_of_buffer (); 1357 syms_of_buffer ();
diff --git a/src/eval.c b/src/eval.c
index 975204da017..dcd48cb7250 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1876,26 +1876,19 @@ this does nothing and returns nil. */)
1876 CHECK_STRING (file); 1876 CHECK_STRING (file);
1877 1877
1878 /* If function is defined and not as an autoload, don't override. */ 1878 /* If function is defined and not as an autoload, don't override. */
1879 if ((CONSP (XSYMBOL (function)->function) 1879 if (!EQ (XSYMBOL (function)->function, Qunbound)
1880 && EQ (XCAR (XSYMBOL (function)->function), Qautoload))) 1880 && !AUTOLOADP (XSYMBOL (function)->function))
1881 /* Remember that the function was already an autoload. */
1882 LOADHIST_ATTACH (Fcons (Qt, function));
1883 else if (!EQ (XSYMBOL (function)->function, Qunbound))
1884 return Qnil; 1881 return Qnil;
1885 1882
1886 if (NILP (Vpurify_flag)) 1883 if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0)))
1887 /* Only add entries after dumping, because the ones before are
1888 not useful and else we get loads of them from the loaddefs.el. */
1889 LOADHIST_ATTACH (Fcons (Qautoload, function));
1890 else if (EQ (docstring, make_number (0)))
1891 /* `read1' in lread.c has found the docstring starting with "\ 1884 /* `read1' in lread.c has found the docstring starting with "\
1892 and assumed the docstring will be provided by Snarf-documentation, so it 1885 and assumed the docstring will be provided by Snarf-documentation, so it
1893 passed us 0 instead. But that leads to accidental sharing in purecopy's 1886 passed us 0 instead. But that leads to accidental sharing in purecopy's
1894 hash-consing, so we use a (hopefully) unique integer instead. */ 1887 hash-consing, so we use a (hopefully) unique integer instead. */
1895 docstring = make_number (XUNTAG (function, Lisp_Symbol)); 1888 docstring = make_number (XHASH (function));
1896 return Ffset (function, 1889 return Fdefalias (function,
1897 Fpurecopy (list5 (Qautoload, file, docstring, 1890 list5 (Qautoload, file, docstring, interactive, type),
1898 interactive, type))); 1891 Qnil);
1899} 1892}
1900 1893
1901Lisp_Object 1894Lisp_Object
diff --git a/src/fileio.c b/src/fileio.c
index d47d7dd9e0b..b9541e78838 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5076,7 +5076,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5076 struct stat st; 5076 struct stat st;
5077 Lisp_Object handler; 5077 Lisp_Object handler;
5078 Lisp_Object filename; 5078 Lisp_Object filename;
5079 EMACS_TIME mtime, diff; 5079 EMACS_TIME mtime;
5080 5080
5081 if (NILP (buf)) 5081 if (NILP (buf))
5082 b = current_buffer; 5082 b = current_buffer;
@@ -5101,13 +5101,7 @@ See Info node `(elisp)Modification Time' for more details. */)
5101 mtime = (stat (SSDATA (filename), &st) == 0 5101 mtime = (stat (SSDATA (filename), &st) == 0
5102 ? get_stat_mtime (&st) 5102 ? get_stat_mtime (&st)
5103 : time_error_value (errno)); 5103 : time_error_value (errno));
5104 if ((EMACS_TIME_EQ (mtime, b->modtime) 5104 if (EMACS_TIME_EQ (mtime, b->modtime)
5105 /* If both exist, accept them if they are off by one second. */
5106 || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
5107 && ((diff = (EMACS_TIME_LT (mtime, b->modtime)
5108 ? sub_emacs_time (b->modtime, mtime)
5109 : sub_emacs_time (mtime, b->modtime))),
5110 EMACS_TIME_LE (diff, make_emacs_time (1, 0)))))
5111 && (st.st_size == b->modtime_size 5105 && (st.st_size == b->modtime_size
5112 || b->modtime_size < 0)) 5106 || b->modtime_size < 0))
5113 return Qt; 5107 return Qt;
diff --git a/src/fns.c b/src/fns.c
index b1ba5ce9509..7c2222e9805 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2014,7 +2014,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2014 d1 = extract_float (o1); 2014 d1 = extract_float (o1);
2015 d2 = extract_float (o2); 2015 d2 = extract_float (o2);
2016 /* If d is a NaN, then d != d. Two NaNs should be `equal' even 2016 /* If d is a NaN, then d != d. Two NaNs should be `equal' even
2017 though they are not =. */ 2017 though they are not =. */
2018 return d1 == d2 || (d1 != d1 && d2 != d2); 2018 return d1 == d2 || (d1 != d1 && d2 != d2);
2019 } 2019 }
2020 2020
@@ -2076,9 +2076,8 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
2076 are sensible to compare, so eliminate the others now. */ 2076 are sensible to compare, so eliminate the others now. */
2077 if (size & PSEUDOVECTOR_FLAG) 2077 if (size & PSEUDOVECTOR_FLAG)
2078 { 2078 {
2079 if (!(size & ((PVEC_COMPILED | PVEC_CHAR_TABLE 2079 if (((size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS)
2080 | PVEC_SUB_CHAR_TABLE | PVEC_FONT) 2080 < PVEC_COMPILED)
2081 << PSEUDOVECTOR_SIZE_BITS)))
2082 return 0; 2081 return 0;
2083 size &= PSEUDOVECTOR_SIZE_MASK; 2082 size &= PSEUDOVECTOR_SIZE_MASK;
2084 } 2083 }
@@ -3332,8 +3331,8 @@ static struct Lisp_Hash_Table *weak_hash_tables;
3332 3331
3333/* Various symbols. */ 3332/* Various symbols. */
3334 3333
3335static Lisp_Object Qhash_table_p, Qkey, Qvalue; 3334static Lisp_Object Qhash_table_p, Qkey, Qvalue, Qeql;
3336Lisp_Object Qeq, Qeql, Qequal; 3335Lisp_Object Qeq, Qequal;
3337Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness; 3336Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
3338static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value; 3337static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
3339 3338
@@ -3425,14 +3424,17 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3425 Low-level Functions 3424 Low-level Functions
3426 ***********************************************************************/ 3425 ***********************************************************************/
3427 3426
3427static struct hash_table_test hashtest_eq;
3428struct hash_table_test hashtest_eql, hashtest_equal;
3429
3428/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code 3430/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3429 HASH2 in hash table H using `eql'. Value is true if KEY1 and 3431 HASH2 in hash table H using `eql'. Value is true if KEY1 and
3430 KEY2 are the same. */ 3432 KEY2 are the same. */
3431 3433
3432static bool 3434static bool
3433cmpfn_eql (struct Lisp_Hash_Table *h, 3435cmpfn_eql (struct hash_table_test *ht,
3434 Lisp_Object key1, EMACS_UINT hash1, 3436 Lisp_Object key1,
3435 Lisp_Object key2, EMACS_UINT hash2) 3437 Lisp_Object key2)
3436{ 3438{
3437 return (FLOATP (key1) 3439 return (FLOATP (key1)
3438 && FLOATP (key2) 3440 && FLOATP (key2)
@@ -3445,11 +3447,11 @@ cmpfn_eql (struct Lisp_Hash_Table *h,
3445 KEY2 are the same. */ 3447 KEY2 are the same. */
3446 3448
3447static bool 3449static bool
3448cmpfn_equal (struct Lisp_Hash_Table *h, 3450cmpfn_equal (struct hash_table_test *ht,
3449 Lisp_Object key1, EMACS_UINT hash1, 3451 Lisp_Object key1,
3450 Lisp_Object key2, EMACS_UINT hash2) 3452 Lisp_Object key2)
3451{ 3453{
3452 return hash1 == hash2 && !NILP (Fequal (key1, key2)); 3454 return !NILP (Fequal (key1, key2));
3453} 3455}
3454 3456
3455 3457
@@ -3458,21 +3460,16 @@ cmpfn_equal (struct Lisp_Hash_Table *h,
3458 if KEY1 and KEY2 are the same. */ 3460 if KEY1 and KEY2 are the same. */
3459 3461
3460static bool 3462static bool
3461cmpfn_user_defined (struct Lisp_Hash_Table *h, 3463cmpfn_user_defined (struct hash_table_test *ht,
3462 Lisp_Object key1, EMACS_UINT hash1, 3464 Lisp_Object key1,
3463 Lisp_Object key2, EMACS_UINT hash2) 3465 Lisp_Object key2)
3464{ 3466{
3465 if (hash1 == hash2) 3467 Lisp_Object args[3];
3466 {
3467 Lisp_Object args[3];
3468 3468
3469 args[0] = h->user_cmp_function; 3469 args[0] = ht->user_cmp_function;
3470 args[1] = key1; 3470 args[1] = key1;
3471 args[2] = key2; 3471 args[2] = key2;
3472 return !NILP (Ffuncall (3, args)); 3472 return !NILP (Ffuncall (3, args));
3473 }
3474 else
3475 return 0;
3476} 3473}
3477 3474
3478 3475
@@ -3481,54 +3478,48 @@ cmpfn_user_defined (struct Lisp_Hash_Table *h,
3481 in a Lisp integer. */ 3478 in a Lisp integer. */
3482 3479
3483static EMACS_UINT 3480static EMACS_UINT
3484hashfn_eq (struct Lisp_Hash_Table *h, Lisp_Object key) 3481hashfn_eq (struct hash_table_test *ht, Lisp_Object key)
3485{ 3482{
3486 EMACS_UINT hash = XUINT (key) ^ XTYPE (key); 3483 EMACS_UINT hash = XHASH (key) ^ XTYPE (key);
3487 eassert ((hash & ~INTMASK) == 0);
3488 return hash; 3484 return hash;
3489} 3485}
3490 3486
3491
3492/* Value is a hash code for KEY for use in hash table H which uses 3487/* Value is a hash code for KEY for use in hash table H which uses
3493 `eql' to compare keys. The hash code returned is guaranteed to fit 3488 `eql' to compare keys. The hash code returned is guaranteed to fit
3494 in a Lisp integer. */ 3489 in a Lisp integer. */
3495 3490
3496static EMACS_UINT 3491static EMACS_UINT
3497hashfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key) 3492hashfn_eql (struct hash_table_test *ht, Lisp_Object key)
3498{ 3493{
3499 EMACS_UINT hash; 3494 EMACS_UINT hash;
3500 if (FLOATP (key)) 3495 if (FLOATP (key))
3501 hash = sxhash (key, 0); 3496 hash = sxhash (key, 0);
3502 else 3497 else
3503 hash = XUINT (key) ^ XTYPE (key); 3498 hash = XHASH (key) ^ XTYPE (key);
3504 eassert ((hash & ~INTMASK) == 0);
3505 return hash; 3499 return hash;
3506} 3500}
3507 3501
3508
3509/* Value is a hash code for KEY for use in hash table H which uses 3502/* Value is a hash code for KEY for use in hash table H which uses
3510 `equal' to compare keys. The hash code returned is guaranteed to fit 3503 `equal' to compare keys. The hash code returned is guaranteed to fit
3511 in a Lisp integer. */ 3504 in a Lisp integer. */
3512 3505
3513static EMACS_UINT 3506static EMACS_UINT
3514hashfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key) 3507hashfn_equal (struct hash_table_test *ht, Lisp_Object key)
3515{ 3508{
3516 EMACS_UINT hash = sxhash (key, 0); 3509 EMACS_UINT hash = sxhash (key, 0);
3517 eassert ((hash & ~INTMASK) == 0);
3518 return hash; 3510 return hash;
3519} 3511}
3520 3512
3521
3522/* Value is a hash code for KEY for use in hash table H which uses as 3513/* Value is a hash code for KEY for use in hash table H which uses as
3523 user-defined function to compare keys. The hash code returned is 3514 user-defined function to compare keys. The hash code returned is
3524 guaranteed to fit in a Lisp integer. */ 3515 guaranteed to fit in a Lisp integer. */
3525 3516
3526static EMACS_UINT 3517static EMACS_UINT
3527hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key) 3518hashfn_user_defined (struct hash_table_test *ht, Lisp_Object key)
3528{ 3519{
3529 Lisp_Object args[2], hash; 3520 Lisp_Object args[2], hash;
3530 3521
3531 args[0] = h->user_hash_function; 3522 args[0] = ht->user_hash_function;
3532 args[1] = key; 3523 args[1] = key;
3533 hash = Ffuncall (2, args); 3524 hash = Ffuncall (2, args);
3534 if (!INTEGERP (hash)) 3525 if (!INTEGERP (hash))
@@ -3564,9 +3555,9 @@ hashfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key)
3564 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */ 3555 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */
3565 3556
3566Lisp_Object 3557Lisp_Object
3567make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size, 3558make_hash_table (struct hash_table_test test,
3568 Lisp_Object rehash_threshold, Lisp_Object weak, 3559 Lisp_Object size, Lisp_Object rehash_size,
3569 Lisp_Object user_test, Lisp_Object user_hash) 3560 Lisp_Object rehash_threshold, Lisp_Object weak)
3570{ 3561{
3571 struct Lisp_Hash_Table *h; 3562 struct Lisp_Hash_Table *h;
3572 Lisp_Object table; 3563 Lisp_Object table;
@@ -3575,7 +3566,7 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3575 double index_float; 3566 double index_float;
3576 3567
3577 /* Preconditions. */ 3568 /* Preconditions. */
3578 eassert (SYMBOLP (test)); 3569 eassert (SYMBOLP (test.name));
3579 eassert (INTEGERP (size) && XINT (size) >= 0); 3570 eassert (INTEGERP (size) && XINT (size) >= 0);
3580 eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0) 3571 eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
3581 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))); 3572 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
@@ -3599,29 +3590,6 @@ make_hash_table (Lisp_Object test, Lisp_Object size, Lisp_Object rehash_size,
3599 3590
3600 /* Initialize hash table slots. */ 3591 /* Initialize hash table slots. */
3601 h->test = test; 3592 h->test = test;
3602 if (EQ (test, Qeql))
3603 {
3604 h->cmpfn = cmpfn_eql;
3605 h->hashfn = hashfn_eql;
3606 }
3607 else if (EQ (test, Qeq))
3608 {
3609 h->cmpfn = NULL;
3610 h->hashfn = hashfn_eq;
3611 }
3612 else if (EQ (test, Qequal))
3613 {
3614 h->cmpfn = cmpfn_equal;
3615 h->hashfn = hashfn_equal;
3616 }
3617 else
3618 {
3619 h->user_cmp_function = user_test;
3620 h->user_hash_function = user_hash;
3621 h->cmpfn = cmpfn_user_defined;
3622 h->hashfn = hashfn_user_defined;
3623 }
3624
3625 h->weak = weak; 3593 h->weak = weak;
3626 h->rehash_threshold = rehash_threshold; 3594 h->rehash_threshold = rehash_threshold;
3627 h->rehash_size = rehash_size; 3595 h->rehash_size = rehash_size;
@@ -3661,12 +3629,9 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
3661{ 3629{
3662 Lisp_Object table; 3630 Lisp_Object table;
3663 struct Lisp_Hash_Table *h2; 3631 struct Lisp_Hash_Table *h2;
3664 struct Lisp_Vector *next;
3665 3632
3666 h2 = allocate_hash_table (); 3633 h2 = allocate_hash_table ();
3667 next = h2->header.next.vector;
3668 *h2 = *h1; 3634 *h2 = *h1;
3669 h2->header.next.vector = next;
3670 h2->key_and_value = Fcopy_sequence (h1->key_and_value); 3635 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
3671 h2->hash = Fcopy_sequence (h1->hash); 3636 h2->hash = Fcopy_sequence (h1->hash);
3672 h2->next = Fcopy_sequence (h1->next); 3637 h2->next = Fcopy_sequence (h1->next);
@@ -3780,7 +3745,8 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
3780 ptrdiff_t start_of_bucket; 3745 ptrdiff_t start_of_bucket;
3781 Lisp_Object idx; 3746 Lisp_Object idx;
3782 3747
3783 hash_code = h->hashfn (h, key); 3748 hash_code = h->test.hashfn (&h->test, key);
3749 eassert ((hash_code & ~INTMASK) == 0);
3784 if (hash) 3750 if (hash)
3785 *hash = hash_code; 3751 *hash = hash_code;
3786 3752
@@ -3792,9 +3758,9 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
3792 { 3758 {
3793 ptrdiff_t i = XFASTINT (idx); 3759 ptrdiff_t i = XFASTINT (idx);
3794 if (EQ (key, HASH_KEY (h, i)) 3760 if (EQ (key, HASH_KEY (h, i))
3795 || (h->cmpfn 3761 || (h->test.cmpfn
3796 && h->cmpfn (h, key, hash_code, 3762 && hash_code == XUINT (HASH_HASH (h, i))
3797 HASH_KEY (h, i), XUINT (HASH_HASH (h, i))))) 3763 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
3798 break; 3764 break;
3799 idx = HASH_NEXT (h, i); 3765 idx = HASH_NEXT (h, i);
3800 } 3766 }
@@ -3845,7 +3811,8 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3845 ptrdiff_t start_of_bucket; 3811 ptrdiff_t start_of_bucket;
3846 Lisp_Object idx, prev; 3812 Lisp_Object idx, prev;
3847 3813
3848 hash_code = h->hashfn (h, key); 3814 hash_code = h->test.hashfn (&h->test, key);
3815 eassert ((hash_code & ~INTMASK) == 0);
3849 start_of_bucket = hash_code % ASIZE (h->index); 3816 start_of_bucket = hash_code % ASIZE (h->index);
3850 idx = HASH_INDEX (h, start_of_bucket); 3817 idx = HASH_INDEX (h, start_of_bucket);
3851 prev = Qnil; 3818 prev = Qnil;
@@ -3856,9 +3823,9 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3856 ptrdiff_t i = XFASTINT (idx); 3823 ptrdiff_t i = XFASTINT (idx);
3857 3824
3858 if (EQ (key, HASH_KEY (h, i)) 3825 if (EQ (key, HASH_KEY (h, i))
3859 || (h->cmpfn 3826 || (h->test.cmpfn
3860 && h->cmpfn (h, key, hash_code, 3827 && hash_code == XUINT (HASH_HASH (h, i))
3861 HASH_KEY (h, i), XUINT (HASH_HASH (h, i))))) 3828 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
3862 { 3829 {
3863 /* Take entry out of collision chain. */ 3830 /* Take entry out of collision chain. */
3864 if (NILP (prev)) 3831 if (NILP (prev))
@@ -4070,13 +4037,6 @@ sweep_weak_hash_tables (void)
4070 4037
4071#define SXHASH_MAX_LEN 7 4038#define SXHASH_MAX_LEN 7
4072 4039
4073/* Combine two integers X and Y for hashing. The result might not fit
4074 into a Lisp integer. */
4075
4076#define SXHASH_COMBINE(X, Y) \
4077 ((((EMACS_UINT) (X) << 4) + ((EMACS_UINT) (X) >> (BITS_PER_EMACS_INT - 4))) \
4078 + (EMACS_UINT) (Y))
4079
4080/* Hash X, returning a value that fits into a Lisp integer. */ 4040/* Hash X, returning a value that fits into a Lisp integer. */
4081#define SXHASH_REDUCE(X) \ 4041#define SXHASH_REDUCE(X) \
4082 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK) 4042 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
@@ -4095,7 +4055,7 @@ hash_string (char const *ptr, ptrdiff_t len)
4095 while (p != end) 4055 while (p != end)
4096 { 4056 {
4097 c = *p++; 4057 c = *p++;
4098 hash = SXHASH_COMBINE (hash, c); 4058 hash = sxhash_combine (hash, c);
4099 } 4059 }
4100 4060
4101 return hash; 4061 return hash;
@@ -4129,7 +4089,7 @@ sxhash_float (double val)
4129 u.val = val; 4089 u.val = val;
4130 memset (&u.val + 1, 0, sizeof u - sizeof u.val); 4090 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4131 for (i = 0; i < WORDS_PER_DOUBLE; i++) 4091 for (i = 0; i < WORDS_PER_DOUBLE; i++)
4132 hash = SXHASH_COMBINE (hash, u.word[i]); 4092 hash = sxhash_combine (hash, u.word[i]);
4133 return SXHASH_REDUCE (hash); 4093 return SXHASH_REDUCE (hash);
4134} 4094}
4135 4095
@@ -4148,13 +4108,13 @@ sxhash_list (Lisp_Object list, int depth)
4148 list = XCDR (list), ++i) 4108 list = XCDR (list), ++i)
4149 { 4109 {
4150 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1); 4110 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
4151 hash = SXHASH_COMBINE (hash, hash2); 4111 hash = sxhash_combine (hash, hash2);
4152 } 4112 }
4153 4113
4154 if (!NILP (list)) 4114 if (!NILP (list))
4155 { 4115 {
4156 EMACS_UINT hash2 = sxhash (list, depth + 1); 4116 EMACS_UINT hash2 = sxhash (list, depth + 1);
4157 hash = SXHASH_COMBINE (hash, hash2); 4117 hash = sxhash_combine (hash, hash2);
4158 } 4118 }
4159 4119
4160 return SXHASH_REDUCE (hash); 4120 return SXHASH_REDUCE (hash);
@@ -4174,7 +4134,7 @@ sxhash_vector (Lisp_Object vec, int depth)
4174 for (i = 0; i < n; ++i) 4134 for (i = 0; i < n; ++i)
4175 { 4135 {
4176 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1); 4136 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
4177 hash = SXHASH_COMBINE (hash, hash2); 4137 hash = sxhash_combine (hash, hash2);
4178 } 4138 }
4179 4139
4180 return SXHASH_REDUCE (hash); 4140 return SXHASH_REDUCE (hash);
@@ -4190,7 +4150,7 @@ sxhash_bool_vector (Lisp_Object vec)
4190 4150
4191 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size); 4151 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
4192 for (i = 0; i < n; ++i) 4152 for (i = 0; i < n; ++i)
4193 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]); 4153 hash = sxhash_combine (hash, XBOOL_VECTOR (vec)->data[i]);
4194 4154
4195 return SXHASH_REDUCE (hash); 4155 return SXHASH_REDUCE (hash);
4196} 4156}
@@ -4214,7 +4174,7 @@ sxhash (Lisp_Object obj, int depth)
4214 break; 4174 break;
4215 4175
4216 case Lisp_Misc: 4176 case Lisp_Misc:
4217 hash = XUINT (obj); 4177 hash = XHASH (obj);
4218 break; 4178 break;
4219 4179
4220 case Lisp_Symbol: 4180 case Lisp_Symbol:
@@ -4238,7 +4198,7 @@ sxhash (Lisp_Object obj, int depth)
4238 else 4198 else
4239 /* Others are `equal' if they are `eq', so let's take their 4199 /* Others are `equal' if they are `eq', so let's take their
4240 address as hash. */ 4200 address as hash. */
4241 hash = XUINT (obj); 4201 hash = XHASH (obj);
4242 break; 4202 break;
4243 4203
4244 case Lisp_Cons: 4204 case Lisp_Cons:
@@ -4307,7 +4267,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4307 (ptrdiff_t nargs, Lisp_Object *args) 4267 (ptrdiff_t nargs, Lisp_Object *args)
4308{ 4268{
4309 Lisp_Object test, size, rehash_size, rehash_threshold, weak; 4269 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4310 Lisp_Object user_test, user_hash; 4270 struct hash_table_test testdesc;
4311 char *used; 4271 char *used;
4312 ptrdiff_t i; 4272 ptrdiff_t i;
4313 4273
@@ -4319,7 +4279,13 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4319 /* See if there's a `:test TEST' among the arguments. */ 4279 /* See if there's a `:test TEST' among the arguments. */
4320 i = get_key_arg (QCtest, nargs, args, used); 4280 i = get_key_arg (QCtest, nargs, args, used);
4321 test = i ? args[i] : Qeql; 4281 test = i ? args[i] : Qeql;
4322 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal)) 4282 if (EQ (test, Qeq))
4283 testdesc = hashtest_eq;
4284 else if (EQ (test, Qeql))
4285 testdesc = hashtest_eql;
4286 else if (EQ (test, Qequal))
4287 testdesc = hashtest_equal;
4288 else
4323 { 4289 {
4324 /* See if it is a user-defined test. */ 4290 /* See if it is a user-defined test. */
4325 Lisp_Object prop; 4291 Lisp_Object prop;
@@ -4327,11 +4293,12 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4327 prop = Fget (test, Qhash_table_test); 4293 prop = Fget (test, Qhash_table_test);
4328 if (!CONSP (prop) || !CONSP (XCDR (prop))) 4294 if (!CONSP (prop) || !CONSP (XCDR (prop)))
4329 signal_error ("Invalid hash table test", test); 4295 signal_error ("Invalid hash table test", test);
4330 user_test = XCAR (prop); 4296 testdesc.name = test;
4331 user_hash = XCAR (XCDR (prop)); 4297 testdesc.user_cmp_function = XCAR (prop);
4298 testdesc.user_hash_function = XCAR (XCDR (prop));
4299 testdesc.hashfn = hashfn_user_defined;
4300 testdesc.cmpfn = cmpfn_user_defined;
4332 } 4301 }
4333 else
4334 user_test = user_hash = Qnil;
4335 4302
4336 /* See if there's a `:size SIZE' argument. */ 4303 /* See if there's a `:size SIZE' argument. */
4337 i = get_key_arg (QCsize, nargs, args, used); 4304 i = get_key_arg (QCsize, nargs, args, used);
@@ -4373,8 +4340,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
4373 if (!used[i]) 4340 if (!used[i])
4374 signal_error ("Invalid argument list", args[i]); 4341 signal_error ("Invalid argument list", args[i]);
4375 4342
4376 return make_hash_table (test, size, rehash_size, rehash_threshold, weak, 4343 return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
4377 user_test, user_hash);
4378} 4344}
4379 4345
4380 4346
@@ -4428,7 +4394,7 @@ DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
4428 doc: /* Return the test TABLE uses. */) 4394 doc: /* Return the test TABLE uses. */)
4429 (Lisp_Object table) 4395 (Lisp_Object table)
4430{ 4396{
4431 return check_hash_table (table)->test; 4397 return check_hash_table (table)->test.name;
4432} 4398}
4433 4399
4434 4400
@@ -4992,4 +4958,14 @@ this variable. */);
4992 defsubr (&Smd5); 4958 defsubr (&Smd5);
4993 defsubr (&Ssecure_hash); 4959 defsubr (&Ssecure_hash);
4994 defsubr (&Slocale_info); 4960 defsubr (&Slocale_info);
4961
4962 {
4963 struct hash_table_test
4964 eq = { Qeq, Qnil, Qnil, NULL, hashfn_eq },
4965 eql = { Qeql, Qnil, Qnil, cmpfn_eql, hashfn_eql },
4966 equal = { Qequal, Qnil, Qnil, cmpfn_equal, hashfn_equal };
4967 hashtest_eq = eq;
4968 hashtest_eql = eql;
4969 hashtest_equal = equal;
4970 }
4995} 4971}
diff --git a/src/frame.c b/src/frame.c
index 52be8be270e..d580bf7f148 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -906,7 +906,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
906static Lisp_Object 906static Lisp_Object
907next_frame (Lisp_Object frame, Lisp_Object minibuf) 907next_frame (Lisp_Object frame, Lisp_Object minibuf)
908{ 908{
909 Lisp_Object tail; 909 Lisp_Object f, tail;
910 int passed = 0; 910 int passed = 0;
911 911
912 /* There must always be at least one frame in Vframe_list. */ 912 /* There must always be at least one frame in Vframe_list. */
@@ -918,12 +918,8 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
918 CHECK_LIVE_FRAME (frame); 918 CHECK_LIVE_FRAME (frame);
919 919
920 while (1) 920 while (1)
921 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 921 FOR_EACH_FRAME (tail, f)
922 { 922 {
923 Lisp_Object f;
924
925 f = XCAR (tail);
926
927 if (passed 923 if (passed
928 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) 924 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
929 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) 925 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
@@ -984,22 +980,13 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf)
984static Lisp_Object 980static Lisp_Object
985prev_frame (Lisp_Object frame, Lisp_Object minibuf) 981prev_frame (Lisp_Object frame, Lisp_Object minibuf)
986{ 982{
987 Lisp_Object tail; 983 Lisp_Object f, tail, prev = Qnil;
988 Lisp_Object prev;
989 984
990 /* There must always be at least one frame in Vframe_list. */ 985 /* There must always be at least one frame in Vframe_list. */
991 if (! CONSP (Vframe_list)) 986 eassert (CONSP (Vframe_list));
992 emacs_abort ();
993 987
994 prev = Qnil; 988 FOR_EACH_FRAME (tail, f)
995 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
996 { 989 {
997 Lisp_Object f;
998
999 f = XCAR (tail);
1000 if (!FRAMEP (f))
1001 emacs_abort ();
1002
1003 if (EQ (frame, f) && !NILP (prev)) 990 if (EQ (frame, f) && !NILP (prev))
1004 return prev; 991 return prev;
1005 992
@@ -1100,11 +1087,10 @@ Otherwise, include all frames. */)
1100static int 1087static int
1101other_visible_frames (FRAME_PTR f) 1088other_visible_frames (FRAME_PTR f)
1102{ 1089{
1103 Lisp_Object frames; 1090 Lisp_Object frames, this;
1104 1091
1105 for (frames = Vframe_list; CONSP (frames); frames = XCDR (frames)) 1092 FOR_EACH_FRAME (frames, this)
1106 { 1093 {
1107 Lisp_Object this = XCAR (frames);
1108 if (f == XFRAME (this)) 1094 if (f == XFRAME (this))
1109 continue; 1095 continue;
1110 1096
@@ -1158,15 +1144,10 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1158 minibuffer for any other frame? */ 1144 minibuffer for any other frame? */
1159 if (FRAME_HAS_MINIBUF_P (f)) 1145 if (FRAME_HAS_MINIBUF_P (f))
1160 { 1146 {
1161 Lisp_Object frames; 1147 Lisp_Object frames, this;
1162 1148
1163 for (frames = Vframe_list; 1149 FOR_EACH_FRAME (frames, this)
1164 CONSP (frames);
1165 frames = XCDR (frames))
1166 { 1150 {
1167 Lisp_Object this;
1168 this = XCAR (frames);
1169
1170 if (! EQ (this, frame) 1151 if (! EQ (this, frame)
1171 && EQ (frame, 1152 && EQ (frame,
1172 WINDOW_FRAME (XWINDOW 1153 WINDOW_FRAME (XWINDOW
@@ -1359,15 +1340,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1359 another one. */ 1340 another one. */
1360 if (f == last_nonminibuf_frame) 1341 if (f == last_nonminibuf_frame)
1361 { 1342 {
1362 Lisp_Object frames; 1343 Lisp_Object frames, this;
1363 1344
1364 last_nonminibuf_frame = 0; 1345 last_nonminibuf_frame = 0;
1365 1346
1366 for (frames = Vframe_list; 1347 FOR_EACH_FRAME (frames, this)
1367 CONSP (frames);
1368 frames = XCDR (frames))
1369 { 1348 {
1370 f = XFRAME (XCAR (frames)); 1349 f = XFRAME (this);
1371 if (!FRAME_MINIBUF_ONLY_P (f)) 1350 if (!FRAME_MINIBUF_ONLY_P (f))
1372 { 1351 {
1373 last_nonminibuf_frame = f; 1352 last_nonminibuf_frame = f;
@@ -1380,27 +1359,13 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1380 single-kboard state if we're in it for this kboard. */ 1359 single-kboard state if we're in it for this kboard. */
1381 if (kb != NULL) 1360 if (kb != NULL)
1382 { 1361 {
1383 Lisp_Object frames; 1362 Lisp_Object frames, this;
1384 /* Some frame we found on the same kboard, or nil if there are none. */ 1363 /* Some frame we found on the same kboard, or nil if there are none. */
1385 Lisp_Object frame_on_same_kboard; 1364 Lisp_Object frame_on_same_kboard = Qnil;
1386
1387 frame_on_same_kboard = Qnil;
1388
1389 for (frames = Vframe_list;
1390 CONSP (frames);
1391 frames = XCDR (frames))
1392 {
1393 Lisp_Object this;
1394 struct frame *f1;
1395
1396 this = XCAR (frames);
1397 if (!FRAMEP (this))
1398 emacs_abort ();
1399 f1 = XFRAME (this);
1400 1365
1401 if (kb == FRAME_KBOARD (f1)) 1366 FOR_EACH_FRAME (frames, this)
1402 frame_on_same_kboard = this; 1367 if (kb == FRAME_KBOARD (XFRAME (this)))
1403 } 1368 frame_on_same_kboard = this;
1404 1369
1405 if (NILP (frame_on_same_kboard)) 1370 if (NILP (frame_on_same_kboard))
1406 not_single_kboard_state (kb); 1371 not_single_kboard_state (kb);
@@ -1412,27 +1377,16 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1412 frames with other windows. */ 1377 frames with other windows. */
1413 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame))) 1378 if (kb != NULL && EQ (frame, KVAR (kb, Vdefault_minibuffer_frame)))
1414 { 1379 {
1415 Lisp_Object frames; 1380 Lisp_Object frames, this;
1416 1381
1417 /* The last frame we saw with a minibuffer, minibuffer-only or not. */ 1382 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1418 Lisp_Object frame_with_minibuf; 1383 Lisp_Object frame_with_minibuf = Qnil;
1419 /* Some frame we found on the same kboard, or nil if there are none. */ 1384 /* Some frame we found on the same kboard, or nil if there are none. */
1420 Lisp_Object frame_on_same_kboard; 1385 Lisp_Object frame_on_same_kboard = Qnil;
1421 1386
1422 frame_on_same_kboard = Qnil; 1387 FOR_EACH_FRAME (frames, this)
1423 frame_with_minibuf = Qnil;
1424
1425 for (frames = Vframe_list;
1426 CONSP (frames);
1427 frames = XCDR (frames))
1428 { 1388 {
1429 Lisp_Object this; 1389 struct frame *f1 = XFRAME (this);
1430 struct frame *f1;
1431
1432 this = XCAR (frames);
1433 if (!FRAMEP (this))
1434 emacs_abort ();
1435 f1 = XFRAME (this);
1436 1390
1437 /* Consider only frames on the same kboard 1391 /* Consider only frames on the same kboard
1438 and only those with minibuffers. */ 1392 and only those with minibuffers. */
@@ -1816,20 +1770,12 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1816 doc: /* Return a list of all frames now \"visible\" (being updated). */) 1770 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1817 (void) 1771 (void)
1818{ 1772{
1819 Lisp_Object tail, frame; 1773 Lisp_Object tail, frame, value = Qnil;
1820 struct frame *f; 1774
1821 Lisp_Object value; 1775 FOR_EACH_FRAME (tail, frame)
1776 if (FRAME_VISIBLE_P (XFRAME (frame)))
1777 value = Fcons (frame, value);
1822 1778
1823 value = Qnil;
1824 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1825 {
1826 frame = XCAR (tail);
1827 if (!FRAMEP (frame))
1828 continue;
1829 f = XFRAME (frame);
1830 if (FRAME_VISIBLE_P (f))
1831 value = Fcons (frame, value);
1832 }
1833 return value; 1779 return value;
1834} 1780}
1835 1781
diff --git a/src/frame.h b/src/frame.h
index 1dc3ebbaf13..35cbc44becc 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -237,7 +237,7 @@ struct frame
237 237
238#if defined (USE_GTK) || defined (HAVE_NS) 238#if defined (USE_GTK) || defined (HAVE_NS)
239 /* Nonzero means using a tool bar that comes from the toolkit. */ 239 /* Nonzero means using a tool bar that comes from the toolkit. */
240 int external_tool_bar; 240 unsigned external_tool_bar : 1;
241#endif 241#endif
242 242
243 /* Margin at the top of the frame. Used to display the tool-bar. */ 243 /* Margin at the top of the frame. Used to display the tool-bar. */
diff --git a/src/image.c b/src/image.c
index 538ae2b7772..07db6cece1f 100644
--- a/src/image.c
+++ b/src/image.c
@@ -3731,10 +3731,10 @@ xpm_make_color_table_h (void (**put_func) (Lisp_Object,
3731{ 3731{
3732 *put_func = xpm_put_color_table_h; 3732 *put_func = xpm_put_color_table_h;
3733 *get_func = xpm_get_color_table_h; 3733 *get_func = xpm_get_color_table_h;
3734 return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), 3734 return make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
3735 make_float (DEFAULT_REHASH_SIZE), 3735 make_float (DEFAULT_REHASH_SIZE),
3736 make_float (DEFAULT_REHASH_THRESHOLD), 3736 make_float (DEFAULT_REHASH_THRESHOLD),
3737 Qnil, Qnil, Qnil); 3737 Qnil);
3738} 3738}
3739 3739
3740static void 3740static void
diff --git a/src/keyboard.c b/src/keyboard.c
index 7507b29d494..42c26982086 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3419,13 +3419,20 @@ int stop_character EXTERNALLY_VISIBLE;
3419static KBOARD * 3419static KBOARD *
3420event_to_kboard (struct input_event *event) 3420event_to_kboard (struct input_event *event)
3421{ 3421{
3422 Lisp_Object obj = event->frame_or_window; 3422 /* Not applicable for these special events. */
3423 /* There are some events that set this field to nil or string. */ 3423 if (event->kind == SELECTION_REQUEST_EVENT
3424 if (WINDOWP (obj)) 3424 || event->kind == SELECTION_CLEAR_EVENT)
3425 obj = WINDOW_FRAME (XWINDOW (obj)); 3425 return NULL;
3426 /* Also ignore dead frames here. */ 3426 else
3427 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj))) 3427 {
3428 ? FRAME_KBOARD (XFRAME (obj)) : NULL); 3428 Lisp_Object obj = event->frame_or_window;
3429 /* There are some events that set this field to nil or string. */
3430 if (WINDOWP (obj))
3431 obj = WINDOW_FRAME (XWINDOW (obj));
3432 /* Also ignore dead frames here. */
3433 return ((FRAMEP (obj) && FRAME_LIVE_P (XFRAME (obj)))
3434 ? FRAME_KBOARD (XFRAME (obj)) : NULL);
3435 }
3429} 3436}
3430 3437
3431#ifdef subprocesses 3438#ifdef subprocesses
diff --git a/src/lisp.h b/src/lisp.h
index 7a3b819116f..b56e499ce29 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -413,14 +413,11 @@ enum pvec_type
413 PVEC_XWIDGET_VIEW, 413 PVEC_XWIDGET_VIEW,
414#endif 414#endif
415 415
416 /* These last 4 are special because we OR them in fns.c:internal_equal, 416 /* These should be last, check internal_equal to see why. */
417 so they have to use a disjoint bit pattern: 417 PVEC_COMPILED,
418 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE 418 PVEC_CHAR_TABLE,
419 | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) */ 419 PVEC_SUB_CHAR_TABLE,
420 PVEC_COMPILED = 0x10, 420 PVEC_FONT /* Should be last because it's used for range checking. */
421 PVEC_CHAR_TABLE = 0x20,
422 PVEC_SUB_CHAR_TABLE = 0x30,
423 PVEC_FONT = 0x40
424}; 421};
425 422
426/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers 423/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers
@@ -440,9 +437,18 @@ enum More_Lisp_Bits
440 only the number of Lisp_Object fields (that need to be traced by GC). 437 only the number of Lisp_Object fields (that need to be traced by GC).
441 The distinction is used, e.g., by Lisp_Process, which places extra 438 The distinction is used, e.g., by Lisp_Process, which places extra
442 non-Lisp_Object fields at the end of the structure. */ 439 non-Lisp_Object fields at the end of the structure. */
443 PSEUDOVECTOR_SIZE_BITS = 16, 440 PSEUDOVECTOR_SIZE_BITS = 12,
444 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, 441 PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1,
445 PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS, 442
443 /* To calculate the memory footprint of the pseudovector, it's useful
444 to store the size of non-Lisp area in word_size units here. */
445 PSEUDOVECTOR_REST_BITS = 12,
446 PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1)
447 << PSEUDOVECTOR_SIZE_BITS),
448
449 /* Used to extract pseudovector subtype information. */
450 PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS,
451 PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS,
446 452
447 /* Number of bits to put in each character in the internal representation 453 /* Number of bits to put in each character in the internal representation
448 of bool vectors. This should not vary across implementations. */ 454 of bool vectors. This should not vary across implementations. */
@@ -453,9 +459,6 @@ enum More_Lisp_Bits
453 For example, if tem is a Lisp_Object whose type is Lisp_Cons, 459 For example, if tem is a Lisp_Object whose type is Lisp_Cons,
454 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ 460 XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */
455 461
456/* Return a perfect hash of the Lisp_Object representation. */
457#define XHASH(a) XLI (a)
458
459#if USE_LSB_TAG 462#if USE_LSB_TAG
460 463
461enum lsb_bits 464enum lsb_bits
@@ -508,6 +511,11 @@ static EMACS_INT const VALMASK
508 511
509#endif /* not USE_LSB_TAG */ 512#endif /* not USE_LSB_TAG */
510 513
514/* Return a (Lisp-integer sized) hash of the Lisp_Object value. Happens to be
515 like XUINT right now, but XUINT should only be applied to objects we know
516 are integers. */
517#define XHASH(a) XUINT (a)
518
511/* For integers known to be positive, XFASTINT sometimes provides 519/* For integers known to be positive, XFASTINT sometimes provides
512 faster retrieval and XSETFASTINT provides faster storage. 520 faster retrieval and XSETFASTINT provides faster storage.
513 If not, fallback on the non-accelerated path. */ 521 If not, fallback on the non-accelerated path. */
@@ -523,7 +531,7 @@ static EMACS_INT const VALMASK
523# define XUNTAG(a, type) XPNTR (a) 531# define XUNTAG(a, type) XPNTR (a)
524#endif 532#endif
525 533
526#define EQ(x, y) (XHASH (x) == XHASH (y)) 534#define EQ(x, y) (XLI (x) == XLI (y))
527 535
528/* Largest and smallest representable fixnum values. These are the C 536/* Largest and smallest representable fixnum values. These are the C
529 values. They are macros for use in static initializers. */ 537 values. They are macros for use in static initializers. */
@@ -613,13 +621,13 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
613 621
614/* Pseudovector types. */ 622/* Pseudovector types. */
615 623
616#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code) 624#define XSETPVECTYPE(v, code) \
617#define XSETTYPED_PVECTYPE(v, size_member, code) \ 625 ((v)->header.size |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))
618 ((v)->size_member |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS)) 626#define XSETPVECTYPESIZE(v, code, lispsize, restsize) \
619#define XSETPVECTYPESIZE(v, code, sizeval) \
620 ((v)->header.size = (PSEUDOVECTOR_FLAG \ 627 ((v)->header.size = (PSEUDOVECTOR_FLAG \
621 | ((code) << PSEUDOVECTOR_SIZE_BITS) \ 628 | ((code) << PSEUDOVECTOR_AREA_BITS) \
622 | (sizeval))) 629 | ((restsize) << PSEUDOVECTOR_SIZE_BITS) \
630 | (lispsize)))
623 631
624/* The cast to struct vectorlike_header * avoids aliasing issues. */ 632/* The cast to struct vectorlike_header * avoids aliasing issues. */
625#define XSETPSEUDOVECTOR(a, b, code) \ 633#define XSETPSEUDOVECTOR(a, b, code) \
@@ -631,16 +639,14 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
631#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \ 639#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
632 (XSETVECTOR (a, b), \ 640 (XSETVECTOR (a, b), \
633 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 641 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
634 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS)))) 642 == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))))
635 643
636#define XSETWINDOW_CONFIGURATION(a, b) \ 644#define XSETWINDOW_CONFIGURATION(a, b) \
637 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) 645 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
638#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) 646#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
639#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) 647#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
640#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) 648#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
641/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */ 649#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
642#define XSETSUBR(a, b) \
643 XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
644#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) 650#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
645#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) 651#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
646#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) 652#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
@@ -807,7 +813,7 @@ struct Lisp_String
807 }; 813 };
808 814
809/* Header of vector-like objects. This documents the layout constraints on 815/* Header of vector-like objects. This documents the layout constraints on
810 vectors and pseudovectors other than struct Lisp_Subr. It also prevents 816 vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
811 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR 817 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR
812 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, 818 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *,
813 because when two such pointers potentially alias, a compiler won't 819 because when two such pointers potentially alias, a compiler won't
@@ -815,43 +821,26 @@ struct Lisp_String
815 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ 821 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
816struct vectorlike_header 822struct vectorlike_header
817 { 823 {
818 /* This field contains various pieces of information: 824 /* The only field contains various pieces of information:
819 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. 825 - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit.
820 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain 826 - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain
821 vector (0) or a pseudovector (1). 827 vector (0) or a pseudovector (1).
822 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number 828 - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
823 of slots) of the vector. 829 of slots) of the vector.
824 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into 830 - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
825 a "pvec type" tag held in PVEC_TYPE_MASK and a size held in the lowest 831 - a) pseudovector subtype held in PVEC_TYPE_MASK field;
826 PSEUDOVECTOR_SIZE_BITS. That size normally indicates the number of 832 - b) number of Lisp_Objects slots at the beginning of the object
827 Lisp_Object slots at the beginning of the object that need to be 833 held in PSEUDOVECTOR_SIZE_MASK field. These objects are always
828 traced by the GC, tho some types use it slightly differently. 834 traced by the GC;
829 - E.g. if the pvec type is PVEC_FREE it means this is an unallocated 835 - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
830 vector on a free-list and PSEUDOVECTOR_SIZE_BITS indicates its size 836 measured in word_size units. Rest fields may also include
831 in bytes. */ 837 Lisp_Objects, but these objects usually needs some special treatment
838 during GC.
839 There are some exceptions. For PVEC_FREE, b) is always zero. For
840 PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
841 Current layout limits the pseudovectors to 63 PVEC_xxx subtypes,
842 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */
832 ptrdiff_t size; 843 ptrdiff_t size;
833
834 /* When the vector is allocated from a vector block, NBYTES is used
835 if the vector is not on a free list, and VECTOR is used otherwise.
836 For large vector-like objects, BUFFER or VECTOR is used as a pointer
837 to the next vector-like object. It is generally a buffer or a
838 Lisp_Vector alias, so for convenience it is a union instead of a
839 pointer: this way, one can write P->next.vector instead of ((struct
840 Lisp_Vector *) P->next). */
841 union {
842 /* This is only needed for small vectors that are not free because the
843 `size' field only gives us the number of Lisp_Object slots, whereas we
844 need to know the total size, including non-Lisp_Object data.
845 FIXME: figure out a way to store this info elsewhere so we can
846 finally get rid of this extra word of overhead. */
847 ptrdiff_t nbytes;
848 struct buffer *buffer;
849 /* FIXME: This can be removed: For large vectors, this field could be
850 placed *before* the vector itself. And for small vectors on a free
851 list, this field could be stored in the vector's bytes, since the
852 empty vector is handled specially anyway. */
853 struct Lisp_Vector *vector;
854 } next;
855 }; 844 };
856 845
857/* Regular vector is just a header plus array of Lisp_Objects. */ 846/* Regular vector is just a header plus array of Lisp_Objects. */
@@ -1025,15 +1014,11 @@ struct Lisp_Sub_Char_Table
1025 1014
1026/* This structure describes a built-in function. 1015/* This structure describes a built-in function.
1027 It is generated by the DEFUN macro only. 1016 It is generated by the DEFUN macro only.
1028 defsubr makes it into a Lisp object. 1017 defsubr makes it into a Lisp object. */
1029
1030 This type is treated in most respects as a pseudovector,
1031 but since we never dynamically allocate or free them,
1032 we don't need a struct vectorlike_header and its 'next' field. */
1033 1018
1034struct Lisp_Subr 1019struct Lisp_Subr
1035 { 1020 {
1036 ptrdiff_t size; 1021 struct vectorlike_header header;
1037 union { 1022 union {
1038 Lisp_Object (*a0) (void); 1023 Lisp_Object (*a0) (void);
1039 Lisp_Object (*a1) (Lisp_Object); 1024 Lisp_Object (*a1) (Lisp_Object);
@@ -1181,14 +1166,29 @@ struct Lisp_Symbol
1181 1166
1182/* The structure of a Lisp hash table. */ 1167/* The structure of a Lisp hash table. */
1183 1168
1169struct hash_table_test
1170{
1171 /* Name of the function used to compare keys. */
1172 Lisp_Object name;
1173
1174 /* User-supplied hash function, or nil. */
1175 Lisp_Object user_hash_function;
1176
1177 /* User-supplied key comparison function, or nil. */
1178 Lisp_Object user_cmp_function;
1179
1180 /* C function to compare two keys. */
1181 bool (*cmpfn) (struct hash_table_test *t, Lisp_Object, Lisp_Object);
1182
1183 /* C function to compute hash code. */
1184 EMACS_UINT (*hashfn) (struct hash_table_test *t, Lisp_Object);
1185};
1186
1184struct Lisp_Hash_Table 1187struct Lisp_Hash_Table
1185{ 1188{
1186 /* This is for Lisp; the hash table code does not refer to it. */ 1189 /* This is for Lisp; the hash table code does not refer to it. */
1187 struct vectorlike_header header; 1190 struct vectorlike_header header;
1188 1191
1189 /* Function used to compare keys. */
1190 Lisp_Object test;
1191
1192 /* Nil if table is non-weak. Otherwise a symbol describing the 1192 /* Nil if table is non-weak. Otherwise a symbol describing the
1193 weakness of the table. */ 1193 weakness of the table. */
1194 Lisp_Object weak; 1194 Lisp_Object weak;
@@ -1219,12 +1219,6 @@ struct Lisp_Hash_Table
1219 hash table size to reduce collisions. */ 1219 hash table size to reduce collisions. */
1220 Lisp_Object index; 1220 Lisp_Object index;
1221 1221
1222 /* User-supplied hash function, or nil. */
1223 Lisp_Object user_hash_function;
1224
1225 /* User-supplied key comparison function, or nil. */
1226 Lisp_Object user_cmp_function;
1227
1228 /* Only the fields above are traced normally by the GC. The ones below 1222 /* Only the fields above are traced normally by the GC. The ones below
1229 `count' are special and are either ignored by the GC or traced in 1223 `count' are special and are either ignored by the GC or traced in
1230 a special way (e.g. because of weakness). */ 1224 a special way (e.g. because of weakness). */
@@ -1237,17 +1231,12 @@ struct Lisp_Hash_Table
1237 This is gc_marked specially if the table is weak. */ 1231 This is gc_marked specially if the table is weak. */
1238 Lisp_Object key_and_value; 1232 Lisp_Object key_and_value;
1239 1233
1234 /* The comparison and hash functions. */
1235 struct hash_table_test test;
1236
1240 /* Next weak hash table if this is a weak hash table. The head 1237 /* Next weak hash table if this is a weak hash table. The head
1241 of the list is in weak_hash_tables. */ 1238 of the list is in weak_hash_tables. */
1242 struct Lisp_Hash_Table *next_weak; 1239 struct Lisp_Hash_Table *next_weak;
1243
1244 /* C function to compare two keys. */
1245 bool (*cmpfn) (struct Lisp_Hash_Table *,
1246 Lisp_Object, EMACS_UINT,
1247 Lisp_Object, EMACS_UINT);
1248
1249 /* C function to compute hash code. */
1250 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object);
1251}; 1240};
1252 1241
1253 1242
@@ -1302,6 +1291,15 @@ static double const DEFAULT_REHASH_THRESHOLD = 0.8;
1302 1291
1303static double const DEFAULT_REHASH_SIZE = 1.5; 1292static double const DEFAULT_REHASH_SIZE = 1.5;
1304 1293
1294/* Combine two integers X and Y for hashing. The result might not fit
1295 into a Lisp integer. */
1296
1297LISP_INLINE EMACS_UINT
1298sxhash_combine (EMACS_UINT x, EMACS_UINT y)
1299{
1300 return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y;
1301}
1302
1305/* These structures are used for various misc types. */ 1303/* These structures are used for various misc types. */
1306 1304
1307struct Lisp_Misc_Any /* Supertype of all Misc types. */ 1305struct Lisp_Misc_Any /* Supertype of all Misc types. */
@@ -1701,6 +1699,8 @@ typedef struct {
1701#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) 1699#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
1702#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) 1700#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
1703 1701
1702#define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x)))
1703
1704#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) 1704#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int)
1705#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) 1705#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool)
1706#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) 1706#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj)
@@ -1714,7 +1714,7 @@ typedef struct {
1714 1714
1715#define PSEUDOVECTOR_TYPEP(v, code) \ 1715#define PSEUDOVECTOR_TYPEP(v, code) \
1716 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 1716 (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
1717 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS))) 1717 == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS)))
1718 1718
1719/* True if object X, with internal type struct T *, is a pseudovector whose 1719/* True if object X, with internal type struct T *, is a pseudovector whose
1720 code is CODE. */ 1720 code is CODE. */
@@ -1727,8 +1727,7 @@ typedef struct {
1727#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) 1727#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
1728#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) 1728#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
1729#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) 1729#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
1730/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ 1730#define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR)
1731#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
1732#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) 1731#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
1733#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) 1732#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
1734#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) 1733#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
@@ -1903,8 +1902,8 @@ typedef struct {
1903#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1902#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1904 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1903 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1905 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1904 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1906 { (PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS) \ 1905 { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \
1907 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ 1906 | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \
1908 { (Lisp_Object (__cdecl *)(void))fnname }, \ 1907 { (Lisp_Object (__cdecl *)(void))fnname }, \
1909 minargs, maxargs, lname, intspec, 0}; \ 1908 minargs, maxargs, lname, intspec, 0}; \
1910 Lisp_Object fnname 1909 Lisp_Object fnname
@@ -1912,8 +1911,8 @@ typedef struct {
1912#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 1911#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
1913 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 1912 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
1914 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 1913 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
1915 { PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS, \ 1914 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
1916 { .a ## maxargs = fnname }, \ 1915 { .a ## maxargs = fnname }, \
1917 minargs, maxargs, lname, intspec, 0}; \ 1916 minargs, maxargs, lname, intspec, 0}; \
1918 Lisp_Object fnname 1917 Lisp_Object fnname
1919#endif 1918#endif
@@ -2727,15 +2726,15 @@ extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
2727extern void sweep_weak_hash_tables (void); 2726extern void sweep_weak_hash_tables (void);
2728extern Lisp_Object Qcursor_in_echo_area; 2727extern Lisp_Object Qcursor_in_echo_area;
2729extern Lisp_Object Qstring_lessp; 2728extern Lisp_Object Qstring_lessp;
2730extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; 2729extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq;
2731EMACS_UINT hash_string (char const *, ptrdiff_t); 2730EMACS_UINT hash_string (char const *, ptrdiff_t);
2732EMACS_UINT sxhash (Lisp_Object, int); 2731EMACS_UINT sxhash (Lisp_Object, int);
2733Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, 2732Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
2734 Lisp_Object, Lisp_Object, Lisp_Object, 2733 Lisp_Object, Lisp_Object);
2735 Lisp_Object);
2736ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); 2734ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
2737ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, 2735ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
2738 EMACS_UINT); 2736 EMACS_UINT);
2737extern struct hash_table_test hashtest_eql, hashtest_equal;
2739 2738
2740extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, 2739extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
2741 ptrdiff_t, ptrdiff_t); 2740 ptrdiff_t, ptrdiff_t);
@@ -2957,7 +2956,7 @@ extern void make_byte_code (struct Lisp_Vector *);
2957extern Lisp_Object Qautomatic_gc; 2956extern Lisp_Object Qautomatic_gc;
2958extern Lisp_Object Qchar_table_extra_slots; 2957extern Lisp_Object Qchar_table_extra_slots;
2959extern struct Lisp_Vector *allocate_vector (EMACS_INT); 2958extern struct Lisp_Vector *allocate_vector (EMACS_INT);
2960extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); 2959extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type);
2961#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ 2960#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \
2962 ((typ*) \ 2961 ((typ*) \
2963 allocate_pseudovector \ 2962 allocate_pseudovector \
diff --git a/src/lread.c b/src/lread.c
index 94744620279..3a82e0057e2 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3981,7 +3981,7 @@ defsubr (struct Lisp_Subr *sname)
3981{ 3981{
3982 Lisp_Object sym, tem; 3982 Lisp_Object sym, tem;
3983 sym = intern_c_string (sname->symbol_name); 3983 sym = intern_c_string (sname->symbol_name);
3984 XSETTYPED_PVECTYPE (sname, size, PVEC_SUBR); 3984 XSETPVECTYPE (sname, PVEC_SUBR);
3985 XSETSUBR (tem, sname); 3985 XSETSUBR (tem, sname);
3986 set_symbol_function (sym, tem); 3986 set_symbol_function (sym, tem);
3987} 3987}
diff --git a/src/nsfont.m b/src/nsfont.m
index 4f29d1d54a9..2ba38b7570e 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -46,8 +46,9 @@ Author: Adrian Robert (arobert@cogsci.ucsd.edu)
46#define NSFONT_TRACE 0 46#define NSFONT_TRACE 0
47 47
48extern Lisp_Object Qns; 48extern Lisp_Object Qns;
49extern Lisp_Object Qnormal, Qbold, Qitalic, Qcondensed, Qexpanded; 49extern Lisp_Object Qnormal, Qbold, Qitalic;
50static Lisp_Object Qapple, Qroman, Qmedium; 50static Lisp_Object Qapple, Qroman, Qmedium;
51static Lisp_Object Qcondensed, Qexpanded;
51extern Lisp_Object Qappend; 52extern Lisp_Object Qappend;
52extern float ns_antialias_threshold; 53extern float ns_antialias_threshold;
53extern int ns_tmp_flags; 54extern int ns_tmp_flags;
@@ -201,8 +202,8 @@ ns_descriptor_to_entity (NSFontDescriptor *desc,
201 make_number (100 + 100 202 make_number (100 + 100
202 * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/ 203 * ns_attribute_fvalue (desc, NSFontSlantTrait)));*/
203 FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX, 204 FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
204 traits & NSFontCondensedTrait ? Qcondensed : 205 traits & NSFontCondensedTrait ? Qcondensed :
205 traits & NSFontExpandedTrait ? Qexpanded : Qnormal); 206 traits & NSFontExpandedTrait ? Qexpanded : Qnormal);
206/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX, 207/* FONT_SET_STYLE (font_entity, FONT_WIDTH_INDEX,
207 make_number (100 + 100 208 make_number (100 + 100
208 * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/ 209 * ns_attribute_fvalue (desc, NSFontWidthTrait)));*/
@@ -559,7 +560,11 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
559 if (isMatch) 560 if (isMatch)
560 [fkeys removeObject: NSFontFamilyAttribute]; 561 [fkeys removeObject: NSFontFamilyAttribute];
561 562
562 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys]; 563 if ([fkeys count] > 0)
564 matchingDescs = [fdesc matchingFontDescriptorsWithMandatoryKeys: fkeys];
565 else
566 matchingDescs = [NSMutableArray array];
567
563 if (NSFONT_TRACE) 568 if (NSFONT_TRACE)
564 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc, 569 NSLog(@"Got desc %@ and found %d matching fonts from it: ", fdesc,
565 [matchingDescs count]); 570 [matchingDescs count]);
@@ -1507,6 +1512,8 @@ syms_of_nsfont (void)
1507{ 1512{
1508 nsfont_driver.type = Qns; 1513 nsfont_driver.type = Qns;
1509 register_font_driver (&nsfont_driver, NULL); 1514 register_font_driver (&nsfont_driver, NULL);
1515 DEFSYM (Qcondensed, "condensed");
1516 DEFSYM (Qexpanded, "expanded");
1510 DEFSYM (Qapple, "apple"); 1517 DEFSYM (Qapple, "apple");
1511 DEFSYM (Qroman, "roman"); 1518 DEFSYM (Qroman, "roman");
1512 DEFSYM (Qmedium, "medium"); 1519 DEFSYM (Qmedium, "medium");
diff --git a/src/print.c b/src/print.c
index 22ed47bf65f..0788d110784 100644
--- a/src/print.c
+++ b/src/print.c
@@ -800,7 +800,7 @@ safe_debug_print (Lisp_Object arg)
800 else 800 else
801 fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n", 801 fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n",
802 !valid ? "INVALID" : "SOME", 802 !valid ? "INVALID" : "SOME",
803 XHASH (arg)); 803 XLI (arg));
804} 804}
805 805
806 806
@@ -1824,14 +1824,14 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1824#endif 1824#endif
1825 /* Implement a readable output, e.g.: 1825 /* Implement a readable output, e.g.:
1826 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ 1826 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
1827 /* Always print the size. */ 1827 /* Always print the size. */
1828 len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); 1828 len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next));
1829 strout (buf, len, len, printcharfun); 1829 strout (buf, len, len, printcharfun);
1830 1830
1831 if (!NILP (h->test)) 1831 if (!NILP (h->test.name))
1832 { 1832 {
1833 strout (" test ", -1, -1, printcharfun); 1833 strout (" test ", -1, -1, printcharfun);
1834 print_object (h->test, printcharfun, escapeflag); 1834 print_object (h->test.name, printcharfun, escapeflag);
1835 } 1835 }
1836 1836
1837 if (!NILP (h->weak)) 1837 if (!NILP (h->weak))
diff --git a/src/profiler.c b/src/profiler.c
index 51580710f28..3d8f7243d2f 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -35,6 +35,9 @@ saturated_add (EMACS_INT a, EMACS_INT b)
35 35
36typedef struct Lisp_Hash_Table log_t; 36typedef struct Lisp_Hash_Table log_t;
37 37
38static Lisp_Object Qprofiler_backtrace_equal;
39static struct hash_table_test hashtest_profiler;
40
38static Lisp_Object 41static Lisp_Object
39make_log (int heap_size, int max_stack_depth) 42make_log (int heap_size, int max_stack_depth)
40{ 43{
@@ -42,10 +45,11 @@ make_log (int heap_size, int max_stack_depth)
42 a special way. This is OK as long as the object is not exposed 45 a special way. This is OK as long as the object is not exposed
43 to Elisp, i.e. until it is returned by *-profiler-log, after which 46 to Elisp, i.e. until it is returned by *-profiler-log, after which
44 it can't be used any more. */ 47 it can't be used any more. */
45 Lisp_Object log = make_hash_table (Qequal, make_number (heap_size), 48 Lisp_Object log = make_hash_table (hashtest_profiler,
49 make_number (heap_size),
46 make_float (DEFAULT_REHASH_SIZE), 50 make_float (DEFAULT_REHASH_SIZE),
47 make_float (DEFAULT_REHASH_THRESHOLD), 51 make_float (DEFAULT_REHASH_THRESHOLD),
48 Qnil, Qnil, Qnil); 52 Qnil);
49 struct Lisp_Hash_Table *h = XHASH_TABLE (log); 53 struct Lisp_Hash_Table *h = XHASH_TABLE (log);
50 54
51 /* What is special about our hash-tables is that the keys are pre-filled 55 /* What is special about our hash-tables is that the keys are pre-filled
@@ -238,8 +242,6 @@ handle_profiler_signal (int signal)
238 cpu_gc_count = saturated_add (cpu_gc_count, 1); 242 cpu_gc_count = saturated_add (cpu_gc_count, 1);
239 else 243 else
240 { 244 {
241 Lisp_Object oquit;
242 bool saved_pending_signals;
243 EMACS_INT count = 1; 245 EMACS_INT count = 1;
244#ifdef HAVE_ITIMERSPEC 246#ifdef HAVE_ITIMERSPEC
245 if (profiler_timer_ok) 247 if (profiler_timer_ok)
@@ -249,19 +251,8 @@ handle_profiler_signal (int signal)
249 count += overruns; 251 count += overruns;
250 } 252 }
251#endif 253#endif
252 /* record_backtrace uses hash functions that call Fequal, which
253 uses QUIT, which can call malloc, which can cause disaster in
254 a signal handler. So inhibit QUIT. */
255 oquit = Vinhibit_quit;
256 saved_pending_signals = pending_signals;
257 Vinhibit_quit = Qt;
258 pending_signals = 0;
259
260 eassert (HASH_TABLE_P (cpu_log)); 254 eassert (HASH_TABLE_P (cpu_log));
261 record_backtrace (XHASH_TABLE (cpu_log), count); 255 record_backtrace (XHASH_TABLE (cpu_log), count);
262
263 Vinhibit_quit = oquit;
264 pending_signals = saved_pending_signals;
265 } 256 }
266} 257}
267 258
@@ -515,6 +506,66 @@ malloc_probe (size_t size)
515 record_backtrace (XHASH_TABLE (memory_log), min (size, MOST_POSITIVE_FIXNUM)); 506 record_backtrace (XHASH_TABLE (memory_log), min (size, MOST_POSITIVE_FIXNUM));
516} 507}
517 508
509DEFUN ("function-equal", Ffunction_equal, Sfunction_equal, 2, 2, 0,
510 doc: /* Return non-nil if F1 and F2 come from the same source.
511Used to determine if different closures are just different instances of
512the same lambda expression, or are really unrelated function. */)
513 (Lisp_Object f1, Lisp_Object f2)
514{
515 bool res;
516 if (EQ (f1, f2))
517 res = true;
518 else if (COMPILEDP (f1) && COMPILEDP (f2))
519 res = EQ (AREF (f1, COMPILED_BYTECODE), AREF (f2, COMPILED_BYTECODE));
520 else if (CONSP (f1) && CONSP (f2) && CONSP (XCDR (f1)) && CONSP (XCDR (f2))
521 && EQ (Qclosure, XCAR (f1))
522 && EQ (Qclosure, XCAR (f2)))
523 res = EQ (XCDR (XCDR (f1)), XCDR (XCDR (f2)));
524 else
525 res = false;
526 return res ? Qt : Qnil;
527}
528
529static bool
530cmpfn_profiler (struct hash_table_test *t,
531 Lisp_Object bt1, Lisp_Object bt2)
532{
533 if (VECTORP (bt1) && VECTORP (bt2))
534 {
535 ptrdiff_t i, l = ASIZE (bt1);
536 if (l != ASIZE (bt2))
537 return false;
538 for (i = 0; i < l; i++)
539 if (NILP (Ffunction_equal (AREF (bt1, i), AREF (bt2, i))))
540 return false;
541 return true;
542 }
543 else
544 return EQ (bt1, bt2);
545}
546
547static EMACS_UINT
548hashfn_profiler (struct hash_table_test *ht, Lisp_Object bt)
549{
550 if (VECTORP (bt))
551 {
552 EMACS_UINT hash = 0;
553 ptrdiff_t i, l = ASIZE (bt);
554 for (i = 0; i < l; i++)
555 {
556 Lisp_Object f = AREF (bt, i);
557 EMACS_UINT hash1
558 = (COMPILEDP (f) ? XHASH (AREF (f, COMPILED_BYTECODE))
559 : (CONSP (f) && CONSP (XCDR (f)) && EQ (Qclosure, XCAR (f)))
560 ? XHASH (XCDR (XCDR (f))) : XHASH (f));
561 hash = sxhash_combine (hash, hash1);
562 }
563 return (hash & INTMASK);
564 }
565 else
566 return XHASH (bt);
567}
568
518void 569void
519syms_of_profiler (void) 570syms_of_profiler (void)
520{ 571{
@@ -527,6 +578,16 @@ If the log gets full, some of the least-seen call-stacks will be evicted
527to make room for new entries. */); 578to make room for new entries. */);
528 profiler_log_size = 10000; 579 profiler_log_size = 10000;
529 580
581 DEFSYM (Qprofiler_backtrace_equal, "profiler-backtrace-equal");
582 {
583 struct hash_table_test test
584 = { Qprofiler_backtrace_equal, Qnil, Qnil,
585 cmpfn_profiler, hashfn_profiler };
586 hashtest_profiler = test;
587 }
588
589 defsubr (&Sfunction_equal);
590
530#ifdef PROFILER_CPU_SUPPORT 591#ifdef PROFILER_CPU_SUPPORT
531 profiler_cpu_running = NOT_RUNNING; 592 profiler_cpu_running = NOT_RUNNING;
532 cpu_log = Qnil; 593 cpu_log = Qnil;
diff --git a/src/ralloc.c b/src/ralloc.c
index 11897411930..e5bf76b0e6d 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -327,6 +327,8 @@ relinquish (void)
327 327
328 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess) 328 if ((char *)last_heap->end - (char *)last_heap->bloc_start <= excess)
329 { 329 {
330 heap_ptr lh_prev;
331
330 /* This heap should have no blocs in it. If it does, we 332 /* This heap should have no blocs in it. If it does, we
331 cannot return it to the system. */ 333 cannot return it to the system. */
332 if (last_heap->first_bloc != NIL_BLOC 334 if (last_heap->first_bloc != NIL_BLOC
@@ -335,28 +337,26 @@ relinquish (void)
335 337
336 /* Return the last heap, with its header, to the system. */ 338 /* Return the last heap, with its header, to the system. */
337 excess = (char *)last_heap->end - (char *)last_heap->start; 339 excess = (char *)last_heap->end - (char *)last_heap->start;
338 last_heap = last_heap->prev; 340 lh_prev = last_heap->prev;
339 last_heap->next = NIL_HEAP; 341 /* If the system doesn't want that much memory back, leave
342 last_heap unaltered to reflect that. This can occur if
343 break_value is still within the original data segment. */
344 if ((*real_morecore) (- excess) != 0)
345 {
346 last_heap = lh_prev;
347 last_heap->next = NIL_HEAP;
348 }
340 } 349 }
341 else 350 else
342 { 351 {
343 excess = (char *) last_heap->end 352 excess = (char *) last_heap->end
344 - (char *) ROUNDUP ((char *)last_heap->end - excess); 353 - (char *) ROUNDUP ((char *)last_heap->end - excess);
345 last_heap->end = (char *) last_heap->end - excess; 354 /* If the system doesn't want that much memory back, leave
346 } 355 the end of the last heap unchanged to reflect that. This
347 356 can occur if break_value is still within the original
348 if ((*real_morecore) (- excess) == 0) 357 data segment. */
349 { 358 if ((*real_morecore) (- excess) != 0)
350 /* If the system didn't want that much memory back, adjust 359 last_heap->end = (char *) last_heap->end - excess;
351 the end of the last heap to reflect that. This can occur
352 if break_value is still within the original data segment. */
353 last_heap->end = (char *) last_heap->end + excess;
354 /* Make sure that the result of the adjustment is accurate.
355 It should be, for the else clause above; the other case,
356 which returns the entire last heap to the system, seems
357 unlikely to trigger this mode of failure. */
358 if (last_heap->end != (*real_morecore) (0))
359 emacs_abort ();
360 } 360 }
361 } 361 }
362} 362}
diff --git a/src/regex.c b/src/regex.c
index 7443eff3977..1473551e6cc 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -28,7 +28,7 @@
28 rather than at run-time, so that re_match can be reentrant. 28 rather than at run-time, so that re_match can be reentrant.
29*/ 29*/
30 30
31/* AIX requires this to be the first thing in the file. */ 31/* AIX requires this to be the first thing in the file. */
32#if defined _AIX && !defined REGEX_MALLOC 32#if defined _AIX && !defined REGEX_MALLOC
33 #pragma alloca 33 #pragma alloca
34#endif 34#endif
diff --git a/src/termhooks.h b/src/termhooks.h
index 256ba26e435..d4b472cfb24 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -417,14 +417,6 @@ struct terminal
417 int memory_below_frame; /* Terminal remembers lines scrolled 417 int memory_below_frame; /* Terminal remembers lines scrolled
418 off bottom */ 418 off bottom */
419 419
420#if 0 /* These are not used anywhere. */
421 /* EMACS_INT baud_rate; */ /* Output speed in baud */
422 int min_padding_speed; /* Speed below which no padding necessary. */
423 int dont_calculate_costs; /* Nonzero means don't bother computing
424 various cost tables; we won't use them. */
425#endif
426
427
428 /* Window-based redisplay interface for this device (0 for tty 420 /* Window-based redisplay interface for this device (0 for tty
429 devices). */ 421 devices). */
430 struct redisplay_interface *rif; 422 struct redisplay_interface *rif;
@@ -472,10 +464,7 @@ struct terminal
472 Otherwise, set *bar_window to Qnil, and *x and *y to the column and 464 Otherwise, set *bar_window to Qnil, and *x and *y to the column and
473 row of the character cell the mouse is over. 465 row of the character cell the mouse is over.
474 466
475 Set *time to the time the mouse was at the returned position. 467 Set *time to the time the mouse was at the returned position. */
476
477 This should clear mouse_moved until the next motion
478 event arrives. */
479 void (*mouse_position_hook) (struct frame **f, int, 468 void (*mouse_position_hook) (struct frame **f, int,
480 Lisp_Object *bar_window, 469 Lisp_Object *bar_window,
481 enum scroll_bar_part *part, 470 enum scroll_bar_part *part,
@@ -483,11 +472,6 @@ struct terminal
483 Lisp_Object *y, 472 Lisp_Object *y,
484 Time *); 473 Time *);
485 474
486 /* The window system handling code should set this if the mouse has
487 moved since the last call to the mouse_position_hook. Calling that
488 hook should clear this. */
489 int mouse_moved;
490
491 /* When a frame's focus redirection is changed, this hook tells the 475 /* When a frame's focus redirection is changed, this hook tells the
492 window system code to re-decide where to put the highlight. Under 476 window system code to re-decide where to put the highlight. Under
493 X, this means that Emacs lies about where the focus is. */ 477 X, this means that Emacs lies about where the focus is. */
diff --git a/src/w32fns.c b/src/w32fns.c
index f4f5aad90b4..ed5625e802c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -304,19 +304,14 @@ check_x_display_info (Lisp_Object frame)
304/* Return the Emacs frame-object corresponding to an w32 window. 304/* Return the Emacs frame-object corresponding to an w32 window.
305 It could be the frame's main window or an icon window. */ 305 It could be the frame's main window or an icon window. */
306 306
307/* This function can be called during GC, so use GC_xxx type test macros. */
308
309struct frame * 307struct frame *
310x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc) 308x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
311{ 309{
312 Lisp_Object tail, frame; 310 Lisp_Object tail, frame;
313 struct frame *f; 311 struct frame *f;
314 312
315 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 313 FOR_EACH_FRAME (tail, frame)
316 { 314 {
317 frame = XCAR (tail);
318 if (!FRAMEP (frame))
319 continue;
320 f = XFRAME (frame); 315 f = XFRAME (frame);
321 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo) 316 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
322 continue; 317 continue;
@@ -2085,6 +2080,12 @@ sync_modifiers (void)
2085static int 2080static int
2086modifier_set (int vkey) 2081modifier_set (int vkey)
2087{ 2082{
2083 /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
2084 toggle keys is not an omission! If you want to add it, you will
2085 have to make changes in the default sub-case of the WM_KEYDOWN
2086 switch, because if the NUMLOCK modifier is set, the code there
2087 will directly convert any key that looks like an ASCII letter,
2088 and also downcase those that look like upper-case ASCII. */
2088 if (vkey == VK_CAPITAL) 2089 if (vkey == VK_CAPITAL)
2089 { 2090 {
2090 if (NILP (Vw32_enable_caps_lock)) 2091 if (NILP (Vw32_enable_caps_lock))
@@ -2094,7 +2095,15 @@ modifier_set (int vkey)
2094 } 2095 }
2095 if (vkey == VK_SCROLL) 2096 if (vkey == VK_SCROLL)
2096 { 2097 {
2097 if (NILP (Vw32_scroll_lock_modifier)) 2098 if (NILP (Vw32_scroll_lock_modifier)
2099 /* w32-scroll-lock-modifier can be any non-nil value that is
2100 not one of the modifiers, in which case it shall be ignored. */
2101 || !( EQ (Vw32_scroll_lock_modifier, Qhyper)
2102 || EQ (Vw32_scroll_lock_modifier, Qsuper)
2103 || EQ (Vw32_scroll_lock_modifier, Qmeta)
2104 || EQ (Vw32_scroll_lock_modifier, Qalt)
2105 || EQ (Vw32_scroll_lock_modifier, Qcontrol)
2106 || EQ (Vw32_scroll_lock_modifier, Qshift)))
2098 return 0; 2107 return 0;
2099 else 2108 else
2100 return (GetKeyState (vkey) & 0x1); 2109 return (GetKeyState (vkey) & 0x1);
diff --git a/src/w32term.c b/src/w32term.c
index 4cc0b860947..032912c27f4 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3437,16 +3437,11 @@ w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
3437static struct scroll_bar * 3437static struct scroll_bar *
3438x_window_to_scroll_bar (Window window_id) 3438x_window_to_scroll_bar (Window window_id)
3439{ 3439{
3440 Lisp_Object tail; 3440 Lisp_Object tail, frame;
3441 3441
3442 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 3442 FOR_EACH_FRAME (tail, frame)
3443 { 3443 {
3444 Lisp_Object frame, bar, condemned; 3444 Lisp_Object bar, condemned;
3445
3446 frame = XCAR (tail);
3447 /* All elements of Vframe_list should be frames. */
3448 if (! FRAMEP (frame))
3449 emacs_abort ();
3450 3445
3451 /* Scan this frame's scroll bar list for a scroll bar with the 3446 /* Scan this frame's scroll bar list for a scroll bar with the
3452 right window ID. */ 3447 right window ID. */
@@ -3626,7 +3621,7 @@ x_scroll_bar_create (struct window *w, int top, int left, int width, int height)
3626 HWND hwnd; 3621 HWND hwnd;
3627 SCROLLINFO si; 3622 SCROLLINFO si;
3628 struct scroll_bar *bar 3623 struct scroll_bar *bar
3629 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil)); 3624 = XSCROLL_BAR (Fmake_vector (make_number (VECSIZE (struct scroll_bar)), Qnil));
3630 Lisp_Object barobj; 3625 Lisp_Object barobj;
3631 3626
3632 block_input (); 3627 block_input ();
diff --git a/src/w32term.h b/src/w32term.h
index af5b37a1171..72fb8a76e35 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -415,9 +415,8 @@ extern struct w32_output w32term_display;
415 415
416struct scroll_bar { 416struct scroll_bar {
417 417
418 /* These fields are shared by all vectors. */ 418 /* This field is shared by all vectors. */
419 EMACS_INT size_from_Lisp_Vector_struct; 419 struct vectorlike_header header;
420 struct Lisp_Vector *next_from_Lisp_Vector_struct;
421 420
422 /* The window we're a scroll bar for. */ 421 /* The window we're a scroll bar for. */
423 Lisp_Object window; 422 Lisp_Object window;
@@ -460,12 +459,6 @@ struct scroll_bar {
460 Lisp_Object fringe_extended_p; 459 Lisp_Object fringe_extended_p;
461}; 460};
462 461
463/* The number of elements a vector holding a struct scroll_bar needs. */
464#define SCROLL_BAR_VEC_SIZE \
465 ((sizeof (struct scroll_bar) \
466 - sizeof (EMACS_INT) - sizeof (struct Lisp_Vector *)) \
467 / word_size)
468
469/* Turning a lisp vector value into a pointer to a struct scroll_bar. */ 462/* Turning a lisp vector value into a pointer to a struct scroll_bar. */
470#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec)) 463#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
471 464
diff --git a/src/window.c b/src/window.c
index 514119abef5..4c798ad4570 100644
--- a/src/window.c
+++ b/src/window.c
@@ -274,7 +274,7 @@ decode_valid_window (register Lisp_Object window)
274/* Build a frequently used 4-integer (X Y W H) list. */ 274/* Build a frequently used 4-integer (X Y W H) list. */
275 275
276static Lisp_Object 276static Lisp_Object
277quad (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h) 277list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
278{ 278{
279 return list4 (make_number (x), make_number (y), 279 return list4 (make_number (x), make_number (y),
280 make_number (w), make_number (h)); 280 make_number (w), make_number (h));
@@ -619,11 +619,13 @@ internal windows only. */)
619 619
620DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0, 620DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
621 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT. 621 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
622WINDOW must be a valid window and defaults to the selected one.
623If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's 622If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
624siblings. LIMIT t means that child windows of WINDOW are never 623siblings. LIMIT t means that child windows of WINDOW are never
625\(re-)combined with WINDOW's siblings. Other values are reserved for 624\(re-)combined with WINDOW's siblings. Other values are reserved for
626future use. */) 625future use.
626
627WINDOW must be a valid window. Setting the combination limit is
628meaningful for internal windows only. */)
627 (Lisp_Object window, Lisp_Object limit) 629 (Lisp_Object window, Lisp_Object limit)
628{ 630{
629 wset_combination_limit (decode_valid_window (window), limit); 631 wset_combination_limit (decode_valid_window (window), limit);
@@ -883,8 +885,8 @@ header line, and/or mode line. For the edges of just the text area, use
883{ 885{
884 register struct window *w = decode_valid_window (window); 886 register struct window *w = decode_valid_window (window);
885 887
886 return quad (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w), 888 return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
887 WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w)); 889 WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
888} 890}
889 891
890DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0, 892DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
@@ -903,8 +905,8 @@ of just the text area, use `window-inside-pixel-edges'. */)
903{ 905{
904 register struct window *w = decode_valid_window (window); 906 register struct window *w = decode_valid_window (window);
905 907
906 return quad (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w), 908 return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
907 WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w)); 909 WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
908} 910}
909 911
910static void 912static void
@@ -949,10 +951,10 @@ of just the text area, use `window-inside-absolute-pixel-edges'. */)
949 951
950 calc_absolute_offset (w, &add_x, &add_y); 952 calc_absolute_offset (w, &add_x, &add_y);
951 953
952 return quad (WINDOW_LEFT_EDGE_X (w) + add_x, 954 return list4i (WINDOW_LEFT_EDGE_X (w) + add_x,
953 WINDOW_TOP_EDGE_Y (w) + add_y, 955 WINDOW_TOP_EDGE_Y (w) + add_y,
954 WINDOW_RIGHT_EDGE_X (w) + add_x, 956 WINDOW_RIGHT_EDGE_X (w) + add_x,
955 WINDOW_BOTTOM_EDGE_Y (w) + add_y); 957 WINDOW_BOTTOM_EDGE_Y (w) + add_y);
956} 958}
957 959
958DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0, 960DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
@@ -971,16 +973,16 @@ display margins, fringes, header line, and/or mode line. */)
971{ 973{
972 register struct window *w = decode_live_window (window); 974 register struct window *w = decode_live_window (window);
973 975
974 return quad (WINDOW_BOX_LEFT_EDGE_COL (w) 976 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
975 + WINDOW_LEFT_MARGIN_COLS (w) 977 + WINDOW_LEFT_MARGIN_COLS (w)
976 + WINDOW_LEFT_FRINGE_COLS (w), 978 + WINDOW_LEFT_FRINGE_COLS (w)),
977 WINDOW_TOP_EDGE_LINE (w) 979 (WINDOW_TOP_EDGE_LINE (w)
978 + WINDOW_HEADER_LINE_LINES (w), 980 + WINDOW_HEADER_LINE_LINES (w)),
979 WINDOW_BOX_RIGHT_EDGE_COL (w) 981 (WINDOW_BOX_RIGHT_EDGE_COL (w)
980 - WINDOW_RIGHT_MARGIN_COLS (w) 982 - WINDOW_RIGHT_MARGIN_COLS (w)
981 - WINDOW_RIGHT_FRINGE_COLS (w), 983 - WINDOW_RIGHT_FRINGE_COLS (w)),
982 WINDOW_BOTTOM_EDGE_LINE (w) 984 (WINDOW_BOTTOM_EDGE_LINE (w)
983 - WINDOW_MODE_LINE_LINES (w)); 985 - WINDOW_MODE_LINE_LINES (w)));
984} 986}
985 987
986DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0, 988DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
@@ -998,16 +1000,16 @@ display margins, fringes, header line, and/or mode line. */)
998{ 1000{
999 register struct window *w = decode_live_window (window); 1001 register struct window *w = decode_live_window (window);
1000 1002
1001 return quad (WINDOW_BOX_LEFT_EDGE_X (w) 1003 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1002 + WINDOW_LEFT_MARGIN_WIDTH (w) 1004 + WINDOW_LEFT_MARGIN_WIDTH (w)
1003 + WINDOW_LEFT_FRINGE_WIDTH (w), 1005 + WINDOW_LEFT_FRINGE_WIDTH (w)),
1004 WINDOW_TOP_EDGE_Y (w) 1006 (WINDOW_TOP_EDGE_Y (w)
1005 + WINDOW_HEADER_LINE_HEIGHT (w), 1007 + WINDOW_HEADER_LINE_HEIGHT (w)),
1006 WINDOW_BOX_RIGHT_EDGE_X (w) 1008 (WINDOW_BOX_RIGHT_EDGE_X (w)
1007 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1009 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1008 - WINDOW_RIGHT_FRINGE_WIDTH (w), 1010 - WINDOW_RIGHT_FRINGE_WIDTH (w)),
1009 WINDOW_BOTTOM_EDGE_Y (w) 1011 (WINDOW_BOTTOM_EDGE_Y (w)
1010 - WINDOW_MODE_LINE_HEIGHT (w)); 1012 - WINDOW_MODE_LINE_HEIGHT (w)));
1011} 1013}
1012 1014
1013DEFUN ("window-inside-absolute-pixel-edges", 1015DEFUN ("window-inside-absolute-pixel-edges",
@@ -1030,16 +1032,16 @@ display margins, fringes, header line, and/or mode line. */)
1030 1032
1031 calc_absolute_offset (w, &add_x, &add_y); 1033 calc_absolute_offset (w, &add_x, &add_y);
1032 1034
1033 return quad (WINDOW_BOX_LEFT_EDGE_X (w) 1035 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
1034 + WINDOW_LEFT_MARGIN_WIDTH (w) 1036 + WINDOW_LEFT_MARGIN_WIDTH (w)
1035 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x, 1037 + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
1036 WINDOW_TOP_EDGE_Y (w) 1038 (WINDOW_TOP_EDGE_Y (w)
1037 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y, 1039 + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
1038 WINDOW_BOX_RIGHT_EDGE_X (w) 1040 (WINDOW_BOX_RIGHT_EDGE_X (w)
1039 - WINDOW_RIGHT_MARGIN_WIDTH (w) 1041 - WINDOW_RIGHT_MARGIN_WIDTH (w)
1040 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x, 1042 - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
1041 WINDOW_BOTTOM_EDGE_Y (w) 1043 (WINDOW_BOTTOM_EDGE_Y (w)
1042 - WINDOW_MODE_LINE_HEIGHT (w) + add_y); 1044 - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
1043} 1045}
1044 1046
1045/* Test if the character at column X, row Y is within window W. 1047/* Test if the character at column X, row Y is within window W.
@@ -1620,7 +1622,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1620 { 1622 {
1621 Lisp_Object part = Qnil; 1623 Lisp_Object part = Qnil;
1622 if (!fully_p) 1624 if (!fully_p)
1623 part = quad (rtop, rbot, rowh, vpos); 1625 part = list4i (rtop, rbot, rowh, vpos);
1624 in_window = Fcons (make_number (x), 1626 in_window = Fcons (make_number (x),
1625 Fcons (make_number (y), part)); 1627 Fcons (make_number (y), part));
1626 } 1628 }
@@ -1686,17 +1688,18 @@ Return nil if window display is not up-to-date. In that case, use
1686 if (!WINDOW_WANTS_HEADER_LINE_P (w)) 1688 if (!WINDOW_WANTS_HEADER_LINE_P (w))
1687 return Qnil; 1689 return Qnil;
1688 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 1690 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1689 return row->enabled_p ? quad (row->height, 0, 0, 0) : Qnil; 1691 return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
1690 } 1692 }
1691 1693
1692 if (EQ (line, Qmode_line)) 1694 if (EQ (line, Qmode_line))
1693 { 1695 {
1694 row = MATRIX_MODE_LINE_ROW (w->current_matrix); 1696 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1695 return (row->enabled_p ? 1697 return (row->enabled_p ?
1696 quad (row->height, 1698 list4i (row->height,
1697 0, /* not accurate */ 1699 0, /* not accurate */
1698 WINDOW_HEADER_LINE_HEIGHT (w) 1700 (WINDOW_HEADER_LINE_HEIGHT (w)
1699 + window_text_bottom_y (w), 0) 1701 + window_text_bottom_y (w)),
1702 0)
1700 : Qnil); 1703 : Qnil);
1701 } 1704 }
1702 1705
@@ -1726,7 +1729,7 @@ Return nil if window display is not up-to-date. In that case, use
1726 1729
1727 found_row: 1730 found_row:
1728 crop = max (0, (row->y + row->height) - max_y); 1731 crop = max (0, (row->y + row->height) - max_y);
1729 return quad (row->height + min (0, row->y) - crop, i, row->y, crop); 1732 return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
1730} 1733}
1731 1734
1732DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, 1735DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
@@ -2131,10 +2134,10 @@ window_list (void)
2131{ 2134{
2132 if (!CONSP (Vwindow_list)) 2135 if (!CONSP (Vwindow_list))
2133 { 2136 {
2134 Lisp_Object tail; 2137 Lisp_Object tail, frame;
2135 2138
2136 Vwindow_list = Qnil; 2139 Vwindow_list = Qnil;
2137 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 2140 FOR_EACH_FRAME (tail, frame)
2138 { 2141 {
2139 Lisp_Object args[2]; 2142 Lisp_Object args[2];
2140 2143
@@ -2142,7 +2145,7 @@ window_list (void)
2142 new windows at the front of args[1], which means we 2145 new windows at the front of args[1], which means we
2143 have to reverse this list at the end. */ 2146 have to reverse this list at the end. */
2144 args[1] = Qnil; 2147 args[1] = Qnil;
2145 foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]); 2148 foreach_window (XFRAME (frame), add_window_to_list, &args[1]);
2146 args[0] = Vwindow_list; 2149 args[0] = Vwindow_list;
2147 args[1] = Fnreverse (args[1]); 2150 args[1] = Fnreverse (args[1]);
2148 Vwindow_list = Fnconc (2, args); 2151 Vwindow_list = Fnconc (2, args);
@@ -3870,9 +3873,10 @@ set correctly. See the code of `split-window' for how this is done. */)
3870 3873
3871 make_parent_window (old, horflag); 3874 make_parent_window (old, horflag);
3872 p = XWINDOW (o->parent); 3875 p = XWINDOW (o->parent);
3873 /* Store t in the new parent's combination_limit slot to avoid 3876 if (EQ (Vwindow_combination_limit, Qt))
3874 that its children get merged into another window. */ 3877 /* Store t in the new parent's combination_limit slot to avoid
3875 wset_combination_limit (p, Qt); 3878 that its children get merged into another window. */
3879 wset_combination_limit (p, Qt);
3876 /* These get applied below. */ 3880 /* These get applied below. */
3877 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 3881 wset_new_total (p, horflag ? o->total_cols : o->total_lines);
3878 wset_new_normal (p, new_normal); 3882 wset_new_normal (p, new_normal);
diff --git a/src/xdisp.c b/src/xdisp.c
index a98572bde72..67491c681b7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11150,17 +11150,15 @@ x_consider_frame_title (Lisp_Object frame)
11150 || f->explicit_name) 11150 || f->explicit_name)
11151 { 11151 {
11152 /* Do we have more than one visible frame on this X display? */ 11152 /* Do we have more than one visible frame on this X display? */
11153 Lisp_Object tail; 11153 Lisp_Object tail, other_frame, fmt;
11154 Lisp_Object fmt;
11155 ptrdiff_t title_start; 11154 ptrdiff_t title_start;
11156 char *title; 11155 char *title;
11157 ptrdiff_t len; 11156 ptrdiff_t len;
11158 struct it it; 11157 struct it it;
11159 ptrdiff_t count = SPECPDL_INDEX (); 11158 ptrdiff_t count = SPECPDL_INDEX ();
11160 11159
11161 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 11160 FOR_EACH_FRAME (tail, other_frame)
11162 { 11161 {
11163 Lisp_Object other_frame = XCAR (tail);
11164 struct frame *tf = XFRAME (other_frame); 11162 struct frame *tf = XFRAME (other_frame);
11165 11163
11166 if (tf != f 11164 if (tf != f
@@ -14847,13 +14845,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14847 if (NUMBERP (aggressive)) 14845 if (NUMBERP (aggressive))
14848 { 14846 {
14849 double float_amount = XFLOATINT (aggressive) * height; 14847 double float_amount = XFLOATINT (aggressive) * height;
14850 amount_to_scroll = float_amount; 14848 int aggressive_scroll = float_amount;
14851 if (amount_to_scroll == 0 && float_amount > 0) 14849 if (aggressive_scroll == 0 && float_amount > 0)
14852 amount_to_scroll = 1; 14850 aggressive_scroll = 1;
14853 /* Don't let point enter the scroll margin near top of 14851 /* Don't let point enter the scroll margin near top of
14854 the window. */ 14852 the window. This could happen if the value of
14855 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14853 scroll_up_aggressively is too large and there are
14856 amount_to_scroll = height - 2*this_scroll_margin + dy; 14854 non-zero margins, because scroll_up_aggressively
14855 means put point that fraction of window height
14856 _from_the_bottom_margin_. */
14857 if (aggressive_scroll + 2*this_scroll_margin > height)
14858 aggressive_scroll = height - 2*this_scroll_margin;
14859 amount_to_scroll = dy + aggressive_scroll;
14857 } 14860 }
14858 } 14861 }
14859 14862
@@ -14913,7 +14916,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14913 /* Compute the vertical distance from PT to the scroll 14916 /* Compute the vertical distance from PT to the scroll
14914 margin position. Move as far as scroll_max allows, or 14917 margin position. Move as far as scroll_max allows, or
14915 one screenful, or 10 screen lines, whichever is largest. 14918 one screenful, or 10 screen lines, whichever is largest.
14916 Give up if distance is greater than scroll_max. */ 14919 Give up if distance is greater than scroll_max or if we
14920 didn't reach the scroll margin position. */
14917 SET_TEXT_POS (pos, PT, PT_BYTE); 14921 SET_TEXT_POS (pos, PT, PT_BYTE);
14918 start_display (&it, w, pos); 14922 start_display (&it, w, pos);
14919 y0 = it.current_y; 14923 y0 = it.current_y;
@@ -14923,7 +14927,8 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14923 y_to_move, -1, 14927 y_to_move, -1,
14924 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 14928 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14925 dy = it.current_y - y0; 14929 dy = it.current_y - y0;
14926 if (dy > scroll_max) 14930 if (dy > scroll_max
14931 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
14927 return SCROLLING_FAILED; 14932 return SCROLLING_FAILED;
14928 14933
14929 /* Compute new window start. */ 14934 /* Compute new window start. */
@@ -14941,15 +14946,16 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
14941 if (NUMBERP (aggressive)) 14946 if (NUMBERP (aggressive))
14942 { 14947 {
14943 double float_amount = XFLOATINT (aggressive) * height; 14948 double float_amount = XFLOATINT (aggressive) * height;
14944 amount_to_scroll = float_amount; 14949 int aggressive_scroll = float_amount;
14945 if (amount_to_scroll == 0 && float_amount > 0) 14950 if (aggressive_scroll == 0 && float_amount > 0)
14946 amount_to_scroll = 1; 14951 aggressive_scroll = 1;
14947 amount_to_scroll -=
14948 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14949 /* Don't let point enter the scroll margin near 14952 /* Don't let point enter the scroll margin near
14950 bottom of the window. */ 14953 bottom of the window, if the value of
14951 if (amount_to_scroll > height - 2*this_scroll_margin + dy) 14954 scroll_down_aggressively happens to be too
14952 amount_to_scroll = height - 2*this_scroll_margin + dy; 14955 large. */
14956 if (aggressive_scroll + 2*this_scroll_margin > height)
14957 aggressive_scroll = height - 2*this_scroll_margin;
14958 amount_to_scroll = dy + aggressive_scroll;
14953 } 14959 }
14954 } 14960 }
14955 14961
@@ -29664,8 +29670,10 @@ start_hourglass (void)
29664 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0); 29670 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29665 29671
29666#ifdef HAVE_NTGUI 29672#ifdef HAVE_NTGUI
29667 extern void w32_note_current_window (void); 29673 {
29668 w32_note_current_window (); 29674 extern void w32_note_current_window (void);
29675 w32_note_current_window ();
29676 }
29669#endif /* HAVE_NTGUI */ 29677#endif /* HAVE_NTGUI */
29670 29678
29671 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, 29679 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
diff --git a/src/xfaces.c b/src/xfaces.c
index 41c618612ac..daf329791c1 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -314,16 +314,10 @@ static Lisp_Object QCfontset;
314Lisp_Object Qnormal; 314Lisp_Object Qnormal;
315Lisp_Object Qbold; 315Lisp_Object Qbold;
316static Lisp_Object Qline, Qwave; 316static Lisp_Object Qline, Qwave;
317static Lisp_Object Qultra_light, Qreverse_oblique, Qreverse_italic;
318Lisp_Object Qextra_light, Qlight; 317Lisp_Object Qextra_light, Qlight;
319Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; 318Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold;
320Lisp_Object Qoblique; 319Lisp_Object Qoblique;
321Lisp_Object Qitalic; 320Lisp_Object Qitalic;
322static Lisp_Object Qultra_condensed, Qextra_condensed;
323Lisp_Object Qcondensed;
324static Lisp_Object Qsemi_condensed, Qsemi_expanded, Qextra_expanded;
325Lisp_Object Qexpanded;
326static Lisp_Object Qultra_expanded;
327static Lisp_Object Qreleased_button, Qpressed_button; 321static Lisp_Object Qreleased_button, Qpressed_button;
328static Lisp_Object QCstyle, QCcolor, QCline_width; 322static Lisp_Object QCstyle, QCcolor, QCline_width;
329Lisp_Object Qunspecified; /* used in dosfns.c */ 323Lisp_Object Qunspecified; /* used in dosfns.c */
@@ -5018,17 +5012,14 @@ face for italic. */)
5018 else 5012 else
5019 { 5013 {
5020 /* Find any frame on DISPLAY. */ 5014 /* Find any frame on DISPLAY. */
5021 Lisp_Object fl_tail; 5015 Lisp_Object tail;
5022 5016
5023 frame = Qnil; 5017 frame = Qnil;
5024 for (fl_tail = Vframe_list; CONSP (fl_tail); fl_tail = XCDR (fl_tail)) 5018 FOR_EACH_FRAME (tail, frame)
5025 { 5019 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay,
5026 frame = XCAR (fl_tail); 5020 XFRAME (frame)->param_alist)),
5027 if (!NILP (Fequal (Fcdr (Fassq (Qdisplay, 5021 display)))
5028 XFRAME (frame)->param_alist)), 5022 break;
5029 display)))
5030 break;
5031 }
5032 } 5023 }
5033 5024
5034 CHECK_LIVE_FRAME (frame); 5025 CHECK_LIVE_FRAME (frame);
@@ -6451,7 +6442,6 @@ syms_of_xfaces (void)
6451 DEFSYM (Qreleased_button, "released-button"); 6442 DEFSYM (Qreleased_button, "released-button");
6452 DEFSYM (Qpressed_button, "pressed-button"); 6443 DEFSYM (Qpressed_button, "pressed-button");
6453 DEFSYM (Qnormal, "normal"); 6444 DEFSYM (Qnormal, "normal");
6454 DEFSYM (Qultra_light, "ultra-light");
6455 DEFSYM (Qextra_light, "extra-light"); 6445 DEFSYM (Qextra_light, "extra-light");
6456 DEFSYM (Qlight, "light"); 6446 DEFSYM (Qlight, "light");
6457 DEFSYM (Qsemi_light, "semi-light"); 6447 DEFSYM (Qsemi_light, "semi-light");
@@ -6461,16 +6451,6 @@ syms_of_xfaces (void)
6461 DEFSYM (Qultra_bold, "ultra-bold"); 6451 DEFSYM (Qultra_bold, "ultra-bold");
6462 DEFSYM (Qoblique, "oblique"); 6452 DEFSYM (Qoblique, "oblique");
6463 DEFSYM (Qitalic, "italic"); 6453 DEFSYM (Qitalic, "italic");
6464 DEFSYM (Qreverse_oblique, "reverse-oblique");
6465 DEFSYM (Qreverse_italic, "reverse-italic");
6466 DEFSYM (Qultra_condensed, "ultra-condensed");
6467 DEFSYM (Qextra_condensed, "extra-condensed");
6468 DEFSYM (Qcondensed, "condensed");
6469 DEFSYM (Qsemi_condensed, "semi-condensed");
6470 DEFSYM (Qsemi_expanded, "semi-expanded");
6471 DEFSYM (Qexpanded, "expanded");
6472 DEFSYM (Qextra_expanded, "extra-expanded");
6473 DEFSYM (Qultra_expanded, "ultra-expanded");
6474 DEFSYM (Qbackground_color, "background-color"); 6454 DEFSYM (Qbackground_color, "background-color");
6475 DEFSYM (Qforeground_color, "foreground-color"); 6455 DEFSYM (Qforeground_color, "foreground-color");
6476 DEFSYM (Qunspecified, "unspecified"); 6456 DEFSYM (Qunspecified, "unspecified");
diff --git a/src/xfns.c b/src/xfns.c
index 82e218479c8..1f98e9fc8c7 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -224,13 +224,11 @@ x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
224 Lisp_Object tail, frame; 224 Lisp_Object tail, frame;
225 struct frame *f; 225 struct frame *f;
226 226
227 if (wdesc == None) return 0; 227 if (wdesc == None)
228 return NULL;
228 229
229 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 230 FOR_EACH_FRAME (tail, frame)
230 { 231 {
231 frame = XCAR (tail);
232 if (!FRAMEP (frame))
233 continue;
234 f = XFRAME (frame); 232 f = XFRAME (frame);
235 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 233 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
236 continue; 234 continue;
@@ -270,18 +268,16 @@ struct frame *
270x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc) 268x_any_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
271{ 269{
272 Lisp_Object tail, frame; 270 Lisp_Object tail, frame;
273 struct frame *f, *found; 271 struct frame *f, *found = NULL;
274 struct x_output *x; 272 struct x_output *x;
275 273
276 if (wdesc == None) return NULL; 274 if (wdesc == None)
275 return NULL;
277 276
278 found = NULL; 277 FOR_EACH_FRAME (tail, frame)
279 for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail))
280 { 278 {
281 frame = XCAR (tail); 279 if (found)
282 if (!FRAMEP (frame)) 280 break;
283 continue;
284
285 f = XFRAME (frame); 281 f = XFRAME (frame);
286 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo) 282 if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
287 { 283 {
@@ -325,13 +321,11 @@ x_menubar_window_to_frame (struct x_display_info *dpyinfo, XEvent *event)
325 struct frame *f; 321 struct frame *f;
326 struct x_output *x; 322 struct x_output *x;
327 323
328 if (wdesc == None) return 0; 324 if (wdesc == None)
325 return NULL;
329 326
330 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 327 FOR_EACH_FRAME (tail, frame)
331 { 328 {
332 frame = XCAR (tail);
333 if (!FRAMEP (frame))
334 continue;
335 f = XFRAME (frame); 329 f = XFRAME (frame);
336 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 330 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
337 continue; 331 continue;
@@ -359,13 +353,11 @@ x_top_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
359 struct frame *f; 353 struct frame *f;
360 struct x_output *x; 354 struct x_output *x;
361 355
362 if (wdesc == None) return 0; 356 if (wdesc == None)
357 return NULL;
363 358
364 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 359 FOR_EACH_FRAME (tail, frame)
365 { 360 {
366 frame = XCAR (tail);
367 if (!FRAMEP (frame))
368 continue;
369 f = XFRAME (frame); 361 f = XFRAME (frame);
370 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) 362 if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
371 continue; 363 continue;
diff --git a/src/xmenu.c b/src/xmenu.c
index 01d932cf8d8..b585df2125b 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -132,11 +132,8 @@ menubar_id_to_frame (LWLIB_ID id)
132 Lisp_Object tail, frame; 132 Lisp_Object tail, frame;
133 FRAME_PTR f; 133 FRAME_PTR f;
134 134
135 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 135 FOR_EACH_FRAME (tail, frame)
136 { 136 {
137 frame = XCAR (tail);
138 if (!FRAMEP (frame))
139 continue;
140 f = XFRAME (frame); 137 f = XFRAME (frame);
141 if (!FRAME_WINDOW_P (f)) 138 if (!FRAME_WINDOW_P (f))
142 continue; 139 continue;
diff --git a/src/xselect.c b/src/xselect.c
index de9386bd7d9..64c64fa0c76 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -1940,7 +1940,7 @@ x_handle_selection_notify (XSelectionEvent *event)
1940static struct frame * 1940static struct frame *
1941frame_for_x_selection (Lisp_Object object) 1941frame_for_x_selection (Lisp_Object object)
1942{ 1942{
1943 Lisp_Object tail; 1943 Lisp_Object tail, frame;
1944 struct frame *f; 1944 struct frame *f;
1945 1945
1946 if (NILP (object)) 1946 if (NILP (object))
@@ -1949,9 +1949,9 @@ frame_for_x_selection (Lisp_Object object)
1949 if (FRAME_X_P (f) && FRAME_LIVE_P (f)) 1949 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1950 return f; 1950 return f;
1951 1951
1952 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1952 FOR_EACH_FRAME (tail, frame)
1953 { 1953 {
1954 f = XFRAME (XCAR (tail)); 1954 f = XFRAME (frame);
1955 if (FRAME_X_P (f) && FRAME_LIVE_P (f)) 1955 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
1956 return f; 1956 return f;
1957 } 1957 }
@@ -1959,15 +1959,14 @@ frame_for_x_selection (Lisp_Object object)
1959 else if (TERMINALP (object)) 1959 else if (TERMINALP (object))
1960 { 1960 {
1961 struct terminal *t = get_terminal (object, 1); 1961 struct terminal *t = get_terminal (object, 1);
1962
1962 if (t->type == output_x_window) 1963 if (t->type == output_x_window)
1963 { 1964 FOR_EACH_FRAME (tail, frame)
1964 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1965 {
1965 { 1966 f = XFRAME (frame);
1966 f = XFRAME (XCAR (tail)); 1967 if (FRAME_LIVE_P (f) && f->terminal == t)
1967 if (FRAME_LIVE_P (f) && f->terminal == t) 1968 return f;
1968 return f; 1969 }
1969 }
1970 }
1971 } 1970 }
1972 else if (FRAMEP (object)) 1971 else if (FRAMEP (object))
1973 { 1972 {
diff --git a/src/xterm.c b/src/xterm.c
index a36b008c105..ef0b2267dcd 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1441,7 +1441,7 @@ static struct frame *
1441x_frame_of_widget (Widget widget) 1441x_frame_of_widget (Widget widget)
1442{ 1442{
1443 struct x_display_info *dpyinfo; 1443 struct x_display_info *dpyinfo;
1444 Lisp_Object tail; 1444 Lisp_Object tail, frame;
1445 struct frame *f; 1445 struct frame *f;
1446 1446
1447 dpyinfo = x_display_info_for_display (XtDisplay (widget)); 1447 dpyinfo = x_display_info_for_display (XtDisplay (widget));
@@ -1455,15 +1455,15 @@ x_frame_of_widget (Widget widget)
1455 1455
1456 /* Look for a frame with that top-level widget. Allocate the color 1456 /* Look for a frame with that top-level widget. Allocate the color
1457 on that frame to get the right gamma correction value. */ 1457 on that frame to get the right gamma correction value. */
1458 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 1458 FOR_EACH_FRAME (tail, frame)
1459 if (FRAMEP (XCAR (tail)) 1459 {
1460 && (f = XFRAME (XCAR (tail)), 1460 f = XFRAME (frame);
1461 (FRAME_X_P (f) 1461 if (FRAME_X_P (f)
1462 && f->output_data.nothing != 1 1462 && f->output_data.nothing != 1
1463 && FRAME_X_DISPLAY_INFO (f) == dpyinfo)) 1463 && FRAME_X_DISPLAY_INFO (f) == dpyinfo
1464 && f->output_data.x->widget == widget) 1464 && f->output_data.x->widget == widget)
1465 return f; 1465 return f;
1466 1466 }
1467 emacs_abort (); 1467 emacs_abort ();
1468} 1468}
1469 1469
@@ -4107,20 +4107,15 @@ XTmouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
4107static struct scroll_bar * 4107static struct scroll_bar *
4108x_window_to_scroll_bar (Display *display, Window window_id) 4108x_window_to_scroll_bar (Display *display, Window window_id)
4109{ 4109{
4110 Lisp_Object tail; 4110 Lisp_Object tail, frame;
4111 4111
4112#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS) 4112#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
4113 window_id = (Window) xg_get_scroll_id_for_window (display, window_id); 4113 window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
4114#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */ 4114#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */
4115 4115
4116 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 4116 FOR_EACH_FRAME (tail, frame)
4117 { 4117 {
4118 Lisp_Object frame, bar, condemned; 4118 Lisp_Object bar, condemned;
4119
4120 frame = XCAR (tail);
4121 /* All elements of Vframe_list should be frames. */
4122 if (! FRAMEP (frame))
4123 emacs_abort ();
4124 4119
4125 if (! FRAME_X_P (XFRAME (frame))) 4120 if (! FRAME_X_P (XFRAME (frame)))
4126 continue; 4121 continue;
@@ -4152,20 +4147,16 @@ x_window_to_scroll_bar (Display *display, Window window_id)
4152static Widget 4147static Widget
4153x_window_to_menu_bar (Window window) 4148x_window_to_menu_bar (Window window)
4154{ 4149{
4155 Lisp_Object tail; 4150 Lisp_Object tail, frame;
4156 4151
4157 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) 4152 FOR_EACH_FRAME (tail, frame)
4158 { 4153 if (FRAME_X_P (XFRAME (frame)))
4159 if (FRAME_X_P (XFRAME (XCAR (tail)))) 4154 {
4160 { 4155 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
4161 Lisp_Object frame = XCAR (tail);
4162 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
4163
4164 if (menu_bar && xlwmenu_window_p (menu_bar, window))
4165 return menu_bar;
4166 }
4167 }
4168 4156
4157 if (menu_bar && xlwmenu_window_p (menu_bar, window))
4158 return menu_bar;
4159 }
4169 return NULL; 4160 return NULL;
4170} 4161}
4171 4162
@@ -10886,10 +10877,10 @@ default is nil, which is the same as `super'. */);
10886 10877
10887 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table, 10878 DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
10888 doc: /* Hash table of character codes indexed by X keysym codes. */); 10879 doc: /* Hash table of character codes indexed by X keysym codes. */);
10889 Vx_keysym_table = make_hash_table (Qeql, make_number (900), 10880 Vx_keysym_table = make_hash_table (hashtest_eql, make_number (900),
10890 make_float (DEFAULT_REHASH_SIZE), 10881 make_float (DEFAULT_REHASH_SIZE),
10891 make_float (DEFAULT_REHASH_THRESHOLD), 10882 make_float (DEFAULT_REHASH_THRESHOLD),
10892 Qnil, Qnil, Qnil); 10883 Qnil);
10893} 10884}
10894 10885
10895#endif /* HAVE_X_WINDOWS */ 10886#endif /* HAVE_X_WINDOWS */
diff --git a/src/xterm.h b/src/xterm.h
index 4bc8f9813ed..6ef3d11fe48 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -890,10 +890,8 @@ struct scroll_bar
890 by this structure. */ 890 by this structure. */
891 891
892/* For an event of kind SELECTION_REQUEST_EVENT, 892/* For an event of kind SELECTION_REQUEST_EVENT,
893 this structure really describes the contents. 893 this structure really describes the contents. */
894 **Don't make this struct longer!** 894
895 If it overlaps the frame_or_window field of struct input_event,
896 that will cause GC to crash. */
897struct selection_input_event 895struct selection_input_event
898{ 896{
899 int kind; 897 int kind;