emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Emacs-diffs] trunk r117971: Keep stack-allocated Lisp objects fast


From: Stefan Monnier
Subject: Re: [Emacs-diffs] trunk r117971: Keep stack-allocated Lisp objects fast rather than versatile.
Date: Mon, 29 Sep 2014 10:10:50 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4.50 (gnu/linux)

FWIW, I agree with the general idea of this change, but if we focus on
scoped_* rather than local_*, then I have to bring up a serious
issue with those scoped_*: their scoping rule is non-obvious.
So I think we should replace the

  scoped_cons (car, cdr)

expression with a declaration:

  scoped_cons (var, car, cdr)

which would expand to something morally equivalent to:

  struct Lisp_Cons tmp = { car, cdr };
  Lisp_Object var = make_lisp_ptr (tmp, Lisp_Cons);

This will be a bit less convenient to use, but will make its scoping
rule much more clear; and will also make it clear that you won't risk
eating up all the stack by allocating inside a looping.

They'd still be delicate to use because they're stack-allocated, but at
least the other warts would disappear.  And having them less convenient
to use could be considered as a feature (to try and make sure people
don't use them without thinking).


        Stefan


>>>>> "Dmitry" == Dmitry Antipov <address@hidden> writes:

> ------------------------------------------------------------
> revno: 117971
> revision-id: address@hidden
> parent: address@hidden
> committer: Dmitry Antipov <address@hidden>
> branch nick: trunk
> timestamp: Mon 2014-09-29 10:44:31 +0400
> message:
>   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.
> modified:
>   ChangeLog                      
> changelog-20091113204419-o5vbwnq5f7feedwu-1538
>   configure.ac                   
> configure.in-20091113204419-o5vbwnq5f7feedwu-783
>   src/ChangeLog                  
> changelog-20091113204419-o5vbwnq5f7feedwu-1438
>   src/alloc.c                    alloc.c-20091113204419-o5vbwnq5f7feedwu-252
>   src/buffer.c                   buffer.c-20091113204419-o5vbwnq5f7feedwu-264
>   src/charset.c                  
> charset.c-20091113204419-o5vbwnq5f7feedwu-1075
>   src/chartab.c                  
> chartab.c-20091113204419-o5vbwnq5f7feedwu-8539
>   src/data.c                     data.c-20091113204419-o5vbwnq5f7feedwu-251
>   src/editfns.c                  editfns.c-20091113204419-o5vbwnq5f7feedwu-255
>   src/emacs.c                    emacs.c-20091113204419-o5vbwnq5f7feedwu-241
>   src/fileio.c                   fileio.c-20091113204419-o5vbwnq5f7feedwu-210
>   src/fns.c                      fns.c-20091113204419-o5vbwnq5f7feedwu-203
>   src/font.c                     font.c-20091113204419-o5vbwnq5f7feedwu-8540
>   src/fontset.c                  
> fontset.c-20091113204419-o5vbwnq5f7feedwu-1079
>   src/frame.c                    frame.c-20091113204419-o5vbwnq5f7feedwu-243
>   src/keyboard.c                 
> keyboard.c-20091113204419-o5vbwnq5f7feedwu-449
>   src/keymap.c                   keymap.c-20091113204419-o5vbwnq5f7feedwu-219
>   src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
>   src/lread.c                    lread.c-20091113204419-o5vbwnq5f7feedwu-266
>   src/menu.c                     menu.c-20091113204419-o5vbwnq5f7feedwu-8676
>   src/minibuf.c                  minibuf.c-20091113204419-o5vbwnq5f7feedwu-242
>   src/process.c                  process.c-20091113204419-o5vbwnq5f7feedwu-462
>   src/textprop.c                 
> textprop.c-20091113204419-o5vbwnq5f7feedwu-512
>   src/xdisp.c                    xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
>   src/xfns.c                     xfns.c-20091113204419-o5vbwnq5f7feedwu-274
>   src/xfont.c                    xfont.c-20091113204419-o5vbwnq5f7feedwu-8547
>   src/xselect.c                  xselect.c-20091113204419-o5vbwnq5f7feedwu-543
>   src/xterm.c                    xterm.c-20091113204419-o5vbwnq5f7feedwu-244

> === modified file 'ChangeLog'
> --- a/ChangeLog       2014-09-27 23:35:50 +0000
> +++ b/ChangeLog       2014-09-29 06:44:31 +0000
> @@ -1,3 +1,8 @@
> +2014-09-29  Dmitry Antipov  <address@hidden>
> +
> +     * configure.ac (HAVE_STATEMENT_EXPRESSIONS): Remove.
> +     For USE_STACK_LISP_OBJECTS, we always assume __GNUC__.
> +
>  2014-09-27  Ken Brown  <address@hidden>
 
>       * configure.ac [CYGWIN]: Enable sound support.

> === modified file 'configure.ac'
> --- a/configure.ac    2014-09-27 23:35:50 +0000
> +++ b/configure.ac    2014-09-29 06:44:31 +0000
> @@ -4838,17 +4838,6 @@
>       structure to an N-byte boundary.])
>  fi
 
> -AC_CACHE_CHECK([for statement expressions],
> -  [emacs_cv_statement_expressions],
> -  [AC_COMPILE_IFELSE(
> -     [AC_LANG_PROGRAM([], [[return ({ int x = 5; x-x; });]])],
> -     [emacs_cv_statement_expressions=yes],
> -     [emacs_cv_statement_expressions=no])])
> -if test "$emacs_cv_statement_expressions" = yes; then
> -  AC_DEFINE([HAVE_STATEMENT_EXPRESSIONS], 1,
> -    [Define to 1 if statement expressions work.])
> -fi
> -
>  if test "${GNU_MALLOC}" = "yes" ; then
>    AC_DEFINE(GNU_MALLOC, 1,
>           [Define to 1 if you want to use the GNU memory allocator.])

> === modified file 'src/ChangeLog'
> --- a/src/ChangeLog   2014-09-28 22:31:59 +0000
> +++ b/src/ChangeLog   2014-09-29 06:44:31 +0000
> @@ -1,3 +1,28 @@
> +2014-09-29  Dmitry Antipov  <address@hidden>
> +
> +     Keep stack-allocated Lisp objects fast rather than versatile.
> +     * 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.
> +
>  2014-09-28  Ken Brown  <address@hidden>
 
>       * sheap.c (bss_sbrk_buffer_beg): Remove redundant variable.

> === modified file 'src/alloc.c'
> --- a/src/alloc.c     2014-09-17 18:27:36 +0000
> +++ b/src/alloc.c     2014-09-29 06:44:31 +0000
> @@ -69,7 +69,7 @@
>  static bool valgrind_p;
>  #endif
 
> -#ifdef USE_LOCAL_ALLOCATORS
> +#if USE_STACK_LISP_OBJECTS
>  # if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS
>  #  error "Stack-allocated Lisp objects are not compatible with GCPROs"
>  # endif
> @@ -2232,33 +2232,6 @@
>    return val;
>  }
 
> -#ifdef USE_LOCAL_ALLOCATORS
> -
> -/* Initialize the string S from DATA and SIZE.  S must be followed by
> -   SIZE + 1 bytes of memory that can be used.  Return S tagged as a
> -   Lisp object.  */
> -
> -Lisp_Object
> -local_string_init (struct Lisp_String *s, char const *data, ptrdiff_t size)
> -{
> -  unsigned char *data_copy = (unsigned char *) (s + 1);
> -  parse_str_as_multibyte ((unsigned char const *) data,
> -                       size, &s->size, &s->size_byte);
> -  if (size == s->size || size != s->size_byte)
> -    {
> -      s->size = size;
> -      s->size_byte = -1;
> -    }
> -  s->intervals = NULL;
> -  s->data = data_copy;
> -  memcpy (data_copy, data, size);
> -  data_copy[size] = '\0';
> -  return make_lisp_ptr (s, Lisp_String);
> -}
> -
> -#endif
> -
> -
>  /* Make an unibyte string from LENGTH bytes at CONTENTS.  */
 
>  Lisp_Object
> @@ -3320,23 +3293,6 @@
>    return vector;
>  }
 
> -#ifdef USE_LOCAL_ALLOCATORS
> -
> -/* Initialize V with LENGTH objects each with value INIT,
> -   and return it tagged as a Lisp Object.  */
> -
> -Lisp_Object
> -local_vector_init (struct Lisp_Vector *v, ptrdiff_t length, Lisp_Object init)
> -{
> -  v->header.size = length;
> -  for (ptrdiff_t i = 0; i < length; i++)
> -    v->contents[i] = init;
> -  return make_lisp_ptr (v, Lisp_Vectorlike);
> -}
> -
> -#endif
> -
> -
>  DEFUN ("vector", Fvector, Svector, 0, MANY, 0,
>         doc: /* Return a newly created vector with specified arguments as 
> elements.
>  Any number of arguments, even zero arguments, are allowed.
> @@ -7157,7 +7113,22 @@
 
>  #endif /* ENABLE_CHECKING */
 
> -#if defined (ENABLE_CHECKING) && defined (USE_STACK_LISP_OBJECTS)
> +#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
> +
> +/* Debugging check whether STR is ASCII-only.  */
> +
> +const char *
> +verify_ascii (const char *str)
> +{
> +  const unsigned char *ptr = (unsigned char *) str, *end = ptr + strlen 
> (str);
> +  while (ptr < end)
> +    {
> +      int c = STRING_CHAR_ADVANCE (ptr);
> +      if (!ASCII_CHAR_P (c))
> +     emacs_abort ();
> +    }
> +  return str;
> +}
 
>  /* Stress alloca with inconveniently sized requests and check
>     whether all allocated areas may be used for Lisp_Object.  */
> @@ -7175,7 +7146,7 @@
>      }
>  }
 
> -#else /* not (ENABLE_CHECKING && USE_STACK_LISP_OBJECTS) */
> +#else /* not ENABLE_CHECKING && USE_STACK_LISP_OBJECTS */
 
>  #define verify_alloca() ((void) 0)
 

> === modified file 'src/buffer.c'
> --- a/src/buffer.c    2014-09-25 02:01:14 +0000
> +++ b/src/buffer.c    2014-09-29 06:44:31 +0000
> @@ -1511,7 +1511,6 @@
>  exists, return the buffer `*scratch*' (creating it if necessary).  */)
>    (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
>  {
> -  USE_LOCAL_ALLOCA;
>    struct frame *f = decode_any_frame (frame);
>    Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
>    Lisp_Object buf, notsogood = Qnil;
> @@ -1570,7 +1569,6 @@
>  Lisp_Object
>  other_buffer_safely (Lisp_Object buffer)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object tail, buf;
 
>    FOR_EACH_LIVE_BUFFER (tail, buf)
> @@ -5240,7 +5238,6 @@
>  void
>  init_buffer (int initialized)
>  {
> -  USE_LOCAL_ALLOCA;
>    char *pwd;
>    Lisp_Object temp;
>    ptrdiff_t len;

> === modified file 'src/charset.c'
> --- a/src/charset.c   2014-09-25 02:01:14 +0000
> +++ b/src/charset.c   2014-09-29 06:44:31 +0000
> @@ -481,7 +481,6 @@
>  load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
>                           int control_flag)
>  {
> -  USE_LOCAL_ALLOCA;
>    unsigned min_code = CHARSET_MIN_CODE (charset);
>    unsigned max_code = CHARSET_MAX_CODE (charset);
>    int fd;
> @@ -1551,7 +1550,6 @@
>  only `ascii', `eight-bit-control', and `eight-bit-graphic'.  */)
>    (Lisp_Object beg, Lisp_Object end, Lisp_Object table)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object charsets;
>    ptrdiff_t from, from_byte, to, stop, stop_byte;
>    int i;
> @@ -1572,7 +1570,7 @@
 
>    from_byte = CHAR_TO_BYTE (from);
 
> -  charsets = make_local_vector (charset_table_used, Qnil);
> +  charsets = Fmake_vector (make_number (charset_table_used), Qnil);
>    while (1)
>      {
>        find_charsets_in_text (BYTE_POS_ADDR (from_byte), stop - from,
> @@ -1603,14 +1601,13 @@
>  only `ascii', `eight-bit-control', and `eight-bit-graphic'. */)
>    (Lisp_Object str, Lisp_Object table)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object charsets;
>    int i;
>    Lisp_Object val;
 
>    CHECK_STRING (str);
 
> -  charsets = make_local_vector (charset_table_used, Qnil);
> +  charsets = Fmake_vector (make_number (charset_table_used), Qnil);
>    find_charsets_in_text (SDATA (str), SCHARS (str), SBYTES (str),
>                        charsets, table,
>                        STRING_MULTIBYTE (str));

> === modified file 'src/chartab.c'
> --- a/src/chartab.c   2014-09-25 02:01:14 +0000
> +++ b/src/chartab.c   2014-09-29 06:44:31 +0000
> @@ -1249,7 +1249,6 @@
>  static Lisp_Object
>  uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object *value_table = XVECTOR (XCHAR_TABLE 
> (table)->extras[4])->contents;
>    int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
 
> @@ -1260,7 +1259,7 @@
>    value = make_number (i);
>    if (i == size)
>      set_char_table_extras (table, 4, Fvconcat (2, ((Lisp_Object []) {
> -      XCHAR_TABLE (table)->extras[4], make_local_vector (1, value) })));
> +      XCHAR_TABLE (table)->extras[4], Fmake_vector (make_number (1), value) 
> })));
>    return make_number (i);
>  }
 
> @@ -1293,7 +1292,6 @@
>  Lisp_Object
>  uniprop_table (Lisp_Object prop)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object val, table, result;
 
>    val = Fassq (prop, Vchar_code_property_alist);

> === modified file 'src/data.c'
> --- a/src/data.c      2014-09-25 02:01:14 +0000
> +++ b/src/data.c      2014-09-29 06:44:31 +0000
> @@ -1004,7 +1004,6 @@
>  static void
>  wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
>  {
> -  USE_LOCAL_ALLOCA;
>    xsignal2 (Qerror, Fconcat (4, ((Lisp_Object [])
>      { build_local_string ("Value should be from "),
>        Fnumber_to_string (min),

> === modified file 'src/editfns.c'
> --- a/src/editfns.c   2014-09-25 02:01:14 +0000
> +++ b/src/editfns.c   2014-09-29 06:44:31 +0000
> @@ -3531,7 +3531,6 @@
>  usage: (propertize STRING &rest PROPERTIES)  */)
>    (ptrdiff_t nargs, Lisp_Object *args)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object properties, string;
>    struct gcpro gcpro1, gcpro2;
>    ptrdiff_t i;
> @@ -3548,7 +3547,7 @@
>    string = Fcopy_sequence (args[0]);
 
>    for (i = 1; i < nargs; i += 2)
> -    properties = local_cons (args[i], local_cons (args[i + 1], properties));
> +    properties = Fcons (args[i], Fcons (args[i + 1], properties));
 
>    Fadd_text_properties (make_number (0),
>                       make_number (SCHARS (string)),
> @@ -4363,7 +4362,6 @@
>  Lisp_Object
>  format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1)
>  {
> -  USE_LOCAL_ALLOCA;
>    return Fformat (3, ((Lisp_Object [])
>      { build_local_string (string1), arg0, arg1 }));
>  }

> === modified file 'src/emacs.c'
> --- a/src/emacs.c     2014-09-25 02:01:14 +0000
> +++ b/src/emacs.c     2014-09-29 06:44:31 +0000
> @@ -396,7 +396,6 @@
>  static void
>  init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
>  {
> -  USE_LOCAL_ALLOCA;
>    int i;
>    Lisp_Object name, dir, handler;
>    ptrdiff_t count = SPECPDL_INDEX ();
> @@ -2209,7 +2208,6 @@
>  Lisp_Object
>  decode_env_path (const char *evarname, const char *defalt, bool empty)
>  {
> -  USE_LOCAL_ALLOCA;
>    const char *path, *p;
>    Lisp_Object lpath, element, tem;
>    /* Default is to use "." for empty path elements.

> === modified file 'src/fileio.c'
> --- a/src/fileio.c    2014-09-25 02:01:14 +0000
> +++ b/src/fileio.c    2014-09-29 06:44:31 +0000
> @@ -5411,7 +5411,6 @@
>  static Lisp_Object
>  auto_save_error (Lisp_Object error_val)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object msg;
>    int i;
>    struct gcpro gcpro1;

> === modified file 'src/fns.c'
> --- a/src/fns.c       2014-09-25 02:01:14 +0000
> +++ b/src/fns.c       2014-09-29 06:44:31 +0000
> @@ -2706,7 +2706,6 @@
>  if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil.  */)
>    (Lisp_Object prompt)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object ans;
>    struct gcpro gcpro1;
 

> === modified file 'src/font.c'
> --- a/src/font.c      2014-09-25 02:01:14 +0000
> +++ b/src/font.c      2014-09-29 06:44:31 +0000
> @@ -357,7 +357,6 @@
>  font_style_to_value (enum font_property_index prop, Lisp_Object val,
>                       bool noerror)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX);
>    int len;
 
> @@ -402,7 +401,7 @@
>        ASET (elt, 1, val);
>        ASET (font_style_table, prop - FONT_WEIGHT_INDEX,
>           Fvconcat (2, ((Lisp_Object [])
> -           { table, make_local_vector (1, elt) })));
> +           { table, Fmake_vector (make_number (1), elt) })));
>        return (100 << 8) | (i << 4);
>      }
>    else
> @@ -1050,7 +1049,6 @@
>  int
>  font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font)
>  {
> -  USE_LOCAL_ALLOCA;
>    int i, j, n;
>    char *f[XLFD_LAST_INDEX + 1];
>    Lisp_Object val;
> @@ -1760,7 +1758,6 @@
>  void
>  font_parse_family_registry (Lisp_Object family, Lisp_Object registry, 
> Lisp_Object font_spec)
>  {
> -  USE_LOCAL_ALLOCA;
>    ptrdiff_t len;
>    char *p0, *p1;
 
> @@ -2686,7 +2683,6 @@
>  static Lisp_Object
>  font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object entity, val;
>    enum font_property_index prop;
>    ptrdiff_t i;
> @@ -2717,7 +2713,7 @@
>       }
>        if (NILP (spec))
>       {
> -       val = local_cons (entity, val);
> +       val = Fcons (entity, val);
>         continue;
>       }
>        for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++)
> @@ -2748,7 +2744,7 @@
>                  AREF (entity, FONT_AVGWIDTH_INDEX)))
>       prop = FONT_SPEC_MAX;
>        if (prop < FONT_SPEC_MAX)
> -     val = local_cons (entity, val);
> +     val = Fcons (entity, val);
>      }
>    return (Fvconcat (1, &val));
>  }
> @@ -5006,7 +5002,6 @@
>  void
>  font_add_log (const char *action, Lisp_Object arg, Lisp_Object result)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object val;
>    int i;
 

> === modified file 'src/fontset.c'
> --- a/src/fontset.c   2014-09-25 02:01:14 +0000
> +++ b/src/fontset.c   2014-09-29 06:44:31 +0000
> @@ -1420,7 +1420,6 @@
>  appended.  By default, FONT-SPEC overrides the previous settings.  */)
>    (Lisp_Object name, Lisp_Object target, Lisp_Object font_spec, Lisp_Object 
> frame, Lisp_Object add)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object fontset;
>    Lisp_Object font_def, registry, family;
>    Lisp_Object range_list;

> === modified file 'src/frame.c'
> --- a/src/frame.c     2014-09-25 07:01:35 +0000
> +++ b/src/frame.c     2014-09-29 06:44:31 +0000
> @@ -4122,7 +4122,6 @@
>  x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
>          const char *attribute, const char *class, enum resource_types type)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object tem;
 
>    tem = Fassq (param, alist);

> === modified file 'src/keyboard.c'
> --- a/src/keyboard.c  2014-09-27 15:52:28 +0000
> +++ b/src/keyboard.c  2014-09-29 06:44:31 +0000
> @@ -573,7 +573,7 @@
 
>    kset_echo_string
>      (current_kboard,
> -     concat2 (echo_string, make_local_string (buffer, ptr - buffer)));
> +     concat2 (echo_string, make_string (buffer, ptr - buffer)));
>    SAFE_FREE ();
>  }
 
> @@ -597,8 +597,6 @@
>  static void
>  echo_dash (void)
>  {
> -  USE_LOCAL_ALLOCA;
> -
>    /* Do nothing if not echoing at all.  */
>    if (NILP (KVAR (current_kboard, echo_string)))
>      return;
> @@ -1892,7 +1890,6 @@
>  static Lisp_Object
>  safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object hook, fun;
 
>    eassert (nargs == 2);
> @@ -7699,7 +7696,6 @@
>  bool
>  parse_menu_item (Lisp_Object item, int inmenubar)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object def, tem, item_string, start;
>    Lisp_Object filter;
>    Lisp_Object keyhint;
> @@ -8523,7 +8519,6 @@
>  read_char_minibuf_menu_prompt (int commandflag,
>                              Lisp_Object map)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object name;
>    ptrdiff_t nlength;
>    /* FIXME: Use the minibuffer's frame width.  */

> === modified file 'src/keymap.c'
> --- a/src/keymap.c    2014-09-25 02:01:14 +0000
> +++ b/src/keymap.c    2014-09-29 06:44:31 +0000
> @@ -1308,7 +1308,6 @@
>  static void
>  silly_event_symbol_error (Lisp_Object c)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object parsed, base, name, assoc;
>    int modifiers;
 
> @@ -3418,7 +3417,6 @@
>                bool partial, Lisp_Object shadow, Lisp_Object entire_map,
>                bool keymap_p, bool mention_shadow)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object definition;
>    Lisp_Object tem2;
>    Lisp_Object elt_prefix = Qnil;

> === modified file 'src/lisp.h'
> --- a/src/lisp.h      2014-09-25 17:49:02 +0000
> +++ b/src/lisp.h      2014-09-29 06:44:31 +0000
> @@ -3705,8 +3705,6 @@
>  extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object);
>  extern _Noreturn void string_overflow (void);
>  extern Lisp_Object make_string (const char *, ptrdiff_t);
> -extern Lisp_Object local_string_init (struct Lisp_String *, char const *,
> -                                   ptrdiff_t);
>  extern Lisp_Object make_formatted_string (char *, const char *, ...)
>    ATTRIBUTE_FORMAT_PRINTF (2, 3);
>  extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t);
> @@ -3795,8 +3793,6 @@
>  extern struct window *allocate_window (void);
>  extern struct frame *allocate_frame (void);
>  extern struct Lisp_Process *allocate_process (void);
> -extern Lisp_Object local_vector_init (struct Lisp_Vector *, ptrdiff_t,
> -                                   Lisp_Object);
>  extern struct terminal *allocate_terminal (void);
>  extern bool gc_in_progress;
>  extern bool abort_on_gc;
> @@ -4602,17 +4598,25 @@
 
 
>  /* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate
> -   block-scoped conses and function-scoped vectors and strings.  These 
> objects
> -   are not managed by the garbage collector, so they are dangerous: passing
> -   them out of their scope (e.g., to user code) results in undefined 
> behavior.
> +   block-scoped conses and function-scoped strings.  These objects are not
> +   managed by the garbage collector, so they are dangerous: passing them
> +   out of their scope (e.g., to user code) results in undefined behavior.
>     Conversely, they have better performance because GC is not involved.
 
>     This feature is experimental and requires careful debugging.  It's enabled
>     by default if GCC or a compiler that mimics GCC well (like Intel C/C++) is
>     used, except clang (see notice above).  For other compilers, brave users 
> can
> -   compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS' to get into the game.
> +   compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=1' to get into the game.
>     Note that this feature requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS.  */
 
> +#ifdef GCALIGNED
> +
> +/* No tricks if struct Lisp_Cons is always aligned.  */
> +
> +# define SCOPED_CONS_INITIALIZER(a, b) &((struct Lisp_Cons) { a, { b } })
> +
> +#else /* not GCALIGNED */
> +
>  /* A struct Lisp_Cons inside a union that is no larger and may be
>     better-aligned.  */
 
> @@ -4621,153 +4625,89 @@
>    struct Lisp_Cons s;
>    double d; intmax_t i; void *p;
>  };
> +
> +verify (alignof (union Aligned_Cons) % GCALIGNMENT == 0);
>  verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons));
 
> -/* Allocate a block-scoped cons.  */
> -
> -#define scoped_cons(car, cdr)                                                
> \
> -   ((USE_STACK_LISP_OBJECTS                                          \
> -     && alignof (union Aligned_Cons) % GCALIGNMENT == 0)             \
> -    ? make_lisp_ptr (&((union Aligned_Cons) {{car, {cdr}}}).s, Lisp_Cons) \
> -    : Fcons (car, cdr))
> -
> -/* Convenient utility macros similar to listX functions.  */
> +# define SCOPED_CONS_INITIALIZER(a, b)               \
> +    &((union Aligned_Cons) { { a, { b } } }.s)
> +
> +#endif /* GCALIGNED */
> +
> +/* Basic stack-based cons allocation.  */
 
>  #if USE_STACK_LISP_OBJECTS
> +# define scoped_cons(a, b) \
> +    make_lisp_ptr (SCOPED_CONS_INITIALIZER (a, b), Lisp_Cons)
>  # define scoped_list1(a) scoped_cons (a, Qnil)
>  # define scoped_list2(a, b) scoped_cons (a, scoped_list1 (b))
>  # define scoped_list3(a, b, c) scoped_cons (a, scoped_list2 (b, c))
>  # define scoped_list4(a, b, c, d) scoped_cons (a, scoped_list3 (b, c, d))
>  #else
> +# define scoped_cons(a, b) Fcons (a, b)
>  # define scoped_list1(a) list1 (a)
>  # define scoped_list2(a, b) list2 (a, b)
>  # define scoped_list3(a, b, c) list3 (a, b, c)
>  # define scoped_list4(a, b, c, d) list4 (a, b, c, d)
>  #endif
 
> -/* Local allocators require both statement expressions and a
> -   GCALIGNMENT-aligned alloca.  clang's alloca isn't properly aligned
> -   in some cases.  In the absence of solid information, play it safe
> -   for other non-GCC compilers.  */
> -#if (USE_STACK_LISP_OBJECTS && HAVE_STATEMENT_EXPRESSIONS \
> -     && __GNUC__ && !__clang__)
> -# define USE_LOCAL_ALLOCATORS
> -#endif
> -
> -/* Any function that uses a local allocator should start with either
> -   'USE_SAFE_ALLOCA; or 'USE_LOCAL_ALLOCA;' (but not both).  */
> -#ifdef USE_LOCAL_ALLOCATORS
> -# define USE_LOCAL_ALLOCA ptrdiff_t sa_avail = MAX_ALLOCA
> -#else
> -# define USE_LOCAL_ALLOCA
> -#endif
> -
> -#ifdef USE_LOCAL_ALLOCATORS
> -
> -/* Return a function-scoped cons whose car is X and cdr is Y.  */
> -
> -# define local_cons(x, y)                                            \
> -    (sizeof (struct Lisp_Cons) <= sa_avail                           \
> -     ? ({                                                            \
> -       struct Lisp_Cons *c_ = AVAIL_ALLOCA (sizeof (struct Lisp_Cons)); \
> -       c_->car = (x);                                                \
> -       c_->u.cdr = (y);                                              \
> -       make_lisp_ptr (c_, Lisp_Cons);                                \
> -       })                                                            \
> -     : Fcons (x, y))
> -
> -# define local_list1(a) local_cons (a, Qnil)
> -# define local_list2(a, b) local_cons (a, local_list1 (b))
> -# define local_list3(a, b, c) local_cons (a, local_list2 (b, c))
> -# define local_list4(a, b, c, d) local_cons (a, local_list3 (b, c, d))
> -
> -/* Return a function-scoped vector of length SIZE, with each element
> -   being INIT.  */
> -
> -# define make_local_vector(size, init)                                       
> \
> -    ({                                                                       
> \
> -       ptrdiff_t size_ = size;                                               
> \
> -       Lisp_Object vec_;                                             \
> -       if (size_ <= lisp_word_count (sa_avail - header_size))                
> \
> -      {                                                              \
> -        void *ptr_ = AVAIL_ALLOCA (size_ * word_size + header_size); \
> -        vec_ = local_vector_init (ptr_, size_, init);                \
> -      }                                                              \
> -       else                                                          \
> -      vec_ = Fmake_vector (make_number (size_), init);               \
> -       vec_;                                                         \
> -    })
> -
> -enum { LISP_STRING_OVERHEAD = sizeof (struct Lisp_String) + 1 };
> -
> -/* Return a function-scoped string with contents DATA and length NBYTES.  */
> -
> -# define make_local_string(data, nbytes)                             \
> -    ({                                                                       
> \
> -       ptrdiff_t nbytes_ = nbytes;                                   \
> -       Lisp_Object string_;                                          \
> -       if (nbytes_ <= sa_avail - LISP_STRING_OVERHEAD)                       
> \
> -      {                                                              \
> -        struct Lisp_String *ptr_ = AVAIL_ALLOCA (LISP_STRING_OVERHEAD \
> -                                                 + nbytes_);         \
> -        string_ = local_string_init (ptr_, data, nbytes_);           \
> -      }                                                              \
> -       else                                                          \
> -      string_ = make_string (data, nbytes_);                         \
> -       string_;                                                              
> \
> -    })
> -
> -/* Return a function-scoped string with contents DATA.  */
> -
> -# define build_local_string(data)                    \
> -    ({ char const *data1_ = (data);                  \
> -       make_local_string (data1_, strlen (data1_)); })
> -
> -#else
> -
> -/* Safer but slower implementations.  */
> -INLINE Lisp_Object
> -local_cons (Lisp_Object car, Lisp_Object cdr)
> -{
> -  return Fcons (car, cdr);
> -}
> -INLINE Lisp_Object
> -local_list1 (Lisp_Object a)
> -{
> -  return list1 (a);
> -}
> -INLINE Lisp_Object
> -local_list2 (Lisp_Object a, Lisp_Object b)
> -{
> -  return list2 (a, b);
> -}
> -INLINE Lisp_Object
> -local_list3 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
> -{
> -  return list3 (a, b, c);
> -}
> -INLINE Lisp_Object
> -local_list4 (Lisp_Object a, Lisp_Object b, Lisp_Object c, Lisp_Object d)
> -{
> -  return list4 (a, b, c, d);
> -}
> -INLINE Lisp_Object
> -make_local_vector (ptrdiff_t size, Lisp_Object init)
> -{
> -  return Fmake_vector (make_number (size), init);
> -}
> -INLINE Lisp_Object
> -make_local_string (char const *str, ptrdiff_t nbytes)
> -{
> -  return make_string (str, nbytes);
> -}
> +/* On-stack string allocation requires __builtin_constant_p, statement
> +   expressions and GCALIGNMENT-aligned alloca.  All from the above is
> +   assumed for GCC.  At least for clang < 3.6, alloca isn't properly
> +   aligned in some cases.  In the absence of solid information, play
> +   it safe for other non-GCC compilers.  */
> +
> +#if USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__
> +
> +/* Used to check whether stack-allocated strings are ASCII-only.  */
> +
> +#ifdef ENABLE_CHECKING
> +extern const char * verify_ascii (const char *);
> +#else
> +#define verify_ascii(str) (str)
> +#endif
> +
> +/* Return number of bytes needed for Lisp string of length NBYTES.  */
> +
> +INLINE ptrdiff_t
> +lisp_string_size (ptrdiff_t nbytes)
> +{
> +  return sizeof (struct Lisp_String) + nbytes + 1;
> +}
> +
> +/* Return function-scoped unibyte Lisp string with contents STR of length
> +   NBYTES and memory footprint of MEMSIZE bytes if the latter doesn't exceed
> +   MAX_ALLOCA, abort otherwise.  */
> +
> +# define make_local_string(str, memsize, nbytes)             \
> +    ((memsize < MAX_ALLOCA)                                  \
> +      ? ({ struct Lisp_String *s_ = alloca (memsize);                \
> +        s_->data = (unsigned char *) (s_ + 1);               \
> +        memcpy (s_->data, verify_ascii (str), nbytes + 1);   \
> +        s_->size = nbytes, s_->size_byte = -1;               \
> +        s_->intervals = NULL;                                \
> +        make_lisp_ptr (s_, Lisp_String); })                  \
> +     : (emacs_abort (), Qnil))
> +
> +/* If STR is a compile-time string constant, build function-scoped Lisp 
> string
> +   from it, fall back to regular Lisp string otherwise.  We assume 
> compile-time
> +   string constants never exceeds MAX_ALLOCA - sizeof (Lisp_String) - 1.  */
> +
> +# define build_local_string(str)                             \
> +    (__builtin_constant_p (str)                                      \
> +     ? make_local_string                                     \
> +         (str, lisp_string_size (strlen (str)), strlen (str))        \
> +     : build_string (str))
> +
> +#else /* not USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ */
> +
>  INLINE Lisp_Object
>  build_local_string (const char *str)
>  {
>    return build_string (str);
>  }
> -#endif
 
> +#endif /* not USE_STACK_LISP_OBJECTS && __GNUC__ && !__clang__ */
 
>  /* Loop over all tails of a list, checking for cycles.
>     FIXME: Make tortoise and n internal declarations.

> === modified file 'src/lread.c'
> --- a/src/lread.c     2014-09-25 02:01:14 +0000
> +++ b/src/lread.c     2014-09-29 06:44:31 +0000
> @@ -968,7 +968,6 @@
>  static void
>  load_warn_old_style_backquotes (Lisp_Object file)
>  {
> -  USE_LOCAL_ALLOCA;
>    if (!NILP (Vold_style_backquotes))
>      Fmessage (2, ((Lisp_Object [])
>        { build_local_string ("Loading `%s': old-style backquotes detected!"),
> @@ -3639,7 +3638,6 @@
>  static Lisp_Object
>  read_list (bool flag, Lisp_Object readcharfun)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object val, tail;
>    Lisp_Object elt, tem;
>    struct gcpro gcpro1, gcpro2;

> === modified file 'src/menu.c'
> --- a/src/menu.c      2014-09-25 02:01:14 +0000
> +++ b/src/menu.c      2014-09-29 06:44:31 +0000
> @@ -324,7 +324,6 @@
>  static void
>  single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void 
> *skp_v)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object map, item_string, enabled;
>    struct gcpro gcpro1, gcpro2;
>    bool res;

> === modified file 'src/minibuf.c'
> --- a/src/minibuf.c   2014-09-25 02:01:14 +0000
> +++ b/src/minibuf.c   2014-09-29 06:44:31 +0000
> @@ -1123,7 +1123,6 @@
>  function, instead of the usual behavior.  */)
>    (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object result;
>    char *s;
>    ptrdiff_t len;

> === modified file 'src/process.c'
> --- a/src/process.c   2014-09-25 02:01:14 +0000
> +++ b/src/process.c   2014-09-29 06:44:31 +0000
> @@ -592,7 +592,6 @@
>  static Lisp_Object
>  status_message (struct Lisp_Process *p)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object status = p->status;
>    Lisp_Object symbol;
>    int code;
> @@ -1291,8 +1290,6 @@
>  Returns nil if format of ADDRESS is invalid.  */)
>    (Lisp_Object address, Lisp_Object omit_port)
>  {
> -  USE_LOCAL_ALLOCA;
> -
>    if (NILP (address))
>      return Qnil;
 
> @@ -4006,7 +4003,6 @@
>  static void
>  server_accept_connection (Lisp_Object server, int channel)
>  {
> -  USE_LOCAL_ALLOCA;
>    Lisp_Object proc, caller, name, buffer;
>    Lisp_Object contact, host, service;
>    struct Lisp_Process *ps= XPROCESS (server);

> === modified file 'src/textprop.c'
> --- a/src/textprop.c  2014-09-25 02:01:14 +0000
> +++ b/src/textprop.c  2014-09-29 06:44:31 +0000
> @@ -1913,7 +1913,6 @@
>  copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src,
>                     Lisp_Object pos, Lisp_Object dest, Lisp_Object prop)
>  {
> -  USE_LOCAL_ALLOCA;
>    INTERVAL i;
>    Lisp_Object res;
>    Lisp_Object stuff;
> @@ -1967,9 +1966,8 @@
>        if (! NILP (plist))
>       /* Must defer modifications to the interval tree in case
>          src and dest refer to the same string or buffer.  */
> -     stuff = local_cons
> -       (local_list3 (make_number (p), make_number (p + len), plist),
> -        stuff);
> +     stuff = Fcons (list3 (make_number (p), make_number (p + len), plist),
> +                    stuff);
 
>        i = next_interval (i);
>        if (!i)

> === modified file 'src/xdisp.c'
> --- a/src/xdisp.c     2014-09-25 07:01:35 +0000
> +++ b/src/xdisp.c     2014-09-29 06:44:31 +0000
> @@ -20892,7 +20892,6 @@
>  See also `bidi-paragraph-direction'.  */)
>    (Lisp_Object buffer)
>  {
> -  USE_LOCAL_ALLOCA;
>    struct buffer *buf = current_buffer;
>    struct buffer *old = buf;
 

> === modified file 'src/xfns.c'
> --- a/src/xfns.c      2014-09-26 16:49:10 +0000
> +++ b/src/xfns.c      2014-09-29 06:44:31 +0000
> @@ -1559,9 +1559,6 @@
>                                     const char *xprop, const char *xclass,
>                                     int foreground_p)
>  {
> -#ifdef USE_TOOLKIT_SCROLL_BARS
> -  USE_LOCAL_ALLOCA;
> -#endif
>    struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
>    Lisp_Object tem;
 
> @@ -4273,7 +4270,6 @@
>  void
>  select_visual (struct x_display_info *dpyinfo)
>  {
> -  USE_LOCAL_ALLOCA;
>    Display *dpy = dpyinfo->display;
>    Screen *screen = dpyinfo->screen;
 

> === modified file 'src/xfont.c'
> --- a/src/xfont.c     2014-09-25 02:01:14 +0000
> +++ b/src/xfont.c     2014-09-29 06:44:31 +0000
> @@ -677,7 +677,6 @@
>  static Lisp_Object
>  xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
>  {
> -  USE_LOCAL_ALLOCA;
>    Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
>    Display *display = dpyinfo->display;
>    char name[512];
> @@ -776,7 +775,7 @@
>        if (dashes >= 13)
>       {
>         len = xfont_decode_coding_xlfd (p0, -1, name);
> -       fullname = Fdowncase (make_local_string (name, len));
> +       fullname = Fdowncase (make_string (name, len));
>       }
>        XFree (p0);
>      }

> === modified file 'src/xselect.c'
> --- a/src/xselect.c   2014-09-25 02:01:14 +0000
> +++ b/src/xselect.c   2014-09-29 06:44:31 +0000
> @@ -2159,7 +2159,6 @@
>  static Lisp_Object
>  x_clipboard_manager_error_1 (Lisp_Object err)
>  {
> -  USE_LOCAL_ALLOCA;
>    Fmessage (2, ((Lisp_Object [])
>      { build_local_string ("X clipboard manager error: %s\n\
>  If the problem persists, set `x-select-enable-clipboard-manager' to nil."),
> @@ -2213,7 +2212,6 @@
>  x_clipboard_manager_save_all (void)
>  {
>    /* Loop through all X displays, saving owned clipboards.  */
> -  USE_LOCAL_ALLOCA;
>    struct x_display_info *dpyinfo;
>    Lisp_Object local_selection, local_frame;
 

> === modified file 'src/xterm.c'
> --- a/src/xterm.c     2014-09-25 11:16:25 +0000
> +++ b/src/xterm.c     2014-09-29 06:44:31 +0000
> @@ -10666,7 +10666,6 @@
>  struct x_display_info *
>  x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
>  {
> -  USE_LOCAL_ALLOCA;
>    Display *dpy;
>    struct terminal *terminal;
>    struct x_display_info *dpyinfo;

> _______________________________________________
> Emacs-diffs mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/emacs-diffs




reply via email to

[Prev in Thread] Current Thread [Next in Thread]