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 {