diff options
| author | Paul Eggert | 2014-04-28 09:59:41 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-04-28 09:59:41 -0700 |
| commit | 9c23779a9d8474af16cfadb1a08d2c05ececcbec (patch) | |
| tree | 5b4079b064da29fc379838f9f2bcedb7826d312b | |
| parent | 90119853b1306f6792c690a802b4c81f279186dc (diff) | |
| download | emacs-9c23779a9d8474af16cfadb1a08d2c05ececcbec.tar.gz emacs-9c23779a9d8474af16cfadb1a08d2c05ececcbec.zip | |
Use bits_word for gcmarkbits.
* alloc.c (struct cons_block, struct float_block): On 64-bit hosts,
bits_word is typically a tad more efficient for mark bits than
unsigned is, so use bits_word. All uses changed.
* lisp.h (BITS_PER_INT): Remove; no longer used.
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/alloc.c | 38 | ||||
| -rw-r--r-- | src/lisp.h | 3 |
3 files changed, 26 insertions, 21 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 90223d6d103..619dce7a731 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | 2014-04-28 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2014-04-28 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Use bits_word for gcmarkbits. | ||
| 4 | * alloc.c (struct cons_block, struct float_block): On 64-bit hosts, | ||
| 5 | bits_word is typically a tad more efficient for mark bits than | ||
| 6 | unsigned is, so use bits_word. All uses changed. | ||
| 7 | * lisp.h (BITS_PER_INT): Remove; no longer used. | ||
| 8 | |||
| 3 | Avoid undefined behavior in signed left shift. | 9 | Avoid undefined behavior in signed left shift. |
| 4 | This ports to GCC 4.9.0 with -fsanitize=undefined. | 10 | This ports to GCC 4.9.0 with -fsanitize=undefined. |
| 5 | * alloc.c (bool_vector_fill, SETMARKBIT, UNSETMARKBIT): | 11 | * alloc.c (bool_vector_fill, SETMARKBIT, UNSETMARKBIT): |
diff --git a/src/alloc.c b/src/alloc.c index 32d3333cea8..7159d1fa747 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2332,21 +2332,21 @@ make_formatted_string (char *buf, const char *format, ...) | |||
| 2332 | #define FLOAT_BLOCK_SIZE \ | 2332 | #define FLOAT_BLOCK_SIZE \ |
| 2333 | (((BLOCK_BYTES - sizeof (struct float_block *) \ | 2333 | (((BLOCK_BYTES - sizeof (struct float_block *) \ |
| 2334 | /* The compiler might add padding at the end. */ \ | 2334 | /* The compiler might add padding at the end. */ \ |
| 2335 | - (sizeof (struct Lisp_Float) - sizeof (int))) * CHAR_BIT) \ | 2335 | - (sizeof (struct Lisp_Float) - sizeof (bits_word))) * CHAR_BIT) \ |
| 2336 | / (sizeof (struct Lisp_Float) * CHAR_BIT + 1)) | 2336 | / (sizeof (struct Lisp_Float) * CHAR_BIT + 1)) |
| 2337 | 2337 | ||
| 2338 | #define GETMARKBIT(block,n) \ | 2338 | #define GETMARKBIT(block,n) \ |
| 2339 | (((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \ | 2339 | (((block)->gcmarkbits[(n) / BITS_PER_BITS_WORD] \ |
| 2340 | >> ((n) % (sizeof (unsigned) * CHAR_BIT))) \ | 2340 | >> ((n) % BITS_PER_BITS_WORD)) \ |
| 2341 | & 1) | 2341 | & 1) |
| 2342 | 2342 | ||
| 2343 | #define SETMARKBIT(block,n) \ | 2343 | #define SETMARKBIT(block,n) \ |
| 2344 | ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \ | 2344 | ((block)->gcmarkbits[(n) / BITS_PER_BITS_WORD] \ |
| 2345 | |= 1u << ((n) % (sizeof (unsigned) * CHAR_BIT))) | 2345 | |= (bits_word) 1 << ((n) % BITS_PER_BITS_WORD)) |
| 2346 | 2346 | ||
| 2347 | #define UNSETMARKBIT(block,n) \ | 2347 | #define UNSETMARKBIT(block,n) \ |
| 2348 | ((block)->gcmarkbits[(n) / (sizeof (unsigned) * CHAR_BIT)] \ | 2348 | ((block)->gcmarkbits[(n) / BITS_PER_BITS_WORD] \ |
| 2349 | &= ~(1u << ((n) % (sizeof (unsigned) * CHAR_BIT)))) | 2349 | &= ~((bits_word) 1 << ((n) % BITS_PER_BITS_WORD))) |
| 2350 | 2350 | ||
| 2351 | #define FLOAT_BLOCK(fptr) \ | 2351 | #define FLOAT_BLOCK(fptr) \ |
| 2352 | ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1))) | 2352 | ((struct float_block *) (((uintptr_t) (fptr)) & ~(BLOCK_ALIGN - 1))) |
| @@ -2358,7 +2358,7 @@ struct float_block | |||
| 2358 | { | 2358 | { |
| 2359 | /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job. */ | 2359 | /* Place `floats' at the beginning, to ease up FLOAT_INDEX's job. */ |
| 2360 | struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; | 2360 | struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; |
| 2361 | unsigned gcmarkbits[1 + FLOAT_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)]; | 2361 | bits_word gcmarkbits[1 + FLOAT_BLOCK_SIZE / BITS_PER_BITS_WORD]; |
| 2362 | struct float_block *next; | 2362 | struct float_block *next; |
| 2363 | }; | 2363 | }; |
| 2364 | 2364 | ||
| @@ -2439,7 +2439,7 @@ make_float (double float_value) | |||
| 2439 | #define CONS_BLOCK_SIZE \ | 2439 | #define CONS_BLOCK_SIZE \ |
| 2440 | (((BLOCK_BYTES - sizeof (struct cons_block *) \ | 2440 | (((BLOCK_BYTES - sizeof (struct cons_block *) \ |
| 2441 | /* The compiler might add padding at the end. */ \ | 2441 | /* The compiler might add padding at the end. */ \ |
| 2442 | - (sizeof (struct Lisp_Cons) - sizeof (int))) * CHAR_BIT) \ | 2442 | - (sizeof (struct Lisp_Cons) - sizeof (bits_word))) * CHAR_BIT) \ |
| 2443 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) | 2443 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) |
| 2444 | 2444 | ||
| 2445 | #define CONS_BLOCK(fptr) \ | 2445 | #define CONS_BLOCK(fptr) \ |
| @@ -2452,7 +2452,7 @@ struct cons_block | |||
| 2452 | { | 2452 | { |
| 2453 | /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ | 2453 | /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ |
| 2454 | struct Lisp_Cons conses[CONS_BLOCK_SIZE]; | 2454 | struct Lisp_Cons conses[CONS_BLOCK_SIZE]; |
| 2455 | unsigned gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof (unsigned) * CHAR_BIT)]; | 2455 | bits_word gcmarkbits[1 + CONS_BLOCK_SIZE / BITS_PER_BITS_WORD]; |
| 2456 | struct cons_block *next; | 2456 | struct cons_block *next; |
| 2457 | }; | 2457 | }; |
| 2458 | 2458 | ||
| @@ -6436,27 +6436,27 @@ NO_INLINE /* For better stack traces */ | |||
| 6436 | static void | 6436 | static void |
| 6437 | sweep_conses (void) | 6437 | sweep_conses (void) |
| 6438 | { | 6438 | { |
| 6439 | register struct cons_block *cblk; | 6439 | struct cons_block *cblk; |
| 6440 | struct cons_block **cprev = &cons_block; | 6440 | struct cons_block **cprev = &cons_block; |
| 6441 | register int lim = cons_block_index; | 6441 | int lim = cons_block_index; |
| 6442 | EMACS_INT num_free = 0, num_used = 0; | 6442 | EMACS_INT num_free = 0, num_used = 0; |
| 6443 | 6443 | ||
| 6444 | cons_free_list = 0; | 6444 | cons_free_list = 0; |
| 6445 | 6445 | ||
| 6446 | for (cblk = cons_block; cblk; cblk = *cprev) | 6446 | for (cblk = cons_block; cblk; cblk = *cprev) |
| 6447 | { | 6447 | { |
| 6448 | register int i = 0; | 6448 | int i = 0; |
| 6449 | int this_free = 0; | 6449 | int this_free = 0; |
| 6450 | int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; | 6450 | int ilim = (lim + BITS_PER_BITS_WORD - 1) / BITS_PER_BITS_WORD; |
| 6451 | 6451 | ||
| 6452 | /* Scan the mark bits an int at a time. */ | 6452 | /* Scan the mark bits an int at a time. */ |
| 6453 | for (i = 0; i < ilim; i++) | 6453 | for (i = 0; i < ilim; i++) |
| 6454 | { | 6454 | { |
| 6455 | if (cblk->gcmarkbits[i] == -1) | 6455 | if (cblk->gcmarkbits[i] == BITS_WORD_MAX) |
| 6456 | { | 6456 | { |
| 6457 | /* Fast path - all cons cells for this int are marked. */ | 6457 | /* Fast path - all cons cells for this int are marked. */ |
| 6458 | cblk->gcmarkbits[i] = 0; | 6458 | cblk->gcmarkbits[i] = 0; |
| 6459 | num_used += BITS_PER_INT; | 6459 | num_used += BITS_PER_BITS_WORD; |
| 6460 | } | 6460 | } |
| 6461 | else | 6461 | else |
| 6462 | { | 6462 | { |
| @@ -6464,10 +6464,10 @@ sweep_conses (void) | |||
| 6464 | Find which ones, and free them. */ | 6464 | Find which ones, and free them. */ |
| 6465 | int start, pos, stop; | 6465 | int start, pos, stop; |
| 6466 | 6466 | ||
| 6467 | start = i * BITS_PER_INT; | 6467 | start = i * BITS_PER_BITS_WORD; |
| 6468 | stop = lim - start; | 6468 | stop = lim - start; |
| 6469 | if (stop > BITS_PER_INT) | 6469 | if (stop > BITS_PER_BITS_WORD) |
| 6470 | stop = BITS_PER_INT; | 6470 | stop = BITS_PER_BITS_WORD; |
| 6471 | stop += start; | 6471 | stop += start; |
| 6472 | 6472 | ||
| 6473 | for (pos = start; pos < stop; pos++) | 6473 | for (pos = start; pos < stop; pos++) |
diff --git a/src/lisp.h b/src/lisp.h index 5e0f141cc9c..f47fb0c2a24 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -115,7 +115,7 @@ enum { BOOL_VECTOR_BITS_PER_CHAR = | |||
| 115 | }; | 115 | }; |
| 116 | 116 | ||
| 117 | /* An unsigned integer type representing a fixed-length bit sequence, | 117 | /* An unsigned integer type representing a fixed-length bit sequence, |
| 118 | suitable for words in a Lisp bool vector. Normally it is size_t | 118 | suitable for bool vector words, GC mark bits, etc. Normally it is size_t |
| 119 | for speed, but it is unsigned char on weird platforms. */ | 119 | for speed, but it is unsigned char on weird platforms. */ |
| 120 | #if BOOL_VECTOR_BITS_PER_CHAR == CHAR_BIT | 120 | #if BOOL_VECTOR_BITS_PER_CHAR == CHAR_BIT |
| 121 | typedef size_t bits_word; | 121 | typedef size_t bits_word; |
| @@ -133,7 +133,6 @@ enum | |||
| 133 | { | 133 | { |
| 134 | BITS_PER_CHAR = CHAR_BIT, | 134 | BITS_PER_CHAR = CHAR_BIT, |
| 135 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), | 135 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), |
| 136 | BITS_PER_INT = CHAR_BIT * sizeof (int), | ||
| 137 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), | 136 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), |
| 138 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) | 137 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) |
| 139 | }; | 138 | }; |