diff options
| author | Paul Eggert | 2018-06-14 15:59:08 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-06-14 17:13:38 -0700 |
| commit | 12fd59bba0b04fb6727f4fa54e3305a65fae1d44 (patch) | |
| tree | a01a32e9fd01e35f566d97647e79acb43b43f9a3 /src | |
| parent | ef66660c17d1b164414c46d67ba3494f8a18c8ec (diff) | |
| download | emacs-12fd59bba0b04fb6727f4fa54e3305a65fae1d44.tar.gz emacs-12fd59bba0b04fb6727f4fa54e3305a65fae1d44.zip | |
Avoid Lisp_Misc allocation if C stack suffices
* src/fileio.c (union read_non_regular): New type.
(read_non_regular, Finsert_file_contents):
Use it to avoid allocating a Lisp_Misc.
* src/keymap.c (union map_keymap): New type.
(map_keymap_char_table_item, map_keymap_internal):
Use it to avoid allocating a Lisp_Misc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 29 | ||||
| -rw-r--r-- | src/keymap.c | 26 |
2 files changed, 37 insertions, 18 deletions
diff --git a/src/fileio.c b/src/fileio.c index 47c5fec8532..7f678dd8216 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -3362,20 +3362,27 @@ decide_coding_unwind (Lisp_Object unwind_data) | |||
| 3362 | bset_undo_list (current_buffer, undo_list); | 3362 | bset_undo_list (current_buffer, undo_list); |
| 3363 | } | 3363 | } |
| 3364 | 3364 | ||
| 3365 | /* Read from a non-regular file. STATE is a Lisp_Save_Value | 3365 | /* Read from a non-regular file. Return the number of bytes read. */ |
| 3366 | object where slot 0 is the file descriptor, slot 1 specifies | 3366 | |
| 3367 | an offset to put the read bytes, and slot 2 is the maximum | 3367 | union read_non_regular |
| 3368 | amount of bytes to read. Value is the number of bytes read. */ | 3368 | { |
| 3369 | struct | ||
| 3370 | { | ||
| 3371 | int fd; | ||
| 3372 | ptrdiff_t inserted, trytry; | ||
| 3373 | } s; | ||
| 3374 | GCALIGNED_UNION | ||
| 3375 | }; | ||
| 3376 | verify (alignof (union read_non_regular) % GCALIGNMENT == 0); | ||
| 3369 | 3377 | ||
| 3370 | static Lisp_Object | 3378 | static Lisp_Object |
| 3371 | read_non_regular (Lisp_Object state) | 3379 | read_non_regular (Lisp_Object state) |
| 3372 | { | 3380 | { |
| 3373 | int nbytes = emacs_read_quit (XSAVE_INTEGER (state, 0), | 3381 | union read_non_regular *data = XINTPTR (state); |
| 3382 | int nbytes = emacs_read_quit (data->s.fd, | ||
| 3374 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE | 3383 | ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE |
| 3375 | + XSAVE_INTEGER (state, 1)), | 3384 | + data->s.inserted), |
| 3376 | XSAVE_INTEGER (state, 2)); | 3385 | data->s.trytry); |
| 3377 | /* Fast recycle this object for the likely next call. */ | ||
| 3378 | free_misc (state); | ||
| 3379 | return make_number (nbytes); | 3386 | return make_number (nbytes); |
| 3380 | } | 3387 | } |
| 3381 | 3388 | ||
| @@ -4230,9 +4237,9 @@ by calling `format-decode', which see. */) | |||
| 4230 | /* Read from the file, capturing `quit'. When an | 4237 | /* Read from the file, capturing `quit'. When an |
| 4231 | error occurs, end the loop, and arrange for a quit | 4238 | error occurs, end the loop, and arrange for a quit |
| 4232 | to be signaled after decoding the text we read. */ | 4239 | to be signaled after decoding the text we read. */ |
| 4240 | union read_non_regular data = {{fd, inserted, trytry}}; | ||
| 4233 | nbytes = internal_condition_case_1 | 4241 | nbytes = internal_condition_case_1 |
| 4234 | (read_non_regular, | 4242 | (read_non_regular, make_pointer_integer (&data), |
| 4235 | make_save_int_int_int (fd, inserted, trytry), | ||
| 4236 | Qerror, read_non_regular_quit); | 4243 | Qerror, read_non_regular_quit); |
| 4237 | 4244 | ||
| 4238 | if (NILP (nbytes)) | 4245 | if (NILP (nbytes)) |
diff --git a/src/keymap.c b/src/keymap.c index c8cc933e782..982c014f01f 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -546,19 +546,29 @@ map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, L | |||
| 546 | (*fun) (key, val, args, data); | 546 | (*fun) (key, val, args, data); |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | union map_keymap | ||
| 550 | { | ||
| 551 | struct | ||
| 552 | { | ||
| 553 | map_keymap_function_t fun; | ||
| 554 | Lisp_Object args; | ||
| 555 | void *data; | ||
| 556 | } s; | ||
| 557 | GCALIGNED_UNION | ||
| 558 | }; | ||
| 559 | verify (alignof (union map_keymap) % GCALIGNMENT == 0); | ||
| 560 | |||
| 549 | static void | 561 | static void |
| 550 | map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val) | 562 | map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val) |
| 551 | { | 563 | { |
| 552 | if (!NILP (val)) | 564 | if (!NILP (val)) |
| 553 | { | 565 | { |
| 554 | map_keymap_function_t fun | ||
| 555 | = (map_keymap_function_t) XSAVE_FUNCPOINTER (args, 0); | ||
| 556 | /* If the key is a range, make a copy since map_char_table modifies | 566 | /* If the key is a range, make a copy since map_char_table modifies |
| 557 | it in place. */ | 567 | it in place. */ |
| 558 | if (CONSP (key)) | 568 | if (CONSP (key)) |
| 559 | key = Fcons (XCAR (key), XCDR (key)); | 569 | key = Fcons (XCAR (key), XCDR (key)); |
| 560 | map_keymap_item (fun, XSAVE_OBJECT (args, 2), key, | 570 | union map_keymap *md = XINTPTR (args); |
| 561 | val, XSAVE_POINTER (args, 1)); | 571 | map_keymap_item (md->s.fun, md->s.args, key, val, md->s.data); |
| 562 | } | 572 | } |
| 563 | } | 573 | } |
| 564 | 574 | ||
| @@ -594,9 +604,11 @@ map_keymap_internal (Lisp_Object map, | |||
| 594 | } | 604 | } |
| 595 | } | 605 | } |
| 596 | else if (CHAR_TABLE_P (binding)) | 606 | else if (CHAR_TABLE_P (binding)) |
| 597 | map_char_table (map_keymap_char_table_item, Qnil, binding, | 607 | { |
| 598 | make_save_funcptr_ptr_obj ((voidfuncptr) fun, data, | 608 | union map_keymap mapdata = {{fun, args, data}}; |
| 599 | args)); | 609 | map_char_table (map_keymap_char_table_item, Qnil, binding, |
| 610 | make_pointer_integer (&mapdata)); | ||
| 611 | } | ||
| 600 | } | 612 | } |
| 601 | 613 | ||
| 602 | return tail; | 614 | return tail; |