diff options
| author | Mattias Engdegård | 2023-09-25 17:19:00 +0200 |
|---|---|---|
| committer | Mattias Engdegård | 2023-09-25 17:33:21 +0200 |
| commit | 091b8de586efc41c3dbd8606445c99c541e90076 (patch) | |
| tree | 492d61f5c27b628eff5df7c332da384dcff4c41b /src/alloc.c | |
| parent | aa28527500210e542349cca3cd805a61a01c9dac (diff) | |
| download | emacs-091b8de586efc41c3dbd8606445c99c541e90076.tar.gz emacs-091b8de586efc41c3dbd8606445c99c541e90076.zip | |
Use heuristic to speed up allocation of small vectors (bug#65491)
Instead of scanning vector_free_lists from the appropriate size until
we find a nonempty bucket, start at the last bucket where we last put
something in. This may favour splitting larger vectors than necessary
but in general saves a lot of time in the allocation of small vectors.
Original patch by Ihor Radchenko.
* src/alloc.c (last_inserted_vector_free_idx): New variable.
(setup_on_free_list): Set it.
(allocate_vector_from_block): Use it.
(sweep_vectors): Reset it.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/alloc.c b/src/alloc.c index b2d3f734d4f..45a950c4f81 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3155,6 +3155,11 @@ static struct vector_block *vector_blocks; | |||
| 3155 | - For I = VECTOR_FREE_LIST_ARRAY_SIZE-1, VINDEX(BS(V)) ≥ I */ | 3155 | - For I = VECTOR_FREE_LIST_ARRAY_SIZE-1, VINDEX(BS(V)) ≥ I */ |
| 3156 | static struct Lisp_Vector *vector_free_lists[VECTOR_FREE_LIST_ARRAY_SIZE]; | 3156 | static struct Lisp_Vector *vector_free_lists[VECTOR_FREE_LIST_ARRAY_SIZE]; |
| 3157 | 3157 | ||
| 3158 | /* Index to the bucket in vector_free_lists into which we last inserted | ||
| 3159 | or split a free vector. We use this as a heuristic telling us where | ||
| 3160 | to start looking for free vectors when the exact-size bucket is empty. */ | ||
| 3161 | static ptrdiff_t last_inserted_vector_free_idx = VECTOR_FREE_LIST_ARRAY_SIZE; | ||
| 3162 | |||
| 3158 | /* Singly-linked list of large vectors. */ | 3163 | /* Singly-linked list of large vectors. */ |
| 3159 | 3164 | ||
| 3160 | static struct large_vector *large_vectors; | 3165 | static struct large_vector *large_vectors; |
| @@ -3191,6 +3196,7 @@ setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes) | |||
| 3191 | set_next_vector (v, vector_free_lists[vindex]); | 3196 | set_next_vector (v, vector_free_lists[vindex]); |
| 3192 | ASAN_POISON_VECTOR_CONTENTS (v, nbytes - header_size); | 3197 | ASAN_POISON_VECTOR_CONTENTS (v, nbytes - header_size); |
| 3193 | vector_free_lists[vindex] = v; | 3198 | vector_free_lists[vindex] = v; |
| 3199 | last_inserted_vector_free_idx = vindex; | ||
| 3194 | } | 3200 | } |
| 3195 | 3201 | ||
| 3196 | /* Get a new vector block. */ | 3202 | /* Get a new vector block. */ |
| @@ -3256,7 +3262,8 @@ allocate_vector_from_block (ptrdiff_t nbytes) | |||
| 3256 | /* Next, check free lists containing larger vectors. Since | 3262 | /* Next, check free lists containing larger vectors. Since |
| 3257 | we will split the result, we should have remaining space | 3263 | we will split the result, we should have remaining space |
| 3258 | large enough to use for one-slot vector at least. */ | 3264 | large enough to use for one-slot vector at least. */ |
| 3259 | for (index = VINDEX (nbytes + VBLOCK_BYTES_MIN); | 3265 | for (index = max (VINDEX (nbytes + VBLOCK_BYTES_MIN), |
| 3266 | last_inserted_vector_free_idx); | ||
| 3260 | index < VECTOR_FREE_LIST_ARRAY_SIZE; index++) | 3267 | index < VECTOR_FREE_LIST_ARRAY_SIZE; index++) |
| 3261 | if (vector_free_lists[index]) | 3268 | if (vector_free_lists[index]) |
| 3262 | { | 3269 | { |
| @@ -3489,6 +3496,7 @@ sweep_vectors (void) | |||
| 3489 | gcstat.total_vectors = 0; | 3496 | gcstat.total_vectors = 0; |
| 3490 | gcstat.total_vector_slots = gcstat.total_free_vector_slots = 0; | 3497 | gcstat.total_vector_slots = gcstat.total_free_vector_slots = 0; |
| 3491 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); | 3498 | memset (vector_free_lists, 0, sizeof (vector_free_lists)); |
| 3499 | last_inserted_vector_free_idx = VECTOR_FREE_LIST_ARRAY_SIZE; | ||
| 3492 | 3500 | ||
| 3493 | /* Looking through vector blocks. */ | 3501 | /* Looking through vector blocks. */ |
| 3494 | 3502 | ||