Mercurial > hg > xemacs-beta
annotate src/marker.c @ 5160:ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
-------------------- ChangeLog entries follow: --------------------
lisp/ChangeLog addition:
2010-03-20 Ben Wing <ben@xemacs.org>
* diagnose.el (show-memory-usage):
* diagnose.el (show-object-memory-usage-stats):
Further changes to correspond with changes in the C code;
add an additional column showing the overhead used with each type,
and add it into the grand total memory usage.
src/ChangeLog addition:
2010-03-20 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (init_lrecord_stats):
* alloc.c (free_normal_lisp_object):
* alloc.c (struct):
* alloc.c (clear_lrecord_stats):
* alloc.c (tick_lrecord_stats):
* alloc.c (COUNT_FROB_BLOCK_USAGE):
* alloc.c (COPY_INTO_LRECORD_STATS):
* alloc.c (sweep_strings):
* alloc.c (UNMARK_string):
* alloc.c (gc_sweep_1):
* alloc.c (finish_object_memory_usage_stats):
* alloc.c (object_memory_usage_stats):
* alloc.c (object_dead_p):
* alloc.c (fixed_type_block_overhead):
* alloc.c (lisp_object_storage_size):
* emacs.c (main_1):
* lisp.h:
* lrecord.h:
Export lisp_object_storage_size() and malloced_storage_size() even
when not MEMORY_USAGE_STATS, to get the non-MEMORY_USAGE_STATS
build to compile.
Don't export fixed_type_block_overhead() any more.
Some code cleanup, rearrangement, add some section headers.
Clean up various bugs especially involving computation of overhead
and double-counting certain usage in total_gc_usage. Add
statistics computing the overhead used by all types. Don't add a
special entry for string headers in the object-memory-usage-stats
because it's already present as just "string". But do count the
overhead used by long strings. Don't try to call the
memory_usage() methods when NEW_GC because there's nowhere obvious
in the sweep stage to make the calls.
* marker.c (compute_buffer_marker_usage):
Just use lisp_object_storage_size() rather than trying to
reimplement it.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 20 Mar 2010 20:20:30 -0500 |
parents | 1fae11d56ad2 |
children | 6c6d78781d59 |
rev | line source |
---|---|
428 | 1 /* Markers: examining, setting and killing. |
2 Copyright (C) 1985, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
3 Copyright (C) 2002, 2010 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: FSF 19.30. */ | |
23 | |
24 /* This file has been Mule-ized. */ | |
25 | |
26 /* Note that markers are currently kept in an unordered list. | |
27 This means that marker operations may be inefficient if | |
28 there are a bunch of markers in the buffer. This probably | |
29 won't have a significant impact on redisplay (which uses | |
30 markers), but if it does, it wouldn't be too hard to change | |
31 to an ordered gap array. (Just copy the code from extents.c.) | |
32 */ | |
33 | |
34 #include <config.h> | |
35 #include "lisp.h" | |
36 | |
37 #include "buffer.h" | |
38 | |
39 static Lisp_Object | |
40 mark_marker (Lisp_Object obj) | |
41 { | |
440 | 42 Lisp_Marker *marker = XMARKER (obj); |
428 | 43 Lisp_Object buf; |
44 /* DO NOT mark through the marker's chain. | |
45 The buffer's markers chain does not preserve markers from gc; | |
46 Instead, markers are removed from the chain when they are freed | |
47 by gc. | |
48 */ | |
49 if (!marker->buffer) | |
50 return (Qnil); | |
51 | |
793 | 52 buf = wrap_buffer (marker->buffer); |
428 | 53 return (buf); |
54 } | |
55 | |
56 static void | |
2286 | 57 print_marker (Lisp_Object obj, Lisp_Object printcharfun, |
58 int UNUSED (escapeflag)) | |
428 | 59 { |
440 | 60 Lisp_Marker *marker = XMARKER (obj); |
428 | 61 |
62 if (print_readably) | |
5146
88bd4f3ef8e4
make lrecord UID's have a separate UID space for each object, resurrect debug SOE code in extents.c
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
63 printing_unreadable_object_fmt ("#<marker 0x%x>", LISP_OBJECT_UID (obj)); |
428 | 64 |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3263
diff
changeset
|
65 write_ascstring (printcharfun, GETTEXT ("#<marker ")); |
428 | 66 if (!marker->buffer) |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3263
diff
changeset
|
67 write_ascstring (printcharfun, GETTEXT ("in no buffer")); |
428 | 68 else |
69 { | |
826 | 70 write_fmt_string (printcharfun, "at %ld in ", |
71 (long) marker_position (obj)); | |
428 | 72 print_internal (marker->buffer->name, printcharfun, 0); |
73 } | |
826 | 74 if (marker->insertion_type) |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3263
diff
changeset
|
75 write_ascstring (printcharfun, " insertion-type=t"); |
5146
88bd4f3ef8e4
make lrecord UID's have a separate UID space for each object, resurrect debug SOE code in extents.c
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
76 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj)); |
428 | 77 } |
78 | |
79 static int | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
3263
diff
changeset
|
80 marker_equal (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth), |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
3263
diff
changeset
|
81 int UNUSED (foldcase)) |
428 | 82 { |
440 | 83 Lisp_Marker *marker1 = XMARKER (obj1); |
84 Lisp_Marker *marker2 = XMARKER (obj2); | |
428 | 85 |
86 return ((marker1->buffer == marker2->buffer) && | |
665 | 87 (marker1->membpos == marker2->membpos || |
428 | 88 /* All markers pointing nowhere are equal */ |
89 !marker1->buffer)); | |
90 } | |
91 | |
2515 | 92 static Hashcode |
2286 | 93 marker_hash (Lisp_Object obj, int UNUSED (depth)) |
428 | 94 { |
2515 | 95 Hashcode hash = (Hashcode) XMARKER (obj)->buffer; |
428 | 96 if (hash) |
665 | 97 hash = HASH2 (hash, XMARKER (obj)->membpos); |
428 | 98 return hash; |
99 } | |
100 | |
1204 | 101 static const struct memory_description marker_description[] = { |
2551 | 102 { XD_LISP_OBJECT, offsetof (Lisp_Marker, next), 0, { 0 }, XD_FLAG_NO_KKCC }, |
103 { XD_LISP_OBJECT, offsetof (Lisp_Marker, prev), 0, { 0 }, XD_FLAG_NO_KKCC }, | |
440 | 104 { XD_LISP_OBJECT, offsetof (Lisp_Marker, buffer) }, |
428 | 105 { XD_END } |
106 }; | |
107 | |
3263 | 108 #ifdef NEW_GC |
2720 | 109 static void |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
110 finalize_marker (Lisp_Object obj) |
2720 | 111 { |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
112 unchain_marker (obj); |
2720 | 113 } |
114 | |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
115 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("marker", marker, |
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
116 mark_marker, print_marker, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
117 finalize_marker, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
118 marker_equal, marker_hash, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
119 marker_description, Lisp_Marker); |
3263 | 120 #else /* not NEW_GC */ |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
121 DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT ("marker", marker, |
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
122 mark_marker, print_marker, 0, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
123 marker_equal, marker_hash, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
124 marker_description, Lisp_Marker); |
3263 | 125 #endif /* not NEW_GC */ |
428 | 126 |
127 /* Operations on markers. */ | |
128 | |
129 DEFUN ("marker-buffer", Fmarker_buffer, 1, 1, 0, /* | |
130 Return the buffer that MARKER points into, or nil if none. | |
131 Return nil if MARKER points into a dead buffer or doesn't point anywhere. | |
132 */ | |
133 (marker)) | |
134 { | |
135 struct buffer *buf; | |
136 CHECK_MARKER (marker); | |
137 /* Return marker's buffer only if it is not dead. */ | |
138 if ((buf = XMARKER (marker)->buffer) && BUFFER_LIVE_P (buf)) | |
139 { | |
793 | 140 return wrap_buffer (buf); |
428 | 141 } |
142 return Qnil; | |
143 } | |
144 | |
145 DEFUN ("marker-position", Fmarker_position, 1, 1, 0, /* | |
146 Return the position MARKER points at, as a character number. | |
147 Return `nil' if marker doesn't point anywhere. | |
148 */ | |
149 (marker)) | |
150 { | |
151 CHECK_MARKER (marker); | |
152 return XMARKER (marker)->buffer ? make_int (marker_position (marker)) : Qnil; | |
153 } | |
154 | |
155 #if 0 /* useful debugging function */ | |
156 | |
157 static void | |
158 check_marker_circularities (struct buffer *buf) | |
159 { | |
440 | 160 Lisp_Marker *tortoise, *hare; |
428 | 161 |
162 tortoise = BUF_MARKERS (buf); | |
163 hare = tortoise; | |
164 | |
165 if (!tortoise) | |
166 return; | |
167 | |
168 while (1) | |
169 { | |
170 assert (hare->buffer == buf); | |
171 hare = hare->next; | |
172 if (!hare) | |
173 return; | |
174 assert (hare->buffer == buf); | |
175 hare = hare->next; | |
176 if (!hare) | |
177 return; | |
178 tortoise = tortoise->next; | |
179 assert (tortoise != hare); | |
180 } | |
181 } | |
182 | |
183 #endif | |
184 | |
185 static Lisp_Object | |
444 | 186 set_marker_internal (Lisp_Object marker, Lisp_Object position, |
187 Lisp_Object buffer, int restricted_p) | |
428 | 188 { |
665 | 189 Charbpos charno; |
428 | 190 struct buffer *b; |
440 | 191 Lisp_Marker *m; |
428 | 192 int point_p; |
193 | |
194 CHECK_MARKER (marker); | |
195 | |
196 point_p = POINT_MARKER_P (marker); | |
197 | |
198 /* If position is nil or a marker that points nowhere, | |
199 make this marker point nowhere. */ | |
444 | 200 if (NILP (position) || |
201 (MARKERP (position) && !XMARKER (position)->buffer)) | |
428 | 202 { |
203 if (point_p) | |
563 | 204 invalid_operation ("Can't make point-marker point nowhere", |
205 marker); | |
428 | 206 if (XMARKER (marker)->buffer) |
207 unchain_marker (marker); | |
208 return marker; | |
209 } | |
210 | |
444 | 211 CHECK_INT_COERCE_MARKER (position); |
428 | 212 if (NILP (buffer)) |
213 b = current_buffer; | |
214 else | |
215 { | |
216 CHECK_BUFFER (buffer); | |
217 b = XBUFFER (buffer); | |
218 /* If buffer is dead, set marker to point nowhere. */ | |
219 if (!BUFFER_LIVE_P (XBUFFER (buffer))) | |
220 { | |
221 if (point_p) | |
563 | 222 invalid_operation |
428 | 223 ("Can't move point-marker in a killed buffer", marker); |
224 if (XMARKER (marker)->buffer) | |
225 unchain_marker (marker); | |
226 return marker; | |
227 } | |
228 } | |
229 | |
444 | 230 charno = XINT (position); |
428 | 231 m = XMARKER (marker); |
232 | |
233 if (restricted_p) | |
234 { | |
235 if (charno < BUF_BEGV (b)) charno = BUF_BEGV (b); | |
236 if (charno > BUF_ZV (b)) charno = BUF_ZV (b); | |
237 } | |
238 else | |
239 { | |
240 if (charno < BUF_BEG (b)) charno = BUF_BEG (b); | |
241 if (charno > BUF_Z (b)) charno = BUF_Z (b); | |
242 } | |
243 | |
244 if (point_p) | |
245 { | |
246 #ifndef moving_point_by_moving_its_marker_is_a_bug | |
247 BUF_SET_PT (b, charno); /* this will move the marker */ | |
248 #else /* It's not a feature, so it must be a bug */ | |
563 | 249 invalid_operation ("DEBUG: attempt to move point via point-marker", |
250 marker); | |
428 | 251 #endif |
252 } | |
253 else | |
254 { | |
665 | 255 m->membpos = charbpos_to_membpos (b, charno); |
428 | 256 } |
257 | |
258 if (m->buffer != b) | |
259 { | |
260 if (point_p) | |
563 | 261 invalid_operation ("Can't change buffer of point-marker", marker); |
428 | 262 if (m->buffer != 0) |
263 unchain_marker (marker); | |
264 m->buffer = b; | |
265 marker_next (m) = BUF_MARKERS (b); | |
266 marker_prev (m) = 0; | |
267 if (BUF_MARKERS (b)) | |
268 marker_prev (BUF_MARKERS (b)) = m; | |
269 BUF_MARKERS (b) = m; | |
270 } | |
271 | |
272 return marker; | |
273 } | |
274 | |
275 | |
276 DEFUN ("set-marker", Fset_marker, 2, 3, 0, /* | |
444 | 277 Move MARKER to position POSITION in BUFFER. |
278 POSITION can be a marker, an integer or nil. If POSITION is an | |
279 integer, make MARKER point before the POSITIONth character in BUFFER. | |
280 If POSITION is nil, makes MARKER point nowhere. Then it no longer | |
281 slows down editing in any buffer. If POSITION is less than 1, move | |
282 MARKER to the beginning of BUFFER. If POSITION is greater than the | |
283 size of BUFFER, move MARKER to the end of BUFFER. | |
428 | 284 BUFFER defaults to the current buffer. |
444 | 285 If this marker was returned by (point-marker t), then changing its |
286 position moves point. You cannot change its buffer or make it point | |
287 nowhere. | |
288 The return value is MARKER. | |
428 | 289 */ |
444 | 290 (marker, position, buffer)) |
428 | 291 { |
444 | 292 return set_marker_internal (marker, position, buffer, 0); |
428 | 293 } |
294 | |
295 | |
296 /* This version of Fset_marker won't let the position | |
297 be outside the visible part. */ | |
298 Lisp_Object | |
444 | 299 set_marker_restricted (Lisp_Object marker, Lisp_Object position, |
300 Lisp_Object buffer) | |
428 | 301 { |
444 | 302 return set_marker_internal (marker, position, buffer, 1); |
428 | 303 } |
304 | |
305 | |
306 /* This is called during garbage collection, | |
307 so we must be careful to ignore and preserve mark bits, | |
308 including those in chain fields of markers. */ | |
309 | |
310 void | |
311 unchain_marker (Lisp_Object m) | |
312 { | |
440 | 313 Lisp_Marker *marker = XMARKER (m); |
428 | 314 struct buffer *b = marker->buffer; |
315 | |
316 if (b == 0) | |
317 return; | |
318 | |
800 | 319 #ifdef ERROR_CHECK_STRUCTURES |
428 | 320 assert (BUFFER_LIVE_P (b)); |
321 #endif | |
322 | |
323 if (marker_next (marker)) | |
324 marker_prev (marker_next (marker)) = marker_prev (marker); | |
325 if (marker_prev (marker)) | |
326 marker_next (marker_prev (marker)) = marker_next (marker); | |
327 else | |
328 BUF_MARKERS (b) = marker_next (marker); | |
329 | |
800 | 330 #ifdef ERROR_CHECK_STRUCTURES |
428 | 331 assert (marker != XMARKER (b->point_marker)); |
332 #endif | |
333 | |
334 marker->buffer = 0; | |
335 } | |
336 | |
665 | 337 Bytebpos |
826 | 338 byte_marker_position (Lisp_Object marker) |
428 | 339 { |
440 | 340 Lisp_Marker *m = XMARKER (marker); |
428 | 341 struct buffer *buf = m->buffer; |
665 | 342 Bytebpos pos; |
428 | 343 |
344 if (!buf) | |
563 | 345 invalid_argument ("Marker does not point anywhere", Qunbound); |
428 | 346 |
347 /* FSF claims that marker indices could end up denormalized, i.e. | |
348 in the gap. This is way bogus if it ever happens, and means | |
349 something fucked up elsewhere. Since I've overhauled all this | |
350 shit, I don't think this can happen. In any case, the following | |
351 macro has an assert() in it that will catch these denormalized | |
352 positions. */ | |
665 | 353 pos = membpos_to_bytebpos (buf, m->membpos); |
428 | 354 |
355 return pos; | |
356 } | |
357 | |
665 | 358 Charbpos |
428 | 359 marker_position (Lisp_Object marker) |
360 { | |
361 struct buffer *buf = XMARKER (marker)->buffer; | |
362 | |
363 if (!buf) | |
563 | 364 invalid_argument ("Marker does not point anywhere", Qunbound); |
428 | 365 |
826 | 366 return bytebpos_to_charbpos (buf, byte_marker_position (marker)); |
428 | 367 } |
368 | |
369 void | |
826 | 370 set_byte_marker_position (Lisp_Object marker, Bytebpos pos) |
428 | 371 { |
440 | 372 Lisp_Marker *m = XMARKER (marker); |
428 | 373 struct buffer *buf = m->buffer; |
374 | |
375 if (!buf) | |
563 | 376 invalid_argument ("Marker does not point anywhere", Qunbound); |
428 | 377 |
665 | 378 m->membpos = bytebpos_to_membpos (buf, pos); |
428 | 379 } |
380 | |
381 void | |
665 | 382 set_marker_position (Lisp_Object marker, Charbpos pos) |
428 | 383 { |
384 struct buffer *buf = XMARKER (marker)->buffer; | |
385 | |
386 if (!buf) | |
563 | 387 invalid_argument ("Marker does not point anywhere", Qunbound); |
428 | 388 |
826 | 389 set_byte_marker_position (marker, charbpos_to_bytebpos (buf, pos)); |
428 | 390 } |
391 | |
392 static Lisp_Object | |
393 copy_marker_1 (Lisp_Object marker, Lisp_Object type, int noseeum) | |
394 { | |
3025 | 395 REGISTER Lisp_Object new_; |
428 | 396 |
397 while (1) | |
398 { | |
399 if (INTP (marker) || MARKERP (marker)) | |
400 { | |
401 if (noseeum) | |
3025 | 402 new_ = noseeum_make_marker (); |
428 | 403 else |
3025 | 404 new_ = Fmake_marker (); |
405 Fset_marker (new_, marker, | |
428 | 406 (MARKERP (marker) ? Fmarker_buffer (marker) : Qnil)); |
3025 | 407 XMARKER (new_)->insertion_type = !NILP (type); |
408 return new_; | |
428 | 409 } |
410 else | |
411 marker = wrong_type_argument (Qinteger_or_marker_p, marker); | |
412 } | |
413 | |
1204 | 414 RETURN_NOT_REACHED (Qnil); /* not reached */ |
428 | 415 } |
416 | |
417 DEFUN ("copy-marker", Fcopy_marker, 1, 2, 0, /* | |
444 | 418 Return a new marker pointing at the same place as MARKER-OR-INTEGER. |
419 If MARKER-OR-INTEGER is an integer, return a new marker pointing | |
428 | 420 at that position in the current buffer. |
444 | 421 Optional argument MARKER-TYPE specifies the insertion type of the new |
422 marker; see `marker-insertion-type'. | |
428 | 423 */ |
444 | 424 (marker_or_integer, marker_type)) |
428 | 425 { |
444 | 426 return copy_marker_1 (marker_or_integer, marker_type, 0); |
428 | 427 } |
428 | |
429 Lisp_Object | |
444 | 430 noseeum_copy_marker (Lisp_Object marker, Lisp_Object marker_type) |
428 | 431 { |
444 | 432 return copy_marker_1 (marker, marker_type, 1); |
428 | 433 } |
434 | |
435 DEFUN ("marker-insertion-type", Fmarker_insertion_type, 1, 1, 0, /* | |
436 Return insertion type of MARKER: t if it stays after inserted text. | |
437 nil means the marker stays before text inserted there. | |
438 */ | |
439 (marker)) | |
440 { | |
441 CHECK_MARKER (marker); | |
442 return XMARKER (marker)->insertion_type ? Qt : Qnil; | |
443 } | |
444 | |
445 DEFUN ("set-marker-insertion-type", Fset_marker_insertion_type, 2, 2, 0, /* | |
446 Set the insertion-type of MARKER to TYPE. | |
447 If TYPE is t, it means the marker advances when you insert text at it. | |
448 If TYPE is nil, it means the marker stays behind when you insert text at it. | |
449 */ | |
450 (marker, type)) | |
451 { | |
452 CHECK_MARKER (marker); | |
453 | |
454 XMARKER (marker)->insertion_type = ! NILP (type); | |
455 return type; | |
456 } | |
457 | |
458 /* #### What is the possible use of this? It looks quite useless to | |
459 me, because there is no way to find *which* markers are positioned | |
460 at POSITION. Additional bogosity bonus: (buffer-has-markers-at | |
461 (point)) will always return t because of the `point-marker'. The | |
462 same goes for the position of mark. Bletch! | |
463 | |
464 Someone should discuss this with Stallman, but I don't have the | |
465 stomach. In fact, this function sucks so badly that I'm disabling | |
466 it by default (although I've debugged it). If you want to use it, | |
467 use extents instead. --hniksic */ | |
468 #if 0 | |
826 | 469 DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, 1, 1, 0, /* |
428 | 470 Return t if there are markers pointing at POSITION in the current buffer. |
471 */ | |
472 (position)) | |
473 { | |
440 | 474 Lisp_Marker *marker; |
665 | 475 Membpos pos; |
428 | 476 |
665 | 477 /* A small optimization trick: convert POS to membpos now, rather |
478 than converting every marker's memory index to charbpos. */ | |
479 pos = bytebpos_to_membpos (current_buffer, | |
428 | 480 get_buffer_pos_byte (current_buffer, position, |
481 GB_COERCE_RANGE)); | |
482 | |
483 for (marker = BUF_MARKERS (current_buffer); | |
484 marker; | |
485 marker = marker_next (marker)) | |
486 { | |
665 | 487 /* We use marker->membpos, so we don't have to go through the |
428 | 488 unwieldy operation of creating a Lisp_Object for |
489 marker_position() every time around. */ | |
665 | 490 if (marker->membpos == pos) |
428 | 491 return Qt; |
492 } | |
493 | |
494 return Qnil; | |
495 } | |
496 #endif /* 0 */ | |
497 | |
498 #ifdef MEMORY_USAGE_STATS | |
499 | |
5160
ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
500 Bytecount |
5157
1fae11d56ad2
redo memory-usage mechanism, add way of dynamically initializing Lisp objects
Ben Wing <ben@xemacs.org>
parents:
5146
diff
changeset
|
501 compute_buffer_marker_usage (struct buffer *b, struct usage_stats *ustats) |
428 | 502 { |
440 | 503 Lisp_Marker *m; |
5160
ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
504 Bytecount total = 0; |
428 | 505 |
506 for (m = BUF_MARKERS (b); m; m = m->next) | |
5160
ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
507 total += lisp_object_storage_size (wrap_marker (m), ustats); |
ab9ee10a53e4
fix various problems with allocation statistics, track overhead properly
Ben Wing <ben@xemacs.org>
parents:
5157
diff
changeset
|
508 return total; |
428 | 509 } |
510 | |
511 #endif /* MEMORY_USAGE_STATS */ | |
512 | |
513 | |
514 void | |
515 syms_of_marker (void) | |
516 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
517 INIT_LISP_OBJECT (marker); |
442 | 518 |
428 | 519 DEFSUBR (Fmarker_position); |
520 DEFSUBR (Fmarker_buffer); | |
521 DEFSUBR (Fset_marker); | |
522 DEFSUBR (Fcopy_marker); | |
523 DEFSUBR (Fmarker_insertion_type); | |
524 DEFSUBR (Fset_marker_insertion_type); | |
525 #if 0 /* FSFmacs crock */ | |
526 DEFSUBR (Fbuffer_has_markers_at); | |
527 #endif | |
528 } | |
529 | |
530 void | |
531 init_buffer_markers (struct buffer *b) | |
532 { | |
793 | 533 Lisp_Object buf = wrap_buffer (b); |
428 | 534 |
535 b->mark = Fmake_marker (); | |
536 BUF_MARKERS (b) = 0; | |
537 b->point_marker = Fmake_marker (); | |
538 Fset_marker (b->point_marker, | |
539 /* For indirect buffers, point is already set. */ | |
540 b->base_buffer ? make_int (BUF_PT (b)) : make_int (1), | |
541 buf); | |
542 } | |
543 | |
544 void | |
545 uninit_buffer_markers (struct buffer *b) | |
546 { | |
547 /* Unchain all markers of this buffer | |
548 and leave them pointing nowhere. */ | |
440 | 549 REGISTER Lisp_Marker *m, *next; |
428 | 550 for (m = BUF_MARKERS (b); m; m = next) |
551 { | |
552 m->buffer = 0; | |
553 next = marker_next (m); | |
554 marker_next (m) = 0; | |
555 marker_prev (m) = 0; | |
556 } | |
557 BUF_MARKERS (b) = 0; | |
558 } |