diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2016-02-08 20:24:55 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2016-02-08 20:25:23 -0800 |
commit | b1079c0f86c218f016a6c2e84ea402f4e175fc53 (patch) | |
tree | 1103d4fb608cd77bb3b8a8b3cc33904a63906a61 /src | |
parent | a3bf4a387fdc44e5631a6431a2e40e741c672359 (diff) |
Increase success rate of fallback lmalloc
* src/alloc.c (lmalloc, lrealloc): Reallocate with (typically)
larger and larger sizes, to increase the probability that
the allocator will return a Lisp-aligned pointer.
Diffstat (limited to 'src')
-rw-r--r-- | src/alloc.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c index 8816411bca..668bbc7594 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1380,7 +1380,12 @@ laligned (void *p, size_t size) } /* Like malloc and realloc except that if SIZE is Lisp-aligned, make - sure the result is too. */ + sure the result is too, if necessary by reallocating (typically + with larger and larger sizes) until the allocator returns a + Lisp-aligned pointer. Code that needs to allocate C heap memory + for a Lisp object should use one of these functions to obtain a + pointer P; that way, if T is an enum Lisp_Type value and L == + make_lisp_ptr (P, T), then XPNTR (L) == P and XTYPE (L) == T. */ static void * lmalloc (size_t size) @@ -1397,6 +1402,9 @@ lmalloc (size_t size) if (laligned (p, size)) break; free (p); + size_t bigger; + if (! INT_ADD_WRAPV (size, GCALIGNMENT, &bigger)) + size = bigger; } eassert ((intptr_t) p % GCALIGNMENT == 0); @@ -1406,9 +1414,15 @@ lmalloc (size_t size) static void * lrealloc (void *p, size_t size) { - do - p = realloc (p, size); - while (! laligned (p, size)); + while (true) + { + p = realloc (p, size); + if (laligned (p, size)) + break; + size_t bigger; + if (! INT_ADD_WRAPV (size, GCALIGNMENT, &bigger)) + size = bigger; + } eassert ((intptr_t) p % GCALIGNMENT == 0); return p; |