From 3b48f99542d822c0647334524035e93f4a094358 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Fri, 16 Jan 2015 11:42:24 +0300 Subject: [PATCH] Tune pseudovector allocation assuming Qnil == 0 * alloc.c (allocate_pseudovector): Use memset for both Lisp_Objects and regular slots. Add zerolen arg. * lisp.h (allocate_pseudovector): Adjust prototype. (ALLOCATE_PSEUDOVECTOR): Adjust user. (ALLOCATE_ZEROED_PSEUDOVECTOR): New macro. (allocate_hash_table, allocate_window, allocate_frame) (allocate_process, allocate_terminal): Remove prototypes. * fns.c (allocate_hash_table): Now static here. * frame.c (allocate_frame): * process.c (allocate_process): * terminal.c (allocate_terminal): * window.c (allocate_window): Now static here. Use ALLOCATE_ZEROED_PSEUDOVECTOR. Add comment. --- src/ChangeLog | 17 ++++++++++++++ src/alloc.c | 64 ++++---------------------------------------------- src/fns.c | 9 +++++++ src/font.c | 7 +++--- src/frame.c | 7 ++++++ src/lisp.h | 29 +++++++++++++++-------- src/process.c | 10 +++++++- src/terminal.c | 9 +++++++ src/window.c | 11 ++++++++- 9 files changed, 89 insertions(+), 74 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index ae634f318f0..63da5cbd972 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2015-01-16 Dmitry Antipov + + Tune pseudovector allocation assuming Qnil == 0. + * alloc.c (allocate_pseudovector): Use memset for both + Lisp_Objects and regular slots. Add zerolen arg. + * lisp.h (allocate_pseudovector): Adjust prototype. + (ALLOCATE_PSEUDOVECTOR): Adjust user. + (ALLOCATE_ZEROED_PSEUDOVECTOR): New macro. + (allocate_hash_table, allocate_window, allocate_frame) + (allocate_process, allocate_terminal): Remove prototypes. + * fns.c (allocate_hash_table): Now static here. + * frame.c (allocate_frame): + * process.c (allocate_process): + * terminal.c (allocate_terminal): + * window.c (allocate_window): Now static here. + Use ALLOCATE_ZEROED_PSEUDOVECTOR. Add comment. + 2015-01-16 Paul Eggert Give up on -Wsuggest-attribute=const diff --git a/src/alloc.c b/src/alloc.c index 7c937332407..22a15b4ac59 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3163,19 +3163,19 @@ allocate_vector (EMACS_INT len) /* Allocate other vector-like structures. */ struct Lisp_Vector * -allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag) +allocate_pseudovector (int memlen, int lisplen, + int zerolen, enum pvec_type tag) { struct Lisp_Vector *v = allocate_vectorlike (memlen); - int i; /* Catch bogus values. */ eassert (tag <= PVEC_FONT); eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1); - /* Only the first lisplen slots will be traced normally by the GC. */ - for (i = 0; i < lisplen; ++i) - v->contents[i] = Qnil; + /* Only the first lisplen slots will be traced normally by the GC. + But since Qnil == 0, we can memset Lisp_Object slots as well. */ + memset (v->contents, 0, zerolen * word_size); XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); return v; @@ -3194,60 +3194,6 @@ allocate_buffer (void) return b; } -struct Lisp_Hash_Table * -allocate_hash_table (void) -{ - return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); -} - -struct window * -allocate_window (void) -{ - struct window *w; - - w = ALLOCATE_PSEUDOVECTOR (struct window, current_matrix, PVEC_WINDOW); - /* Users assumes that non-Lisp data is zeroed. */ - memset (&w->current_matrix, 0, - sizeof (*w) - offsetof (struct window, current_matrix)); - return w; -} - -struct terminal * -allocate_terminal (void) -{ - struct terminal *t; - - t = ALLOCATE_PSEUDOVECTOR (struct terminal, next_terminal, PVEC_TERMINAL); - /* Users assumes that non-Lisp data is zeroed. */ - memset (&t->next_terminal, 0, - sizeof (*t) - offsetof (struct terminal, next_terminal)); - return t; -} - -struct frame * -allocate_frame (void) -{ - struct frame *f; - - f = ALLOCATE_PSEUDOVECTOR (struct frame, face_cache, PVEC_FRAME); - /* Users assumes that non-Lisp data is zeroed. */ - memset (&f->face_cache, 0, - sizeof (*f) - offsetof (struct frame, face_cache)); - return f; -} - -struct Lisp_Process * -allocate_process (void) -{ - struct Lisp_Process *p; - - p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); - /* Users assumes that non-Lisp data is zeroed. */ - memset (&p->pid, 0, - sizeof (*p) - offsetof (struct Lisp_Process, pid)); - return p; -} - DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, doc: /* Return a newly created vector of length LENGTH, with each element being INIT. See also the function `vector'. */) diff --git a/src/fns.c b/src/fns.c index 91cd5132546..ca3d98b23dd 100644 --- a/src/fns.c +++ b/src/fns.c @@ -3814,6 +3814,15 @@ hashfn_user_defined (struct hash_table_test *ht, Lisp_Object key) return hashfn_eq (ht, hash); } +/* Allocate basically initialized hash table. */ + +static struct Lisp_Hash_Table * +allocate_hash_table (void) +{ + return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, + count, PVEC_HASH_TABLE); +} + /* An upper bound on the size of a hash table index. It must fit in ptrdiff_t and be a valid Emacs fixnum. */ #define INDEX_SIZE_BOUND \ diff --git a/src/font.c b/src/font.c index a68c3c707c8..074e86687a1 100644 --- a/src/font.c +++ b/src/font.c @@ -156,7 +156,7 @@ font_make_spec (void) struct font_spec *spec = ((struct font_spec *) allocate_pseudovector (VECSIZE (struct font_spec), - FONT_SPEC_MAX, PVEC_FONT)); + FONT_SPEC_MAX, FONT_SPEC_MAX, PVEC_FONT)); XSETFONT (font_spec, spec); return font_spec; } @@ -168,7 +168,7 @@ font_make_entity (void) struct font_entity *entity = ((struct font_entity *) allocate_pseudovector (VECSIZE (struct font_entity), - FONT_ENTITY_MAX, PVEC_FONT)); + FONT_ENTITY_MAX, FONT_ENTITY_MAX, PVEC_FONT)); XSETFONT (font_entity, entity); return font_entity; } @@ -181,7 +181,8 @@ font_make_object (int size, Lisp_Object entity, int pixelsize) { Lisp_Object font_object; struct font *font - = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT); + = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, + FONT_OBJECT_MAX, PVEC_FONT); int i; /* GC can happen before the driver is set up, diff --git a/src/frame.c b/src/frame.c index ec580f37c5b..2ce5a623853 100644 --- a/src/frame.c +++ b/src/frame.c @@ -570,6 +570,13 @@ adjust_frame_size (struct frame *f, int new_width, int new_height, int inhibit, run_window_configuration_change_hook (f); } +/* Allocate basically initialized frame. */ + +static struct frame * +allocate_frame (void) +{ + return ALLOCATE_ZEROED_PSEUDOVECTOR (struct frame, face_cache, PVEC_FRAME); +} struct frame * make_frame (bool mini_p) diff --git a/src/lisp.h b/src/lisp.h index 51556fcc91c..fd0a0342cf8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3780,16 +3780,25 @@ make_uninit_sub_char_table (int depth, int min_char) return v; } -extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type); -#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ - ((typ*) \ - allocate_pseudovector \ - (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag)) -extern struct Lisp_Hash_Table *allocate_hash_table (void); -extern struct window *allocate_window (void); -extern struct frame *allocate_frame (void); -extern struct Lisp_Process *allocate_process (void); -extern struct terminal *allocate_terminal (void); +extern struct Lisp_Vector *allocate_pseudovector (int, int, int, + enum pvec_type); + +/* Allocate partially initialized pseudovector where all Lisp_Object + slots are set to Qnil but the rest (if any) is left uninitialized. */ + +#define ALLOCATE_PSEUDOVECTOR(type, field, tag) \ + ((type *) allocate_pseudovector (VECSIZE (type), \ + PSEUDOVECSIZE (type, field), \ + PSEUDOVECSIZE (type, field), tag)) + +/* Allocate fully initialized pseudovector where all Lisp_Object + slots are set to Qnil and the rest (if any) is zeroed. */ + +#define ALLOCATE_ZEROED_PSEUDOVECTOR(type, field, tag) \ + ((type *) allocate_pseudovector (VECSIZE (type), \ + PSEUDOVECSIZE (type, field), \ + VECSIZE (type), tag)) + extern bool gc_in_progress; extern bool abort_on_gc; extern Lisp_Object make_float (double); diff --git a/src/process.c b/src/process.c index 77c94f29211..30380548210 100644 --- a/src/process.c +++ b/src/process.c @@ -687,7 +687,15 @@ allocate_pty (char pty_name[PTY_NAME_SIZE]) #endif /* HAVE_PTYS */ return -1; } - + +/* Allocate basically initialized process. */ + +static struct Lisp_Process * +allocate_process (void) +{ + return ALLOCATE_ZEROED_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); +} + static Lisp_Object make_process (Lisp_Object name) { diff --git a/src/terminal.c b/src/terminal.c index 92befd28543..b48d0623e12 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -254,6 +254,15 @@ get_named_terminal (const char *name) return NULL; } +/* Allocate basically initialized terminal. */ + +static struct terminal * +allocate_terminal (void) +{ + return ALLOCATE_ZEROED_PSEUDOVECTOR + (struct terminal, next_terminal, PVEC_TERMINAL); +} + /* Create a new terminal object of TYPE and add it to the terminal list. RIF may be NULL if this terminal type doesn't support window-based redisplay. */ diff --git a/src/window.c b/src/window.c index e5ddef5fa40..53a235f8446 100644 --- a/src/window.c +++ b/src/window.c @@ -3642,7 +3642,16 @@ temp_output_buffer_show (register Lisp_Object buf) } } } - + +/* Allocate basically initialized window. */ + +static struct window * +allocate_window (void) +{ + return ALLOCATE_ZEROED_PSEUDOVECTOR + (struct window, current_matrix, PVEC_WINDOW); +} + /* Make new window, have it replace WINDOW in window-tree, and make WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only horizontal child). */ -- 2.39.2