From b7ffe0402bda8231943066a1ce34e60b3dfdb6e7 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 17 Jul 2012 16:31:29 +0400 Subject: [PATCH] Restore old code in allocate_string_data to avoid Faset breakage. Reported by Julien Danjou in http://lists.gnu.org/archive/html/emacs-devel/2012-07/msg00371.html. * alloc.c (allocate_string_data): Restore old code with minor adjustments, fix comment to explain this subtle issue. --- src/ChangeLog | 8 ++++++++ src/alloc.c | 21 +++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index b78f261b496..7487e0723a5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2012-07-17 Dmitry Antipov + + Restore old code in allocate_string_data to avoid Faset breakage. + Reported by Julien Danjou in + http://lists.gnu.org/archive/html/emacs-devel/2012-07/msg00371.html. + * alloc.c (allocate_string_data): Restore old code with minor + adjustments, fix comment to explain this subtle issue. + 2012-07-17 Eli Zaretskii Remove FILE_SYSTEM_CASE. diff --git a/src/alloc.c b/src/alloc.c index 67ff3459e71..f8456e3645f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1971,9 +1971,9 @@ void allocate_string_data (struct Lisp_String *s, EMACS_INT nchars, EMACS_INT nbytes) { - struct sdata *data; + struct sdata *data, *old_data; struct sblock *b; - ptrdiff_t needed; + ptrdiff_t needed, old_nbytes; if (STRING_BYTES_MAX < nbytes) string_overflow (); @@ -1981,6 +1981,13 @@ allocate_string_data (struct Lisp_String *s, /* Determine the number of bytes needed to store NBYTES bytes of string data. */ needed = SDATA_SIZE (nbytes); + if (s->data) + { + old_data = SDATA_OF_STRING (s); + old_nbytes = GC_STRING_BYTES (s); + } + else + old_data = NULL; MALLOC_BLOCK_INPUT; @@ -2050,6 +2057,16 @@ allocate_string_data (struct Lisp_String *s, memcpy ((char *) data + needed, string_overrun_cookie, GC_STRING_OVERRUN_COOKIE_SIZE); #endif + + /* Note that Faset may call to this function when S has already data + assigned. In this case, mark data as free by setting it's string + back-pointer to null, and record the size of the data in it. */ + if (old_data) + { + SDATA_NBYTES (old_data) = old_nbytes; + old_data->string = NULL; + } + consing_since_gc += needed; } -- 2.39.2