aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorGerd Möllmann2024-08-05 06:32:17 +0200
committerGerd Möllmann2024-08-05 06:32:17 +0200
commit6a137e0c1dd8670d95134bab4ef8d6103c2c9602 (patch)
treec9b5440ca8dfa8a0fb9389b487655af6672bfd7f /src/alloc.c
parent05c19f8e5439606f841689ef325a867951e04902 (diff)
parent5ecd35555e9e20de9717f0184f58a15d8a2e68a3 (diff)
downloademacs-6a137e0c1dd8670d95134bab4ef8d6103c2c9602.tar.gz
emacs-6a137e0c1dd8670d95134bab4ef8d6103c2c9602.zip
Merge branch 'master' into scratch/igc
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c111
1 files changed, 39 insertions, 72 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 320a5adaf0b..d9423a1b444 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -462,8 +462,9 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size)
462 462
463#endif /* MAX_SAVE_STACK > 0 */ 463#endif /* MAX_SAVE_STACK > 0 */
464 464
465static struct Lisp_Vector *allocate_clear_vector (ptrdiff_t, bool);
465#ifndef HAVE_MPS 466#ifndef HAVE_MPS
466 static void mark_terminals (void); 467static void mark_terminals (void);
467static void gc_sweep (void); 468static void gc_sweep (void);
468static void mark_buffer (struct buffer *); 469static void mark_buffer (struct buffer *);
469 470
@@ -1012,6 +1013,7 @@ record_xmalloc (size_t size)
1012 allocated memory block (for strings, for conses, ...). */ 1013 allocated memory block (for strings, for conses, ...). */
1013 1014
1014#if ! USE_LSB_TAG 1015#if ! USE_LSB_TAG
1016extern void *lisp_malloc_loser;
1015void *lisp_malloc_loser EXTERNALLY_VISIBLE; 1017void *lisp_malloc_loser EXTERNALLY_VISIBLE;
1016#endif 1018#endif
1017 1019
@@ -1423,8 +1425,8 @@ lmalloc (size_t size, bool clearit)
1423 if (laligned (p, size) && (MALLOC_0_IS_NONNULL || size || p)) 1425 if (laligned (p, size) && (MALLOC_0_IS_NONNULL || size || p))
1424 return p; 1426 return p;
1425 free (p); 1427 free (p);
1426 size_t bigger = size + LISP_ALIGNMENT; 1428 size_t bigger;
1427 if (size < bigger) 1429 if (!ckd_add (&bigger, size, LISP_ALIGNMENT))
1428 size = bigger; 1430 size = bigger;
1429 } 1431 }
1430} 1432}
@@ -1437,8 +1439,8 @@ lrealloc (void *p, size_t size)
1437 p = realloc (p, size); 1439 p = realloc (p, size);
1438 if (laligned (p, size) && (size || p)) 1440 if (laligned (p, size) && (size || p))
1439 return p; 1441 return p;
1440 size_t bigger = size + LISP_ALIGNMENT; 1442 size_t bigger;
1441 if (size < bigger) 1443 if (!ckd_add (&bigger, size, LISP_ALIGNMENT))
1442 size = bigger; 1444 size = bigger;
1443 } 1445 }
1444} 1446}
@@ -2471,30 +2473,39 @@ bool_vector_fill (Lisp_Object a, Lisp_Object init)
2471 return a; 2473 return a;
2472} 2474}
2473 2475
2474/* Return a newly allocated, uninitialized bool vector of size NBITS. */ 2476/* Return a newly allocated, bool vector of size NBITS. If CLEARIT,
2477 clear its slots; otherwise the vector's slots are uninitialized. */
2475 2478
2476Lisp_Object 2479Lisp_Object
2477make_uninit_bool_vector (EMACS_INT nbits) 2480make_clear_bool_vector (EMACS_INT nbits, bool clearit)
2478{ 2481{
2482 eassert (0 <= nbits && nbits <= BOOL_VECTOR_LENGTH_MAX);
2479 Lisp_Object val; 2483 Lisp_Object val;
2480 EMACS_INT words = bool_vector_words (nbits); 2484 ptrdiff_t words = bool_vector_words (nbits);
2481 EMACS_INT word_bytes = words * sizeof (bits_word); 2485 ptrdiff_t word_bytes = words * sizeof (bits_word);
2482 EMACS_INT needed_elements = ((bool_header_size - header_size + word_bytes 2486 ptrdiff_t needed_elements = ((bool_header_size - header_size + word_bytes
2483 + word_size - 1) 2487 + word_size - 1)
2484 / word_size); 2488 / word_size);
2485 if (PTRDIFF_MAX < needed_elements)
2486 memory_full (SIZE_MAX);
2487 struct Lisp_Bool_Vector *p 2489 struct Lisp_Bool_Vector *p
2488 = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements); 2490 = (struct Lisp_Bool_Vector *) allocate_clear_vector (needed_elements,
2491 clearit);
2492 /* Clear padding at end; but only if necessary, to avoid polluting the
2493 data cache. */
2494 if (!clearit && nbits % BITS_PER_BITS_WORD != 0)
2495 p->data[words - 1] = 0;
2496
2489 XSETVECTOR (val, p); 2497 XSETVECTOR (val, p);
2490 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0); 2498 XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
2491 p->size = nbits; 2499 p->size = nbits;
2500 return val;
2501}
2492 2502
2493 /* Clear padding at the end. */ 2503/* Return a newly allocated, uninitialized bool vector of size NBITS. */
2494 if (words)
2495 p->data[words - 1] = 0;
2496 2504
2497 return val; 2505Lisp_Object
2506make_uninit_bool_vector (EMACS_INT nbits)
2507{
2508 return make_clear_bool_vector (nbits, false);
2498} 2509}
2499 2510
2500DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, 2511DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0,
@@ -2502,11 +2513,12 @@ DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0,
2502LENGTH must be a number. INIT matters only in whether it is t or nil. */) 2513LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2503 (Lisp_Object length, Lisp_Object init) 2514 (Lisp_Object length, Lisp_Object init)
2504{ 2515{
2505 Lisp_Object val;
2506
2507 CHECK_FIXNAT (length); 2516 CHECK_FIXNAT (length);
2508 val = make_uninit_bool_vector (XFIXNAT (length)); 2517 EMACS_INT len = XFIXNAT (length);
2509 return bool_vector_fill (val, init); 2518 if (BOOL_VECTOR_LENGTH_MAX < len)
2519 memory_full (SIZE_MAX);
2520 Lisp_Object val = make_clear_bool_vector (len, NILP (init));
2521 return NILP (init) ? val : bool_vector_fill (val, init);
2510} 2522}
2511 2523
2512DEFUN ("bool-vector", Fbool_vector, Sbool_vector, 0, MANY, 0, 2524DEFUN ("bool-vector", Fbool_vector, Sbool_vector, 0, MANY, 0,
@@ -2515,13 +2527,12 @@ Allows any number of arguments, including zero.
2515usage: (bool-vector &rest OBJECTS) */) 2527usage: (bool-vector &rest OBJECTS) */)
2516 (ptrdiff_t nargs, Lisp_Object *args) 2528 (ptrdiff_t nargs, Lisp_Object *args)
2517{ 2529{
2518 ptrdiff_t i; 2530 if (BOOL_VECTOR_LENGTH_MAX < nargs)
2519 Lisp_Object vector; 2531 memory_full (SIZE_MAX);
2520 2532 Lisp_Object vector = make_clear_bool_vector (nargs, true);
2521 vector = make_uninit_bool_vector (nargs); 2533 for (ptrdiff_t i = 0; i < nargs; i++)
2522 for (i = 0; i < nargs; i++) 2534 if (!NILP (args[i]))
2523 bool_vector_set (vector, i, !NILP (args[i])); 2535 bool_vector_set (vector, i, true);
2524
2525 return vector; 2536 return vector;
2526} 2537}
2527 2538
@@ -7291,41 +7302,6 @@ mark_face_cache (struct face_cache *c)
7291 } 7302 }
7292} 7303}
7293 7304
7294/* Remove killed buffers or items whose car is a killed buffer from
7295 LIST, and mark other items. Return changed LIST, which is marked. */
7296
7297static Lisp_Object
7298mark_discard_killed_buffers (Lisp_Object list)
7299{
7300 Lisp_Object tail, *prev = &list;
7301
7302#ifndef HAVE_MPS
7303#define CONS_MARKED_P(x) cons_marked_p (x)
7304#define SET_CONS_MARKED(x) set_cons_marked (x)
7305#else
7306#define CONS_MARKED_P(x) 1
7307#define SET_CONS_MARKED(x) (void) 0
7308#endif
7309
7310 for (tail = list; CONSP (tail) && !CONS_MARKED_P (XCONS (tail));
7311 tail = XCDR (tail))
7312 {
7313 Lisp_Object tem = XCAR (tail);
7314 if (CONSP (tem))
7315 tem = XCAR (tem);
7316 if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem)))
7317 *prev = XCDR (tail);
7318 else
7319 {
7320 SET_CONS_MARKED (XCONS (tail));
7321 mark_object (XCAR (tail));
7322 prev = xcdr_addr (tail);
7323 }
7324 }
7325 mark_object (tail);
7326 return list;
7327}
7328
7329static void 7305static void
7330mark_frame (struct Lisp_Vector *ptr) 7306mark_frame (struct Lisp_Vector *ptr)
7331{ 7307{
@@ -7380,15 +7356,6 @@ mark_window (struct Lisp_Vector *ptr)
7380 mark_glyph_matrix (w->current_matrix); 7356 mark_glyph_matrix (w->current_matrix);
7381 mark_glyph_matrix (w->desired_matrix); 7357 mark_glyph_matrix (w->desired_matrix);
7382 } 7358 }
7383
7384 /* Filter out killed buffers from both buffer lists
7385 in attempt to help GC to reclaim killed buffers faster.
7386 We can do it elsewhere for live windows, but this is the
7387 best place to do it for dead windows. */
7388 wset_prev_buffers
7389 (w, mark_discard_killed_buffers (w->prev_buffers));
7390 wset_next_buffers
7391 (w, mark_discard_killed_buffers (w->next_buffers));
7392} 7359}
7393 7360
7394/* Entry of the mark stack. */ 7361/* Entry of the mark stack. */