diff options
| author | Tom Tromey | 2018-08-09 17:56:53 -0600 |
|---|---|---|
| committer | Tom Tromey | 2018-08-09 17:56:53 -0600 |
| commit | accb7b7ecc19f85c2750ded1046a464bc73c6a52 (patch) | |
| tree | 1aa94af022d6700a93a8ff2b73f5b210046ac010 /src/alloc.c | |
| parent | f822a2516d88eeb2118fbbc8554f155e86dfd74e (diff) | |
| parent | 53483df0de0085dbc9ef0b15a0f629ab808b0147 (diff) | |
| download | emacs-accb7b7ecc19f85c2750ded1046a464bc73c6a52.tar.gz emacs-accb7b7ecc19f85c2750ded1046a464bc73c6a52.zip | |
Merge remote-tracking branch 'origin/master' into feature/bignum
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/src/alloc.c b/src/alloc.c index a8bc55beb40..c3e02c20f85 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2932,7 +2932,7 @@ set_next_vector (struct Lisp_Vector *v, struct Lisp_Vector *p) | |||
| 2932 | for the most common cases; it's not required to be a power of two, but | 2932 | for the most common cases; it's not required to be a power of two, but |
| 2933 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ | 2933 | it's expected to be a mult-of-ROUNDUP_SIZE (see below). */ |
| 2934 | 2934 | ||
| 2935 | #define VECTOR_BLOCK_SIZE 4096 | 2935 | enum { VECTOR_BLOCK_SIZE = 4096 }; |
| 2936 | 2936 | ||
| 2937 | /* Vector size requests are a multiple of this. */ | 2937 | /* Vector size requests are a multiple of this. */ |
| 2938 | enum { roundup_size = COMMON_MULTIPLE (LISP_ALIGNMENT, word_size) }; | 2938 | enum { roundup_size = COMMON_MULTIPLE (LISP_ALIGNMENT, word_size) }; |
| @@ -2948,22 +2948,21 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | |||
| 2948 | 2948 | ||
| 2949 | /* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ | 2949 | /* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */ |
| 2950 | 2950 | ||
| 2951 | #define VECTOR_BLOCK_BYTES (VECTOR_BLOCK_SIZE - vroundup_ct (sizeof (void *))) | 2951 | enum {VECTOR_BLOCK_BYTES = VECTOR_BLOCK_SIZE - vroundup_ct (sizeof (void *))}; |
| 2952 | 2952 | ||
| 2953 | /* Size of the minimal vector allocated from block. */ | 2953 | /* Size of the minimal vector allocated from block. */ |
| 2954 | 2954 | ||
| 2955 | #define VBLOCK_BYTES_MIN vroundup_ct (header_size + sizeof (Lisp_Object)) | 2955 | enum { VBLOCK_BYTES_MIN = vroundup_ct (header_size + sizeof (Lisp_Object)) }; |
| 2956 | 2956 | ||
| 2957 | /* Size of the largest vector allocated from block. */ | 2957 | /* Size of the largest vector allocated from block. */ |
| 2958 | 2958 | ||
| 2959 | #define VBLOCK_BYTES_MAX \ | 2959 | enum { VBLOCK_BYTES_MAX = vroundup_ct ((VECTOR_BLOCK_BYTES / 2) - word_size) }; |
| 2960 | vroundup ((VECTOR_BLOCK_BYTES / 2) - word_size) | ||
| 2961 | 2960 | ||
| 2962 | /* We maintain one free list for each possible block-allocated | 2961 | /* We maintain one free list for each possible block-allocated |
| 2963 | vector size, and this is the number of free lists we have. */ | 2962 | vector size, and this is the number of free lists we have. */ |
| 2964 | 2963 | ||
| 2965 | #define VECTOR_MAX_FREE_LIST_INDEX \ | 2964 | enum { VECTOR_MAX_FREE_LIST_INDEX = |
| 2966 | ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1) | 2965 | (VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1 }; |
| 2967 | 2966 | ||
| 2968 | /* Common shortcut to advance vector pointer over a block data. */ | 2967 | /* Common shortcut to advance vector pointer over a block data. */ |
| 2969 | 2968 | ||
| @@ -3090,14 +3089,14 @@ init_vectors (void) | |||
| 3090 | /* Allocate vector from a vector block. */ | 3089 | /* Allocate vector from a vector block. */ |
| 3091 | 3090 | ||
| 3092 | static struct Lisp_Vector * | 3091 | static struct Lisp_Vector * |
| 3093 | allocate_vector_from_block (size_t nbytes) | 3092 | allocate_vector_from_block (ptrdiff_t nbytes) |
| 3094 | { | 3093 | { |
| 3095 | struct Lisp_Vector *vector; | 3094 | struct Lisp_Vector *vector; |
| 3096 | struct vector_block *block; | 3095 | struct vector_block *block; |
| 3097 | size_t index, restbytes; | 3096 | size_t index, restbytes; |
| 3098 | 3097 | ||
| 3099 | eassert (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX); | 3098 | eassume (VBLOCK_BYTES_MIN <= nbytes && nbytes <= VBLOCK_BYTES_MAX); |
| 3100 | eassert (nbytes % roundup_size == 0); | 3099 | eassume (nbytes % roundup_size == 0); |
| 3101 | 3100 | ||
| 3102 | /* First, try to allocate from a free list | 3101 | /* First, try to allocate from a free list |
| 3103 | containing vectors of the requested size. */ | 3102 | containing vectors of the requested size. */ |
| @@ -3182,35 +3181,45 @@ vector_nbytes (struct Lisp_Vector *v) | |||
| 3182 | return vroundup (header_size + word_size * nwords); | 3181 | return vroundup (header_size + word_size * nwords); |
| 3183 | } | 3182 | } |
| 3184 | 3183 | ||
| 3184 | /* Convert a pseudovector pointer P to its underlying struct T pointer. | ||
| 3185 | Verify that the struct is small, since cleanup_vector is called | ||
| 3186 | only on small vector-like objects. */ | ||
| 3187 | |||
| 3188 | #define PSEUDOVEC_STRUCT(p, t) \ | ||
| 3189 | verify_expr ((header_size + VECSIZE (struct t) * word_size \ | ||
| 3190 | <= VBLOCK_BYTES_MAX), \ | ||
| 3191 | (struct t *) (p)) | ||
| 3192 | |||
| 3185 | /* Release extra resources still in use by VECTOR, which may be any | 3193 | /* Release extra resources still in use by VECTOR, which may be any |
| 3186 | vector-like object. */ | 3194 | small vector-like object. */ |
| 3187 | 3195 | ||
| 3188 | static void | 3196 | static void |
| 3189 | cleanup_vector (struct Lisp_Vector *vector) | 3197 | cleanup_vector (struct Lisp_Vector *vector) |
| 3190 | { | 3198 | { |
| 3191 | detect_suspicious_free (vector); | 3199 | detect_suspicious_free (vector); |
| 3192 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) | 3200 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) |
| 3193 | && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) | ||
| 3194 | == FONT_OBJECT_MAX)) | ||
| 3195 | { | 3201 | { |
| 3196 | struct font_driver const *drv = ((struct font *) vector)->driver; | 3202 | if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) |
| 3197 | |||
| 3198 | /* The font driver might sometimes be NULL, e.g. if Emacs was | ||
| 3199 | interrupted before it had time to set it up. */ | ||
| 3200 | if (drv) | ||
| 3201 | { | 3203 | { |
| 3202 | /* Attempt to catch subtle bugs like Bug#16140. */ | 3204 | struct font *font = PSEUDOVEC_STRUCT (vector, font); |
| 3203 | eassert (valid_font_driver (drv)); | 3205 | struct font_driver const *drv = font->driver; |
| 3204 | drv->close ((struct font *) vector); | 3206 | |
| 3207 | /* The font driver might sometimes be NULL, e.g. if Emacs was | ||
| 3208 | interrupted before it had time to set it up. */ | ||
| 3209 | if (drv) | ||
| 3210 | { | ||
| 3211 | /* Attempt to catch subtle bugs like Bug#16140. */ | ||
| 3212 | eassert (valid_font_driver (drv)); | ||
| 3213 | drv->close (font); | ||
| 3214 | } | ||
| 3205 | } | 3215 | } |
| 3206 | } | 3216 | } |
| 3207 | 3217 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD)) | |
| 3208 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_THREAD)) | 3218 | finalize_one_thread (PSEUDOVEC_STRUCT (vector, thread_state)); |
| 3209 | finalize_one_thread ((struct thread_state *) vector); | ||
| 3210 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MUTEX)) | 3219 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MUTEX)) |
| 3211 | finalize_one_mutex ((struct Lisp_Mutex *) vector); | 3220 | finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); |
| 3212 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) | 3221 | else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) |
| 3213 | finalize_one_condvar ((struct Lisp_CondVar *) vector); | 3222 | finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); |
| 3214 | } | 3223 | } |
| 3215 | 3224 | ||
| 3216 | /* Reclaim space used by unmarked vectors. */ | 3225 | /* Reclaim space used by unmarked vectors. */ |
| @@ -6719,7 +6728,7 @@ mark_object (Lisp_Object arg) | |||
| 6719 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 6728 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 6720 | CONS_MARK (ptr); | 6729 | CONS_MARK (ptr); |
| 6721 | /* If the cdr is nil, avoid recursion for the car. */ | 6730 | /* If the cdr is nil, avoid recursion for the car. */ |
| 6722 | if (EQ (ptr->u.s.u.cdr, Qnil)) | 6731 | if (NILP (ptr->u.s.u.cdr)) |
| 6723 | { | 6732 | { |
| 6724 | obj = ptr->u.s.car; | 6733 | obj = ptr->u.s.car; |
| 6725 | cdr_count = 0; | 6734 | cdr_count = 0; |