Mercurial > emacs
annotate src/alloc.c @ 2506:aba562e560f0
Adjust for autoconf merger.
* config.h.in: Add extra line to top, in case autoconf gets fixed
and decides not to add Makefile-style comments to the top of the
files it generates which we are forced to lop off.
Indicate that the boolean macros here get their definitions via
the DEFS Makefile variable.
Adjust the operating system and machine #includes to use
autoload's @cookies@.
(RETSIGTYPE): Give this a default value.
(SIGTYPE): Set this from RETSIGTYPE.
(LD_SWITCH_X_SITE, C_SWITCH_X_SITE): Get values via @cookies@.
* Makefile.in (DEFS): Renamed from CONFIG_CFLAGS.
(xmakefile): Pass CFLAGS to ${CPP}.
* Makefile.in (tagsfiles): Remove external-lisp from this list of
files; we're not distributing it, so the normal build process
shouldn't depend on it.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Sat, 10 Apr 1993 07:53:50 +0000 |
parents | b6c62e4abf59 |
children | 7ba4316ae840 |
rev | line source |
---|---|
300 | 1 /* Storage allocation and gc for GNU Emacs Lisp interpreter. |
1784
11f62e53acff
Make scrollbar structures into lisp objects, so that they can be
Jim Blandy <jimb@redhat.com>
parents:
1562
diff
changeset
|
2 Copyright (C) 1985, 1986, 1988, 1992, 1993 Free Software Foundation, Inc. |
300 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
1784
11f62e53acff
Make scrollbar structures into lisp objects, so that they can be
Jim Blandy <jimb@redhat.com>
parents:
1562
diff
changeset
|
8 the Free Software Foundation; either version 2, or (at your option) |
300 | 9 any later version. |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 #include "config.h" | |
22 #include "lisp.h" | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
23 #include "intervals.h" |
356 | 24 #include "puresize.h" |
300 | 25 #ifndef standalone |
26 #include "buffer.h" | |
27 #include "window.h" | |
764 | 28 #include "frame.h" |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
29 #include "blockinput.h" |
300 | 30 #endif |
31 | |
638 | 32 #include "syssignal.h" |
33 | |
300 | 34 #define max(A,B) ((A) > (B) ? (A) : (B)) |
35 | |
36 /* Macro to verify that storage intended for Lisp objects is not | |
37 out of range to fit in the space for a pointer. | |
38 ADDRESS is the start of the block, and SIZE | |
39 is the amount of space within which objects can start. */ | |
40 #define VALIDATE_LISP_STORAGE(address, size) \ | |
41 do \ | |
42 { \ | |
43 Lisp_Object val; \ | |
44 XSET (val, Lisp_Cons, (char *) address + size); \ | |
45 if ((char *) XCONS (val) != (char *) address + size) \ | |
46 { \ | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
47 xfree (address); \ |
300 | 48 memory_full (); \ |
49 } \ | |
50 } while (0) | |
51 | |
52 /* Number of bytes of consing done since the last gc */ | |
53 int consing_since_gc; | |
54 | |
55 /* Number of bytes of consing since gc before another gc should be done. */ | |
56 int gc_cons_threshold; | |
57 | |
58 /* Nonzero during gc */ | |
59 int gc_in_progress; | |
60 | |
61 #ifndef VIRT_ADDR_VARIES | |
62 extern | |
63 #endif /* VIRT_ADDR_VARIES */ | |
64 int malloc_sbrk_used; | |
65 | |
66 #ifndef VIRT_ADDR_VARIES | |
67 extern | |
68 #endif /* VIRT_ADDR_VARIES */ | |
69 int malloc_sbrk_unused; | |
70 | |
764 | 71 /* Two limits controlling how much undo information to keep. */ |
72 int undo_limit; | |
73 int undo_strong_limit; | |
300 | 74 |
75 /* Non-nil means defun should do purecopy on the function definition */ | |
76 Lisp_Object Vpurify_flag; | |
77 | |
78 #ifndef HAVE_SHM | |
79 int pure[PURESIZE / sizeof (int)] = {0,}; /* Force it into data space! */ | |
80 #define PUREBEG (char *) pure | |
81 #else | |
82 #define pure PURE_SEG_BITS /* Use shared memory segment */ | |
83 #define PUREBEG (char *)PURE_SEG_BITS | |
356 | 84 |
85 /* This variable is used only by the XPNTR macro when HAVE_SHM is | |
86 defined. If we used the PURESIZE macro directly there, that would | |
87 make most of emacs dependent on puresize.h, which we don't want - | |
88 you should be able to change that without too much recompilation. | |
89 So map_in_data initializes pure_size, and the dependencies work | |
90 out. */ | |
91 int pure_size; | |
300 | 92 #endif /* not HAVE_SHM */ |
93 | |
94 /* Index in pure at which next pure object will be allocated. */ | |
95 int pureptr; | |
96 | |
97 /* If nonzero, this is a warning delivered by malloc and not yet displayed. */ | |
98 char *pending_malloc_warning; | |
99 | |
100 /* Maximum amount of C stack to save when a GC happens. */ | |
101 | |
102 #ifndef MAX_SAVE_STACK | |
103 #define MAX_SAVE_STACK 16000 | |
104 #endif | |
105 | |
106 /* Buffer in which we save a copy of the C stack at each GC. */ | |
107 | |
108 char *stack_copy; | |
109 int stack_copy_size; | |
110 | |
111 /* Non-zero means ignore malloc warnings. Set during initialization. */ | |
112 int ignore_warnings; | |
1318 | 113 |
114 static void mark_object (), mark_buffer (); | |
115 static void clear_marks (), gc_sweep (); | |
116 static void compact_strings (); | |
300 | 117 |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
118 /* Versions of malloc and realloc that print warnings as memory gets full. */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
119 |
300 | 120 Lisp_Object |
121 malloc_warning_1 (str) | |
122 Lisp_Object str; | |
123 { | |
124 Fprinc (str, Vstandard_output); | |
125 write_string ("\nKilling some buffers may delay running out of memory.\n", -1); | |
126 write_string ("However, certainly by the time you receive the 95% warning,\n", -1); | |
127 write_string ("you should clean up, kill this Emacs, and start a new one.", -1); | |
128 return Qnil; | |
129 } | |
130 | |
131 /* malloc calls this if it finds we are near exhausting storage */ | |
132 malloc_warning (str) | |
133 char *str; | |
134 { | |
135 pending_malloc_warning = str; | |
136 } | |
137 | |
138 display_malloc_warning () | |
139 { | |
140 register Lisp_Object val; | |
141 | |
142 val = build_string (pending_malloc_warning); | |
143 pending_malloc_warning = 0; | |
144 internal_with_output_to_temp_buffer (" *Danger*", malloc_warning_1, val); | |
145 } | |
146 | |
147 /* Called if malloc returns zero */ | |
148 memory_full () | |
149 { | |
150 error ("Memory exhausted"); | |
151 } | |
152 | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
153 /* like malloc routines but check for no memory and block interrupt input. */ |
300 | 154 |
155 long * | |
156 xmalloc (size) | |
157 int size; | |
158 { | |
159 register long *val; | |
160 | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
161 BLOCK_INPUT; |
300 | 162 val = (long *) malloc (size); |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
163 UNBLOCK_INPUT; |
300 | 164 |
165 if (!val && size) memory_full (); | |
166 return val; | |
167 } | |
168 | |
169 long * | |
170 xrealloc (block, size) | |
171 long *block; | |
172 int size; | |
173 { | |
174 register long *val; | |
175 | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
176 BLOCK_INPUT; |
590 | 177 /* We must call malloc explicitly when BLOCK is 0, since some |
178 reallocs don't do this. */ | |
179 if (! block) | |
180 val = (long *) malloc (size); | |
600
a8d78999e46d
*** empty log message ***
Noah Friedman <friedman@splode.com>
parents:
590
diff
changeset
|
181 else |
590 | 182 val = (long *) realloc (block, size); |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
183 UNBLOCK_INPUT; |
300 | 184 |
185 if (!val && size) memory_full (); | |
186 return val; | |
187 } | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
188 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
189 void |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
190 xfree (block) |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
191 long *block; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
192 { |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
193 BLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
194 free (block); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
195 UNBLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
196 } |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
197 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
198 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
199 /* Arranging to disable input signals while we're in malloc. |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
200 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
201 This only works with GNU malloc. To help out systems which can't |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
202 use GNU malloc, all the calls to malloc, realloc, and free |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
203 elsewhere in the code should be inside a BLOCK_INPUT/UNBLOCK_INPUT |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
204 pairs; unfortunately, we have no idea what C library functions |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
205 might call malloc, so we can't really protect them unless you're |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
206 using GNU malloc. Fortunately, most of the major operating can use |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
207 GNU malloc. */ |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
208 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
209 #ifndef SYSTEM_MALLOC |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
210 static void (*__malloc_hook) (), (*old_malloc_hook) (); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
211 static void (*__realloc_hook) (), (*old_realloc_hook) (); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
212 static void (*__free_hook) (), (*old_free_hook) (); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
213 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
214 static void |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
215 emacs_blocked_free (ptr) |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
216 void *ptr; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
217 { |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
218 BLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
219 __free_hook = old_free_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
220 free (ptr); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
221 __free_hook = &emacs_blocked_free; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
222 UNBLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
223 } |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
224 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
225 static void * |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
226 emacs_blocked_malloc (size) |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
227 unsigned size; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
228 { |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
229 void *value; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
230 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
231 BLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
232 __malloc_hook = old_malloc_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
233 value = malloc (size); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
234 __malloc_hook = &emacs_blocked_malloc; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
235 UNBLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
236 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
237 return value; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
238 } |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
239 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
240 static void * |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
241 emacs_blocked_realloc (ptr, size) |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
242 void *ptr; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
243 unsigned size; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
244 { |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
245 void *value; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
246 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
247 BLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
248 __realloc_hook = old_realloc_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
249 value = realloc (ptr, size); |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
250 __realloc_hook = &emacs_blocked_realloc; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
251 UNBLOCK_INPUT; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
252 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
253 return value; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
254 } |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
255 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
256 void |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
257 uninterrupt_malloc () |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
258 { |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
259 old_free_hook = __free_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
260 __free_hook = &emacs_blocked_free; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
261 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
262 old_malloc_hook = __malloc_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
263 __malloc_hook = &emacs_blocked_malloc; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
264 |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
265 old_realloc_hook = __realloc_hook; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
266 __realloc_hook = &emacs_blocked_realloc; |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
267 } |
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
268 #endif |
300 | 269 |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
270 /* Interval allocation. */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
271 |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
272 #ifdef USE_TEXT_PROPERTIES |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
273 #define INTERVAL_BLOCK_SIZE \ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
274 ((1020 - sizeof (struct interval_block *)) / sizeof (struct interval)) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
275 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
276 struct interval_block |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
277 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
278 struct interval_block *next; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
279 struct interval intervals[INTERVAL_BLOCK_SIZE]; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
280 }; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
281 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
282 struct interval_block *interval_block; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
283 static int interval_block_index; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
284 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
285 INTERVAL interval_free_list; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
286 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
287 static void |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
288 init_intervals () |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
289 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
290 interval_block |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
291 = (struct interval_block *) malloc (sizeof (struct interval_block)); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
292 interval_block->next = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
293 bzero (interval_block->intervals, sizeof interval_block->intervals); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
294 interval_block_index = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
295 interval_free_list = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
296 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
297 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
298 #define INIT_INTERVALS init_intervals () |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
299 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
300 INTERVAL |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
301 make_interval () |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
302 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
303 INTERVAL val; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
304 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
305 if (interval_free_list) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
306 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
307 val = interval_free_list; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
308 interval_free_list = interval_free_list->parent; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
309 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
310 else |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
311 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
312 if (interval_block_index == INTERVAL_BLOCK_SIZE) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
313 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
314 register struct interval_block *newi |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
315 = (struct interval_block *) xmalloc (sizeof (struct interval_block)); |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
316 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
317 VALIDATE_LISP_STORAGE (newi, sizeof *newi); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
318 newi->next = interval_block; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
319 interval_block = newi; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
320 interval_block_index = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
321 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
322 val = &interval_block->intervals[interval_block_index++]; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
323 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
324 consing_since_gc += sizeof (struct interval); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
325 RESET_INTERVAL (val); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
326 return val; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
327 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
328 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
329 static int total_free_intervals, total_intervals; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
330 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
331 /* Mark the pointers of one interval. */ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
332 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
333 static void |
1957
54c8c66cd9ac
(mark_interval): Add ignored arg.
Richard M. Stallman <rms@gnu.org>
parents:
1939
diff
changeset
|
334 mark_interval (i, dummy) |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
335 register INTERVAL i; |
1957
54c8c66cd9ac
(mark_interval): Add ignored arg.
Richard M. Stallman <rms@gnu.org>
parents:
1939
diff
changeset
|
336 Lisp_Object dummy; |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
337 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
338 if (XMARKBIT (i->plist)) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
339 abort (); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
340 mark_object (&i->plist); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
341 XMARK (i->plist); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
342 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
343 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
344 static void |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
345 mark_interval_tree (tree) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
346 register INTERVAL tree; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
347 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
348 if (XMARKBIT (tree->plist)) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
349 return; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
350 |
1957
54c8c66cd9ac
(mark_interval): Add ignored arg.
Richard M. Stallman <rms@gnu.org>
parents:
1939
diff
changeset
|
351 traverse_intervals (tree, 1, 0, mark_interval, Qnil); |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
352 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
353 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
354 #define MARK_INTERVAL_TREE(i) \ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
355 { if (!NULL_INTERVAL_P (i)) mark_interval_tree (i); } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
356 |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
357 /* The oddity in the call to XUNMARK is necessary because XUNMARK |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
358 expands to an assigment to its argument, and most C compilers don't |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
359 support casts on the left operand of `='. */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
360 #define UNMARK_BALANCE_INTERVALS(i) \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
361 { \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
362 if (! NULL_INTERVAL_P (i)) \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
363 { \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
364 XUNMARK (* (Lisp_Object *) (&(i)->parent)); \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
365 (i) = balance_intervals (i); \ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
366 } \ |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
367 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
368 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
369 #else /* no interval use */ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
370 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
371 #define INIT_INTERVALS |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
372 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
373 #define UNMARK_BALANCE_INTERVALS(i) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
374 #define MARK_INTERVAL_TREE(i) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
375 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
376 #endif /* no interval use */ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
377 |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
378 /* Floating point allocation. */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
379 |
300 | 380 #ifdef LISP_FLOAT_TYPE |
381 /* Allocation of float cells, just like conses */ | |
382 /* We store float cells inside of float_blocks, allocating a new | |
383 float_block with malloc whenever necessary. Float cells reclaimed by | |
384 GC are put on a free list to be reallocated before allocating | |
385 any new float cells from the latest float_block. | |
386 | |
387 Each float_block is just under 1020 bytes long, | |
388 since malloc really allocates in units of powers of two | |
389 and uses 4 bytes for its own overhead. */ | |
390 | |
391 #define FLOAT_BLOCK_SIZE \ | |
392 ((1020 - sizeof (struct float_block *)) / sizeof (struct Lisp_Float)) | |
393 | |
394 struct float_block | |
395 { | |
396 struct float_block *next; | |
397 struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; | |
398 }; | |
399 | |
400 struct float_block *float_block; | |
401 int float_block_index; | |
402 | |
403 struct Lisp_Float *float_free_list; | |
404 | |
405 void | |
406 init_float () | |
407 { | |
408 float_block = (struct float_block *) malloc (sizeof (struct float_block)); | |
409 float_block->next = 0; | |
410 bzero (float_block->floats, sizeof float_block->floats); | |
411 float_block_index = 0; | |
412 float_free_list = 0; | |
413 } | |
414 | |
415 /* Explicitly free a float cell. */ | |
416 free_float (ptr) | |
417 struct Lisp_Float *ptr; | |
418 { | |
419 XFASTINT (ptr->type) = (int) float_free_list; | |
420 float_free_list = ptr; | |
421 } | |
422 | |
423 Lisp_Object | |
424 make_float (float_value) | |
425 double float_value; | |
426 { | |
427 register Lisp_Object val; | |
428 | |
429 if (float_free_list) | |
430 { | |
431 XSET (val, Lisp_Float, float_free_list); | |
432 float_free_list = (struct Lisp_Float *) XFASTINT (float_free_list->type); | |
433 } | |
434 else | |
435 { | |
436 if (float_block_index == FLOAT_BLOCK_SIZE) | |
437 { | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
438 register struct float_block *new = (struct float_block *) xmalloc (sizeof (struct float_block)); |
300 | 439 VALIDATE_LISP_STORAGE (new, sizeof *new); |
440 new->next = float_block; | |
441 float_block = new; | |
442 float_block_index = 0; | |
443 } | |
444 XSET (val, Lisp_Float, &float_block->floats[float_block_index++]); | |
445 } | |
446 XFLOAT (val)->data = float_value; | |
447 XFLOAT (val)->type = 0; /* bug chasing -wsr */ | |
448 consing_since_gc += sizeof (struct Lisp_Float); | |
449 return val; | |
450 } | |
451 | |
452 #endif /* LISP_FLOAT_TYPE */ | |
453 | |
454 /* Allocation of cons cells */ | |
455 /* We store cons cells inside of cons_blocks, allocating a new | |
456 cons_block with malloc whenever necessary. Cons cells reclaimed by | |
457 GC are put on a free list to be reallocated before allocating | |
458 any new cons cells from the latest cons_block. | |
459 | |
460 Each cons_block is just under 1020 bytes long, | |
461 since malloc really allocates in units of powers of two | |
462 and uses 4 bytes for its own overhead. */ | |
463 | |
464 #define CONS_BLOCK_SIZE \ | |
465 ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons)) | |
466 | |
467 struct cons_block | |
468 { | |
469 struct cons_block *next; | |
470 struct Lisp_Cons conses[CONS_BLOCK_SIZE]; | |
471 }; | |
472 | |
473 struct cons_block *cons_block; | |
474 int cons_block_index; | |
475 | |
476 struct Lisp_Cons *cons_free_list; | |
477 | |
478 void | |
479 init_cons () | |
480 { | |
481 cons_block = (struct cons_block *) malloc (sizeof (struct cons_block)); | |
482 cons_block->next = 0; | |
483 bzero (cons_block->conses, sizeof cons_block->conses); | |
484 cons_block_index = 0; | |
485 cons_free_list = 0; | |
486 } | |
487 | |
488 /* Explicitly free a cons cell. */ | |
489 free_cons (ptr) | |
490 struct Lisp_Cons *ptr; | |
491 { | |
492 XFASTINT (ptr->car) = (int) cons_free_list; | |
493 cons_free_list = ptr; | |
494 } | |
495 | |
496 DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |
497 "Create a new cons, give it CAR and CDR as components, and return it.") | |
498 (car, cdr) | |
499 Lisp_Object car, cdr; | |
500 { | |
501 register Lisp_Object val; | |
502 | |
503 if (cons_free_list) | |
504 { | |
505 XSET (val, Lisp_Cons, cons_free_list); | |
506 cons_free_list = (struct Lisp_Cons *) XFASTINT (cons_free_list->car); | |
507 } | |
508 else | |
509 { | |
510 if (cons_block_index == CONS_BLOCK_SIZE) | |
511 { | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
512 register struct cons_block *new = (struct cons_block *) xmalloc (sizeof (struct cons_block)); |
300 | 513 VALIDATE_LISP_STORAGE (new, sizeof *new); |
514 new->next = cons_block; | |
515 cons_block = new; | |
516 cons_block_index = 0; | |
517 } | |
518 XSET (val, Lisp_Cons, &cons_block->conses[cons_block_index++]); | |
519 } | |
520 XCONS (val)->car = car; | |
521 XCONS (val)->cdr = cdr; | |
522 consing_since_gc += sizeof (struct Lisp_Cons); | |
523 return val; | |
524 } | |
525 | |
526 DEFUN ("list", Flist, Slist, 0, MANY, 0, | |
527 "Return a newly created list with specified arguments as elements.\n\ | |
528 Any number of arguments, even zero arguments, are allowed.") | |
529 (nargs, args) | |
530 int nargs; | |
531 register Lisp_Object *args; | |
532 { | |
533 register Lisp_Object len, val, val_tail; | |
534 | |
535 XFASTINT (len) = nargs; | |
536 val = Fmake_list (len, Qnil); | |
537 val_tail = val; | |
485 | 538 while (!NILP (val_tail)) |
300 | 539 { |
540 XCONS (val_tail)->car = *args++; | |
541 val_tail = XCONS (val_tail)->cdr; | |
542 } | |
543 return val; | |
544 } | |
545 | |
546 DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |
547 "Return a newly created list of length LENGTH, with each element being INIT.") | |
548 (length, init) | |
549 register Lisp_Object length, init; | |
550 { | |
551 register Lisp_Object val; | |
552 register int size; | |
553 | |
554 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
555 length = wrong_type_argument (Qnatnump, length); | |
556 size = XINT (length); | |
557 | |
558 val = Qnil; | |
559 while (size-- > 0) | |
560 val = Fcons (init, val); | |
561 return val; | |
562 } | |
563 | |
564 /* Allocation of vectors */ | |
565 | |
566 struct Lisp_Vector *all_vectors; | |
567 | |
568 DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, | |
569 "Return a newly created vector of length LENGTH, with each element being INIT.\n\ | |
570 See also the function `vector'.") | |
571 (length, init) | |
572 register Lisp_Object length, init; | |
573 { | |
574 register int sizei, index; | |
575 register Lisp_Object vector; | |
576 register struct Lisp_Vector *p; | |
577 | |
578 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
579 length = wrong_type_argument (Qnatnump, length); | |
580 sizei = XINT (length); | |
581 | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
582 p = (struct Lisp_Vector *) xmalloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)); |
300 | 583 VALIDATE_LISP_STORAGE (p, 0); |
584 | |
585 XSET (vector, Lisp_Vector, p); | |
586 consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object); | |
587 | |
588 p->size = sizei; | |
589 p->next = all_vectors; | |
590 all_vectors = p; | |
591 | |
592 for (index = 0; index < sizei; index++) | |
593 p->contents[index] = init; | |
594 | |
595 return vector; | |
596 } | |
597 | |
598 DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | |
599 "Return a newly created vector with specified arguments as elements.\n\ | |
600 Any number of arguments, even zero arguments, are allowed.") | |
601 (nargs, args) | |
602 register int nargs; | |
603 Lisp_Object *args; | |
604 { | |
605 register Lisp_Object len, val; | |
606 register int index; | |
607 register struct Lisp_Vector *p; | |
608 | |
609 XFASTINT (len) = nargs; | |
610 val = Fmake_vector (len, Qnil); | |
611 p = XVECTOR (val); | |
612 for (index = 0; index < nargs; index++) | |
613 p->contents[index] = args[index]; | |
614 return val; | |
615 } | |
616 | |
617 DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | |
618 "Create a byte-code object with specified arguments as elements.\n\ | |
619 The arguments should be the arglist, bytecode-string, constant vector,\n\ | |
620 stack size, (optional) doc string, and (optional) interactive spec.\n\ | |
621 The first four arguments are required; at most six have any\n\ | |
622 significance.") | |
623 (nargs, args) | |
624 register int nargs; | |
625 Lisp_Object *args; | |
626 { | |
627 register Lisp_Object len, val; | |
628 register int index; | |
629 register struct Lisp_Vector *p; | |
630 | |
631 XFASTINT (len) = nargs; | |
485 | 632 if (!NILP (Vpurify_flag)) |
300 | 633 val = make_pure_vector (len); |
634 else | |
635 val = Fmake_vector (len, Qnil); | |
636 p = XVECTOR (val); | |
637 for (index = 0; index < nargs; index++) | |
638 { | |
485 | 639 if (!NILP (Vpurify_flag)) |
300 | 640 args[index] = Fpurecopy (args[index]); |
641 p->contents[index] = args[index]; | |
642 } | |
643 XSETTYPE (val, Lisp_Compiled); | |
644 return val; | |
645 } | |
646 | |
647 /* Allocation of symbols. | |
648 Just like allocation of conses! | |
649 | |
650 Each symbol_block is just under 1020 bytes long, | |
651 since malloc really allocates in units of powers of two | |
652 and uses 4 bytes for its own overhead. */ | |
653 | |
654 #define SYMBOL_BLOCK_SIZE \ | |
655 ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) | |
656 | |
657 struct symbol_block | |
658 { | |
659 struct symbol_block *next; | |
660 struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; | |
661 }; | |
662 | |
663 struct symbol_block *symbol_block; | |
664 int symbol_block_index; | |
665 | |
666 struct Lisp_Symbol *symbol_free_list; | |
667 | |
668 void | |
669 init_symbol () | |
670 { | |
671 symbol_block = (struct symbol_block *) malloc (sizeof (struct symbol_block)); | |
672 symbol_block->next = 0; | |
673 bzero (symbol_block->symbols, sizeof symbol_block->symbols); | |
674 symbol_block_index = 0; | |
675 symbol_free_list = 0; | |
676 } | |
677 | |
678 DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | |
679 "Return a newly allocated uninterned symbol whose name is NAME.\n\ | |
680 Its value and function definition are void, and its property list is nil.") | |
681 (str) | |
682 Lisp_Object str; | |
683 { | |
684 register Lisp_Object val; | |
685 register struct Lisp_Symbol *p; | |
686 | |
687 CHECK_STRING (str, 0); | |
688 | |
689 if (symbol_free_list) | |
690 { | |
691 XSET (val, Lisp_Symbol, symbol_free_list); | |
692 symbol_free_list | |
693 = (struct Lisp_Symbol *) XFASTINT (symbol_free_list->value); | |
694 } | |
695 else | |
696 { | |
697 if (symbol_block_index == SYMBOL_BLOCK_SIZE) | |
698 { | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
699 struct symbol_block *new = (struct symbol_block *) xmalloc (sizeof (struct symbol_block)); |
300 | 700 VALIDATE_LISP_STORAGE (new, sizeof *new); |
701 new->next = symbol_block; | |
702 symbol_block = new; | |
703 symbol_block_index = 0; | |
704 } | |
705 XSET (val, Lisp_Symbol, &symbol_block->symbols[symbol_block_index++]); | |
706 } | |
707 p = XSYMBOL (val); | |
708 p->name = XSTRING (str); | |
709 p->plist = Qnil; | |
710 p->value = Qunbound; | |
711 p->function = Qunbound; | |
712 p->next = 0; | |
713 consing_since_gc += sizeof (struct Lisp_Symbol); | |
714 return val; | |
715 } | |
716 | |
717 /* Allocation of markers. | |
718 Works like allocation of conses. */ | |
719 | |
720 #define MARKER_BLOCK_SIZE \ | |
721 ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker)) | |
722 | |
723 struct marker_block | |
724 { | |
725 struct marker_block *next; | |
726 struct Lisp_Marker markers[MARKER_BLOCK_SIZE]; | |
727 }; | |
728 | |
729 struct marker_block *marker_block; | |
730 int marker_block_index; | |
731 | |
732 struct Lisp_Marker *marker_free_list; | |
733 | |
734 void | |
735 init_marker () | |
736 { | |
737 marker_block = (struct marker_block *) malloc (sizeof (struct marker_block)); | |
738 marker_block->next = 0; | |
739 bzero (marker_block->markers, sizeof marker_block->markers); | |
740 marker_block_index = 0; | |
741 marker_free_list = 0; | |
742 } | |
743 | |
744 DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |
745 "Return a newly allocated marker which does not point at any place.") | |
746 () | |
747 { | |
748 register Lisp_Object val; | |
749 register struct Lisp_Marker *p; | |
638 | 750 |
300 | 751 if (marker_free_list) |
752 { | |
753 XSET (val, Lisp_Marker, marker_free_list); | |
754 marker_free_list | |
755 = (struct Lisp_Marker *) XFASTINT (marker_free_list->chain); | |
756 } | |
757 else | |
758 { | |
759 if (marker_block_index == MARKER_BLOCK_SIZE) | |
760 { | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
761 struct marker_block *new = (struct marker_block *) xmalloc (sizeof (struct marker_block)); |
300 | 762 VALIDATE_LISP_STORAGE (new, sizeof *new); |
763 new->next = marker_block; | |
764 marker_block = new; | |
765 marker_block_index = 0; | |
766 } | |
767 XSET (val, Lisp_Marker, &marker_block->markers[marker_block_index++]); | |
768 } | |
769 p = XMARKER (val); | |
770 p->buffer = 0; | |
771 p->bufpos = 0; | |
772 p->chain = Qnil; | |
773 consing_since_gc += sizeof (struct Lisp_Marker); | |
774 return val; | |
775 } | |
776 | |
777 /* Allocation of strings */ | |
778 | |
779 /* Strings reside inside of string_blocks. The entire data of the string, | |
780 both the size and the contents, live in part of the `chars' component of a string_block. | |
781 The `pos' component is the index within `chars' of the first free byte. | |
782 | |
783 first_string_block points to the first string_block ever allocated. | |
784 Each block points to the next one with its `next' field. | |
785 The `prev' fields chain in reverse order. | |
786 The last one allocated is the one currently being filled. | |
787 current_string_block points to it. | |
788 | |
789 The string_blocks that hold individual large strings | |
790 go in a separate chain, started by large_string_blocks. */ | |
791 | |
792 | |
793 /* String blocks contain this many useful bytes. | |
794 8188 is power of 2, minus 4 for malloc overhead. */ | |
795 #define STRING_BLOCK_SIZE (8188 - sizeof (struct string_block_head)) | |
796 | |
797 /* A string bigger than this gets its own specially-made string block | |
798 if it doesn't fit in the current one. */ | |
799 #define STRING_BLOCK_OUTSIZE 1024 | |
800 | |
801 struct string_block_head | |
802 { | |
803 struct string_block *next, *prev; | |
804 int pos; | |
805 }; | |
806 | |
807 struct string_block | |
808 { | |
809 struct string_block *next, *prev; | |
810 int pos; | |
811 char chars[STRING_BLOCK_SIZE]; | |
812 }; | |
813 | |
814 /* This points to the string block we are now allocating strings. */ | |
815 | |
816 struct string_block *current_string_block; | |
817 | |
818 /* This points to the oldest string block, the one that starts the chain. */ | |
819 | |
820 struct string_block *first_string_block; | |
821 | |
822 /* Last string block in chain of those made for individual large strings. */ | |
823 | |
824 struct string_block *large_string_blocks; | |
825 | |
826 /* If SIZE is the length of a string, this returns how many bytes | |
827 the string occupies in a string_block (including padding). */ | |
828 | |
829 #define STRING_FULLSIZE(size) (((size) + sizeof (struct Lisp_String) + PAD) \ | |
830 & ~(PAD - 1)) | |
831 #define PAD (sizeof (int)) | |
832 | |
833 #if 0 | |
834 #define STRING_FULLSIZE(SIZE) \ | |
835 (((SIZE) + 2 * sizeof (int)) & ~(sizeof (int) - 1)) | |
836 #endif | |
837 | |
838 void | |
839 init_strings () | |
840 { | |
841 current_string_block = (struct string_block *) malloc (sizeof (struct string_block)); | |
842 first_string_block = current_string_block; | |
843 consing_since_gc += sizeof (struct string_block); | |
844 current_string_block->next = 0; | |
845 current_string_block->prev = 0; | |
846 current_string_block->pos = 0; | |
847 large_string_blocks = 0; | |
848 } | |
849 | |
850 DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, | |
851 "Return a newly created string of length LENGTH, with each element being INIT.\n\ | |
852 Both LENGTH and INIT must be numbers.") | |
853 (length, init) | |
854 Lisp_Object length, init; | |
855 { | |
856 register Lisp_Object val; | |
857 register unsigned char *p, *end, c; | |
858 | |
859 if (XTYPE (length) != Lisp_Int || XINT (length) < 0) | |
860 length = wrong_type_argument (Qnatnump, length); | |
861 CHECK_NUMBER (init, 1); | |
862 val = make_uninit_string (XINT (length)); | |
863 c = XINT (init); | |
864 p = XSTRING (val)->data; | |
865 end = p + XSTRING (val)->size; | |
866 while (p != end) | |
867 *p++ = c; | |
868 *p = 0; | |
869 return val; | |
870 } | |
871 | |
872 Lisp_Object | |
873 make_string (contents, length) | |
874 char *contents; | |
875 int length; | |
876 { | |
877 register Lisp_Object val; | |
878 val = make_uninit_string (length); | |
879 bcopy (contents, XSTRING (val)->data, length); | |
880 return val; | |
881 } | |
882 | |
883 Lisp_Object | |
884 build_string (str) | |
885 char *str; | |
886 { | |
887 return make_string (str, strlen (str)); | |
888 } | |
889 | |
890 Lisp_Object | |
891 make_uninit_string (length) | |
892 int length; | |
893 { | |
894 register Lisp_Object val; | |
895 register int fullsize = STRING_FULLSIZE (length); | |
896 | |
897 if (length < 0) abort (); | |
898 | |
899 if (fullsize <= STRING_BLOCK_SIZE - current_string_block->pos) | |
900 /* This string can fit in the current string block */ | |
901 { | |
902 XSET (val, Lisp_String, | |
903 (struct Lisp_String *) (current_string_block->chars + current_string_block->pos)); | |
904 current_string_block->pos += fullsize; | |
905 } | |
906 else if (fullsize > STRING_BLOCK_OUTSIZE) | |
907 /* This string gets its own string block */ | |
908 { | |
909 register struct string_block *new | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
910 = (struct string_block *) xmalloc (sizeof (struct string_block_head) + fullsize); |
300 | 911 VALIDATE_LISP_STORAGE (new, 0); |
912 consing_since_gc += sizeof (struct string_block_head) + fullsize; | |
913 new->pos = fullsize; | |
914 new->next = large_string_blocks; | |
915 large_string_blocks = new; | |
916 XSET (val, Lisp_String, | |
917 (struct Lisp_String *) ((struct string_block_head *)new + 1)); | |
918 } | |
919 else | |
920 /* Make a new current string block and start it off with this string */ | |
921 { | |
922 register struct string_block *new | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
923 = (struct string_block *) xmalloc (sizeof (struct string_block)); |
300 | 924 VALIDATE_LISP_STORAGE (new, sizeof *new); |
925 consing_since_gc += sizeof (struct string_block); | |
926 current_string_block->next = new; | |
927 new->prev = current_string_block; | |
928 new->next = 0; | |
929 current_string_block = new; | |
930 new->pos = fullsize; | |
931 XSET (val, Lisp_String, | |
932 (struct Lisp_String *) current_string_block->chars); | |
933 } | |
934 | |
935 XSTRING (val)->size = length; | |
936 XSTRING (val)->data[length] = 0; | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
937 INITIALIZE_INTERVAL (XSTRING (val), NULL_INTERVAL); |
300 | 938 |
939 return val; | |
940 } | |
941 | |
942 /* Return a newly created vector or string with specified arguments as | |
2013
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
943 elements. If all the arguments are characters that can fit |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
944 in a string of events, make a string; otherwise, make a vector. |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
945 |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
946 Any number of arguments, even zero arguments, are allowed. */ |
300 | 947 |
948 Lisp_Object | |
2013
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
949 make_event_array (nargs, args) |
300 | 950 register int nargs; |
951 Lisp_Object *args; | |
952 { | |
953 int i; | |
954 | |
955 for (i = 0; i < nargs; i++) | |
2013
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
956 /* The things that fit in a string |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
957 are characters that are in 0...127 after discarding the meta bit. */ |
300 | 958 if (XTYPE (args[i]) != Lisp_Int |
2013
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
959 || (XUINT (args[i]) & ~CHAR_META) >= 0200) |
300 | 960 return Fvector (nargs, args); |
961 | |
962 /* Since the loop exited, we know that all the things in it are | |
963 characters, so we can make a string. */ | |
964 { | |
965 Lisp_Object result = Fmake_string (nargs, make_number (0)); | |
966 | |
967 for (i = 0; i < nargs; i++) | |
2013
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
968 { |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
969 XSTRING (result)->data[i] = XINT (args[i]); |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
970 /* Move the meta bit to the right place for a string char. */ |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
971 if (XINT (args[i]) & CHAR_META) |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
972 XSTRING (result)->data[i] |= 0x80; |
e2a164ac4088
(Fmake_rope, Frope_elt): Fns deleted.
Richard M. Stallman <rms@gnu.org>
parents:
1994
diff
changeset
|
973 } |
300 | 974 |
975 return result; | |
976 } | |
977 } | |
978 | |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
979 /* Pure storage management. */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
980 |
300 | 981 /* Must get an error if pure storage is full, |
982 since if it cannot hold a large string | |
983 it may be able to hold conses that point to that string; | |
984 then the string is not protected from gc. */ | |
985 | |
986 Lisp_Object | |
987 make_pure_string (data, length) | |
988 char *data; | |
989 int length; | |
990 { | |
991 register Lisp_Object new; | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
992 register int size = sizeof (int) + INTERVAL_PTR_SIZE + length + 1; |
300 | 993 |
994 if (pureptr + size > PURESIZE) | |
995 error ("Pure Lisp storage exhausted"); | |
996 XSET (new, Lisp_String, PUREBEG + pureptr); | |
997 XSTRING (new)->size = length; | |
998 bcopy (data, XSTRING (new)->data, length); | |
999 XSTRING (new)->data[length] = 0; | |
1000 pureptr += (size + sizeof (int) - 1) | |
1001 / sizeof (int) * sizeof (int); | |
1002 return new; | |
1003 } | |
1004 | |
1005 Lisp_Object | |
1006 pure_cons (car, cdr) | |
1007 Lisp_Object car, cdr; | |
1008 { | |
1009 register Lisp_Object new; | |
1010 | |
1011 if (pureptr + sizeof (struct Lisp_Cons) > PURESIZE) | |
1012 error ("Pure Lisp storage exhausted"); | |
1013 XSET (new, Lisp_Cons, PUREBEG + pureptr); | |
1014 pureptr += sizeof (struct Lisp_Cons); | |
1015 XCONS (new)->car = Fpurecopy (car); | |
1016 XCONS (new)->cdr = Fpurecopy (cdr); | |
1017 return new; | |
1018 } | |
1019 | |
1020 #ifdef LISP_FLOAT_TYPE | |
1021 | |
1022 Lisp_Object | |
1023 make_pure_float (num) | |
1024 double num; | |
1025 { | |
1026 register Lisp_Object new; | |
1027 | |
1939
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1028 /* Make sure that PUREBEG + pureptr is aligned on at least a sizeof |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1029 (double) boundary. Some architectures (like the sparc) require |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1030 this, and I suspect that floats are rare enough that it's no |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1031 tragedy for those that do. */ |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1032 { |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1033 int alignment; |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1034 char *p = PUREBEG + pureptr; |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1035 |
1936
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1036 #ifdef __GNUC__ |
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1037 #if __GNUC__ >= 2 |
1939
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1038 alignment = __alignof (struct Lisp_Float); |
1936
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1039 #else |
1939
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1040 alignment = sizeof (struct Lisp_Float); |
1936
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1041 #endif |
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1042 #else |
1939
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1043 alignment = sizeof (struct Lisp_Float); |
1936
82bbf90208d4
* alloc.c (make_pure_float): Align pureptr according to __alignof,
Jim Blandy <jimb@redhat.com>
parents:
1908
diff
changeset
|
1044 #endif |
1939
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1045 p = (char *) (((unsigned long) p + alignment - 1) & - alignment); |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1046 pureptr = p - PUREBEG; |
def7b9c64935
* alloc.c (make_pure_float): Assure that PUREBEG + pureptr is
Jim Blandy <jimb@redhat.com>
parents:
1936
diff
changeset
|
1047 } |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1048 |
300 | 1049 if (pureptr + sizeof (struct Lisp_Float) > PURESIZE) |
1050 error ("Pure Lisp storage exhausted"); | |
1051 XSET (new, Lisp_Float, PUREBEG + pureptr); | |
1052 pureptr += sizeof (struct Lisp_Float); | |
1053 XFLOAT (new)->data = num; | |
1054 XFLOAT (new)->type = 0; /* bug chasing -wsr */ | |
1055 return new; | |
1056 } | |
1057 | |
1058 #endif /* LISP_FLOAT_TYPE */ | |
1059 | |
1060 Lisp_Object | |
1061 make_pure_vector (len) | |
1062 int len; | |
1063 { | |
1064 register Lisp_Object new; | |
1065 register int size = sizeof (struct Lisp_Vector) + (len - 1) * sizeof (Lisp_Object); | |
1066 | |
1067 if (pureptr + size > PURESIZE) | |
1068 error ("Pure Lisp storage exhausted"); | |
1069 | |
1070 XSET (new, Lisp_Vector, PUREBEG + pureptr); | |
1071 pureptr += size; | |
1072 XVECTOR (new)->size = len; | |
1073 return new; | |
1074 } | |
1075 | |
1076 DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, | |
1077 "Make a copy of OBJECT in pure storage.\n\ | |
1078 Recursively copies contents of vectors and cons cells.\n\ | |
1079 Does not copy symbols.") | |
1080 (obj) | |
1081 register Lisp_Object obj; | |
1082 { | |
1083 register Lisp_Object new, tem; | |
1084 register int i; | |
1085 | |
485 | 1086 if (NILP (Vpurify_flag)) |
300 | 1087 return obj; |
1088 | |
1089 if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) | |
1090 && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) | |
1091 return obj; | |
1092 | |
1093 #ifdef SWITCH_ENUM_BUG | |
1094 switch ((int) XTYPE (obj)) | |
1095 #else | |
1096 switch (XTYPE (obj)) | |
1097 #endif | |
1098 { | |
1099 case Lisp_Marker: | |
1100 error ("Attempt to copy a marker to pure storage"); | |
1101 | |
1102 case Lisp_Cons: | |
1103 return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr); | |
1104 | |
1105 #ifdef LISP_FLOAT_TYPE | |
1106 case Lisp_Float: | |
1107 return make_pure_float (XFLOAT (obj)->data); | |
1108 #endif /* LISP_FLOAT_TYPE */ | |
1109 | |
1110 case Lisp_String: | |
1111 return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size); | |
1112 | |
1113 case Lisp_Compiled: | |
1114 case Lisp_Vector: | |
1115 new = make_pure_vector (XVECTOR (obj)->size); | |
1116 for (i = 0; i < XVECTOR (obj)->size; i++) | |
1117 { | |
1118 tem = XVECTOR (obj)->contents[i]; | |
1119 XVECTOR (new)->contents[i] = Fpurecopy (tem); | |
1120 } | |
1121 XSETTYPE (new, XTYPE (obj)); | |
1122 return new; | |
1123 | |
1124 default: | |
1125 return obj; | |
1126 } | |
1127 } | |
1128 | |
1129 /* Recording what needs to be marked for gc. */ | |
1130 | |
1131 struct gcpro *gcprolist; | |
1132 | |
727 | 1133 #define NSTATICS 512 |
300 | 1134 |
1135 Lisp_Object *staticvec[NSTATICS] = {0}; | |
1136 | |
1137 int staticidx = 0; | |
1138 | |
1139 /* Put an entry in staticvec, pointing at the variable whose address is given */ | |
1140 | |
1141 void | |
1142 staticpro (varaddress) | |
1143 Lisp_Object *varaddress; | |
1144 { | |
1145 staticvec[staticidx++] = varaddress; | |
1146 if (staticidx >= NSTATICS) | |
1147 abort (); | |
1148 } | |
1149 | |
1150 struct catchtag | |
1151 { | |
1152 Lisp_Object tag; | |
1153 Lisp_Object val; | |
1154 struct catchtag *next; | |
1155 /* jmp_buf jmp; /* We don't need this for GC purposes */ | |
1156 }; | |
1157 | |
1158 struct backtrace | |
1159 { | |
1160 struct backtrace *next; | |
1161 Lisp_Object *function; | |
1162 Lisp_Object *args; /* Points to vector of args. */ | |
1163 int nargs; /* length of vector */ | |
1164 /* if nargs is UNEVALLED, args points to slot holding list of unevalled args */ | |
1165 char evalargs; | |
1166 }; | |
1167 | |
1168 /* Two flags that are set during GC in the `size' component | |
1169 of a string or vector. On some machines, these flags | |
1170 are defined by the m- file to be different bits. */ | |
1171 | |
1172 /* On vector, means it has been marked. | |
1173 On string size field or a reference to a string, | |
1174 means not the last reference in the chain. */ | |
1175 | |
1176 #ifndef ARRAY_MARK_FLAG | |
1177 #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT) | |
1178 #endif /* no ARRAY_MARK_FLAG */ | |
1179 | |
1180 /* Any slot that is a Lisp_Object can point to a string | |
1181 and thus can be put on a string's reference-chain | |
1182 and thus may need to have its ARRAY_MARK_FLAG set. | |
1183 This includes the slots whose markbits are used to mark | |
1184 the containing objects. */ | |
1185 | |
1186 #if ARRAY_MARK_FLAG == MARKBIT | |
1187 you lose | |
1188 #endif | |
1189 | |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1190 /* Garbage collection! */ |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1191 |
300 | 1192 int total_conses, total_markers, total_symbols, total_string_size, total_vector_size; |
1193 int total_free_conses, total_free_markers, total_free_symbols; | |
1194 #ifdef LISP_FLOAT_TYPE | |
1195 int total_free_floats, total_floats; | |
1196 #endif /* LISP_FLOAT_TYPE */ | |
1197 | |
1198 DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", | |
1199 "Reclaim storage for Lisp objects no longer needed.\n\ | |
1200 Returns info on amount of space in use:\n\ | |
1201 ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\ | |
1202 (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS\n\ | |
1203 (USED-FLOATS . FREE-FLOATS))\n\ | |
1204 Garbage collection happens automatically if you cons more than\n\ | |
1205 `gc-cons-threshold' bytes of Lisp data since previous garbage collection.") | |
1206 () | |
1207 { | |
1208 register struct gcpro *tail; | |
1209 register struct specbinding *bind; | |
1210 struct catchtag *catch; | |
1211 struct handler *handler; | |
1212 register struct backtrace *backlist; | |
1213 register Lisp_Object tem; | |
1214 char *omessage = echo_area_glyphs; | |
1215 char stack_top_variable; | |
1216 register int i; | |
1217 | |
1218 /* Save a copy of the contents of the stack, for debugging. */ | |
1219 #if MAX_SAVE_STACK > 0 | |
485 | 1220 if (NILP (Vpurify_flag)) |
300 | 1221 { |
1222 i = &stack_top_variable - stack_bottom; | |
1223 if (i < 0) i = -i; | |
1224 if (i < MAX_SAVE_STACK) | |
1225 { | |
1226 if (stack_copy == 0) | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
1227 stack_copy = (char *) xmalloc (stack_copy_size = i); |
300 | 1228 else if (stack_copy_size < i) |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
1229 stack_copy = (char *) xrealloc (stack_copy, (stack_copy_size = i)); |
300 | 1230 if (stack_copy) |
1231 { | |
1232 if ((int) (&stack_top_variable - stack_bottom) > 0) | |
1233 bcopy (stack_bottom, stack_copy, i); | |
1234 else | |
1235 bcopy (&stack_top_variable, stack_copy, i); | |
1236 } | |
1237 } | |
1238 } | |
1239 #endif /* MAX_SAVE_STACK > 0 */ | |
1240 | |
1241 if (!noninteractive) | |
1242 message1 ("Garbage collecting..."); | |
1243 | |
1244 /* Don't keep command history around forever */ | |
1245 tem = Fnthcdr (make_number (30), Vcommand_history); | |
1246 if (CONSP (tem)) | |
1247 XCONS (tem)->cdr = Qnil; | |
648 | 1248 |
300 | 1249 /* Likewise for undo information. */ |
1250 { | |
1251 register struct buffer *nextb = all_buffers; | |
1252 | |
1253 while (nextb) | |
1254 { | |
648 | 1255 /* If a buffer's undo list is Qt, that means that undo is |
1256 turned off in that buffer. Calling truncate_undo_list on | |
1257 Qt tends to return NULL, which effectively turns undo back on. | |
1258 So don't call truncate_undo_list if undo_list is Qt. */ | |
1259 if (! EQ (nextb->undo_list, Qt)) | |
1260 nextb->undo_list | |
764 | 1261 = truncate_undo_list (nextb->undo_list, undo_limit, |
1262 undo_strong_limit); | |
300 | 1263 nextb = nextb->next; |
1264 } | |
1265 } | |
1266 | |
1267 gc_in_progress = 1; | |
1268 | |
1269 /* clear_marks (); */ | |
1270 | |
1271 /* In each "large string", set the MARKBIT of the size field. | |
1272 That enables mark_object to recognize them. */ | |
1273 { | |
1274 register struct string_block *b; | |
1275 for (b = large_string_blocks; b; b = b->next) | |
1276 ((struct Lisp_String *)(&b->chars[0]))->size |= MARKBIT; | |
1277 } | |
1278 | |
1279 /* Mark all the special slots that serve as the roots of accessibility. | |
1280 | |
1281 Usually the special slots to mark are contained in particular structures. | |
1282 Then we know no slot is marked twice because the structures don't overlap. | |
1283 In some cases, the structures point to the slots to be marked. | |
1284 For these, we use MARKBIT to avoid double marking of the slot. */ | |
1285 | |
1286 for (i = 0; i < staticidx; i++) | |
1287 mark_object (staticvec[i]); | |
1288 for (tail = gcprolist; tail; tail = tail->next) | |
1289 for (i = 0; i < tail->nvars; i++) | |
1290 if (!XMARKBIT (tail->var[i])) | |
1291 { | |
1292 mark_object (&tail->var[i]); | |
1293 XMARK (tail->var[i]); | |
1294 } | |
1295 for (bind = specpdl; bind != specpdl_ptr; bind++) | |
1296 { | |
1297 mark_object (&bind->symbol); | |
1298 mark_object (&bind->old_value); | |
1299 } | |
1300 for (catch = catchlist; catch; catch = catch->next) | |
1301 { | |
1302 mark_object (&catch->tag); | |
1303 mark_object (&catch->val); | |
1304 } | |
1305 for (handler = handlerlist; handler; handler = handler->next) | |
1306 { | |
1307 mark_object (&handler->handler); | |
1308 mark_object (&handler->var); | |
1309 } | |
1310 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
1311 { | |
1312 if (!XMARKBIT (*backlist->function)) | |
1313 { | |
1314 mark_object (backlist->function); | |
1315 XMARK (*backlist->function); | |
1316 } | |
1317 if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | |
1318 i = 0; | |
1319 else | |
1320 i = backlist->nargs - 1; | |
1321 for (; i >= 0; i--) | |
1322 if (!XMARKBIT (backlist->args[i])) | |
1323 { | |
1324 mark_object (&backlist->args[i]); | |
1325 XMARK (backlist->args[i]); | |
1326 } | |
1327 } | |
1328 | |
1329 gc_sweep (); | |
1330 | |
1331 /* Clear the mark bits that we set in certain root slots. */ | |
1332 | |
1333 for (tail = gcprolist; tail; tail = tail->next) | |
1334 for (i = 0; i < tail->nvars; i++) | |
1335 XUNMARK (tail->var[i]); | |
1336 for (backlist = backtrace_list; backlist; backlist = backlist->next) | |
1337 { | |
1338 XUNMARK (*backlist->function); | |
1339 if (backlist->nargs == UNEVALLED || backlist->nargs == MANY) | |
1340 i = 0; | |
1341 else | |
1342 i = backlist->nargs - 1; | |
1343 for (; i >= 0; i--) | |
1344 XUNMARK (backlist->args[i]); | |
1345 } | |
1346 XUNMARK (buffer_defaults.name); | |
1347 XUNMARK (buffer_local_symbols.name); | |
1348 | |
1349 /* clear_marks (); */ | |
1350 gc_in_progress = 0; | |
1351 | |
1352 consing_since_gc = 0; | |
1353 if (gc_cons_threshold < 10000) | |
1354 gc_cons_threshold = 10000; | |
1355 | |
1356 if (omessage) | |
1357 message1 (omessage); | |
1358 else if (!noninteractive) | |
1359 message1 ("Garbage collecting...done"); | |
1360 | |
1361 return Fcons (Fcons (make_number (total_conses), | |
1362 make_number (total_free_conses)), | |
1363 Fcons (Fcons (make_number (total_symbols), | |
1364 make_number (total_free_symbols)), | |
1365 Fcons (Fcons (make_number (total_markers), | |
1366 make_number (total_free_markers)), | |
1367 Fcons (make_number (total_string_size), | |
1368 Fcons (make_number (total_vector_size), | |
1369 | |
1370 #ifdef LISP_FLOAT_TYPE | |
1371 Fcons (Fcons (make_number (total_floats), | |
1372 make_number (total_free_floats)), | |
1373 Qnil) | |
1374 #else /* not LISP_FLOAT_TYPE */ | |
1375 Qnil | |
1376 #endif /* not LISP_FLOAT_TYPE */ | |
1377 ))))); | |
1378 } | |
1379 | |
1380 #if 0 | |
1381 static void | |
1382 clear_marks () | |
1383 { | |
1384 /* Clear marks on all conses */ | |
1385 { | |
1386 register struct cons_block *cblk; | |
1387 register int lim = cons_block_index; | |
1388 | |
1389 for (cblk = cons_block; cblk; cblk = cblk->next) | |
1390 { | |
1391 register int i; | |
1392 for (i = 0; i < lim; i++) | |
1393 XUNMARK (cblk->conses[i].car); | |
1394 lim = CONS_BLOCK_SIZE; | |
1395 } | |
1396 } | |
1397 /* Clear marks on all symbols */ | |
1398 { | |
1399 register struct symbol_block *sblk; | |
1400 register int lim = symbol_block_index; | |
1401 | |
1402 for (sblk = symbol_block; sblk; sblk = sblk->next) | |
1403 { | |
1404 register int i; | |
1405 for (i = 0; i < lim; i++) | |
1406 { | |
1407 XUNMARK (sblk->symbols[i].plist); | |
1408 } | |
1409 lim = SYMBOL_BLOCK_SIZE; | |
1410 } | |
1411 } | |
1412 /* Clear marks on all markers */ | |
1413 { | |
1414 register struct marker_block *sblk; | |
1415 register int lim = marker_block_index; | |
1416 | |
1417 for (sblk = marker_block; sblk; sblk = sblk->next) | |
1418 { | |
1419 register int i; | |
1420 for (i = 0; i < lim; i++) | |
1421 XUNMARK (sblk->markers[i].chain); | |
1422 lim = MARKER_BLOCK_SIZE; | |
1423 } | |
1424 } | |
1425 /* Clear mark bits on all buffers */ | |
1426 { | |
1427 register struct buffer *nextb = all_buffers; | |
1428 | |
1429 while (nextb) | |
1430 { | |
1431 XUNMARK (nextb->name); | |
1432 nextb = nextb->next; | |
1433 } | |
1434 } | |
1435 } | |
1436 #endif | |
1437 | |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1438 /* Mark reference to a Lisp_Object. |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1439 If the object referred to has not been seen yet, recursively mark |
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1440 all the references contained in it. |
300 | 1441 |
1442 If the object referenced is a short string, the referrencing slot | |
1443 is threaded into a chain of such slots, pointed to from | |
1444 the `size' field of the string. The actual string size | |
1445 lives in the last slot in the chain. We recognize the end | |
1446 because it is < (unsigned) STRING_BLOCK_SIZE. */ | |
1447 | |
1168
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1448 #define LAST_MARKED_SIZE 500 |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1449 Lisp_Object *last_marked[LAST_MARKED_SIZE]; |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1450 int last_marked_index; |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1451 |
300 | 1452 static void |
1453 mark_object (objptr) | |
1454 Lisp_Object *objptr; | |
1455 { | |
1456 register Lisp_Object obj; | |
1457 | |
1458 obj = *objptr; | |
1459 XUNMARK (obj); | |
1460 | |
1461 loop: | |
1462 | |
1463 if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) | |
1464 && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) | |
1465 return; | |
1466 | |
1168
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1467 last_marked[last_marked_index++] = objptr; |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1468 if (last_marked_index == LAST_MARKED_SIZE) |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1469 last_marked_index = 0; |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1470 |
300 | 1471 #ifdef SWITCH_ENUM_BUG |
1472 switch ((int) XGCTYPE (obj)) | |
1473 #else | |
1474 switch (XGCTYPE (obj)) | |
1475 #endif | |
1476 { | |
1477 case Lisp_String: | |
1478 { | |
1479 register struct Lisp_String *ptr = XSTRING (obj); | |
1480 | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1481 MARK_INTERVAL_TREE (ptr->intervals); |
300 | 1482 if (ptr->size & MARKBIT) |
1483 /* A large string. Just set ARRAY_MARK_FLAG. */ | |
1484 ptr->size |= ARRAY_MARK_FLAG; | |
1485 else | |
1486 { | |
1487 /* A small string. Put this reference | |
1488 into the chain of references to it. | |
1489 The address OBJPTR is even, so if the address | |
1490 includes MARKBIT, put it in the low bit | |
1491 when we store OBJPTR into the size field. */ | |
1492 | |
1493 if (XMARKBIT (*objptr)) | |
1494 { | |
1495 XFASTINT (*objptr) = ptr->size; | |
1496 XMARK (*objptr); | |
1497 } | |
1498 else | |
1499 XFASTINT (*objptr) = ptr->size; | |
1500 if ((int)objptr & 1) abort (); | |
1501 ptr->size = (int) objptr & ~MARKBIT; | |
1502 if ((int) objptr & MARKBIT) | |
1503 ptr->size ++; | |
1504 } | |
1505 } | |
1506 break; | |
1507 | |
1508 case Lisp_Vector: | |
1509 case Lisp_Window: | |
1510 case Lisp_Process: | |
1511 case Lisp_Window_Configuration: | |
1512 { | |
1513 register struct Lisp_Vector *ptr = XVECTOR (obj); | |
1514 register int size = ptr->size; | |
1168
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1515 struct Lisp_Vector *volatile ptr1 = ptr; |
300 | 1516 register int i; |
1517 | |
1518 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | |
1519 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | |
1520 for (i = 0; i < size; i++) /* and then mark its elements */ | |
1168
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1521 { |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1522 if (ptr != ptr1) |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1523 abort (); |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1524 mark_object (&ptr->contents[i]); |
2b07af77d7ec
(mark_object): Save last 500 values of objptr.
Richard M. Stallman <rms@gnu.org>
parents:
1114
diff
changeset
|
1525 } |
300 | 1526 } |
1527 break; | |
1528 | |
1295
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1529 case Lisp_Compiled: |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1530 /* We could treat this just like a vector, but it is better |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1531 to save the COMPILED_CONSTANTS element for last and avoid recursion |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1532 there. */ |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1533 { |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1534 register struct Lisp_Vector *ptr = XVECTOR (obj); |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1535 register int size = ptr->size; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1536 struct Lisp_Vector *volatile ptr1 = ptr; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1537 register int i; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1538 |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1539 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1540 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1541 for (i = 0; i < size; i++) /* and then mark its elements */ |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1542 { |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1543 if (ptr != ptr1) |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1544 abort (); |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1545 if (i != COMPILED_CONSTANTS) |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1546 mark_object (&ptr->contents[i]); |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1547 } |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1548 objptr = &ptr->contents[COMPILED_CONSTANTS]; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1549 obj = *objptr; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1550 goto loop; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1551 } |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1552 |
764 | 1553 #ifdef MULTI_FRAME |
1554 case Lisp_Frame: | |
300 | 1555 { |
764 | 1556 register struct frame *ptr = XFRAME (obj); |
300 | 1557 register int size = ptr->size; |
1558 | |
1559 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | |
1560 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | |
1561 | |
1562 mark_object (&ptr->name); | |
764 | 1563 mark_object (&ptr->focus_frame); |
300 | 1564 mark_object (&ptr->width); |
1565 mark_object (&ptr->height); | |
1566 mark_object (&ptr->selected_window); | |
1567 mark_object (&ptr->minibuffer_window); | |
1568 mark_object (&ptr->param_alist); | |
1994
73ce9dd21093
Use the term `scroll bar', instead of `scrollbar'.
Jim Blandy <jimb@redhat.com>
parents:
1957
diff
changeset
|
1569 mark_object (&ptr->scroll_bars); |
73ce9dd21093
Use the term `scroll bar', instead of `scrollbar'.
Jim Blandy <jimb@redhat.com>
parents:
1957
diff
changeset
|
1570 mark_object (&ptr->condemned_scroll_bars); |
2151
6775c932a51b
(mark_object): Mark the menu_bar_items field.
Richard M. Stallman <rms@gnu.org>
parents:
2013
diff
changeset
|
1571 mark_object (&ptr->menu_bar_items); |
2370
4817a2197ac2
(mark_object): Mark face_alist of a frame.
Richard M. Stallman <rms@gnu.org>
parents:
2152
diff
changeset
|
1572 mark_object (&ptr->face_alist); |
300 | 1573 } |
1574 break; | |
2152 | 1575 #endif /* MULTI_FRAME */ |
300 | 1576 |
1577 case Lisp_Symbol: | |
1578 { | |
1579 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | |
1580 struct Lisp_Symbol *ptrx; | |
1581 | |
1582 if (XMARKBIT (ptr->plist)) break; | |
1583 XMARK (ptr->plist); | |
1584 mark_object ((Lisp_Object *) &ptr->value); | |
1585 mark_object (&ptr->function); | |
1586 mark_object (&ptr->plist); | |
1114
903883eed4de
* alloc.c (mark_object): mark a symbol's name after marking its
Jim Blandy <jimb@redhat.com>
parents:
1000
diff
changeset
|
1587 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); |
903883eed4de
* alloc.c (mark_object): mark a symbol's name after marking its
Jim Blandy <jimb@redhat.com>
parents:
1000
diff
changeset
|
1588 mark_object (&ptr->name); |
300 | 1589 ptr = ptr->next; |
1590 if (ptr) | |
1591 { | |
1592 ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */ | |
1593 XSETSYMBOL (obj, ptrx); | |
1594 goto loop; | |
1595 } | |
1596 } | |
1597 break; | |
1598 | |
1599 case Lisp_Marker: | |
1600 XMARK (XMARKER (obj)->chain); | |
1601 /* DO NOT mark thru the marker's chain. | |
1602 The buffer's markers chain does not preserve markers from gc; | |
1295
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1603 instead, markers are removed from the chain when freed by gc. */ |
300 | 1604 break; |
1605 | |
1606 case Lisp_Cons: | |
1607 case Lisp_Buffer_Local_Value: | |
1608 case Lisp_Some_Buffer_Local_Value: | |
1609 { | |
1610 register struct Lisp_Cons *ptr = XCONS (obj); | |
1611 if (XMARKBIT (ptr->car)) break; | |
1612 XMARK (ptr->car); | |
1295
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1613 /* If the cdr is nil, avoid recursion for the car. */ |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1614 if (EQ (ptr->cdr, Qnil)) |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1615 { |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1616 objptr = &ptr->car; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1617 obj = ptr->car; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1618 XUNMARK (obj); |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1619 goto loop; |
a9241dc503ab
(mark_object): Avoid car recursion on cons with nil in cdr.
Richard M. Stallman <rms@gnu.org>
parents:
1168
diff
changeset
|
1620 } |
300 | 1621 mark_object (&ptr->car); |
1622 objptr = &ptr->cdr; | |
1623 obj = ptr->cdr; | |
1624 goto loop; | |
1625 } | |
1626 | |
1627 #ifdef LISP_FLOAT_TYPE | |
1628 case Lisp_Float: | |
1629 XMARK (XFLOAT (obj)->type); | |
1630 break; | |
1631 #endif /* LISP_FLOAT_TYPE */ | |
1632 | |
1633 case Lisp_Buffer: | |
1634 if (!XMARKBIT (XBUFFER (obj)->name)) | |
1635 mark_buffer (obj); | |
1636 break; | |
1637 | |
1638 case Lisp_Int: | |
1639 case Lisp_Void: | |
1640 case Lisp_Subr: | |
1641 case Lisp_Intfwd: | |
1642 case Lisp_Boolfwd: | |
1643 case Lisp_Objfwd: | |
1644 case Lisp_Buffer_Objfwd: | |
1645 case Lisp_Internal_Stream: | |
1646 /* Don't bother with Lisp_Buffer_Objfwd, | |
1647 since all markable slots in current buffer marked anyway. */ | |
1648 /* Don't need to do Lisp_Objfwd, since the places they point | |
1649 are protected with staticpro. */ | |
1650 break; | |
1651 | |
1652 default: | |
1653 abort (); | |
1654 } | |
1655 } | |
1656 | |
1657 /* Mark the pointers in a buffer structure. */ | |
1658 | |
1659 static void | |
1660 mark_buffer (buf) | |
1661 Lisp_Object buf; | |
1662 { | |
1663 register struct buffer *buffer = XBUFFER (buf); | |
1664 register Lisp_Object *ptr; | |
1665 | |
1666 /* This is the buffer's markbit */ | |
1667 mark_object (&buffer->name); | |
1668 XMARK (buffer->name); | |
1669 | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1670 MARK_INTERVAL_TREE (buffer->intervals); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1671 |
300 | 1672 #if 0 |
1673 mark_object (buffer->syntax_table); | |
1674 | |
1675 /* Mark the various string-pointers in the buffer object. | |
1676 Since the strings may be relocated, we must mark them | |
1677 in their actual slots. So gc_sweep must convert each slot | |
1678 back to an ordinary C pointer. */ | |
1679 XSET (*(Lisp_Object *)&buffer->upcase_table, | |
1680 Lisp_String, buffer->upcase_table); | |
1681 mark_object ((Lisp_Object *)&buffer->upcase_table); | |
1682 XSET (*(Lisp_Object *)&buffer->downcase_table, | |
1683 Lisp_String, buffer->downcase_table); | |
1684 mark_object ((Lisp_Object *)&buffer->downcase_table); | |
1685 | |
1686 XSET (*(Lisp_Object *)&buffer->sort_table, | |
1687 Lisp_String, buffer->sort_table); | |
1688 mark_object ((Lisp_Object *)&buffer->sort_table); | |
1689 XSET (*(Lisp_Object *)&buffer->folding_sort_table, | |
1690 Lisp_String, buffer->folding_sort_table); | |
1691 mark_object ((Lisp_Object *)&buffer->folding_sort_table); | |
1692 #endif | |
1693 | |
1694 for (ptr = &buffer->name + 1; | |
1695 (char *)ptr < (char *)buffer + sizeof (struct buffer); | |
1696 ptr++) | |
1697 mark_object (ptr); | |
1698 } | |
1699 | |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1700 /* Sweep: find all structures not marked, and free them. */ |
300 | 1701 |
1702 static void | |
1703 gc_sweep () | |
1704 { | |
1705 total_string_size = 0; | |
1706 compact_strings (); | |
1707 | |
1708 /* Put all unmarked conses on free list */ | |
1709 { | |
1710 register struct cons_block *cblk; | |
1711 register int lim = cons_block_index; | |
1712 register int num_free = 0, num_used = 0; | |
1713 | |
1714 cons_free_list = 0; | |
1715 | |
1716 for (cblk = cons_block; cblk; cblk = cblk->next) | |
1717 { | |
1718 register int i; | |
1719 for (i = 0; i < lim; i++) | |
1720 if (!XMARKBIT (cblk->conses[i].car)) | |
1721 { | |
1722 XFASTINT (cblk->conses[i].car) = (int) cons_free_list; | |
1723 num_free++; | |
1724 cons_free_list = &cblk->conses[i]; | |
1725 } | |
1726 else | |
1727 { | |
1728 num_used++; | |
1729 XUNMARK (cblk->conses[i].car); | |
1730 } | |
1731 lim = CONS_BLOCK_SIZE; | |
1732 } | |
1733 total_conses = num_used; | |
1734 total_free_conses = num_free; | |
1735 } | |
1736 | |
1737 #ifdef LISP_FLOAT_TYPE | |
1738 /* Put all unmarked floats on free list */ | |
1739 { | |
1740 register struct float_block *fblk; | |
1741 register int lim = float_block_index; | |
1742 register int num_free = 0, num_used = 0; | |
1743 | |
1744 float_free_list = 0; | |
1745 | |
1746 for (fblk = float_block; fblk; fblk = fblk->next) | |
1747 { | |
1748 register int i; | |
1749 for (i = 0; i < lim; i++) | |
1750 if (!XMARKBIT (fblk->floats[i].type)) | |
1751 { | |
1752 XFASTINT (fblk->floats[i].type) = (int) float_free_list; | |
1753 num_free++; | |
1754 float_free_list = &fblk->floats[i]; | |
1755 } | |
1756 else | |
1757 { | |
1758 num_used++; | |
1759 XUNMARK (fblk->floats[i].type); | |
1760 } | |
1761 lim = FLOAT_BLOCK_SIZE; | |
1762 } | |
1763 total_floats = num_used; | |
1764 total_free_floats = num_free; | |
1765 } | |
1766 #endif /* LISP_FLOAT_TYPE */ | |
1767 | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1768 #ifdef USE_TEXT_PROPERTIES |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1769 /* Put all unmarked intervals on free list */ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1770 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1771 register struct interval_block *iblk; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1772 register int lim = interval_block_index; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1773 register int num_free = 0, num_used = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1774 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1775 interval_free_list = 0; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1776 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1777 for (iblk = interval_block; iblk; iblk = iblk->next) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1778 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1779 register int i; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1780 |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1781 for (i = 0; i < lim; i++) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1782 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1783 if (! XMARKBIT (iblk->intervals[i].plist)) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1784 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1785 iblk->intervals[i].parent = interval_free_list; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1786 interval_free_list = &iblk->intervals[i]; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1787 num_free++; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1788 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1789 else |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1790 { |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1791 num_used++; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1792 XUNMARK (iblk->intervals[i].plist); |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1793 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1794 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1795 lim = INTERVAL_BLOCK_SIZE; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1796 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1797 total_intervals = num_used; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1798 total_free_intervals = num_free; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1799 } |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1800 #endif /* USE_TEXT_PROPERTIES */ |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1801 |
300 | 1802 /* Put all unmarked symbols on free list */ |
1803 { | |
1804 register struct symbol_block *sblk; | |
1805 register int lim = symbol_block_index; | |
1806 register int num_free = 0, num_used = 0; | |
1807 | |
1808 symbol_free_list = 0; | |
1809 | |
1810 for (sblk = symbol_block; sblk; sblk = sblk->next) | |
1811 { | |
1812 register int i; | |
1813 for (i = 0; i < lim; i++) | |
1814 if (!XMARKBIT (sblk->symbols[i].plist)) | |
1815 { | |
1816 XFASTINT (sblk->symbols[i].value) = (int) symbol_free_list; | |
1817 symbol_free_list = &sblk->symbols[i]; | |
1818 num_free++; | |
1819 } | |
1820 else | |
1821 { | |
1822 num_used++; | |
1823 sblk->symbols[i].name | |
1824 = XSTRING (*(Lisp_Object *) &sblk->symbols[i].name); | |
1825 XUNMARK (sblk->symbols[i].plist); | |
1826 } | |
1827 lim = SYMBOL_BLOCK_SIZE; | |
1828 } | |
1829 total_symbols = num_used; | |
1830 total_free_symbols = num_free; | |
1831 } | |
1832 | |
1833 #ifndef standalone | |
1834 /* Put all unmarked markers on free list. | |
1835 Dechain each one first from the buffer it points into. */ | |
1836 { | |
1837 register struct marker_block *mblk; | |
1838 struct Lisp_Marker *tem1; | |
1839 register int lim = marker_block_index; | |
1840 register int num_free = 0, num_used = 0; | |
1841 | |
1842 marker_free_list = 0; | |
1843 | |
1844 for (mblk = marker_block; mblk; mblk = mblk->next) | |
1845 { | |
1846 register int i; | |
1847 for (i = 0; i < lim; i++) | |
1848 if (!XMARKBIT (mblk->markers[i].chain)) | |
1849 { | |
1850 Lisp_Object tem; | |
1851 tem1 = &mblk->markers[i]; /* tem1 avoids Sun compiler bug */ | |
1852 XSET (tem, Lisp_Marker, tem1); | |
1853 unchain_marker (tem); | |
1854 XFASTINT (mblk->markers[i].chain) = (int) marker_free_list; | |
1855 marker_free_list = &mblk->markers[i]; | |
1856 num_free++; | |
1857 } | |
1858 else | |
1859 { | |
1860 num_used++; | |
1861 XUNMARK (mblk->markers[i].chain); | |
1862 } | |
1863 lim = MARKER_BLOCK_SIZE; | |
1864 } | |
1865 | |
1866 total_markers = num_used; | |
1867 total_free_markers = num_free; | |
1868 } | |
1869 | |
1870 /* Free all unmarked buffers */ | |
1871 { | |
1872 register struct buffer *buffer = all_buffers, *prev = 0, *next; | |
1873 | |
1874 while (buffer) | |
1875 if (!XMARKBIT (buffer->name)) | |
1876 { | |
1877 if (prev) | |
1878 prev->next = buffer->next; | |
1879 else | |
1880 all_buffers = buffer->next; | |
1881 next = buffer->next; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
1882 xfree (buffer); |
300 | 1883 buffer = next; |
1884 } | |
1885 else | |
1886 { | |
1887 XUNMARK (buffer->name); | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
1888 UNMARK_BALANCE_INTERVALS (buffer->intervals); |
300 | 1889 |
1890 #if 0 | |
1891 /* Each `struct Lisp_String *' was turned into a Lisp_Object | |
1892 for purposes of marking and relocation. | |
1893 Turn them back into C pointers now. */ | |
1894 buffer->upcase_table | |
1895 = XSTRING (*(Lisp_Object *)&buffer->upcase_table); | |
1896 buffer->downcase_table | |
1897 = XSTRING (*(Lisp_Object *)&buffer->downcase_table); | |
1898 buffer->sort_table | |
1899 = XSTRING (*(Lisp_Object *)&buffer->sort_table); | |
1900 buffer->folding_sort_table | |
1901 = XSTRING (*(Lisp_Object *)&buffer->folding_sort_table); | |
1902 #endif | |
1903 | |
1904 prev = buffer, buffer = buffer->next; | |
1905 } | |
1906 } | |
1907 | |
1908 #endif /* standalone */ | |
1909 | |
1910 /* Free all unmarked vectors */ | |
1911 { | |
1912 register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next; | |
1913 total_vector_size = 0; | |
1914 | |
1915 while (vector) | |
1916 if (!(vector->size & ARRAY_MARK_FLAG)) | |
1917 { | |
1918 if (prev) | |
1919 prev->next = vector->next; | |
1920 else | |
1921 all_vectors = vector->next; | |
1922 next = vector->next; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
1923 xfree (vector); |
300 | 1924 vector = next; |
1925 } | |
1926 else | |
1927 { | |
1928 vector->size &= ~ARRAY_MARK_FLAG; | |
1929 total_vector_size += vector->size; | |
1930 prev = vector, vector = vector->next; | |
1931 } | |
1932 } | |
1933 | |
1934 /* Free all "large strings" not marked with ARRAY_MARK_FLAG. */ | |
1935 { | |
1936 register struct string_block *sb = large_string_blocks, *prev = 0, *next; | |
1937 | |
1938 while (sb) | |
1939 if (!(((struct Lisp_String *)(&sb->chars[0]))->size & ARRAY_MARK_FLAG)) | |
1940 { | |
1941 if (prev) | |
1942 prev->next = sb->next; | |
1943 else | |
1944 large_string_blocks = sb->next; | |
1945 next = sb->next; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
1946 xfree (sb); |
300 | 1947 sb = next; |
1948 } | |
1949 else | |
1950 { | |
1951 ((struct Lisp_String *)(&sb->chars[0]))->size | |
1952 &= ~ARRAY_MARK_FLAG & ~MARKBIT; | |
1953 total_string_size += ((struct Lisp_String *)(&sb->chars[0]))->size; | |
1954 prev = sb, sb = sb->next; | |
1955 } | |
1956 } | |
1957 } | |
1958 | |
1908
d649f2179d67
* alloc.c (make_pure_float): Align pureptr on a sizeof (double)
Jim Blandy <jimb@redhat.com>
parents:
1893
diff
changeset
|
1959 /* Compactify strings, relocate references, and free empty string blocks. */ |
300 | 1960 |
1961 static void | |
1962 compact_strings () | |
1963 { | |
1964 /* String block of old strings we are scanning. */ | |
1965 register struct string_block *from_sb; | |
1966 /* A preceding string block (or maybe the same one) | |
1967 where we are copying the still-live strings to. */ | |
1968 register struct string_block *to_sb; | |
1969 int pos; | |
1970 int to_pos; | |
1971 | |
1972 to_sb = first_string_block; | |
1973 to_pos = 0; | |
1974 | |
1975 /* Scan each existing string block sequentially, string by string. */ | |
1976 for (from_sb = first_string_block; from_sb; from_sb = from_sb->next) | |
1977 { | |
1978 pos = 0; | |
1979 /* POS is the index of the next string in the block. */ | |
1980 while (pos < from_sb->pos) | |
1981 { | |
1982 register struct Lisp_String *nextstr | |
1983 = (struct Lisp_String *) &from_sb->chars[pos]; | |
1984 | |
1985 register struct Lisp_String *newaddr; | |
1986 register int size = nextstr->size; | |
1987 | |
1988 /* NEXTSTR is the old address of the next string. | |
1989 Just skip it if it isn't marked. */ | |
1990 if ((unsigned) size > STRING_BLOCK_SIZE) | |
1991 { | |
1992 /* It is marked, so its size field is really a chain of refs. | |
1993 Find the end of the chain, where the actual size lives. */ | |
1994 while ((unsigned) size > STRING_BLOCK_SIZE) | |
1995 { | |
1996 if (size & 1) size ^= MARKBIT | 1; | |
1997 size = *(int *)size & ~MARKBIT; | |
1998 } | |
1999 | |
2000 total_string_size += size; | |
2001 | |
2002 /* If it won't fit in TO_SB, close it out, | |
2003 and move to the next sb. Keep doing so until | |
2004 TO_SB reaches a large enough, empty enough string block. | |
2005 We know that TO_SB cannot advance past FROM_SB here | |
2006 since FROM_SB is large enough to contain this string. | |
2007 Any string blocks skipped here | |
2008 will be patched out and freed later. */ | |
2009 while (to_pos + STRING_FULLSIZE (size) | |
2010 > max (to_sb->pos, STRING_BLOCK_SIZE)) | |
2011 { | |
2012 to_sb->pos = to_pos; | |
2013 to_sb = to_sb->next; | |
2014 to_pos = 0; | |
2015 } | |
2016 /* Compute new address of this string | |
2017 and update TO_POS for the space being used. */ | |
2018 newaddr = (struct Lisp_String *) &to_sb->chars[to_pos]; | |
2019 to_pos += STRING_FULLSIZE (size); | |
2020 | |
2021 /* Copy the string itself to the new place. */ | |
2022 if (nextstr != newaddr) | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
2023 bcopy (nextstr, newaddr, size + 1 + sizeof (int) |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
2024 + INTERVAL_PTR_SIZE); |
300 | 2025 |
2026 /* Go through NEXTSTR's chain of references | |
2027 and make each slot in the chain point to | |
2028 the new address of this string. */ | |
2029 size = newaddr->size; | |
2030 while ((unsigned) size > STRING_BLOCK_SIZE) | |
2031 { | |
2032 register Lisp_Object *objptr; | |
2033 if (size & 1) size ^= MARKBIT | 1; | |
2034 objptr = (Lisp_Object *)size; | |
2035 | |
2036 size = XFASTINT (*objptr) & ~MARKBIT; | |
2037 if (XMARKBIT (*objptr)) | |
2038 { | |
2039 XSET (*objptr, Lisp_String, newaddr); | |
2040 XMARK (*objptr); | |
2041 } | |
2042 else | |
2043 XSET (*objptr, Lisp_String, newaddr); | |
2044 } | |
2045 /* Store the actual size in the size field. */ | |
2046 newaddr->size = size; | |
2047 } | |
2048 pos += STRING_FULLSIZE (size); | |
2049 } | |
2050 } | |
2051 | |
2052 /* Close out the last string block still used and free any that follow. */ | |
2053 to_sb->pos = to_pos; | |
2054 current_string_block = to_sb; | |
2055 | |
2056 from_sb = to_sb->next; | |
2057 to_sb->next = 0; | |
2058 while (from_sb) | |
2059 { | |
2060 to_sb = from_sb->next; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
2061 xfree (from_sb); |
300 | 2062 from_sb = to_sb; |
2063 } | |
2064 | |
2065 /* Free any empty string blocks further back in the chain. | |
2066 This loop will never free first_string_block, but it is very | |
2067 unlikely that that one will become empty, so why bother checking? */ | |
2068 | |
2069 from_sb = first_string_block; | |
2070 while (to_sb = from_sb->next) | |
2071 { | |
2072 if (to_sb->pos == 0) | |
2073 { | |
2074 if (from_sb->next = to_sb->next) | |
2075 from_sb->next->prev = from_sb; | |
2439
b6c62e4abf59
Put interrupt input blocking in a separate file from xterm.h.
Jim Blandy <jimb@redhat.com>
parents:
2370
diff
changeset
|
2076 xfree (to_sb); |
300 | 2077 } |
2078 else | |
2079 from_sb = to_sb; | |
2080 } | |
2081 } | |
2082 | |
1327
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2083 /* Debugging aids. */ |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2084 |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2085 DEFUN ("memory-limit", Fmemory_limit, Smemory_limit, 0, 0, "", |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2086 "Return the address of the last byte Emacs has allocated, divided by 1024.\n\ |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2087 This may be helpful in debugging Emacs's memory usage.\n\ |
1893
b047e77f3be4
(Fmemory_limit): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
1784
diff
changeset
|
2088 We divide the value by 1024 to make sure it fits in a Lisp integer.") |
1327
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2089 () |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2090 { |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2091 Lisp_Object end; |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2092 |
1362
4bea5980f778
* alloc.c (Fmemory_limit): Explain why we divide by 1024.
Jim Blandy <jimb@redhat.com>
parents:
1327
diff
changeset
|
2093 XSET (end, Lisp_Int, (int) sbrk (0) / 1024); |
1327
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2094 |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2095 return end; |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2096 } |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2097 |
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2098 |
300 | 2099 /* Initialization */ |
2100 | |
2101 init_alloc_once () | |
2102 { | |
2103 /* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */ | |
2104 pureptr = 0; | |
356 | 2105 #ifdef HAVE_SHM |
2106 pure_size = PURESIZE; | |
2107 #endif | |
300 | 2108 all_vectors = 0; |
2109 ignore_warnings = 1; | |
2110 init_strings (); | |
2111 init_cons (); | |
2112 init_symbol (); | |
2113 init_marker (); | |
2114 #ifdef LISP_FLOAT_TYPE | |
2115 init_float (); | |
2116 #endif /* LISP_FLOAT_TYPE */ | |
1300
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
2117 INIT_INTERVALS; |
b13b79e28eb5
* alloc.c: #include "intervals.h".
Joseph Arceneaux <jla@gnu.org>
parents:
1295
diff
changeset
|
2118 |
300 | 2119 ignore_warnings = 0; |
2120 gcprolist = 0; | |
2121 staticidx = 0; | |
2122 consing_since_gc = 0; | |
2123 gc_cons_threshold = 100000; | |
2124 #ifdef VIRT_ADDR_VARIES | |
2125 malloc_sbrk_unused = 1<<22; /* A large number */ | |
2126 malloc_sbrk_used = 100000; /* as reasonable as any number */ | |
2127 #endif /* VIRT_ADDR_VARIES */ | |
2128 } | |
2129 | |
2130 init_alloc () | |
2131 { | |
2132 gcprolist = 0; | |
2133 } | |
2134 | |
2135 void | |
2136 syms_of_alloc () | |
2137 { | |
2138 DEFVAR_INT ("gc-cons-threshold", &gc_cons_threshold, | |
2139 "*Number of bytes of consing between garbage collections.\n\ | |
2140 Garbage collection can happen automatically once this many bytes have been\n\ | |
2141 allocated since the last garbage collection. All data types count.\n\n\ | |
2142 Garbage collection happens automatically only when `eval' is called.\n\n\ | |
2143 By binding this temporarily to a large number, you can effectively\n\ | |
2144 prevent garbage collection during a part of the program."); | |
2145 | |
2146 DEFVAR_INT ("pure-bytes-used", &pureptr, | |
2147 "Number of bytes of sharable Lisp data allocated so far."); | |
2148 | |
2149 #if 0 | |
2150 DEFVAR_INT ("data-bytes-used", &malloc_sbrk_used, | |
2151 "Number of bytes of unshared memory allocated in this session."); | |
2152 | |
2153 DEFVAR_INT ("data-bytes-free", &malloc_sbrk_unused, | |
2154 "Number of bytes of unshared memory remaining available in this session."); | |
2155 #endif | |
2156 | |
2157 DEFVAR_LISP ("purify-flag", &Vpurify_flag, | |
2158 "Non-nil means loading Lisp code in order to dump an executable.\n\ | |
2159 This means that certain objects should be allocated in shared (pure) space."); | |
2160 | |
764 | 2161 DEFVAR_INT ("undo-limit", &undo_limit, |
300 | 2162 "Keep no more undo information once it exceeds this size.\n\ |
764 | 2163 This limit is applied when garbage collection happens.\n\ |
300 | 2164 The size is counted as the number of bytes occupied,\n\ |
2165 which includes both saved text and other data."); | |
764 | 2166 undo_limit = 20000; |
300 | 2167 |
764 | 2168 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit, |
300 | 2169 "Don't keep more than this much size of undo information.\n\ |
2170 A command which pushes past this size is itself forgotten.\n\ | |
764 | 2171 This limit is applied when garbage collection happens.\n\ |
300 | 2172 The size is counted as the number of bytes occupied,\n\ |
2173 which includes both saved text and other data."); | |
764 | 2174 undo_strong_limit = 30000; |
300 | 2175 |
2176 defsubr (&Scons); | |
2177 defsubr (&Slist); | |
2178 defsubr (&Svector); | |
2179 defsubr (&Smake_byte_code); | |
2180 defsubr (&Smake_list); | |
2181 defsubr (&Smake_vector); | |
2182 defsubr (&Smake_string); | |
2183 defsubr (&Smake_symbol); | |
2184 defsubr (&Smake_marker); | |
2185 defsubr (&Spurecopy); | |
2186 defsubr (&Sgarbage_collect); | |
1327
ef16e7c0d402
* alloc.c (Fmemory_limit): New function.
Jim Blandy <jimb@redhat.com>
parents:
1318
diff
changeset
|
2187 defsubr (&Smemory_limit); |
300 | 2188 } |