aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c87
1 files changed, 58 insertions, 29 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 29ccb38e7b7..d6d456a8fc0 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1782,11 +1782,13 @@ allocate_string (void)
1782 plus a NUL byte at the end. Allocate an sdata structure DATA for 1782 plus a NUL byte at the end. Allocate an sdata structure DATA for
1783 S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the 1783 S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the
1784 end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte 1784 end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte
1785 to NBYTES. Free S->u.s.data if it was initially non-null. */ 1785 to NBYTES. Free S->u.s.data if it was initially non-null.
1786
1787 If CLEARIT, also clear the other bytes of S->u.s.data. */
1786 1788
1787void 1789void
1788allocate_string_data (struct Lisp_String *s, 1790allocate_string_data (struct Lisp_String *s,
1789 EMACS_INT nchars, EMACS_INT nbytes) 1791 EMACS_INT nchars, EMACS_INT nbytes, bool clearit)
1790{ 1792{
1791 sdata *data, *old_data; 1793 sdata *data, *old_data;
1792 struct sblock *b; 1794 struct sblock *b;
@@ -1817,7 +1819,7 @@ allocate_string_data (struct Lisp_String *s,
1817 mallopt (M_MMAP_MAX, 0); 1819 mallopt (M_MMAP_MAX, 0);
1818#endif 1820#endif
1819 1821
1820 b = lisp_malloc (size + GC_STRING_EXTRA, false, MEM_TYPE_NON_LISP); 1822 b = lisp_malloc (size + GC_STRING_EXTRA, clearit, MEM_TYPE_NON_LISP);
1821 1823
1822#ifdef DOUG_LEA_MALLOC 1824#ifdef DOUG_LEA_MALLOC
1823 if (!mmap_lisp_allowed_p ()) 1825 if (!mmap_lisp_allowed_p ())
@@ -1850,6 +1852,8 @@ allocate_string_data (struct Lisp_String *s,
1850 { 1852 {
1851 b = current_sblock; 1853 b = current_sblock;
1852 data = b->next_free; 1854 data = b->next_free;
1855 if (clearit)
1856 memset (SDATA_DATA (data), 0, nbytes);
1853 } 1857 }
1854 1858
1855 data->string = s; 1859 data->string = s;
@@ -2114,6 +2118,9 @@ string_overflow (void)
2114 error ("Maximum string size exceeded"); 2118 error ("Maximum string size exceeded");
2115} 2119}
2116 2120
2121static Lisp_Object make_clear_string (EMACS_INT, bool);
2122static Lisp_Object make_clear_multibyte_string (EMACS_INT, EMACS_INT, bool);
2123
2117DEFUN ("make-string", Fmake_string, Smake_string, 2, 3, 0, 2124DEFUN ("make-string", Fmake_string, Smake_string, 2, 3, 0,
2118 doc: /* Return a newly created string of length LENGTH, with INIT in each element. 2125 doc: /* Return a newly created string of length LENGTH, with INIT in each element.
2119LENGTH must be an integer. 2126LENGTH must be an integer.
@@ -2122,19 +2129,20 @@ If optional argument MULTIBYTE is non-nil, the result will be
2122a multibyte string even if INIT is an ASCII character. */) 2129a multibyte string even if INIT is an ASCII character. */)
2123 (Lisp_Object length, Lisp_Object init, Lisp_Object multibyte) 2130 (Lisp_Object length, Lisp_Object init, Lisp_Object multibyte)
2124{ 2131{
2125 register Lisp_Object val; 2132 Lisp_Object val;
2126 int c;
2127 EMACS_INT nbytes; 2133 EMACS_INT nbytes;
2128 2134
2129 CHECK_FIXNAT (length); 2135 CHECK_FIXNAT (length);
2130 CHECK_CHARACTER (init); 2136 CHECK_CHARACTER (init);
2131 2137
2132 c = XFIXNAT (init); 2138 int c = XFIXNAT (init);
2139 bool clearit = !c;
2140
2133 if (ASCII_CHAR_P (c) && NILP (multibyte)) 2141 if (ASCII_CHAR_P (c) && NILP (multibyte))
2134 { 2142 {
2135 nbytes = XFIXNUM (length); 2143 nbytes = XFIXNUM (length);
2136 val = make_uninit_string (nbytes); 2144 val = make_clear_string (nbytes, clearit);
2137 if (nbytes) 2145 if (nbytes && !clearit)
2138 { 2146 {
2139 memset (SDATA (val), c, nbytes); 2147 memset (SDATA (val), c, nbytes);
2140 SDATA (val)[nbytes] = 0; 2148 SDATA (val)[nbytes] = 0;
@@ -2145,26 +2153,27 @@ a multibyte string even if INIT is an ASCII character. */)
2145 unsigned char str[MAX_MULTIBYTE_LENGTH]; 2153 unsigned char str[MAX_MULTIBYTE_LENGTH];
2146 ptrdiff_t len = CHAR_STRING (c, str); 2154 ptrdiff_t len = CHAR_STRING (c, str);
2147 EMACS_INT string_len = XFIXNUM (length); 2155 EMACS_INT string_len = XFIXNUM (length);
2148 unsigned char *p, *beg, *end;
2149 2156
2150 if (INT_MULTIPLY_WRAPV (len, string_len, &nbytes)) 2157 if (INT_MULTIPLY_WRAPV (len, string_len, &nbytes))
2151 string_overflow (); 2158 string_overflow ();
2152 val = make_uninit_multibyte_string (string_len, nbytes); 2159 val = make_clear_multibyte_string (string_len, nbytes, clearit);
2153 for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len) 2160 if (!clearit)
2154 { 2161 {
2155 /* First time we just copy `str' to the data of `val'. */ 2162 unsigned char *beg = SDATA (val), *end = beg + nbytes;
2156 if (p == beg) 2163 for (unsigned char *p = beg; p < end; p += len)
2157 memcpy (p, str, len);
2158 else
2159 { 2164 {
2160 /* Next time we copy largest possible chunk from 2165 /* First time we just copy STR to the data of VAL. */
2161 initialized to uninitialized part of `val'. */ 2166 if (p == beg)
2162 len = min (p - beg, end - p); 2167 memcpy (p, str, len);
2163 memcpy (p, beg, len); 2168 else
2169 {
2170 /* Next time we copy largest possible chunk from
2171 initialized to uninitialized part of VAL. */
2172 len = min (p - beg, end - p);
2173 memcpy (p, beg, len);
2174 }
2164 } 2175 }
2165 } 2176 }
2166 if (nbytes)
2167 *p = 0;
2168 } 2177 }
2169 2178
2170 return val; 2179 return val;
@@ -2334,26 +2343,37 @@ make_specified_string (const char *contents,
2334 2343
2335 2344
2336/* Return a unibyte Lisp_String set up to hold LENGTH characters 2345/* Return a unibyte Lisp_String set up to hold LENGTH characters
2337 occupying LENGTH bytes. */ 2346 occupying LENGTH bytes. If CLEARIT, clear its contents to null
2347 bytes; otherwise, the contents are uninitialized. */
2338 2348
2339Lisp_Object 2349static Lisp_Object
2340make_uninit_string (EMACS_INT length) 2350make_clear_string (EMACS_INT length, bool clearit)
2341{ 2351{
2342 Lisp_Object val; 2352 Lisp_Object val;
2343 2353
2344 if (!length) 2354 if (!length)
2345 return empty_unibyte_string; 2355 return empty_unibyte_string;
2346 val = make_uninit_multibyte_string (length, length); 2356 val = make_clear_multibyte_string (length, length, clearit);
2347 STRING_SET_UNIBYTE (val); 2357 STRING_SET_UNIBYTE (val);
2348 return val; 2358 return val;
2349} 2359}
2350 2360
2361/* Return a unibyte Lisp_String set up to hold LENGTH characters
2362 occupying LENGTH bytes. */
2363
2364Lisp_Object
2365make_uninit_string (EMACS_INT length)
2366{
2367 return make_clear_string (length, false);
2368}
2369
2351 2370
2352/* Return a multibyte Lisp_String set up to hold NCHARS characters 2371/* Return a multibyte Lisp_String set up to hold NCHARS characters
2353 which occupy NBYTES bytes. */ 2372 which occupy NBYTES bytes. If CLEARIT, clear its contents to null
2373 bytes; otherwise, the contents are uninitialized. */
2354 2374
2355Lisp_Object 2375static Lisp_Object
2356make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) 2376make_clear_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes, bool clearit)
2357{ 2377{
2358 Lisp_Object string; 2378 Lisp_Object string;
2359 struct Lisp_String *s; 2379 struct Lisp_String *s;
@@ -2365,12 +2385,21 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
2365 2385
2366 s = allocate_string (); 2386 s = allocate_string ();
2367 s->u.s.intervals = NULL; 2387 s->u.s.intervals = NULL;
2368 allocate_string_data (s, nchars, nbytes); 2388 allocate_string_data (s, nchars, nbytes, clearit);
2369 XSETSTRING (string, s); 2389 XSETSTRING (string, s);
2370 string_chars_consed += nbytes; 2390 string_chars_consed += nbytes;
2371 return string; 2391 return string;
2372} 2392}
2373 2393
2394/* Return a multibyte Lisp_String set up to hold NCHARS characters
2395 which occupy NBYTES bytes. */
2396
2397Lisp_Object
2398make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
2399{
2400 return make_clear_multibyte_string (nchars, nbytes, false);
2401}
2402
2374/* Print arguments to BUF according to a FORMAT, then return 2403/* Print arguments to BUF according to a FORMAT, then return
2375 a Lisp_String initialized with the data from BUF. */ 2404 a Lisp_String initialized with the data from BUF. */
2376 2405