From 2c70e6b00aec31c455eee2a939863a4e382986fc Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 9 Jun 2014 19:03:49 +0400 Subject: [PATCH] Further adjustments to mark_object and friends. Now the mark_object's stack is just 32 bytes on a 64-bit system, which means extra 20% off the stack usage. * alloc.c (mark_save_value): As before, refactored out from ... (mark_object): ... adjusted user. Also add comment. --- src/ChangeLog | 8 ++++++++ src/alloc.c | 54 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 9c6596c306a..5fbf2e377e5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2014-06-09 Dmitry Antipov + + Further adjustments to mark_object and friends. + Now the mark_object's stack is just 32 bytes on a 64-bit + system, which means extra 20% off the stack usage. + * alloc.c (mark_save_value): As before, refactored out from ... + (mark_object): ... adjusted user. Also add comment. + 2014-06-09 Paul Eggert Fix core dump after a dropped X connection (Bug#17704). diff --git a/src/alloc.c b/src/alloc.c index 98a35853e02..a7446e6b708 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -6068,6 +6068,30 @@ mark_localized_symbol (struct Lisp_Symbol *ptr) mark_object (blv->defcell); } +NO_INLINE /* To reduce stack depth in mark_object. */ +static void +mark_save_value (struct Lisp_Save_Value *ptr) +{ + /* If `save_type' is zero, `data[0].pointer' is the address + of a memory area containing `data[1].integer' potential + Lisp_Objects. */ + if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY) + { + Lisp_Object *p = ptr->data[0].pointer; + ptrdiff_t nelt; + for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++) + mark_maybe_object (*p); + } + else + { + /* Find Lisp_Objects in `data[N]' slots and mark them. */ + int i; + for (i = 0; i < SAVE_VALUE_SLOTS; i++) + if (save_type (ptr, i) == SAVE_OBJECT) + mark_object (ptr->data[i].object); + } +} + /* Remove killed buffers or items whose car is a killed buffer from LIST, and mark other items. Return changed LIST, which is marked. */ @@ -6095,7 +6119,13 @@ mark_discard_killed_buffers (Lisp_Object list) return list; } -/* Determine type of generic Lisp_Object and mark it accordingly. */ +/* Determine type of generic Lisp_Object and mark it accordingly. + + This function implements a straightforward depth-first marking + algorithm and so the recursion depth may be very high (a few + tens of thousands is not uncommon). To minimize stack usage, + a few cold paths are moved out to NO_INLINE functions above. + In general, inlining them doesn't help you to gain more speed. */ void mark_object (Lisp_Object arg) @@ -6363,27 +6393,7 @@ mark_object (Lisp_Object arg) case Lisp_Misc_Save_Value: XMISCANY (obj)->gcmarkbit = 1; - { - struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); - /* If `save_type' is zero, `data[0].pointer' is the address - of a memory area containing `data[1].integer' potential - Lisp_Objects. */ - if (GC_MARK_STACK && ptr->save_type == SAVE_TYPE_MEMORY) - { - Lisp_Object *p = ptr->data[0].pointer; - ptrdiff_t nelt; - for (nelt = ptr->data[1].integer; nelt > 0; nelt--, p++) - mark_maybe_object (*p); - } - else - { - /* Find Lisp_Objects in `data[N]' slots and mark them. */ - int i; - for (i = 0; i < SAVE_VALUE_SLOTS; i++) - if (save_type (ptr, i) == SAVE_OBJECT) - mark_object (ptr->data[i].object); - } - } + mark_save_value (XSAVE_VALUE (obj)); break; case Lisp_Misc_Overlay: -- 2.39.2