aboutsummaryrefslogtreecommitdiffstats
path: root/src/lisp.h
diff options
context:
space:
mode:
authorPaul Eggert2014-09-29 19:43:23 -0700
committerPaul Eggert2014-09-29 19:43:23 -0700
commitdc4525691c2c236abdb6c074438223413f80091c (patch)
tree86305e7415bcf1b5cc6ddad6879e922f9e5e163c /src/lisp.h
parenta19f0977a96ee74b96410b41a8ea793c86f64b58 (diff)
downloademacs-dc4525691c2c236abdb6c074438223413f80091c.tar.gz
emacs-dc4525691c2c236abdb6c074438223413f80091c.zip
Simplify stack-allocated Lisp objects, and make them more portable.
The build_local_string macro was used in two ways: (1) string literals for which scoped allocation suffices, and (2) file name components, where it's not safe in general to assume bounded-size ASCII data. Simplify by defining a new macro SCOPED_STRING that allocates a block-scope string, and by using SCOPED_STRING for (1) and build_string for (2). Furthermore, actually use stack allocation only for objects known to have sufficient alignment. This simpler implementation means Emacs can make USE_STACK_LISP_OBJECTS the default unless GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS. * lisp.h (GCALIGNED): Align even if !USE_STACK_LISP_OBJECTS, for fewer differences among implementations. (struct Lisp_String): Now GCALIGNED. (USE_STACK_LISP_OBJECTS): Default to true, since the implementation no longer insists on a nonempty GCALIGNED. But make it false if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS. (SCOPED_CONS_INITIALIZER): Remove, since it's no longer needed separately. Move definiens to scoped_cons. The old definition was incorrect when GCALIGNED was defined to be empty. (union Aligned_String): New type. (USE_STACK_CONS, USE_STACK_STRING): New constants, so that the implementation ports to compilers that don't align strictly enough. Don't worry about the union sizes; it's not worth bothering about. (scoped_cons, scoped_list1, scoped_list3, scoped_list4): Rewrite using USE_STACK_CONS. (scoped_cons): Assume the use of union Aligned_Cons. (lisp_string_size, make_local_string, build_local_string): Remove. Unless otherwise specified, all callers of build_local_string changed to use SCOPED_STRING. (SCOPED_STRING): New macro. * data.c (wrong_choice): * menu.c (single_menu_item): * process.c (Fformat_network_address): Hoist use of SCOPED_STRING out of a scope, so that its returned object lives long enough. * fileio.c (Fexpand_file_name): Use build_string, not SCOPED_STRING, as the string might be long or might not be ASCII.
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h166
1 files changed, 61 insertions, 105 deletions
diff --git a/src/lisp.h b/src/lisp.h
index d2cac17fbc7..27751af2f5b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -282,23 +282,7 @@ error !;
282# endif 282# endif
283#endif 283#endif
284 284
285/* This should work with GCC. Clang has known problems; see 285#ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED
286 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00506.html. */
287#ifndef USE_STACK_LISP_OBJECTS
288# if defined __GNUC__ && !defined __clang__
289 /* 32-bit MinGW builds need at least GCC 4.2 to support this. */
290# if defined __MINGW32__ && !defined _W64 \
291 && __GNUC__ + (__GNUC_MINOR__ > 1) < 5
292# define USE_STACK_LISP_OBJECTS false
293# else /* !(__MINGW32__ && __GNUC__ < 4.2) */
294# define USE_STACK_LISP_OBJECTS true
295# endif
296# else
297# define USE_STACK_LISP_OBJECTS false
298# endif
299#endif
300
301#if defined HAVE_STRUCT_ATTRIBUTE_ALIGNED && USE_STACK_LISP_OBJECTS
302# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) 286# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT)))
303#else 287#else
304# define GCALIGNED /* empty */ 288# define GCALIGNED /* empty */
@@ -1088,7 +1072,7 @@ CDR_SAFE (Lisp_Object c)
1088 1072
1089/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ 1073/* In a string or vector, the sign bit of the `size' is the gc mark bit. */
1090 1074
1091struct Lisp_String 1075struct GCALIGNED Lisp_String
1092 { 1076 {
1093 ptrdiff_t size; 1077 ptrdiff_t size;
1094 ptrdiff_t size_byte; 1078 ptrdiff_t size_byte;
@@ -4598,27 +4582,26 @@ lisp_word_count (ptrdiff_t nbytes)
4598 4582
4599 4583
4600/* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate 4584/* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate
4601 block-scoped conses and function-scoped strings. These objects are not 4585 block-scoped conses and strings. These objects are not
4602 managed by the garbage collector, so they are dangerous: passing them 4586 managed by the garbage collector, so they are dangerous: passing them
4603 out of their scope (e.g., to user code) results in undefined behavior. 4587 out of their scope (e.g., to user code) results in undefined behavior.
4604 Conversely, they have better performance because GC is not involved. 4588 Conversely, they have better performance because GC is not involved.
4605 4589
4606 This feature is experimental and requires careful debugging. It's enabled 4590 This feature is experimental and requires careful debugging.
4607 by default if GCC or a compiler that mimics GCC well (like Intel C/C++) is 4591 Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */
4608 used, except clang (see notice above). For other compilers, brave users can
4609 compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=1' to get into the game.
4610 Note that this feature requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */
4611 4592
4612#ifdef GCALIGNED 4593#ifndef USE_STACK_LISP_OBJECTS
4613 4594# define USE_STACK_LISP_OBJECTS true
4614/* No tricks if struct Lisp_Cons is always aligned. */ 4595#endif
4615 4596
4616# define SCOPED_CONS_INITIALIZER(a, b) &((struct Lisp_Cons) { a, { b } }) 4597/* USE_STACK_LISP_OBJECTS requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */
4617 4598
4618#else /* not GCALIGNED */ 4599#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS
4600# undef USE_STACK_LISP_OBJECTS
4601# define USE_STACK_LISP_OBJECTS false
4602#endif
4619 4603
4620/* A struct Lisp_Cons inside a union that is no larger and may be 4604/* Struct inside unions that are typically no larger and aligned enough. */
4621 better-aligned. */
4622 4605
4623union Aligned_Cons 4606union Aligned_Cons
4624{ 4607{
@@ -4626,88 +4609,61 @@ union Aligned_Cons
4626 double d; intmax_t i; void *p; 4609 double d; intmax_t i; void *p;
4627}; 4610};
4628 4611
4629verify (alignof (union Aligned_Cons) % GCALIGNMENT == 0); 4612union Aligned_String
4630verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons)); 4613{
4631 4614 struct Lisp_String s;
4632# define SCOPED_CONS_INITIALIZER(a, b) \ 4615 double d; intmax_t i; void *p;
4633 &((union Aligned_Cons) { { a, { b } } }.s) 4616};
4634
4635#endif /* GCALIGNED */
4636
4637/* Basic stack-based cons allocation. */
4638
4639#if USE_STACK_LISP_OBJECTS
4640# define scoped_cons(a, b) \
4641 make_lisp_ptr (SCOPED_CONS_INITIALIZER (a, b), Lisp_Cons)
4642# define scoped_list1(a) scoped_cons (a, Qnil)
4643# define scoped_list2(a, b) scoped_cons (a, scoped_list1 (b))
4644# define scoped_list3(a, b, c) scoped_cons (a, scoped_list2 (b, c))
4645# define scoped_list4(a, b, c, d) scoped_cons (a, scoped_list3 (b, c, d))
4646#else
4647# define scoped_cons(a, b) Fcons (a, b)
4648# define scoped_list1(a) list1 (a)
4649# define scoped_list2(a, b) list2 (a, b)
4650# define scoped_list3(a, b, c) list3 (a, b, c)
4651# define scoped_list4(a, b, c, d) list4 (a, b, c, d)
4652#endif
4653 4617
4654/* On-stack string allocation requires __builtin_constant_p, statement 4618/* True for stack-based cons and string implementations. */
4655 expressions and GCALIGNMENT-aligned alloca. All from the above is
4656 assumed for GCC. At least for clang < 3.6, alloca isn't properly
4657 aligned in some cases. In the absence of solid information, play
4658 it safe for other non-GCC compilers. */
4659 4619
4660#if USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ 4620enum
4621 {
4622 USE_STACK_CONS = (USE_STACK_LISP_OBJECTS
4623 && alignof (union Aligned_Cons) % GCALIGNMENT == 0),
4624 USE_STACK_STRING = (USE_STACK_LISP_OBJECTS
4625 && alignof (union Aligned_String) % GCALIGNMENT == 0)
4626 };
4661 4627
4662/* Used to check whether stack-allocated strings are ASCII-only. */ 4628/* Build a stack-based Lisp cons or short list if possible, a GC-based
4629 one otherwise. The resulting object should not be modified or made
4630 visible to user code. */
4631
4632#define scoped_cons(a, b) \
4633 (USE_STACK_CONS \
4634 ? make_lisp_ptr (&(union Aligned_Cons) { { a, { b } } }.s, Lisp_Cons) \
4635 : Fcons (a, b))
4636#define scoped_list1(a) \
4637 (USE_STACK_CONS ? scoped_cons (a, Qnil) : list1 (a))
4638#define scoped_list2(a, b) \
4639 (USE_STACK_CONS ? scoped_cons (a, scoped_list1 (b)) : list2 (a,b))
4640#define scoped_list3(a, b, c) \
4641 (USE_STACK_CONS ? scoped_cons (a, scoped_list2 (b, c)) : list3 (a, b, c))
4642#define scoped_list4(a, b, c, d) \
4643 (USE_STACK_CONS \
4644 ? scoped_cons (a, scoped_list3 (b, c, d)) : \
4645 list4 (a, b, c, d))
4646
4647/* Check whether stack-allocated strings are ASCII-only. */
4663 4648
4664#ifdef ENABLE_CHECKING 4649#ifdef ENABLE_CHECKING
4665extern const char * verify_ascii (const char *); 4650extern const char *verify_ascii (const char *);
4666#else 4651#else
4667#define verify_ascii(str) (str) 4652# define verify_ascii(str) (str)
4668#endif 4653#endif
4669 4654
4670/* Return number of bytes needed for Lisp string of length NBYTES. */ 4655/* Build a stack-based Lisp string from STR if possible, a GC-based
4671 4656 one if not. STR is not necessarily copied and should contain only
4672INLINE ptrdiff_t 4657 ASCII characters. The resulting Lisp string should not be modified
4673lisp_string_size (ptrdiff_t nbytes) 4658 or made visible to user code. */
4674{ 4659
4675 return sizeof (struct Lisp_String) + nbytes + 1; 4660#define SCOPED_STRING(str) \
4676} 4661 (USE_STACK_STRING \
4677 4662 ? (make_lisp_ptr \
4678/* Return function-scoped unibyte Lisp string with contents STR of length 4663 ((&(union Aligned_String) \
4679 NBYTES and memory footprint of MEMSIZE bytes if the latter doesn't exceed 4664 { { strlen (str), -1, 0, (unsigned char *) verify_ascii (str) } }.s), \
4680 MAX_ALLOCA, abort otherwise. */ 4665 Lisp_String)) \
4681 4666 : build_string (verify_ascii (str)))
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
4704INLINE Lisp_Object
4705build_local_string (const char *str)
4706{
4707 return build_string (str);
4708}
4709
4710#endif /* not USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ */
4711 4667
4712/* Loop over all tails of a list, checking for cycles. 4668/* Loop over all tails of a list, checking for cycles.
4713 FIXME: Make tortoise and n internal declarations. 4669 FIXME: Make tortoise and n internal declarations.