diff options
| author | Paul Eggert | 2016-06-20 02:05:39 +0200 |
|---|---|---|
| committer | Paul Eggert | 2016-06-20 02:06:17 +0200 |
| commit | 9341142dc876f4d93c442242206a7d2d40fd03af (patch) | |
| tree | 4938e096b91a75282b63fdcf59947533d4a6d3c3 /src | |
| parent | dd39c6fbeb299f0b203f01388e83f5e02767b8ff (diff) | |
| download | emacs-9341142dc876f4d93c442242206a7d2d40fd03af.tar.gz emacs-9341142dc876f4d93c442242206a7d2d40fd03af.zip | |
Minor ABLOCKS_BUSY cleanups in alloc.c
* src/alloc.c (ABLOCKS_BUSY): Rename arg to avoid potential clash
with member ‘abase’ in definiens.
(lisp_align_malloc, lisp_align_free): Use bool for boolean.
Avoid compiler warning with fewer casts.
(lisp_align_free): Check busy-field values; this can help the
compiler a bit when optimizing, too.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/src/alloc.c b/src/alloc.c index 0a3e7d42a4f..5f9d6ada5a1 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1178,16 +1178,18 @@ struct ablock | |||
| 1178 | char payload[BLOCK_BYTES]; | 1178 | char payload[BLOCK_BYTES]; |
| 1179 | struct ablock *next_free; | 1179 | struct ablock *next_free; |
| 1180 | } x; | 1180 | } x; |
| 1181 | /* `abase' is the aligned base of the ablocks. */ | 1181 | |
| 1182 | /* It is overloaded to hold the virtual `busy' field that counts | 1182 | /* ABASE is the aligned base of the ablocks. It is overloaded to |
| 1183 | the number of used ablock in the parent ablocks. | 1183 | hold a virtual "busy" field that counts twice the number of used |
| 1184 | The first ablock has the `busy' field, the others have the `abase' | 1184 | ablock values in the parent ablocks, plus one if the real base of |
| 1185 | field. To tell the difference, we assume that pointers will have | 1185 | the parent ablocks is ABASE (if the "busy" field is even, the |
| 1186 | integer values larger than 2 * ABLOCKS_SIZE. The lowest bit of `busy' | 1186 | word before the first ablock holds a pointer to the real base). |
| 1187 | is used to tell whether the real base of the parent ablocks is `abase' | 1187 | The first ablock has a "busy" ABASE, and the others have an |
| 1188 | (if not, the word before the first ablock holds a pointer to the | 1188 | ordinary pointer ABASE. To tell the difference, the code assumes |
| 1189 | real base). */ | 1189 | that pointers, when cast to uintptr_t, are at least 2 * |
| 1190 | ABLOCKS_SIZE + 1. */ | ||
| 1190 | struct ablocks *abase; | 1191 | struct ablocks *abase; |
| 1192 | |||
| 1191 | /* The padding of all but the last ablock is unused. The padding of | 1193 | /* The padding of all but the last ablock is unused. The padding of |
| 1192 | the last ablock in an ablocks is not allocated. */ | 1194 | the last ablock in an ablocks is not allocated. */ |
| 1193 | #if BLOCK_PADDING | 1195 | #if BLOCK_PADDING |
| @@ -1206,18 +1208,18 @@ struct ablocks | |||
| 1206 | 1208 | ||
| 1207 | #define ABLOCK_ABASE(block) \ | 1209 | #define ABLOCK_ABASE(block) \ |
| 1208 | (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ | 1210 | (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ |
| 1209 | ? (struct ablocks *)(block) \ | 1211 | ? (struct ablocks *) (block) \ |
| 1210 | : (block)->abase) | 1212 | : (block)->abase) |
| 1211 | 1213 | ||
| 1212 | /* Virtual `busy' field. */ | 1214 | /* Virtual `busy' field. */ |
| 1213 | #define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) | 1215 | #define ABLOCKS_BUSY(a_base) ((a_base)->blocks[0].abase) |
| 1214 | 1216 | ||
| 1215 | /* Pointer to the (not necessarily aligned) malloc block. */ | 1217 | /* Pointer to the (not necessarily aligned) malloc block. */ |
| 1216 | #ifdef USE_ALIGNED_ALLOC | 1218 | #ifdef USE_ALIGNED_ALLOC |
| 1217 | #define ABLOCKS_BASE(abase) (abase) | 1219 | #define ABLOCKS_BASE(abase) (abase) |
| 1218 | #else | 1220 | #else |
| 1219 | #define ABLOCKS_BASE(abase) \ | 1221 | #define ABLOCKS_BASE(abase) \ |
| 1220 | (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1]) | 1222 | (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **) (abase))[-1]) |
| 1221 | #endif | 1223 | #endif |
| 1222 | 1224 | ||
| 1223 | /* The list of free ablock. */ | 1225 | /* The list of free ablock. */ |
| @@ -1243,7 +1245,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1243 | if (!free_ablock) | 1245 | if (!free_ablock) |
| 1244 | { | 1246 | { |
| 1245 | int i; | 1247 | int i; |
| 1246 | intptr_t aligned; /* int gets warning casting to 64-bit pointer. */ | 1248 | bool aligned; |
| 1247 | 1249 | ||
| 1248 | #ifdef DOUG_LEA_MALLOC | 1250 | #ifdef DOUG_LEA_MALLOC |
| 1249 | if (!mmap_lisp_allowed_p ()) | 1251 | if (!mmap_lisp_allowed_p ()) |
| @@ -1299,13 +1301,14 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1299 | abase->blocks[i].x.next_free = free_ablock; | 1301 | abase->blocks[i].x.next_free = free_ablock; |
| 1300 | free_ablock = &abase->blocks[i]; | 1302 | free_ablock = &abase->blocks[i]; |
| 1301 | } | 1303 | } |
| 1302 | ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; | 1304 | intptr_t ialigned = aligned; |
| 1305 | ABLOCKS_BUSY (abase) = (struct ablocks *) ialigned; | ||
| 1303 | 1306 | ||
| 1304 | eassert (0 == ((uintptr_t) abase) % BLOCK_ALIGN); | 1307 | eassert ((uintptr_t) abase % BLOCK_ALIGN == 0); |
| 1305 | eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ | 1308 | eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ |
| 1306 | eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); | 1309 | eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); |
| 1307 | eassert (ABLOCKS_BASE (abase) == base); | 1310 | eassert (ABLOCKS_BASE (abase) == base); |
| 1308 | eassert (aligned == (intptr_t) ABLOCKS_BUSY (abase)); | 1311 | eassert ((intptr_t) ABLOCKS_BUSY (abase) == aligned); |
| 1309 | } | 1312 | } |
| 1310 | 1313 | ||
| 1311 | abase = ABLOCK_ABASE (free_ablock); | 1314 | abase = ABLOCK_ABASE (free_ablock); |
| @@ -1341,12 +1344,14 @@ lisp_align_free (void *block) | |||
| 1341 | ablock->x.next_free = free_ablock; | 1344 | ablock->x.next_free = free_ablock; |
| 1342 | free_ablock = ablock; | 1345 | free_ablock = ablock; |
| 1343 | /* Update busy count. */ | 1346 | /* Update busy count. */ |
| 1344 | ABLOCKS_BUSY (abase) | 1347 | intptr_t busy = (intptr_t) ABLOCKS_BUSY (abase) - 2; |
| 1345 | = (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); | 1348 | eassume (0 <= busy && busy <= 2 * ABLOCKS_SIZE - 1); |
| 1349 | ABLOCKS_BUSY (abase) = (struct ablocks *) busy; | ||
| 1346 | 1350 | ||
| 1347 | if (2 > (intptr_t) ABLOCKS_BUSY (abase)) | 1351 | if (busy < 2) |
| 1348 | { /* All the blocks are free. */ | 1352 | { /* All the blocks are free. */ |
| 1349 | int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase); | 1353 | int i = 0; |
| 1354 | bool aligned = busy; | ||
| 1350 | struct ablock **tem = &free_ablock; | 1355 | struct ablock **tem = &free_ablock; |
| 1351 | struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; | 1356 | struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; |
| 1352 | 1357 | ||