diff options
| author | Gerd Möllmann | 2024-08-05 06:32:17 +0200 |
|---|---|---|
| committer | Gerd Möllmann | 2024-08-05 06:32:17 +0200 |
| commit | 6a137e0c1dd8670d95134bab4ef8d6103c2c9602 (patch) | |
| tree | c9b5440ca8dfa8a0fb9389b487655af6672bfd7f /src/alloc.c | |
| parent | 05c19f8e5439606f841689ef325a867951e04902 (diff) | |
| parent | 5ecd35555e9e20de9717f0184f58a15d8a2e68a3 (diff) | |
| download | emacs-6a137e0c1dd8670d95134bab4ef8d6103c2c9602.tar.gz emacs-6a137e0c1dd8670d95134bab4ef8d6103c2c9602.zip | |
Merge branch 'master' into scratch/igc
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 111 |
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 | ||
| 465 | static struct Lisp_Vector *allocate_clear_vector (ptrdiff_t, bool); | ||
| 465 | #ifndef HAVE_MPS | 466 | #ifndef HAVE_MPS |
| 466 | static void mark_terminals (void); | 467 | static void mark_terminals (void); |
| 467 | static void gc_sweep (void); | 468 | static void gc_sweep (void); |
| 468 | static void mark_buffer (struct buffer *); | 469 | static 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 |
| 1016 | extern void *lisp_malloc_loser; | ||
| 1015 | void *lisp_malloc_loser EXTERNALLY_VISIBLE; | 1017 | void *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 | ||
| 2476 | Lisp_Object | 2479 | Lisp_Object |
| 2477 | make_uninit_bool_vector (EMACS_INT nbits) | 2480 | make_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; | 2505 | Lisp_Object |
| 2506 | make_uninit_bool_vector (EMACS_INT nbits) | ||
| 2507 | { | ||
| 2508 | return make_clear_bool_vector (nbits, false); | ||
| 2498 | } | 2509 | } |
| 2499 | 2510 | ||
| 2500 | DEFUN ("make-bool-vector", Fmake_bool_vector, Smake_bool_vector, 2, 2, 0, | 2511 | DEFUN ("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, | |||
| 2502 | LENGTH must be a number. INIT matters only in whether it is t or nil. */) | 2513 | LENGTH 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 | ||
| 2512 | DEFUN ("bool-vector", Fbool_vector, Sbool_vector, 0, MANY, 0, | 2524 | DEFUN ("bool-vector", Fbool_vector, Sbool_vector, 0, MANY, 0, |
| @@ -2515,13 +2527,12 @@ Allows any number of arguments, including zero. | |||
| 2515 | usage: (bool-vector &rest OBJECTS) */) | 2527 | usage: (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 | |||
| 7297 | static Lisp_Object | ||
| 7298 | mark_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 | |||
| 7329 | static void | 7305 | static void |
| 7330 | mark_frame (struct Lisp_Vector *ptr) | 7306 | mark_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. */ |