Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 5142:f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-13 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Working with Lisp Objects):
* internals/internals.texi (Writing Macros):
* internals/internals.texi (lrecords):
More rewriting to correspond with changes from
*LRECORD* to *LISP_OBJECT*.
modules/ChangeLog addition:
2010-03-13 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (print_pgconn):
* postgresql/postgresql.c (print_pgresult):
printing_unreadable_object -> printing_unreadable_object_fmt.
2010-03-13 Ben Wing <ben@xemacs.org>
* ldap/eldap.c (print_ldap):
printing_unreadable_object -> printing_unreadable_object_fmt.
src/ChangeLog addition:
2010-03-13 Ben Wing <ben@xemacs.org>
* alloc.c (alloc_sized_lrecord_1):
* alloc.c (alloc_sized_lrecord_array):
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (disksave_object_finalization_1):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (tick_lcrecord_stats):
* alloc.c (sweep_lcrecords_1):
* buffer.c (print_buffer):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* casetab.c:
* casetab.c (print_case_table):
* console.c (print_console):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* data.c (print_weak_list):
* data.c (print_weak_box):
* data.c (print_ephemeron):
* data.c (ephemeron_equal):
* database.c (print_database):
* database.c (finalize_database):
* device-msw.c (sync_printer_with_devmode):
* device-msw.c (print_devmode):
* device-msw.c (finalize_devmode):
* device.c:
* device.c (print_device):
* elhash.c:
* elhash.c (print_hash_table):
* eval.c (print_subr):
* eval.c (print_multiple_value):
* event-stream.c (event_stream_resignal_wakeup):
* events.c (clear_event_resource):
* events.c (zero_event):
* events.c (print_event):
* extents.c:
* extents.c (print_extent):
* file-coding.c (print_coding_system):
* font-mgr.c:
* font-mgr.c (Ffc_init):
* frame.c:
* frame.c (print_frame):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c:
* glyphs.c (print_image_instance):
* glyphs.c (print_glyph):
* gui.c (print_gui_item):
* gui.c (copy_gui_item):
* keymap.c (print_keymap):
* keymap.c (MARKED_SLOT):
* lisp.h:
* lisp.h (struct Lisp_String):
* lisp.h (DEFUN):
* lisp.h (DEFUN_NORETURN):
* lrecord.h:
* lrecord.h (NORMAL_LISP_OBJECT_UID):
* lrecord.h (struct lrecord_header):
* lrecord.h (set_lheader_implementation):
* lrecord.h (struct old_lcrecord_header):
* lrecord.h (struct free_lcrecord_header):
* marker.c (print_marker):
* mule-charset.c:
* mule-charset.c (print_charset):
* objects.c (print_color_instance):
* objects.c (print_font_instance):
* objects.c (finalize_font_instance):
* print.c (print_cons):
* print.c (printing_unreadable_object_fmt):
* print.c (printing_unreadable_lisp_object):
* print.c (external_object_printer):
* print.c (internal_object_printer):
* print.c (debug_p4):
* print.c (ext_print_begin):
* process.c (print_process):
* rangetab.c (print_range_table):
* rangetab.c (range_table_equal):
* scrollbar.c (free_scrollbar_instance):
* specifier.c (print_specifier):
* specifier.c (finalize_specifier):
* symbols.c (guts_of_unbound_marker):
* symeval.h:
* symeval.h (DEFVAR_SYMVAL_FWD):
* tooltalk.c:
* tooltalk.c (print_tooltalk_message):
* tooltalk.c (print_tooltalk_pattern):
* ui-gtk.c (ffi_object_printer):
* ui-gtk.c (emacs_gtk_object_printer):
* ui-gtk.c (emacs_gtk_boxed_printer):
* window.c (print_window):
* window.c (free_window_mirror):
* window.c (debug_print_window):
* xemacs.def.in.in:
(1) printing_unreadable_object -> printing_unreadable_object_fmt.
(2) printing_unreadable_lcrecord -> printing_unreadable_lisp_object
and fix up so it no longer requires an lcrecord.
These previous changes eliminate most of the remaining places where
the terms `lcrecord' and `lrecord' occurred outside of specialized
code.
(3) Fairly major change: Reduce the number of words in an lcrecord
from 3 to 2. The third word consisted of a uid that duplicated the
lrecord uid, and a single free bit, which was moved into the lrecord
structure. This reduces the size of the `uid' slot from 21 bits to
20 bits. Arguably this isn't enough -- we could easily have more than
1,000,000 or so objects created in a session. The answer is
(a) It doesn't really matter if we overflow the uid field because
it's only used for debugging, to identify an object uniquely
(or pretty much so).
(b) If we cared about it overflowing and wanted to reduce this,
we could make it so that cons, string, float and certain other
frob-block types that never print out the uid simply don't
store a uid in them and don't increment the lrecord_uid_counter.
(4) In conjunction with (3), create new macro NORMAL_LISP_OBJECT_UID()
and use it to abstract out the differences between NEWGC and old-GC
in accessing the `uid' value from a "normal Lisp Object pointer".
(5) In events.c, use zero_nonsized_lisp_object() in place of custom-
written equivalent. In font-mgr.c use external_object_printer()
in place of custom-written equivalents.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 13 Mar 2010 05:38:08 -0600 |
parents | 7be849cb8828 |
children | 88bd4f3ef8e4 |
comparison
equal
deleted
inserted
replaced
5141:0dcd22290039 | 5142:f965e31a35f0 |
---|---|
55 garbage collector, and the remaining 21 or 22 bits hold the UID. | 55 garbage collector, and the remaining 21 or 22 bits hold the UID. |
56 | 56 |
57 Under NEW_GC, NORMAL_LISP_OBJECT_HEADER also resolves to `struct | 57 Under NEW_GC, NORMAL_LISP_OBJECT_HEADER also resolves to `struct |
58 lrecord_header'. Under old-GC, however, NORMAL_LISP_OBJECT_HEADER | 58 lrecord_header'. Under old-GC, however, NORMAL_LISP_OBJECT_HEADER |
59 resolves to a `struct old_lcrecord_header' (note the `c'), which is a | 59 resolves to a `struct old_lcrecord_header' (note the `c'), which is a |
60 larger structure -- on 32-bit machines it occupies 3 machine words | 60 larger structure -- on 32-bit machines it occupies 2 machine words |
61 instead of 1. Such an object is known internally as an "lcrecord". The | 61 instead of 1. Such an object is known internally as an "lcrecord". The |
62 first word of `struct old_lcrecord_header' is an embedded `struct | 62 first word of `struct old_lcrecord_header' is an embedded `struct |
63 lrecord_header' with the same information as for frob-block objects; | 63 lrecord_header' with the same information as for frob-block objects; |
64 that way, all objects can be cast to a `struct lrecord_header' to | 64 that way, all objects can be cast to a `struct lrecord_header' to |
65 determine their type or other info. The other words consist of a | 65 determine their type or other info. The other word is a pointer, used |
66 pointer, used to thread all lcrecords together in one big linked list, | 66 to thread all lcrecords together in one big linked list. |
67 and a 32-bit structure that contains another UID field (#### which | |
68 should be deleted, as it is redundant; it dates back to the days when | |
69 the lrecord_header consisted of a pointer to an object's implementation | |
70 structure rather than an index). | |
71 | 67 |
72 Under old-GC, normal objects (i.e. lcrecords) are allocated in | 68 Under old-GC, normal objects (i.e. lcrecords) are allocated in |
73 individual chunks using the underlying allocator (i.e. xmalloc(), which | 69 individual chunks using the underlying allocator (i.e. xmalloc(), which |
74 is a thin wrapper around malloc()). Frob-block objects are more | 70 is a thin wrapper around malloc()). Frob-block objects are more |
75 efficient than normal objects, as they have a smaller header and don't | 71 efficient than normal objects, as they have a smaller header and don't |
189 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ | 185 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ |
190 alloc_sized_lrecord (size, &lrecord_##type) | 186 alloc_sized_lrecord (size, &lrecord_##type) |
191 #define NORMAL_LISP_OBJECT_HEADER struct lrecord_header | 187 #define NORMAL_LISP_OBJECT_HEADER struct lrecord_header |
192 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header | 188 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header |
193 #define LISP_OBJECT_FROB_BLOCK_P(obj) 0 | 189 #define LISP_OBJECT_FROB_BLOCK_P(obj) 0 |
190 #define NORMAL_LISP_OBJECT_UID(obj) ((obj)->header.uid) | |
194 #else /* not NEW_GC */ | 191 #else /* not NEW_GC */ |
195 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type) | 192 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type) |
196 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ | 193 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ |
197 old_alloc_sized_lcrecord (size, &lrecord_##type) | 194 old_alloc_sized_lcrecord (size, &lrecord_##type) |
198 #define NORMAL_LISP_OBJECT_HEADER struct old_lcrecord_header | 195 #define NORMAL_LISP_OBJECT_HEADER struct old_lcrecord_header |
199 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header | 196 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header |
200 #define LISP_OBJECT_FROB_BLOCK_P(obj) (XRECORD_LHEADER_IMPLEMENTATION(obj)->frob_block_p) | 197 #define LISP_OBJECT_FROB_BLOCK_P(obj) (XRECORD_LHEADER_IMPLEMENTATION(obj)->frob_block_p) |
198 #define NORMAL_LISP_OBJECT_UID(obj) ((obj)->header.lheader.uid) | |
201 #endif /* not NEW_GC */ | 199 #endif /* not NEW_GC */ |
202 | 200 |
203 BEGIN_C_DECLS | 201 BEGIN_C_DECLS |
204 | 202 |
205 struct lrecord_header | 203 struct lrecord_header |
236 unsigned int c_readonly :1; | 234 unsigned int c_readonly :1; |
237 | 235 |
238 /* 1 if the object is readonly from lisp */ | 236 /* 1 if the object is readonly from lisp */ |
239 unsigned int lisp_readonly :1; | 237 unsigned int lisp_readonly :1; |
240 | 238 |
239 /* The `free' field is currently used only for lcrecords under old-GC. | |
240 It is a flag that indicates whether this lcrecord is on a "free list". | |
241 Free lists are used to minimize the number of calls to malloc() when | |
242 we're repeatedly allocating and freeing a number of the same sort of | |
243 lcrecord. Lcrecords on a free list always get marked in a different | |
244 fashion, so we can use this flag as a sanity check to make sure that | |
245 free lists only have freed lcrecords and there are no freed lcrecords | |
246 elsewhere. */ | |
247 unsigned int free :1; | |
248 | |
241 /* The `uid' field is just for debugging/printing convenience. Having | 249 /* The `uid' field is just for debugging/printing convenience. Having |
242 this slot doesn't hurt us spacewise, since the bits are unused | 250 this slot doesn't hurt us spacewise, since the bits are unused |
243 anyway. (The bits are used for strings, though.) */ | 251 anyway. (The bits are used for strings, though.) */ |
244 unsigned int uid :21; | 252 unsigned int uid :20; |
245 | 253 |
246 #endif /* not NEW_GC */ | 254 #endif /* not NEW_GC */ |
247 }; | 255 }; |
248 | 256 |
249 struct lrecord_implementation; | 257 struct lrecord_implementation; |
263 struct lrecord_header* SLI_header = (header); \ | 271 struct lrecord_header* SLI_header = (header); \ |
264 SLI_header->type = (imp)->lrecord_type_index; \ | 272 SLI_header->type = (imp)->lrecord_type_index; \ |
265 SLI_header->mark = 0; \ | 273 SLI_header->mark = 0; \ |
266 SLI_header->c_readonly = 0; \ | 274 SLI_header->c_readonly = 0; \ |
267 SLI_header->lisp_readonly = 0; \ | 275 SLI_header->lisp_readonly = 0; \ |
276 SLI_header->free = 0; \ | |
268 SLI_header->uid = lrecord_uid_counter++; \ | 277 SLI_header->uid = lrecord_uid_counter++; \ |
269 } while (0) | 278 } while (0) |
270 #endif /* not NEW_GC */ | 279 #endif /* not NEW_GC */ |
271 | 280 |
272 #ifndef NEW_GC | 281 #ifndef NEW_GC |
283 | 292 |
284 For example, the event and marker object types allocate members | 293 For example, the event and marker object types allocate members |
285 out of memory chunks, and are able to find all unmarked members | 294 out of memory chunks, and are able to find all unmarked members |
286 by sweeping through the elements of the list of chunks. */ | 295 by sweeping through the elements of the list of chunks. */ |
287 struct old_lcrecord_header *next; | 296 struct old_lcrecord_header *next; |
288 | |
289 /* The `uid' field is just for debugging/printing convenience. | |
290 Having this slot doesn't hurt us much spacewise, since an | |
291 lcrecord already has the above slots plus malloc overhead. */ | |
292 unsigned int uid :31; | |
293 | |
294 /* The `free' field is a flag that indicates whether this lcrecord | |
295 is on a "free list". Free lists are used to minimize the number | |
296 of calls to malloc() when we're repeatedly allocating and freeing | |
297 a number of the same sort of lcrecord. Lcrecords on a free list | |
298 always get marked in a different fashion, so we can use this flag | |
299 as a sanity check to make sure that free lists only have freed | |
300 lcrecords and there are no freed lcrecords elsewhere. */ | |
301 unsigned int free :1; | |
302 }; | 297 }; |
303 | 298 |
304 /* Used for lcrecords in an lcrecord-list. */ | 299 /* Used for lcrecords in an lcrecord-list. */ |
305 struct free_lcrecord_header | 300 struct free_lcrecord_header |
306 { | 301 { |