diff options
| author | Dmitry Antipov | 2014-09-29 10:44:31 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-09-29 10:44:31 +0400 |
| commit | 71a72686e3e81253f2bc0ad74568aafdbd86879c (patch) | |
| tree | e2f2d44e9a01c782e71e8de88e3b345733c86fc7 /src | |
| parent | c3301e3c7f146a3aa017fa24f6ed240d6ecbafb4 (diff) | |
| download | emacs-71a72686e3e81253f2bc0ad74568aafdbd86879c.tar.gz emacs-71a72686e3e81253f2bc0ad74568aafdbd86879c.zip | |
Keep stack-allocated Lisp objects fast rather than versatile.
* configure.ac (HAVE_STATEMENT_EXPRESSIONS): Remove.
For USE_STACK_LISP_OBJECTS, we always assume __GNUC__.
* lisp.h (union Aligned_Cons) [!GCALIGNED]: Define as such.
(SCOPED_CONS_INITIALIZER): New macro.
(scoped_cons) [USE_STACK_LISP_OBJECTS]: Use it.
(USE_LOCAL_ALLOCA): Remove.
(local_cons, local_list1, local_list2, local_list3, local_list4):
Remove. Stack overflow checking makes them too slow.
(make_local_vector): Likewise. Also we just don't have enough
users for it.
(enum LISP_STRING_OVERHEAD): Remove.
(local_string_init, local_vector_init): Remove prototypes.
(make_local_string, build_local_string): Redesign to target short
compile-time string constants, fall back to regular string allocation
where appropriate.
(lisp_string_size): New function.
(verify_ascii) [ENABLE_CHECKING]: Add prototype.
* alloc.c (local_string_init, local_vector_init): Remove.
(verify_ascii) [ENABLE_CHECKING]: New function.
* buffer.c, charset.c, chartab.c, data.c, editfns.c, emacs.c, fileio.c:
* fns.c, font.c, fontset.c, frame.c, keyboard.c, keymap.c, lread.c:
* menu.c, minibuf.c, process.c, textprop.c, xdisp.c, xfns.c, xfont.c:
* xselect.c, xterm.c: All related users changed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 25 | ||||
| -rw-r--r-- | src/alloc.c | 65 | ||||
| -rw-r--r-- | src/buffer.c | 3 | ||||
| -rw-r--r-- | src/charset.c | 7 | ||||
| -rw-r--r-- | src/chartab.c | 4 | ||||
| -rw-r--r-- | src/data.c | 1 | ||||
| -rw-r--r-- | src/editfns.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 2 | ||||
| -rw-r--r-- | src/fileio.c | 1 | ||||
| -rw-r--r-- | src/fns.c | 1 | ||||
| -rw-r--r-- | src/font.c | 11 | ||||
| -rw-r--r-- | src/fontset.c | 1 | ||||
| -rw-r--r-- | src/frame.c | 1 | ||||
| -rw-r--r-- | src/keyboard.c | 7 | ||||
| -rw-r--r-- | src/keymap.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 190 | ||||
| -rw-r--r-- | src/lread.c | 2 | ||||
| -rw-r--r-- | src/menu.c | 1 | ||||
| -rw-r--r-- | src/minibuf.c | 1 | ||||
| -rw-r--r-- | src/process.c | 4 | ||||
| -rw-r--r-- | src/textprop.c | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 1 | ||||
| -rw-r--r-- | src/xfns.c | 4 | ||||
| -rw-r--r-- | src/xfont.c | 3 | ||||
| -rw-r--r-- | src/xselect.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 1 |
26 files changed, 119 insertions, 231 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 20f9abd3ebf..89fc763fc53 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,28 @@ | |||
| 1 | 2014-09-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Keep stack-allocated Lisp objects fast rather than versatile. | ||
| 4 | * lisp.h (union Aligned_Cons) [!GCALIGNED]: Define as such. | ||
| 5 | (SCOPED_CONS_INITIALIZER): New macro. | ||
| 6 | (scoped_cons) [USE_STACK_LISP_OBJECTS]: Use it. | ||
| 7 | (USE_LOCAL_ALLOCA): Remove. | ||
| 8 | (local_cons, local_list1, local_list2, local_list3, local_list4): | ||
| 9 | Remove. Stack overflow checking makes them too slow. | ||
| 10 | (make_local_vector): Likewise. Also we just don't have enough | ||
| 11 | users for it. | ||
| 12 | (enum LISP_STRING_OVERHEAD): Remove. | ||
| 13 | (local_string_init, local_vector_init): Remove prototypes. | ||
| 14 | (make_local_string, build_local_string): Redesign to target short | ||
| 15 | compile-time string constants, fall back to regular string allocation | ||
| 16 | where appropriate. | ||
| 17 | (lisp_string_size): New function. | ||
| 18 | (verify_ascii) [ENABLE_CHECKING]: Add prototype. | ||
| 19 | * alloc.c (local_string_init, local_vector_init): Remove. | ||
| 20 | (verify_ascii) [ENABLE_CHECKING]: New function. | ||
| 21 | * buffer.c, charset.c, chartab.c, data.c, editfns.c, emacs.c, fileio.c: | ||
| 22 | * fns.c, font.c, fontset.c, frame.c, keyboard.c, keymap.c, lread.c: | ||
| 23 | * menu.c, minibuf.c, process.c, textprop.c, xdisp.c, xfns.c, xfont.c: | ||
| 24 | * xselect.c, xterm.c: All related users changed. | ||
| 25 | |||
| 1 | 2014-09-28 Ken Brown <kbrown@cornell.edu> | 26 | 2014-09-28 Ken Brown <kbrown@cornell.edu> |
| 2 | 27 | ||
| 3 | * sheap.c (bss_sbrk_buffer_beg): Remove redundant variable. | 28 | * sheap.c (bss_sbrk_buffer_beg): Remove redundant variable. |
diff --git a/src/alloc.c b/src/alloc.c index 2dd5fae7d8e..93bdd9a2810 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -69,7 +69,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 69 | static bool valgrind_p; | 69 | static bool valgrind_p; |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #ifdef USE_LOCAL_ALLOCATORS | 72 | #if USE_STACK_LISP_OBJECTS |
| 73 | # if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS | 73 | # if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS |
| 74 | # error "Stack-allocated Lisp objects are not compatible with GCPROs" | 74 | # error "Stack-allocated Lisp objects are not compatible with GCPROs" |
| 75 | # endif | 75 | # endif |
| @@ -2232,33 +2232,6 @@ make_string (const char *contents, ptrdiff_t nbytes) | |||
| 2232 | return val; | 2232 | return val; |
| 2233 | } | 2233 | } |
| 2234 | 2234 | ||
| 2235 | #ifdef USE_LOCAL_ALLOCATORS | ||
| 2236 | |||
| 2237 | /* Initialize the string S from DATA and SIZE. S must be followed by | ||
| 2238 | SIZE + 1 bytes of memory that can be used. Return S tagged as a | ||
| 2239 | Lisp object. */ | ||
| 2240 | |||
| 2241 | Lisp_Object | ||
| 2242 | local_string_init (struct Lisp_String *s, char const *data, ptrdiff_t size) | ||
| 2243 | { | ||
| 2244 | unsigned char *data_copy = (unsigned char *) (s + 1); | ||
| 2245 | parse_str_as_multibyte ((unsigned char const *) data, | ||
| 2246 | size, &s->size, &s->size_byte); | ||
| 2247 | if (size == s->size || size != s->size_byte) | ||
| 2248 | { | ||
| 2249 | s->size = size; | ||
| 2250 | s->size_byte = -1; | ||
| 2251 | } | ||
| 2252 | s->intervals = NULL; | ||
| 2253 | s->data = data_copy; | ||
| 2254 | memcpy (data_copy, data, size); | ||
| 2255 | data_copy[size] = '\0'; | ||
| 2256 | return make_lisp_ptr (s, Lisp_String); | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | #endif | ||
| 2260 | |||
| 2261 | |||
| 2262 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ | 2235 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ |
| 2263 | 2236 | ||
| 2264 | Lisp_Object | 2237 | Lisp_Object |
| @@ -3320,23 +3293,6 @@ See also the function `vector'. */) | |||
| 3320 | return vector; | 3293 | return vector; |
| 3321 | } | 3294 | } |
| 3322 | 3295 | ||
| 3323 | #ifdef USE_LOCAL_ALLOCATORS | ||
| 3324 | |||
| 3325 | /* Initialize V with LENGTH objects each with value INIT, | ||
| 3326 | and return it tagged as a Lisp Object. */ | ||
| 3327 | |||
| 3328 | Lisp_Object | ||
| 3329 | local_vector_init (struct Lisp_Vector *v, ptrdiff_t length, Lisp_Object init) | ||
| 3330 | { | ||
| 3331 | v->header.size = length; | ||
| 3332 | for (ptrdiff_t i = 0; i < length; i++) | ||
| 3333 | v->contents[i] = init; | ||
| 3334 | return make_lisp_ptr (v, Lisp_Vectorlike); | ||
| 3335 | } | ||
| 3336 | |||
| 3337 | #endif | ||
| 3338 | |||
| 3339 | |||
| 3340 | DEFUN ("vector", Fvector, Svector, 0, MANY, 0, | 3296 | DEFUN ("vector", Fvector, Svector, 0, MANY, 0, |
| 3341 | doc: /* Return a newly created vector with specified arguments as elements. | 3297 | doc: /* Return a newly created vector with specified arguments as elements. |
| 3342 | Any number of arguments, even zero arguments, are allowed. | 3298 | Any number of arguments, even zero arguments, are allowed. |
| @@ -7157,7 +7113,22 @@ die (const char *msg, const char *file, int line) | |||
| 7157 | 7113 | ||
| 7158 | #endif /* ENABLE_CHECKING */ | 7114 | #endif /* ENABLE_CHECKING */ |
| 7159 | 7115 | ||
| 7160 | #if defined (ENABLE_CHECKING) && defined (USE_STACK_LISP_OBJECTS) | 7116 | #if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS |
| 7117 | |||
| 7118 | /* Debugging check whether STR is ASCII-only. */ | ||
| 7119 | |||
| 7120 | const char * | ||
| 7121 | verify_ascii (const char *str) | ||
| 7122 | { | ||
| 7123 | const unsigned char *ptr = (unsigned char *) str, *end = ptr + strlen (str); | ||
| 7124 | while (ptr < end) | ||
| 7125 | { | ||
| 7126 | int c = STRING_CHAR_ADVANCE (ptr); | ||
| 7127 | if (!ASCII_CHAR_P (c)) | ||
| 7128 | emacs_abort (); | ||
| 7129 | } | ||
| 7130 | return str; | ||
| 7131 | } | ||
| 7161 | 7132 | ||
| 7162 | /* Stress alloca with inconveniently sized requests and check | 7133 | /* Stress alloca with inconveniently sized requests and check |
| 7163 | whether all allocated areas may be used for Lisp_Object. */ | 7134 | whether all allocated areas may be used for Lisp_Object. */ |
| @@ -7175,7 +7146,7 @@ verify_alloca (void) | |||
| 7175 | } | 7146 | } |
| 7176 | } | 7147 | } |
| 7177 | 7148 | ||
| 7178 | #else /* not (ENABLE_CHECKING && USE_STACK_LISP_OBJECTS) */ | 7149 | #else /* not ENABLE_CHECKING && USE_STACK_LISP_OBJECTS */ |
| 7179 | 7150 | ||
| 7180 | #define verify_alloca() ((void) 0) | 7151 | #define verify_alloca() ((void) 0) |
| 7181 | 7152 | ||
diff --git a/src/buffer.c b/src/buffer.c index 591f585a7a9..39d08950bf8 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1511,7 +1511,6 @@ list first, followed by the list of all buffers. If no other buffer | |||
| 1511 | exists, return the buffer `*scratch*' (creating it if necessary). */) | 1511 | exists, return the buffer `*scratch*' (creating it if necessary). */) |
| 1512 | (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) | 1512 | (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) |
| 1513 | { | 1513 | { |
| 1514 | USE_LOCAL_ALLOCA; | ||
| 1515 | struct frame *f = decode_any_frame (frame); | 1514 | struct frame *f = decode_any_frame (frame); |
| 1516 | Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate; | 1515 | Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate; |
| 1517 | Lisp_Object buf, notsogood = Qnil; | 1516 | Lisp_Object buf, notsogood = Qnil; |
| @@ -1570,7 +1569,6 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) | |||
| 1570 | Lisp_Object | 1569 | Lisp_Object |
| 1571 | other_buffer_safely (Lisp_Object buffer) | 1570 | other_buffer_safely (Lisp_Object buffer) |
| 1572 | { | 1571 | { |
| 1573 | USE_LOCAL_ALLOCA; | ||
| 1574 | Lisp_Object tail, buf; | 1572 | Lisp_Object tail, buf; |
| 1575 | 1573 | ||
| 1576 | FOR_EACH_LIVE_BUFFER (tail, buf) | 1574 | FOR_EACH_LIVE_BUFFER (tail, buf) |
| @@ -5240,7 +5238,6 @@ init_buffer_once (void) | |||
| 5240 | void | 5238 | void |
| 5241 | init_buffer (int initialized) | 5239 | init_buffer (int initialized) |
| 5242 | { | 5240 | { |
| 5243 | USE_LOCAL_ALLOCA; | ||
| 5244 | char *pwd; | 5241 | char *pwd; |
| 5245 | Lisp_Object temp; | 5242 | Lisp_Object temp; |
| 5246 | ptrdiff_t len; | 5243 | ptrdiff_t len; |
diff --git a/src/charset.c b/src/charset.c index 30bcc054221..9fe3548be08 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -481,7 +481,6 @@ static void | |||
| 481 | load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, | 481 | load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, |
| 482 | int control_flag) | 482 | int control_flag) |
| 483 | { | 483 | { |
| 484 | USE_LOCAL_ALLOCA; | ||
| 485 | unsigned min_code = CHARSET_MIN_CODE (charset); | 484 | unsigned min_code = CHARSET_MIN_CODE (charset); |
| 486 | unsigned max_code = CHARSET_MAX_CODE (charset); | 485 | unsigned max_code = CHARSET_MAX_CODE (charset); |
| 487 | int fd; | 486 | int fd; |
| @@ -1551,7 +1550,6 @@ If the current buffer is unibyte, the returned list may contain | |||
| 1551 | only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | 1550 | only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) |
| 1552 | (Lisp_Object beg, Lisp_Object end, Lisp_Object table) | 1551 | (Lisp_Object beg, Lisp_Object end, Lisp_Object table) |
| 1553 | { | 1552 | { |
| 1554 | USE_LOCAL_ALLOCA; | ||
| 1555 | Lisp_Object charsets; | 1553 | Lisp_Object charsets; |
| 1556 | ptrdiff_t from, from_byte, to, stop, stop_byte; | 1554 | ptrdiff_t from, from_byte, to, stop, stop_byte; |
| 1557 | int i; | 1555 | int i; |
| @@ -1572,7 +1570,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | |||
| 1572 | 1570 | ||
| 1573 | from_byte = CHAR_TO_BYTE (from); | 1571 | from_byte = CHAR_TO_BYTE (from); |
| 1574 | 1572 | ||
| 1575 | charsets = make_local_vector (charset_table_used, Qnil); | 1573 | charsets = Fmake_vector (make_number (charset_table_used), Qnil); |
| 1576 | while (1) | 1574 | while (1) |
| 1577 | { | 1575 | { |
| 1578 | find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from, | 1576 | find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from, |
| @@ -1603,14 +1601,13 @@ If STR is unibyte, the returned list may contain | |||
| 1603 | only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) | 1601 | only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) |
| 1604 | (Lisp_Object str, Lisp_Object table) | 1602 | (Lisp_Object str, Lisp_Object table) |
| 1605 | { | 1603 | { |
| 1606 | USE_LOCAL_ALLOCA; | ||
| 1607 | Lisp_Object charsets; | 1604 | Lisp_Object charsets; |
| 1608 | int i; | 1605 | int i; |
| 1609 | Lisp_Object val; | 1606 | Lisp_Object val; |
| 1610 | 1607 | ||
| 1611 | CHECK_STRING (str); | 1608 | CHECK_STRING (str); |
| 1612 | 1609 | ||
| 1613 | charsets = make_local_vector (charset_table_used, Qnil); | 1610 | charsets = Fmake_vector (make_number (charset_table_used), Qnil); |
| 1614 | find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str), | 1611 | find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str), |
| 1615 | charsets, table, | 1612 | charsets, table, |
| 1616 | STRING_MULTIBYTE (str)); | 1613 | STRING_MULTIBYTE (str)); |
diff --git a/src/chartab.c b/src/chartab.c index d25169b7a5e..4e4219d8ae3 100644 --- a/src/chartab.c +++ b/src/chartab.c | |||
| @@ -1249,7 +1249,6 @@ uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value) | |||
| 1249 | static Lisp_Object | 1249 | static Lisp_Object |
| 1250 | uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) | 1250 | uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) |
| 1251 | { | 1251 | { |
| 1252 | USE_LOCAL_ALLOCA; | ||
| 1253 | Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents; | 1252 | Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents; |
| 1254 | int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]); | 1253 | int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]); |
| 1255 | 1254 | ||
| @@ -1260,7 +1259,7 @@ uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) | |||
| 1260 | value = make_number (i); | 1259 | value = make_number (i); |
| 1261 | if (i == size) | 1260 | if (i == size) |
| 1262 | set_char_table_extras (table, 4, Fvconcat (2, ((Lisp_Object []) { | 1261 | set_char_table_extras (table, 4, Fvconcat (2, ((Lisp_Object []) { |
| 1263 | XCHAR_TABLE (table)->extras[4], make_local_vector (1, value) }))); | 1262 | XCHAR_TABLE (table)->extras[4], Fmake_vector (make_number (1), value) }))); |
| 1264 | return make_number (i); | 1263 | return make_number (i); |
| 1265 | } | 1264 | } |
| 1266 | 1265 | ||
| @@ -1293,7 +1292,6 @@ uniprop_get_encoder (Lisp_Object table) | |||
| 1293 | Lisp_Object | 1292 | Lisp_Object |
| 1294 | uniprop_table (Lisp_Object prop) | 1293 | uniprop_table (Lisp_Object prop) |
| 1295 | { | 1294 | { |
| 1296 | USE_LOCAL_ALLOCA; | ||
| 1297 | Lisp_Object val, table, result; | 1295 | Lisp_Object val, table, result; |
| 1298 | 1296 | ||
| 1299 | val = Fassq (prop, Vchar_code_property_alist); | 1297 | val = Fassq (prop, Vchar_code_property_alist); |
diff --git a/src/data.c b/src/data.c index f839cc9d6f8..414da4cf6f7 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -1004,7 +1004,6 @@ wrong_choice (Lisp_Object choice, Lisp_Object wrong) | |||
| 1004 | static void | 1004 | static void |
| 1005 | wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) | 1005 | wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) |
| 1006 | { | 1006 | { |
| 1007 | USE_LOCAL_ALLOCA; | ||
| 1008 | xsignal2 (Qerror, Fconcat (4, ((Lisp_Object []) | 1007 | xsignal2 (Qerror, Fconcat (4, ((Lisp_Object []) |
| 1009 | { build_local_string ("Value should be from "), | 1008 | { build_local_string ("Value should be from "), |
| 1010 | Fnumber_to_string (min), | 1009 | Fnumber_to_string (min), |
diff --git a/src/editfns.c b/src/editfns.c index df5d00702fd..47779914c45 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3531,7 +3531,6 @@ properties to add to the result. | |||
| 3531 | usage: (propertize STRING &rest PROPERTIES) */) | 3531 | usage: (propertize STRING &rest PROPERTIES) */) |
| 3532 | (ptrdiff_t nargs, Lisp_Object *args) | 3532 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3533 | { | 3533 | { |
| 3534 | USE_LOCAL_ALLOCA; | ||
| 3535 | Lisp_Object properties, string; | 3534 | Lisp_Object properties, string; |
| 3536 | struct gcpro gcpro1, gcpro2; | 3535 | struct gcpro gcpro1, gcpro2; |
| 3537 | ptrdiff_t i; | 3536 | ptrdiff_t i; |
| @@ -3548,7 +3547,7 @@ usage: (propertize STRING &rest PROPERTIES) */) | |||
| 3548 | string = Fcopy_sequence (args[0]); | 3547 | string = Fcopy_sequence (args[0]); |
| 3549 | 3548 | ||
| 3550 | for (i = 1; i < nargs; i += 2) | 3549 | for (i = 1; i < nargs; i += 2) |
| 3551 | properties = local_cons (args[i], local_cons (args[i + 1], properties)); | 3550 | properties = Fcons (args[i], Fcons (args[i + 1], properties)); |
| 3552 | 3551 | ||
| 3553 | Fadd_text_properties (make_number (0), | 3552 | Fadd_text_properties (make_number (0), |
| 3554 | make_number (SCHARS (string)), | 3553 | make_number (SCHARS (string)), |
| @@ -4363,7 +4362,6 @@ usage: (format STRING &rest OBJECTS) */) | |||
| 4363 | Lisp_Object | 4362 | Lisp_Object |
| 4364 | format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1) | 4363 | format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1) |
| 4365 | { | 4364 | { |
| 4366 | USE_LOCAL_ALLOCA; | ||
| 4367 | return Fformat (3, ((Lisp_Object []) | 4365 | return Fformat (3, ((Lisp_Object []) |
| 4368 | { build_local_string (string1), arg0, arg1 })); | 4366 | { build_local_string (string1), arg0, arg1 })); |
| 4369 | } | 4367 | } |
diff --git a/src/emacs.c b/src/emacs.c index 4ba51d3a7f5..241479fecf2 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -396,7 +396,6 @@ terminate_due_to_signal (int sig, int backtrace_limit) | |||
| 396 | static void | 396 | static void |
| 397 | init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd) | 397 | init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd) |
| 398 | { | 398 | { |
| 399 | USE_LOCAL_ALLOCA; | ||
| 400 | int i; | 399 | int i; |
| 401 | Lisp_Object name, dir, handler; | 400 | Lisp_Object name, dir, handler; |
| 402 | ptrdiff_t count = SPECPDL_INDEX (); | 401 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -2209,7 +2208,6 @@ synchronize_system_messages_locale (void) | |||
| 2209 | Lisp_Object | 2208 | Lisp_Object |
| 2210 | decode_env_path (const char *evarname, const char *defalt, bool empty) | 2209 | decode_env_path (const char *evarname, const char *defalt, bool empty) |
| 2211 | { | 2210 | { |
| 2212 | USE_LOCAL_ALLOCA; | ||
| 2213 | const char *path, *p; | 2211 | const char *path, *p; |
| 2214 | Lisp_Object lpath, element, tem; | 2212 | Lisp_Object lpath, element, tem; |
| 2215 | /* Default is to use "." for empty path elements. | 2213 | /* Default is to use "." for empty path elements. |
diff --git a/src/fileio.c b/src/fileio.c index 0379f0e9115..13e2c889020 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -5411,7 +5411,6 @@ An argument specifies the modification time value to use | |||
| 5411 | static Lisp_Object | 5411 | static Lisp_Object |
| 5412 | auto_save_error (Lisp_Object error_val) | 5412 | auto_save_error (Lisp_Object error_val) |
| 5413 | { | 5413 | { |
| 5414 | USE_LOCAL_ALLOCA; | ||
| 5415 | Lisp_Object msg; | 5414 | Lisp_Object msg; |
| 5416 | int i; | 5415 | int i; |
| 5417 | struct gcpro gcpro1; | 5416 | struct gcpro gcpro1; |
| @@ -2706,7 +2706,6 @@ If dialog boxes are supported, a dialog box will be used | |||
| 2706 | if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) | 2706 | if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) |
| 2707 | (Lisp_Object prompt) | 2707 | (Lisp_Object prompt) |
| 2708 | { | 2708 | { |
| 2709 | USE_LOCAL_ALLOCA; | ||
| 2710 | Lisp_Object ans; | 2709 | Lisp_Object ans; |
| 2711 | struct gcpro gcpro1; | 2710 | struct gcpro gcpro1; |
| 2712 | 2711 | ||
diff --git a/src/font.c b/src/font.c index 3614d97d473..673a934f38f 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -357,7 +357,6 @@ int | |||
| 357 | font_style_to_value (enum font_property_index prop, Lisp_Object val, | 357 | font_style_to_value (enum font_property_index prop, Lisp_Object val, |
| 358 | bool noerror) | 358 | bool noerror) |
| 359 | { | 359 | { |
| 360 | USE_LOCAL_ALLOCA; | ||
| 361 | Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); | 360 | Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); |
| 362 | int len; | 361 | int len; |
| 363 | 362 | ||
| @@ -402,7 +401,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, | |||
| 402 | ASET (elt, 1, val); | 401 | ASET (elt, 1, val); |
| 403 | ASET (font_style_table, prop - FONT_WEIGHT_INDEX, | 402 | ASET (font_style_table, prop - FONT_WEIGHT_INDEX, |
| 404 | Fvconcat (2, ((Lisp_Object []) | 403 | Fvconcat (2, ((Lisp_Object []) |
| 405 | { table, make_local_vector (1, elt) }))); | 404 | { table, Fmake_vector (make_number (1), elt) }))); |
| 406 | return (100 << 8) | (i << 4); | 405 | return (100 << 8) | (i << 4); |
| 407 | } | 406 | } |
| 408 | else | 407 | else |
| @@ -1050,7 +1049,6 @@ font_expand_wildcards (Lisp_Object *field, int n) | |||
| 1050 | int | 1049 | int |
| 1051 | font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font) | 1050 | font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font) |
| 1052 | { | 1051 | { |
| 1053 | USE_LOCAL_ALLOCA; | ||
| 1054 | int i, j, n; | 1052 | int i, j, n; |
| 1055 | char *f[XLFD_LAST_INDEX + 1]; | 1053 | char *f[XLFD_LAST_INDEX + 1]; |
| 1056 | Lisp_Object val; | 1054 | Lisp_Object val; |
| @@ -1760,7 +1758,6 @@ font_parse_name (char *name, ptrdiff_t namelen, Lisp_Object font) | |||
| 1760 | void | 1758 | void |
| 1761 | font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec) | 1759 | font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec) |
| 1762 | { | 1760 | { |
| 1763 | USE_LOCAL_ALLOCA; | ||
| 1764 | ptrdiff_t len; | 1761 | ptrdiff_t len; |
| 1765 | char *p0, *p1; | 1762 | char *p0, *p1; |
| 1766 | 1763 | ||
| @@ -2686,7 +2683,6 @@ static Lisp_Object scratch_font_spec, scratch_font_prefer; | |||
| 2686 | static Lisp_Object | 2683 | static Lisp_Object |
| 2687 | font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) | 2684 | font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) |
| 2688 | { | 2685 | { |
| 2689 | USE_LOCAL_ALLOCA; | ||
| 2690 | Lisp_Object entity, val; | 2686 | Lisp_Object entity, val; |
| 2691 | enum font_property_index prop; | 2687 | enum font_property_index prop; |
| 2692 | ptrdiff_t i; | 2688 | ptrdiff_t i; |
| @@ -2717,7 +2713,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) | |||
| 2717 | } | 2713 | } |
| 2718 | if (NILP (spec)) | 2714 | if (NILP (spec)) |
| 2719 | { | 2715 | { |
| 2720 | val = local_cons (entity, val); | 2716 | val = Fcons (entity, val); |
| 2721 | continue; | 2717 | continue; |
| 2722 | } | 2718 | } |
| 2723 | for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) | 2719 | for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) |
| @@ -2748,7 +2744,7 @@ font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) | |||
| 2748 | AREF (entity, FONT_AVGWIDTH_INDEX))) | 2744 | AREF (entity, FONT_AVGWIDTH_INDEX))) |
| 2749 | prop = FONT_SPEC_MAX; | 2745 | prop = FONT_SPEC_MAX; |
| 2750 | if (prop < FONT_SPEC_MAX) | 2746 | if (prop < FONT_SPEC_MAX) |
| 2751 | val = local_cons (entity, val); | 2747 | val = Fcons (entity, val); |
| 2752 | } | 2748 | } |
| 2753 | return (Fvconcat (1, &val)); | 2749 | return (Fvconcat (1, &val)); |
| 2754 | } | 2750 | } |
| @@ -5006,7 +5002,6 @@ static Lisp_Object Vfont_log_deferred; | |||
| 5006 | void | 5002 | void |
| 5007 | font_add_log (const char *action, Lisp_Object arg, Lisp_Object result) | 5003 | font_add_log (const char *action, Lisp_Object arg, Lisp_Object result) |
| 5008 | { | 5004 | { |
| 5009 | USE_LOCAL_ALLOCA; | ||
| 5010 | Lisp_Object val; | 5005 | Lisp_Object val; |
| 5011 | int i; | 5006 | int i; |
| 5012 | 5007 | ||
diff --git a/src/fontset.c b/src/fontset.c index ff92f16a266..5e18d14bd65 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1420,7 +1420,6 @@ to the font specifications for TARGET previously set. If it is | |||
| 1420 | appended. By default, FONT-SPEC overrides the previous settings. */) | 1420 | appended. By default, FONT-SPEC overrides the previous settings. */) |
| 1421 | (Lisp_Object name, Lisp_Object target, Lisp_Object font_spec, Lisp_Object frame, Lisp_Object add) | 1421 | (Lisp_Object name, Lisp_Object target, Lisp_Object font_spec, Lisp_Object frame, Lisp_Object add) |
| 1422 | { | 1422 | { |
| 1423 | USE_LOCAL_ALLOCA; | ||
| 1424 | Lisp_Object fontset; | 1423 | Lisp_Object fontset; |
| 1425 | Lisp_Object font_def, registry, family; | 1424 | Lisp_Object font_def, registry, family; |
| 1426 | Lisp_Object range_list; | 1425 | Lisp_Object range_list; |
diff --git a/src/frame.c b/src/frame.c index f1d8662aff1..0eea4f4338a 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -4122,7 +4122,6 @@ Lisp_Object | |||
| 4122 | x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param, | 4122 | x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param, |
| 4123 | const char *attribute, const char *class, enum resource_types type) | 4123 | const char *attribute, const char *class, enum resource_types type) |
| 4124 | { | 4124 | { |
| 4125 | USE_LOCAL_ALLOCA; | ||
| 4126 | Lisp_Object tem; | 4125 | Lisp_Object tem; |
| 4127 | 4126 | ||
| 4128 | tem = Fassq (param, alist); | 4127 | tem = Fassq (param, alist); |
diff --git a/src/keyboard.c b/src/keyboard.c index fcba475e5ee..d920ef45f45 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -573,7 +573,7 @@ echo_add_key (Lisp_Object c) | |||
| 573 | 573 | ||
| 574 | kset_echo_string | 574 | kset_echo_string |
| 575 | (current_kboard, | 575 | (current_kboard, |
| 576 | concat2 (echo_string, make_local_string (buffer, ptr - buffer))); | 576 | concat2 (echo_string, make_string (buffer, ptr - buffer))); |
| 577 | SAFE_FREE (); | 577 | SAFE_FREE (); |
| 578 | } | 578 | } |
| 579 | 579 | ||
| @@ -597,8 +597,6 @@ echo_char (Lisp_Object c) | |||
| 597 | static void | 597 | static void |
| 598 | echo_dash (void) | 598 | echo_dash (void) |
| 599 | { | 599 | { |
| 600 | USE_LOCAL_ALLOCA; | ||
| 601 | |||
| 602 | /* Do nothing if not echoing at all. */ | 600 | /* Do nothing if not echoing at all. */ |
| 603 | if (NILP (KVAR (current_kboard, echo_string))) | 601 | if (NILP (KVAR (current_kboard, echo_string))) |
| 604 | return; | 602 | return; |
| @@ -1892,7 +1890,6 @@ safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args) | |||
| 1892 | static Lisp_Object | 1890 | static Lisp_Object |
| 1893 | safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) | 1891 | safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) |
| 1894 | { | 1892 | { |
| 1895 | USE_LOCAL_ALLOCA; | ||
| 1896 | Lisp_Object hook, fun; | 1893 | Lisp_Object hook, fun; |
| 1897 | 1894 | ||
| 1898 | eassert (nargs == 2); | 1895 | eassert (nargs == 2); |
| @@ -7699,7 +7696,6 @@ menu_item_eval_property (Lisp_Object sexpr) | |||
| 7699 | bool | 7696 | bool |
| 7700 | parse_menu_item (Lisp_Object item, int inmenubar) | 7697 | parse_menu_item (Lisp_Object item, int inmenubar) |
| 7701 | { | 7698 | { |
| 7702 | USE_LOCAL_ALLOCA; | ||
| 7703 | Lisp_Object def, tem, item_string, start; | 7699 | Lisp_Object def, tem, item_string, start; |
| 7704 | Lisp_Object filter; | 7700 | Lisp_Object filter; |
| 7705 | Lisp_Object keyhint; | 7701 | Lisp_Object keyhint; |
| @@ -8523,7 +8519,6 @@ static Lisp_Object | |||
| 8523 | read_char_minibuf_menu_prompt (int commandflag, | 8519 | read_char_minibuf_menu_prompt (int commandflag, |
| 8524 | Lisp_Object map) | 8520 | Lisp_Object map) |
| 8525 | { | 8521 | { |
| 8526 | USE_LOCAL_ALLOCA; | ||
| 8527 | Lisp_Object name; | 8522 | Lisp_Object name; |
| 8528 | ptrdiff_t nlength; | 8523 | ptrdiff_t nlength; |
| 8529 | /* FIXME: Use the minibuffer's frame width. */ | 8524 | /* FIXME: Use the minibuffer's frame width. */ |
diff --git a/src/keymap.c b/src/keymap.c index 768df563632..ed572a5a8c1 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1308,7 +1308,6 @@ append_key (Lisp_Object key_sequence, Lisp_Object key) | |||
| 1308 | static void | 1308 | static void |
| 1309 | silly_event_symbol_error (Lisp_Object c) | 1309 | silly_event_symbol_error (Lisp_Object c) |
| 1310 | { | 1310 | { |
| 1311 | USE_LOCAL_ALLOCA; | ||
| 1312 | Lisp_Object parsed, base, name, assoc; | 1311 | Lisp_Object parsed, base, name, assoc; |
| 1313 | int modifiers; | 1312 | int modifiers; |
| 1314 | 1313 | ||
| @@ -3418,7 +3417,6 @@ describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args, | |||
| 3418 | bool partial, Lisp_Object shadow, Lisp_Object entire_map, | 3417 | bool partial, Lisp_Object shadow, Lisp_Object entire_map, |
| 3419 | bool keymap_p, bool mention_shadow) | 3418 | bool keymap_p, bool mention_shadow) |
| 3420 | { | 3419 | { |
| 3421 | USE_LOCAL_ALLOCA; | ||
| 3422 | Lisp_Object definition; | 3420 | Lisp_Object definition; |
| 3423 | Lisp_Object tem2; | 3421 | Lisp_Object tem2; |
| 3424 | Lisp_Object elt_prefix = Qnil; | 3422 | Lisp_Object elt_prefix = Qnil; |
diff --git a/src/lisp.h b/src/lisp.h index b1f793c7282..d2cac17fbc7 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -3705,8 +3705,6 @@ extern Lisp_Object make_uninit_bool_vector (EMACS_INT); | |||
| 3705 | extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object); | 3705 | extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object); |
| 3706 | extern _Noreturn void string_overflow (void); | 3706 | extern _Noreturn void string_overflow (void); |
| 3707 | extern Lisp_Object make_string (const char *, ptrdiff_t); | 3707 | extern Lisp_Object make_string (const char *, ptrdiff_t); |
| 3708 | extern Lisp_Object local_string_init (struct Lisp_String *, char const *, | ||
| 3709 | ptrdiff_t); | ||
| 3710 | extern Lisp_Object make_formatted_string (char *, const char *, ...) | 3708 | extern Lisp_Object make_formatted_string (char *, const char *, ...) |
| 3711 | ATTRIBUTE_FORMAT_PRINTF (2, 3); | 3709 | ATTRIBUTE_FORMAT_PRINTF (2, 3); |
| 3712 | extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); | 3710 | extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); |
| @@ -3795,8 +3793,6 @@ extern struct Lisp_Hash_Table *allocate_hash_table (void); | |||
| 3795 | extern struct window *allocate_window (void); | 3793 | extern struct window *allocate_window (void); |
| 3796 | extern struct frame *allocate_frame (void); | 3794 | extern struct frame *allocate_frame (void); |
| 3797 | extern struct Lisp_Process *allocate_process (void); | 3795 | extern struct Lisp_Process *allocate_process (void); |
| 3798 | extern Lisp_Object local_vector_init (struct Lisp_Vector *, ptrdiff_t, | ||
| 3799 | Lisp_Object); | ||
| 3800 | extern struct terminal *allocate_terminal (void); | 3796 | extern struct terminal *allocate_terminal (void); |
| 3801 | extern bool gc_in_progress; | 3797 | extern bool gc_in_progress; |
| 3802 | extern bool abort_on_gc; | 3798 | extern bool abort_on_gc; |
| @@ -4602,17 +4598,25 @@ lisp_word_count (ptrdiff_t nbytes) | |||
| 4602 | 4598 | ||
| 4603 | 4599 | ||
| 4604 | /* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate | 4600 | /* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate |
| 4605 | block-scoped conses and function-scoped vectors and strings. These objects | 4601 | block-scoped conses and function-scoped strings. These objects are not |
| 4606 | are not managed by the garbage collector, so they are dangerous: passing | 4602 | managed by the garbage collector, so they are dangerous: passing them |
| 4607 | them out of their scope (e.g., to user code) results in undefined behavior. | 4603 | out of their scope (e.g., to user code) results in undefined behavior. |
| 4608 | Conversely, they have better performance because GC is not involved. | 4604 | Conversely, they have better performance because GC is not involved. |
| 4609 | 4605 | ||
| 4610 | This feature is experimental and requires careful debugging. It's enabled | 4606 | This feature is experimental and requires careful debugging. It's enabled |
| 4611 | by default if GCC or a compiler that mimics GCC well (like Intel C/C++) is | 4607 | by default if GCC or a compiler that mimics GCC well (like Intel C/C++) is |
| 4612 | used, except clang (see notice above). For other compilers, brave users can | 4608 | used, except clang (see notice above). For other compilers, brave users can |
| 4613 | compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS' to get into the game. | 4609 | compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=1' to get into the game. |
| 4614 | Note that this feature requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */ | 4610 | Note that this feature requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */ |
| 4615 | 4611 | ||
| 4612 | #ifdef GCALIGNED | ||
| 4613 | |||
| 4614 | /* No tricks if struct Lisp_Cons is always aligned. */ | ||
| 4615 | |||
| 4616 | # define SCOPED_CONS_INITIALIZER(a, b) &((struct Lisp_Cons) { a, { b } }) | ||
| 4617 | |||
| 4618 | #else /* not GCALIGNED */ | ||
| 4619 | |||
| 4616 | /* A struct Lisp_Cons inside a union that is no larger and may be | 4620 | /* A struct Lisp_Cons inside a union that is no larger and may be |
| 4617 | better-aligned. */ | 4621 | better-aligned. */ |
| 4618 | 4622 | ||
| @@ -4621,153 +4625,89 @@ union Aligned_Cons | |||
| 4621 | struct Lisp_Cons s; | 4625 | struct Lisp_Cons s; |
| 4622 | double d; intmax_t i; void *p; | 4626 | double d; intmax_t i; void *p; |
| 4623 | }; | 4627 | }; |
| 4628 | |||
| 4629 | verify (alignof (union Aligned_Cons) % GCALIGNMENT == 0); | ||
| 4624 | verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons)); | 4630 | verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons)); |
| 4625 | 4631 | ||
| 4626 | /* Allocate a block-scoped cons. */ | 4632 | # define SCOPED_CONS_INITIALIZER(a, b) \ |
| 4633 | &((union Aligned_Cons) { { a, { b } } }.s) | ||
| 4627 | 4634 | ||
| 4628 | #define scoped_cons(car, cdr) \ | 4635 | #endif /* GCALIGNED */ |
| 4629 | ((USE_STACK_LISP_OBJECTS \ | ||
| 4630 | && alignof (union Aligned_Cons) % GCALIGNMENT == 0) \ | ||
| 4631 | ? make_lisp_ptr (&((union Aligned_Cons) {{car, {cdr}}}).s, Lisp_Cons) \ | ||
| 4632 | : Fcons (car, cdr)) | ||
| 4633 | 4636 | ||
| 4634 | /* Convenient utility macros similar to listX functions. */ | 4637 | /* Basic stack-based cons allocation. */ |
| 4635 | 4638 | ||
| 4636 | #if USE_STACK_LISP_OBJECTS | 4639 | #if USE_STACK_LISP_OBJECTS |
| 4640 | # define scoped_cons(a, b) \ | ||
| 4641 | make_lisp_ptr (SCOPED_CONS_INITIALIZER (a, b), Lisp_Cons) | ||
| 4637 | # define scoped_list1(a) scoped_cons (a, Qnil) | 4642 | # define scoped_list1(a) scoped_cons (a, Qnil) |
| 4638 | # define scoped_list2(a, b) scoped_cons (a, scoped_list1 (b)) | 4643 | # define scoped_list2(a, b) scoped_cons (a, scoped_list1 (b)) |
| 4639 | # define scoped_list3(a, b, c) scoped_cons (a, scoped_list2 (b, c)) | 4644 | # define scoped_list3(a, b, c) scoped_cons (a, scoped_list2 (b, c)) |
| 4640 | # define scoped_list4(a, b, c, d) scoped_cons (a, scoped_list3 (b, c, d)) | 4645 | # define scoped_list4(a, b, c, d) scoped_cons (a, scoped_list3 (b, c, d)) |
| 4641 | #else | 4646 | #else |
| 4647 | # define scoped_cons(a, b) Fcons (a, b) | ||
| 4642 | # define scoped_list1(a) list1 (a) | 4648 | # define scoped_list1(a) list1 (a) |
| 4643 | # define scoped_list2(a, b) list2 (a, b) | 4649 | # define scoped_list2(a, b) list2 (a, b) |
| 4644 | # define scoped_list3(a, b, c) list3 (a, b, c) | 4650 | # define scoped_list3(a, b, c) list3 (a, b, c) |
| 4645 | # define scoped_list4(a, b, c, d) list4 (a, b, c, d) | 4651 | # define scoped_list4(a, b, c, d) list4 (a, b, c, d) |
| 4646 | #endif | 4652 | #endif |
| 4647 | 4653 | ||
| 4648 | /* Local allocators require both statement expressions and a | 4654 | /* On-stack string allocation requires __builtin_constant_p, statement |
| 4649 | GCALIGNMENT-aligned alloca. clang's alloca isn't properly aligned | 4655 | expressions and GCALIGNMENT-aligned alloca. All from the above is |
| 4650 | in some cases. In the absence of solid information, play it safe | 4656 | assumed for GCC. At least for clang < 3.6, alloca isn't properly |
| 4651 | for other non-GCC compilers. */ | 4657 | aligned in some cases. In the absence of solid information, play |
| 4652 | #if (USE_STACK_LISP_OBJECTS && HAVE_STATEMENT_EXPRESSIONS \ | 4658 | it safe for other non-GCC compilers. */ |
| 4653 | && __GNUC__ && !__clang__) | ||
| 4654 | # define USE_LOCAL_ALLOCATORS | ||
| 4655 | #endif | ||
| 4656 | 4659 | ||
| 4657 | /* Any function that uses a local allocator should start with either | 4660 | #if USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ |
| 4658 | 'USE_SAFE_ALLOCA; or 'USE_LOCAL_ALLOCA;' (but not both). */ | ||
| 4659 | #ifdef USE_LOCAL_ALLOCATORS | ||
| 4660 | # define USE_LOCAL_ALLOCA ptrdiff_t sa_avail = MAX_ALLOCA | ||
| 4661 | #else | ||
| 4662 | # define USE_LOCAL_ALLOCA | ||
| 4663 | #endif | ||
| 4664 | 4661 | ||
| 4665 | #ifdef USE_LOCAL_ALLOCATORS | 4662 | /* Used to check whether stack-allocated strings are ASCII-only. */ |
| 4666 | |||
| 4667 | /* Return a function-scoped cons whose car is X and cdr is Y. */ | ||
| 4668 | |||
| 4669 | # define local_cons(x, y) \ | ||
| 4670 | (sizeof (struct Lisp_Cons) <= sa_avail \ | ||
| 4671 | ? ({ \ | ||
| 4672 | struct Lisp_Cons *c_ = AVAIL_ALLOCA (sizeof (struct Lisp_Cons)); \ | ||
| 4673 | c_->car = (x); \ | ||
| 4674 | c_->u.cdr = (y); \ | ||
| 4675 | make_lisp_ptr (c_, Lisp_Cons); \ | ||
| 4676 | }) \ | ||
| 4677 | : Fcons (x, y)) | ||
| 4678 | |||
| 4679 | # define local_list1(a) local_cons (a, Qnil) | ||
| 4680 | # define local_list2(a, b) local_cons (a, local_list1 (b)) | ||
| 4681 | # define local_list3(a, b, c) local_cons (a, local_list2 (b, c)) | ||
| 4682 | # define local_list4(a, b, c, d) local_cons (a, local_list3 (b, c, d)) | ||
| 4683 | |||
| 4684 | /* Return a function-scoped vector of length SIZE, with each element | ||
| 4685 | being INIT. */ | ||
| 4686 | |||
| 4687 | # define make_local_vector(size, init) \ | ||
| 4688 | ({ \ | ||
| 4689 | ptrdiff_t size_ = size; \ | ||
| 4690 | Lisp_Object vec_; \ | ||
| 4691 | if (size_ <= lisp_word_count (sa_avail - header_size)) \ | ||
| 4692 | { \ | ||
| 4693 | void *ptr_ = AVAIL_ALLOCA (size_ * word_size + header_size); \ | ||
| 4694 | vec_ = local_vector_init (ptr_, size_, init); \ | ||
| 4695 | } \ | ||
| 4696 | else \ | ||
| 4697 | vec_ = Fmake_vector (make_number (size_), init); \ | ||
| 4698 | vec_; \ | ||
| 4699 | }) | ||
| 4700 | |||
| 4701 | enum { LISP_STRING_OVERHEAD = sizeof (struct Lisp_String) + 1 }; | ||
| 4702 | |||
| 4703 | /* Return a function-scoped string with contents DATA and length NBYTES. */ | ||
| 4704 | |||
| 4705 | # define make_local_string(data, nbytes) \ | ||
| 4706 | ({ \ | ||
| 4707 | ptrdiff_t nbytes_ = nbytes; \ | ||
| 4708 | Lisp_Object string_; \ | ||
| 4709 | if (nbytes_ <= sa_avail - LISP_STRING_OVERHEAD) \ | ||
| 4710 | { \ | ||
| 4711 | struct Lisp_String *ptr_ = AVAIL_ALLOCA (LISP_STRING_OVERHEAD \ | ||
| 4712 | + nbytes_); \ | ||
| 4713 | string_ = local_string_init (ptr_, data, nbytes_); \ | ||
| 4714 | } \ | ||
| 4715 | else \ | ||
| 4716 | string_ = make_string (data, nbytes_); \ | ||
| 4717 | string_; \ | ||
| 4718 | }) | ||
| 4719 | |||
| 4720 | /* Return a function-scoped string with contents DATA. */ | ||
| 4721 | |||
| 4722 | # define build_local_string(data) \ | ||
| 4723 | ({ char const *data1_ = (data); \ | ||
| 4724 | make_local_string (data1_, strlen (data1_)); }) | ||
| 4725 | 4663 | ||
| 4664 | #ifdef ENABLE_CHECKING | ||
| 4665 | extern const char * verify_ascii (const char *); | ||
| 4726 | #else | 4666 | #else |
| 4667 | #define verify_ascii(str) (str) | ||
| 4668 | #endif | ||
| 4727 | 4669 | ||
| 4728 | /* Safer but slower implementations. */ | 4670 | /* Return number of bytes needed for Lisp string of length NBYTES. */ |
| 4729 | INLINE Lisp_Object | 4671 | |
| 4730 | local_cons (Lisp_Object car, Lisp_Object cdr) | 4672 | INLINE ptrdiff_t |
| 4731 | { | 4673 | lisp_string_size (ptrdiff_t nbytes) |
| 4732 | return Fcons (car, cdr); | ||
| 4733 | } | ||
| 4734 | INLINE Lisp_Object | ||
| 4735 | local_list1 (Lisp_Object a) | ||
| 4736 | { | ||
| 4737 | return list1 (a); | ||
| 4738 | } | ||
| 4739 | INLINE Lisp_Object | ||
| 4740 | local_list2 (Lisp_Object a, Lisp_Object b) | ||
| 4741 | { | ||
| 4742 | return list2 (a, b); | ||
| 4743 | } | ||
| 4744 | INLINE Lisp_Object | ||
| 4745 | local_list3 (Lisp_Object a, Lisp_Object b, Lisp_Object c) | ||
| 4746 | { | ||
| 4747 | return list3 (a, b, c); | ||
| 4748 | } | ||
| 4749 | INLINE Lisp_Object | ||
| 4750 | local_list4 (Lisp_Object a, Lisp_Object b, Lisp_Object c, Lisp_Object d) | ||
| 4751 | { | ||
| 4752 | return list4 (a, b, c, d); | ||
| 4753 | } | ||
| 4754 | INLINE Lisp_Object | ||
| 4755 | make_local_vector (ptrdiff_t size, Lisp_Object init) | ||
| 4756 | { | ||
| 4757 | return Fmake_vector (make_number (size), init); | ||
| 4758 | } | ||
| 4759 | INLINE Lisp_Object | ||
| 4760 | make_local_string (char const *str, ptrdiff_t nbytes) | ||
| 4761 | { | 4674 | { |
| 4762 | return make_string (str, nbytes); | 4675 | return sizeof (struct Lisp_String) + nbytes + 1; |
| 4763 | } | 4676 | } |
| 4677 | |||
| 4678 | /* Return function-scoped unibyte Lisp string with contents STR of length | ||
| 4679 | NBYTES and memory footprint of MEMSIZE bytes if the latter doesn't exceed | ||
| 4680 | MAX_ALLOCA, abort otherwise. */ | ||
| 4681 | |||
| 4682 | # define make_local_string(str, memsize, nbytes) \ | ||
| 4683 | ((memsize < MAX_ALLOCA) \ | ||
| 4684 | ? ({ struct Lisp_String *s_ = alloca (memsize); \ | ||
| 4685 | s_->data = (unsigned char *) (s_ + 1); \ | ||
| 4686 | memcpy (s_->data, verify_ascii (str), nbytes + 1); \ | ||
| 4687 | s_->size = nbytes, s_->size_byte = -1; \ | ||
| 4688 | s_->intervals = NULL; \ | ||
| 4689 | make_lisp_ptr (s_, Lisp_String); }) \ | ||
| 4690 | : (emacs_abort (), Qnil)) | ||
| 4691 | |||
| 4692 | /* If STR is a compile-time string constant, build function-scoped Lisp string | ||
| 4693 | from it, fall back to regular Lisp string otherwise. We assume compile-time | ||
| 4694 | string constants never exceeds MAX_ALLOCA - sizeof (Lisp_String) - 1. */ | ||
| 4695 | |||
| 4696 | # define build_local_string(str) \ | ||
| 4697 | (__builtin_constant_p (str) \ | ||
| 4698 | ? make_local_string \ | ||
| 4699 | (str, lisp_string_size (strlen (str)), strlen (str)) \ | ||
| 4700 | : build_string (str)) | ||
| 4701 | |||
| 4702 | #else /* not USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ */ | ||
| 4703 | |||
| 4764 | INLINE Lisp_Object | 4704 | INLINE Lisp_Object |
| 4765 | build_local_string (const char *str) | 4705 | build_local_string (const char *str) |
| 4766 | { | 4706 | { |
| 4767 | return build_string (str); | 4707 | return build_string (str); |
| 4768 | } | 4708 | } |
| 4769 | #endif | ||
| 4770 | 4709 | ||
| 4710 | #endif /* not USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ */ | ||
| 4771 | 4711 | ||
| 4772 | /* Loop over all tails of a list, checking for cycles. | 4712 | /* Loop over all tails of a list, checking for cycles. |
| 4773 | FIXME: Make tortoise and n internal declarations. | 4713 | FIXME: Make tortoise and n internal declarations. |
diff --git a/src/lread.c b/src/lread.c index ad4603299af..b6f259f1a95 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -968,7 +968,6 @@ load_error_handler (Lisp_Object data) | |||
| 968 | static void | 968 | static void |
| 969 | load_warn_old_style_backquotes (Lisp_Object file) | 969 | load_warn_old_style_backquotes (Lisp_Object file) |
| 970 | { | 970 | { |
| 971 | USE_LOCAL_ALLOCA; | ||
| 972 | if (!NILP (Vold_style_backquotes)) | 971 | if (!NILP (Vold_style_backquotes)) |
| 973 | Fmessage (2, ((Lisp_Object []) | 972 | Fmessage (2, ((Lisp_Object []) |
| 974 | { build_local_string ("Loading `%s': old-style backquotes detected!"), | 973 | { build_local_string ("Loading `%s': old-style backquotes detected!"), |
| @@ -3639,7 +3638,6 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag) | |||
| 3639 | static Lisp_Object | 3638 | static Lisp_Object |
| 3640 | read_list (bool flag, Lisp_Object readcharfun) | 3639 | read_list (bool flag, Lisp_Object readcharfun) |
| 3641 | { | 3640 | { |
| 3642 | USE_LOCAL_ALLOCA; | ||
| 3643 | Lisp_Object val, tail; | 3641 | Lisp_Object val, tail; |
| 3644 | Lisp_Object elt, tem; | 3642 | Lisp_Object elt, tem; |
| 3645 | struct gcpro gcpro1, gcpro2; | 3643 | struct gcpro gcpro1, gcpro2; |
diff --git a/src/menu.c b/src/menu.c index 8c77f69d995..ea8da7a9d62 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -324,7 +324,6 @@ single_keymap_panes (Lisp_Object keymap, Lisp_Object pane_name, | |||
| 324 | static void | 324 | static void |
| 325 | single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *skp_v) | 325 | single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *skp_v) |
| 326 | { | 326 | { |
| 327 | USE_LOCAL_ALLOCA; | ||
| 328 | Lisp_Object map, item_string, enabled; | 327 | Lisp_Object map, item_string, enabled; |
| 329 | struct gcpro gcpro1, gcpro2; | 328 | struct gcpro gcpro1, gcpro2; |
| 330 | bool res; | 329 | bool res; |
diff --git a/src/minibuf.c b/src/minibuf.c index c5f52f81de4..b5e7e4cd76e 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1123,7 +1123,6 @@ If `read-buffer-function' is non-nil, this works by calling it as a | |||
| 1123 | function, instead of the usual behavior. */) | 1123 | function, instead of the usual behavior. */) |
| 1124 | (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match) | 1124 | (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match) |
| 1125 | { | 1125 | { |
| 1126 | USE_LOCAL_ALLOCA; | ||
| 1127 | Lisp_Object result; | 1126 | Lisp_Object result; |
| 1128 | char *s; | 1127 | char *s; |
| 1129 | ptrdiff_t len; | 1128 | ptrdiff_t len; |
diff --git a/src/process.c b/src/process.c index 28b55d36815..f6484d0370e 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -592,7 +592,6 @@ decode_status (Lisp_Object l, Lisp_Object *symbol, int *code, bool *coredump) | |||
| 592 | static Lisp_Object | 592 | static Lisp_Object |
| 593 | status_message (struct Lisp_Process *p) | 593 | status_message (struct Lisp_Process *p) |
| 594 | { | 594 | { |
| 595 | USE_LOCAL_ALLOCA; | ||
| 596 | Lisp_Object status = p->status; | 595 | Lisp_Object status = p->status; |
| 597 | Lisp_Object symbol; | 596 | Lisp_Object symbol; |
| 598 | int code; | 597 | int code; |
| @@ -1291,8 +1290,6 @@ number in the string, even when present in ADDRESS. | |||
| 1291 | Returns nil if format of ADDRESS is invalid. */) | 1290 | Returns nil if format of ADDRESS is invalid. */) |
| 1292 | (Lisp_Object address, Lisp_Object omit_port) | 1291 | (Lisp_Object address, Lisp_Object omit_port) |
| 1293 | { | 1292 | { |
| 1294 | USE_LOCAL_ALLOCA; | ||
| 1295 | |||
| 1296 | if (NILP (address)) | 1293 | if (NILP (address)) |
| 1297 | return Qnil; | 1294 | return Qnil; |
| 1298 | 1295 | ||
| @@ -4006,7 +4003,6 @@ static EMACS_INT connect_counter = 0; | |||
| 4006 | static void | 4003 | static void |
| 4007 | server_accept_connection (Lisp_Object server, int channel) | 4004 | server_accept_connection (Lisp_Object server, int channel) |
| 4008 | { | 4005 | { |
| 4009 | USE_LOCAL_ALLOCA; | ||
| 4010 | Lisp_Object proc, caller, name, buffer; | 4006 | Lisp_Object proc, caller, name, buffer; |
| 4011 | Lisp_Object contact, host, service; | 4007 | Lisp_Object contact, host, service; |
| 4012 | struct Lisp_Process *ps= XPROCESS (server); | 4008 | struct Lisp_Process *ps= XPROCESS (server); |
diff --git a/src/textprop.c b/src/textprop.c index c7185f3daef..146ee9e97d9 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -1913,7 +1913,6 @@ Lisp_Object | |||
| 1913 | copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, | 1913 | copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, |
| 1914 | Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) | 1914 | Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) |
| 1915 | { | 1915 | { |
| 1916 | USE_LOCAL_ALLOCA; | ||
| 1917 | INTERVAL i; | 1916 | INTERVAL i; |
| 1918 | Lisp_Object res; | 1917 | Lisp_Object res; |
| 1919 | Lisp_Object stuff; | 1918 | Lisp_Object stuff; |
| @@ -1967,9 +1966,8 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, | |||
| 1967 | if (! NILP (plist)) | 1966 | if (! NILP (plist)) |
| 1968 | /* Must defer modifications to the interval tree in case | 1967 | /* Must defer modifications to the interval tree in case |
| 1969 | src and dest refer to the same string or buffer. */ | 1968 | src and dest refer to the same string or buffer. */ |
| 1970 | stuff = local_cons | 1969 | stuff = Fcons (list3 (make_number (p), make_number (p + len), plist), |
| 1971 | (local_list3 (make_number (p), make_number (p + len), plist), | 1970 | stuff); |
| 1972 | stuff); | ||
| 1973 | 1971 | ||
| 1974 | i = next_interval (i); | 1972 | i = next_interval (i); |
| 1975 | if (!i) | 1973 | if (!i) |
diff --git a/src/xdisp.c b/src/xdisp.c index 3137c8438fe..f5043c3866a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -20892,7 +20892,6 @@ paragraphs, text begins at the right margin and is read from right to left. | |||
| 20892 | See also `bidi-paragraph-direction'. */) | 20892 | See also `bidi-paragraph-direction'. */) |
| 20893 | (Lisp_Object buffer) | 20893 | (Lisp_Object buffer) |
| 20894 | { | 20894 | { |
| 20895 | USE_LOCAL_ALLOCA; | ||
| 20896 | struct buffer *buf = current_buffer; | 20895 | struct buffer *buf = current_buffer; |
| 20897 | struct buffer *old = buf; | 20896 | struct buffer *old = buf; |
| 20898 | 20897 | ||
diff --git a/src/xfns.c b/src/xfns.c index d6e4b7bf5ca..3b094554577 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -1559,9 +1559,6 @@ x_default_scroll_bar_color_parameter (struct frame *f, | |||
| 1559 | const char *xprop, const char *xclass, | 1559 | const char *xprop, const char *xclass, |
| 1560 | int foreground_p) | 1560 | int foreground_p) |
| 1561 | { | 1561 | { |
| 1562 | #ifdef USE_TOOLKIT_SCROLL_BARS | ||
| 1563 | USE_LOCAL_ALLOCA; | ||
| 1564 | #endif | ||
| 1565 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | 1562 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 1566 | Lisp_Object tem; | 1563 | Lisp_Object tem; |
| 1567 | 1564 | ||
| @@ -4273,7 +4270,6 @@ XScreenNumberOfScreen (scr) | |||
| 4273 | void | 4270 | void |
| 4274 | select_visual (struct x_display_info *dpyinfo) | 4271 | select_visual (struct x_display_info *dpyinfo) |
| 4275 | { | 4272 | { |
| 4276 | USE_LOCAL_ALLOCA; | ||
| 4277 | Display *dpy = dpyinfo->display; | 4273 | Display *dpy = dpyinfo->display; |
| 4278 | Screen *screen = dpyinfo->screen; | 4274 | Screen *screen = dpyinfo->screen; |
| 4279 | 4275 | ||
diff --git a/src/xfont.c b/src/xfont.c index fc2dc195822..5e8dd370120 100644 --- a/src/xfont.c +++ b/src/xfont.c | |||
| @@ -677,7 +677,6 @@ xfont_list_family (struct frame *f) | |||
| 677 | static Lisp_Object | 677 | static Lisp_Object |
| 678 | xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | 678 | xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) |
| 679 | { | 679 | { |
| 680 | USE_LOCAL_ALLOCA; | ||
| 681 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); | 680 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 682 | Display *display = dpyinfo->display; | 681 | Display *display = dpyinfo->display; |
| 683 | char name[512]; | 682 | char name[512]; |
| @@ -776,7 +775,7 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) | |||
| 776 | if (dashes >= 13) | 775 | if (dashes >= 13) |
| 777 | { | 776 | { |
| 778 | len = xfont_decode_coding_xlfd (p0, -1, name); | 777 | len = xfont_decode_coding_xlfd (p0, -1, name); |
| 779 | fullname = Fdowncase (make_local_string (name, len)); | 778 | fullname = Fdowncase (make_string (name, len)); |
| 780 | } | 779 | } |
| 781 | XFree (p0); | 780 | XFree (p0); |
| 782 | } | 781 | } |
diff --git a/src/xselect.c b/src/xselect.c index 7e6d699dffa..0bc7fbc204a 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -2159,7 +2159,6 @@ x_clipboard_manager_save (Lisp_Object frame) | |||
| 2159 | static Lisp_Object | 2159 | static Lisp_Object |
| 2160 | x_clipboard_manager_error_1 (Lisp_Object err) | 2160 | x_clipboard_manager_error_1 (Lisp_Object err) |
| 2161 | { | 2161 | { |
| 2162 | USE_LOCAL_ALLOCA; | ||
| 2163 | Fmessage (2, ((Lisp_Object []) | 2162 | Fmessage (2, ((Lisp_Object []) |
| 2164 | { build_local_string ("X clipboard manager error: %s\n\ | 2163 | { build_local_string ("X clipboard manager error: %s\n\ |
| 2165 | If the problem persists, set `x-select-enable-clipboard-manager' to nil."), | 2164 | If the problem persists, set `x-select-enable-clipboard-manager' to nil."), |
| @@ -2213,7 +2212,6 @@ void | |||
| 2213 | x_clipboard_manager_save_all (void) | 2212 | x_clipboard_manager_save_all (void) |
| 2214 | { | 2213 | { |
| 2215 | /* Loop through all X displays, saving owned clipboards. */ | 2214 | /* Loop through all X displays, saving owned clipboards. */ |
| 2216 | USE_LOCAL_ALLOCA; | ||
| 2217 | struct x_display_info *dpyinfo; | 2215 | struct x_display_info *dpyinfo; |
| 2218 | Lisp_Object local_selection, local_frame; | 2216 | Lisp_Object local_selection, local_frame; |
| 2219 | 2217 | ||
diff --git a/src/xterm.c b/src/xterm.c index 7a0e861bf77..8d52b2a2815 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10666,7 +10666,6 @@ static unsigned x_display_id; | |||
| 10666 | struct x_display_info * | 10666 | struct x_display_info * |
| 10667 | x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | 10667 | x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) |
| 10668 | { | 10668 | { |
| 10669 | USE_LOCAL_ALLOCA; | ||
| 10670 | Display *dpy; | 10669 | Display *dpy; |
| 10671 | struct terminal *terminal; | 10670 | struct terminal *terminal; |
| 10672 | struct x_display_info *dpyinfo; | 10671 | struct x_display_info *dpyinfo; |