diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 184 |
1 files changed, 96 insertions, 88 deletions
diff --git a/src/alloc.c b/src/alloc.c index b1e2ed0a2ed..bd68f2b31f2 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1529,7 +1529,7 @@ make_interval (void) } -/* Mark Lisp objects in interval I. */ +/* Mark Lisp objects in interval I. */ static void mark_interval (register INTERVAL i, Lisp_Object dummy) @@ -1836,7 +1836,7 @@ check_sblock (struct sblock *b) ptrdiff_t nbytes; /* Check that the string size recorded in the string is the - same as the one recorded in the sdata structure. */ + same as the one recorded in the sdata structure. */ if (from->string) CHECK_STRING_BYTES (from->string); @@ -2869,12 +2869,6 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, #define VECTOR_BLOCK_SIZE 4096 -/* This special value is used to calculate vector size when the vector is - on a free list. It should be VECTOR_BLOCK_SIZE rounded up to nearest - power of two, minus one. */ - -#define VECTOR_FREE_LIST_SIZE_MASK 4095 - /* Handy constants for vectorlike objects. */ enum { @@ -2889,8 +2883,7 @@ verify ((roundup_size & (roundup_size - 1)) == 0); /* Verify assumptions described above. */ verify ((VECTOR_BLOCK_SIZE % roundup_size) == 0); -verify ((VECTOR_FREE_LIST_SIZE_MASK + 1) >= VECTOR_BLOCK_SIZE); -verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0); +verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); /* Round up X to nearest mult-of-ROUNDUP_SIZE. */ @@ -2915,12 +2908,6 @@ verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0); #define VECTOR_MAX_FREE_LIST_INDEX \ ((VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) / roundup_size + 1) -/* When the vector is on a free list, vectorlike_header.SIZE is set to - this special value ORed with vector's memory footprint size. */ - -#define VECTOR_FREE_LIST_FLAG (~(ARRAY_MARK_FLAG | PSEUDOVECTOR_FLAG \ - | VECTOR_FREE_LIST_SIZE_MASK)) - /* Common shortcut to advance vector pointer over a block data. */ #define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes))) @@ -2933,7 +2920,7 @@ verify ((VECTOR_FREE_LIST_SIZE_MASK & (VECTOR_FREE_LIST_SIZE_MASK + 1)) == 0); #define SETUP_ON_FREE_LIST(v, nbytes, index) \ do { \ - (v)->header.size = VECTOR_FREE_LIST_FLAG | (nbytes); \ + XSETPVECTYPESIZE (v, PVEC_FREE, nbytes); \ eassert ((nbytes) % roundup_size == 0); \ (index) = VINDEX (nbytes); \ eassert ((index) < VECTOR_MAX_FREE_LIST_INDEX); \ @@ -3065,6 +3052,16 @@ allocate_vector_from_block (size_t nbytes) ((char *) (vector) <= (block)->data \ + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) +/* Number of bytes used by vector-block-allocated object. This is the only + place where we actually use the `nbytes' field of the vector-header. + I.e. we could get rid of the `nbytes' field by computing it based on the + vector-type. */ + +#define PSEUDOVECTOR_NBYTES(vector) \ + (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ + ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ + : vector->header.next.nbytes); + /* Reclaim space used by unmarked vectors. */ static void @@ -3093,14 +3090,10 @@ sweep_vectors (void) } else { - ptrdiff_t nbytes; + ptrdiff_t nbytes = PSEUDOVECTOR_NBYTES (vector); + ptrdiff_t total_bytes = nbytes; - if ((vector->header.size & VECTOR_FREE_LIST_FLAG) - == VECTOR_FREE_LIST_FLAG) - vector->header.next.nbytes = - vector->header.size & VECTOR_FREE_LIST_SIZE_MASK; - - next = ADVANCE (vector, vector->header.next.nbytes); + next = ADVANCE (vector, nbytes); /* While NEXT is not marked, try to coalesce with VECTOR, thus making VECTOR of the largest possible size. */ @@ -3109,16 +3102,12 @@ sweep_vectors (void) { if (VECTOR_MARKED_P (next)) break; - if ((next->header.size & VECTOR_FREE_LIST_FLAG) - == VECTOR_FREE_LIST_FLAG) - nbytes = next->header.size & VECTOR_FREE_LIST_SIZE_MASK; - else - nbytes = next->header.next.nbytes; - vector->header.next.nbytes += nbytes; + nbytes = PSEUDOVECTOR_NBYTES (next); + total_bytes += nbytes; next = ADVANCE (next, nbytes); } - eassert (vector->header.next.nbytes % roundup_size == 0); + eassert (total_bytes % roundup_size == 0); if (vector == (struct Lisp_Vector *) block->data && !VECTOR_IN_BLOCK (next, block)) @@ -3126,7 +3115,10 @@ sweep_vectors (void) space was coalesced into the only free vector. */ free_this_block = 1; else - SETUP_ON_FREE_LIST (vector, vector->header.next.nbytes, nbytes); + { + int tmp; + SETUP_ON_FREE_LIST (vector, total_bytes, tmp); + } } } @@ -4342,10 +4334,9 @@ live_vector_p (struct mem_node *m, void *p) while (VECTOR_IN_BLOCK (vector, block) && vector <= (struct Lisp_Vector *) p) { - if ((vector->header.size & VECTOR_FREE_LIST_FLAG) - == VECTOR_FREE_LIST_FLAG) + if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) vector = ADVANCE (vector, (vector->header.size - & VECTOR_FREE_LIST_SIZE_MASK)); + & PSEUDOVECTOR_SIZE_MASK)); else if (vector == p) return 1; else @@ -5913,15 +5904,17 @@ mark_object (Lisp_Object arg) #endif /* GC_CHECK_MARKED_OBJECTS */ if (ptr->header.size & PSEUDOVECTOR_FLAG) - pvectype = ptr->header.size & PVEC_TYPE_MASK; + pvectype = ((ptr->header.size & PVEC_TYPE_MASK) + >> PSEUDOVECTOR_SIZE_BITS); else pvectype = 0; if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER) CHECK_LIVE (live_vector_p); - if (pvectype == PVEC_BUFFER) + switch (pvectype) { + case PVEC_BUFFER: #ifdef GC_CHECK_MARKED_OBJECTS if (po != &buffer_defaults && po != &buffer_local_symbols) { @@ -5933,67 +5926,82 @@ mark_object (Lisp_Object arg) } #endif /* GC_CHECK_MARKED_OBJECTS */ mark_buffer ((struct buffer *) ptr); - } + break; - else if (pvectype == PVEC_COMPILED) - /* We could treat this just like a vector, but it is better - to save the COMPILED_CONSTANTS element for last and avoid - recursion there. */ - { - int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; - int i; + case PVEC_COMPILED: + { /* We could treat this just like a vector, but it is better + to save the COMPILED_CONSTANTS element for last and avoid + recursion there. */ + int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; + int i; + + VECTOR_MARK (ptr); + for (i = 0; i < size; i++) + if (i != COMPILED_CONSTANTS) + mark_object (ptr->contents[i]); + if (size > COMPILED_CONSTANTS) + { + obj = ptr->contents[COMPILED_CONSTANTS]; + goto loop; + } + } + break; - VECTOR_MARK (ptr); - for (i = 0; i < size; i++) - if (i != COMPILED_CONSTANTS) - mark_object (ptr->contents[i]); - obj = ptr->contents[COMPILED_CONSTANTS]; - goto loop; - } + case PVEC_FRAME: + { + mark_vectorlike (ptr); + mark_face_cache (((struct frame *) ptr)->face_cache); + } + break; - else if (pvectype == PVEC_FRAME) - { - mark_vectorlike (ptr); - mark_face_cache (((struct frame *) ptr)->face_cache); - } + case PVEC_WINDOW: + { + struct window *w = (struct window *) ptr; - else if (pvectype == PVEC_WINDOW) - { - struct window *w = (struct window *) ptr; + mark_vectorlike (ptr); + /* Mark glyphs for leaf windows. Marking window + matrices is sufficient because frame matrices + use the same glyph memory. */ + if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix) + { + mark_glyph_matrix (w->current_matrix); + mark_glyph_matrix (w->desired_matrix); + } + } + break; - mark_vectorlike (ptr); - /* Mark glyphs for leaf windows. Marking window - matrices is sufficient because frame matrices - use the same glyph memory. */ - if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix) - { - mark_glyph_matrix (w->current_matrix); - mark_glyph_matrix (w->desired_matrix); - } - } + case PVEC_HASH_TABLE: + { + struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; - else if (pvectype == PVEC_HASH_TABLE) - { - struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; + mark_vectorlike (ptr); + /* If hash table is not weak, mark all keys and values. + For weak tables, mark only the vector. */ + if (NILP (h->weak)) + mark_object (h->key_and_value); + else + VECTOR_MARK (XVECTOR (h->key_and_value)); + } + break; - mark_vectorlike (ptr); - /* If hash table is not weak, mark all keys and values. - For weak tables, mark only the vector. */ - if (NILP (h->weak)) - mark_object (h->key_and_value); - else - VECTOR_MARK (XVECTOR (h->key_and_value)); - } + case PVEC_CHAR_TABLE: + mark_char_table (ptr); + break; + + case PVEC_BOOL_VECTOR: + /* No Lisp_Objects to mark in a bool vector. */ + VECTOR_MARK (ptr); + break; - else if (pvectype == PVEC_CHAR_TABLE) - mark_char_table (ptr); + case PVEC_SUBR: + break; - else if (pvectype == PVEC_BOOL_VECTOR) - /* No Lisp_Objects to mark in a bool vector. */ - VECTOR_MARK (ptr); + case PVEC_FREE: + abort (); - else if (pvectype != PVEC_SUBR) - mark_vectorlike (ptr); + default: + mark_vectorlike (ptr); + } } break; |
