aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorVincent Belaïche2016-07-28 18:12:50 +0200
committerVincent Belaïche2016-07-28 18:12:50 +0200
commit90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f (patch)
treedf3235d89ee8e4d32571b8a8521f75f7576913c2 /src/alloc.c
parent41b28dea8587c13b0bc59c1ec70b65afab3aeeca (diff)
parentec359399a47f852b4d022a30245449438e349193 (diff)
downloademacs-90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f.tar.gz
emacs-90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 054e1ca23ca..e25d91ff8aa 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#include <errno.h>
23#include <stdio.h> 24#include <stdio.h>
24#include <limits.h> /* For CHAR_BIT. */ 25#include <limits.h> /* For CHAR_BIT. */
25#include <signal.h> /* For SIGABRT, SIGDANGER. */ 26#include <signal.h> /* For SIGABRT, SIGDANGER. */
@@ -150,7 +151,8 @@ malloc_initialize_hook (void)
150 } 151 }
151 } 152 }
152 153
153 malloc_set_state (malloc_state_ptr); 154 if (malloc_set_state (malloc_state_ptr) != 0)
155 emacs_abort ();
154# ifndef XMALLOC_OVERRUN_CHECK 156# ifndef XMALLOC_OVERRUN_CHECK
155 alloc_unexec_post (); 157 alloc_unexec_post ();
156# endif 158# endif
@@ -174,6 +176,8 @@ alloc_unexec_pre (void)
174{ 176{
175#ifdef DOUG_LEA_MALLOC 177#ifdef DOUG_LEA_MALLOC
176 malloc_state_ptr = malloc_get_state (); 178 malloc_state_ptr = malloc_get_state ();
179 if (!malloc_state_ptr)
180 fatal ("malloc_get_state: %s", strerror (errno));
177#endif 181#endif
178#ifdef HYBRID_MALLOC 182#ifdef HYBRID_MALLOC
179 bss_sbrk_did_unexec = true; 183 bss_sbrk_did_unexec = true;
@@ -485,7 +489,7 @@ static void *pure_alloc (size_t, int);
485/* Return PTR rounded up to the next multiple of ALIGNMENT. */ 489/* Return PTR rounded up to the next multiple of ALIGNMENT. */
486 490
487static void * 491static void *
488ALIGN (void *ptr, int alignment) 492pointer_align (void *ptr, int alignment)
489{ 493{
490 return (void *) ROUNDUP ((uintptr_t) ptr, alignment); 494 return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
491} 495}
@@ -1174,16 +1178,18 @@ struct ablock
1174 char payload[BLOCK_BYTES]; 1178 char payload[BLOCK_BYTES];
1175 struct ablock *next_free; 1179 struct ablock *next_free;
1176 } x; 1180 } x;
1177 /* `abase' is the aligned base of the ablocks. */ 1181
1178 /* It is overloaded to hold the virtual `busy' field that counts 1182 /* ABASE is the aligned base of the ablocks. It is overloaded to
1179 the number of used ablock in the parent ablocks. 1183 hold a virtual "busy" field that counts twice the number of used
1180 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
1181 field. To tell the difference, we assume that pointers will have 1185 the parent ablocks is ABASE (if the "busy" field is even, the
1182 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).
1183 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
1184 (if not, the word before the first ablock holds a pointer to the 1188 ordinary pointer ABASE. To tell the difference, the code assumes
1185 real base). */ 1189 that pointers, when cast to uintptr_t, are at least 2 *
1190 ABLOCKS_SIZE + 1. */
1186 struct ablocks *abase; 1191 struct ablocks *abase;
1192
1187 /* 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
1188 the last ablock in an ablocks is not allocated. */ 1194 the last ablock in an ablocks is not allocated. */
1189#if BLOCK_PADDING 1195#if BLOCK_PADDING
@@ -1202,18 +1208,18 @@ struct ablocks
1202 1208
1203#define ABLOCK_ABASE(block) \ 1209#define ABLOCK_ABASE(block) \
1204 (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \ 1210 (((uintptr_t) (block)->abase) <= (1 + 2 * ABLOCKS_SIZE) \
1205 ? (struct ablocks *)(block) \ 1211 ? (struct ablocks *) (block) \
1206 : (block)->abase) 1212 : (block)->abase)
1207 1213
1208/* Virtual `busy' field. */ 1214/* Virtual `busy' field. */
1209#define ABLOCKS_BUSY(abase) ((abase)->blocks[0].abase) 1215#define ABLOCKS_BUSY(a_base) ((a_base)->blocks[0].abase)
1210 1216
1211/* Pointer to the (not necessarily aligned) malloc block. */ 1217/* Pointer to the (not necessarily aligned) malloc block. */
1212#ifdef USE_ALIGNED_ALLOC 1218#ifdef USE_ALIGNED_ALLOC
1213#define ABLOCKS_BASE(abase) (abase) 1219#define ABLOCKS_BASE(abase) (abase)
1214#else 1220#else
1215#define ABLOCKS_BASE(abase) \ 1221#define ABLOCKS_BASE(abase) \
1216 (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1]) 1222 (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **) (abase))[-1])
1217#endif 1223#endif
1218 1224
1219/* The list of free ablock. */ 1225/* The list of free ablock. */
@@ -1239,7 +1245,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1239 if (!free_ablock) 1245 if (!free_ablock)
1240 { 1246 {
1241 int i; 1247 int i;
1242 intptr_t aligned; /* int gets warning casting to 64-bit pointer. */ 1248 bool aligned;
1243 1249
1244#ifdef DOUG_LEA_MALLOC 1250#ifdef DOUG_LEA_MALLOC
1245 if (!mmap_lisp_allowed_p ()) 1251 if (!mmap_lisp_allowed_p ())
@@ -1250,7 +1256,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1250 abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES); 1256 abase = base = aligned_alloc (BLOCK_ALIGN, ABLOCKS_BYTES);
1251#else 1257#else
1252 base = malloc (ABLOCKS_BYTES); 1258 base = malloc (ABLOCKS_BYTES);
1253 abase = ALIGN (base, BLOCK_ALIGN); 1259 abase = pointer_align (base, BLOCK_ALIGN);
1254#endif 1260#endif
1255 1261
1256 if (base == 0) 1262 if (base == 0)
@@ -1295,13 +1301,14 @@ lisp_align_malloc (size_t nbytes, enum mem_type type)
1295 abase->blocks[i].x.next_free = free_ablock; 1301 abase->blocks[i].x.next_free = free_ablock;
1296 free_ablock = &abase->blocks[i]; 1302 free_ablock = &abase->blocks[i];
1297 } 1303 }
1298 ABLOCKS_BUSY (abase) = (struct ablocks *) aligned; 1304 intptr_t ialigned = aligned;
1305 ABLOCKS_BUSY (abase) = (struct ablocks *) ialigned;
1299 1306
1300 eassert (0 == ((uintptr_t) abase) % BLOCK_ALIGN); 1307 eassert ((uintptr_t) abase % BLOCK_ALIGN == 0);
1301 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */ 1308 eassert (ABLOCK_ABASE (&abase->blocks[3]) == abase); /* 3 is arbitrary */
1302 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase); 1309 eassert (ABLOCK_ABASE (&abase->blocks[0]) == abase);
1303 eassert (ABLOCKS_BASE (abase) == base); 1310 eassert (ABLOCKS_BASE (abase) == base);
1304 eassert (aligned == (intptr_t) ABLOCKS_BUSY (abase)); 1311 eassert ((intptr_t) ABLOCKS_BUSY (abase) == aligned);
1305 } 1312 }
1306 1313
1307 abase = ABLOCK_ABASE (free_ablock); 1314 abase = ABLOCK_ABASE (free_ablock);
@@ -1337,12 +1344,14 @@ lisp_align_free (void *block)
1337 ablock->x.next_free = free_ablock; 1344 ablock->x.next_free = free_ablock;
1338 free_ablock = ablock; 1345 free_ablock = ablock;
1339 /* Update busy count. */ 1346 /* Update busy count. */
1340 ABLOCKS_BUSY (abase) 1347 intptr_t busy = (intptr_t) ABLOCKS_BUSY (abase) - 2;
1341 = (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); 1348 eassume (0 <= busy && busy <= 2 * ABLOCKS_SIZE - 1);
1349 ABLOCKS_BUSY (abase) = (struct ablocks *) busy;
1342 1350
1343 if (2 > (intptr_t) ABLOCKS_BUSY (abase)) 1351 if (busy < 2)
1344 { /* All the blocks are free. */ 1352 { /* All the blocks are free. */
1345 int i = 0, aligned = (intptr_t) ABLOCKS_BUSY (abase); 1353 int i = 0;
1354 bool aligned = busy;
1346 struct ablock **tem = &free_ablock; 1355 struct ablock **tem = &free_ablock;
1347 struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1]; 1356 struct ablock *atop = &abase->blocks[aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1];
1348 1357
@@ -5169,7 +5178,7 @@ pure_alloc (size_t size, int type)
5169 { 5178 {
5170 /* Allocate space for a Lisp object from the beginning of the free 5179 /* Allocate space for a Lisp object from the beginning of the free
5171 space with taking account of alignment. */ 5180 space with taking account of alignment. */
5172 result = ALIGN (purebeg + pure_bytes_used_lisp, GCALIGNMENT); 5181 result = pointer_align (purebeg + pure_bytes_used_lisp, GCALIGNMENT);
5173 pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size; 5182 pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size;
5174 } 5183 }
5175 else 5184 else
@@ -6126,7 +6135,7 @@ mark_face_cache (struct face_cache *c)
6126 int i, j; 6135 int i, j;
6127 for (i = 0; i < c->used; ++i) 6136 for (i = 0; i < c->used; ++i)
6128 { 6137 {
6129 struct face *face = FACE_OPT_FROM_ID (c->f, i); 6138 struct face *face = FACE_FROM_ID_OR_NULL (c->f, i);
6130 6139
6131 if (face) 6140 if (face)
6132 { 6141 {