diff options
author | Keith Packard <keithp@keithp.com> | 2017-12-18 02:12:04 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2017-12-18 02:12:04 -0800 |
commit | 6593570418e087b9f83ed7f90303d4e1e7d20e83 (patch) | |
tree | 998be6c34980656dc99008a07986f5c76a1e4bc7 | |
parent | 9f1849e548e35498f88a0b8adbbc4a57c7a39222 (diff) |
altos/scheme: Work around gcc 7.2.0 optimization bug in memory manager
After marking a set of memory chunks, it's possible that all of them
will be packed tight against 'top', in which case none of them will be
moving. In that case, gcc 7.2.0 appears to generate incorrect code
causing the loop to be abandoned, meaning that we don't actually
collect anything at all.
Add a quick short-circuit test just after the mark phase that skips
the code which wouldn't do anything in this case.
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | src/scheme/ao_scheme_mem.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/scheme/ao_scheme_mem.c b/src/scheme/ao_scheme_mem.c index 3659d3ec..94275451 100644 --- a/src/scheme/ao_scheme_mem.c +++ b/src/scheme/ao_scheme_mem.c @@ -623,6 +623,20 @@ ao_scheme_collect(uint8_t style) top += size; } + /* Short-circuit the rest of the loop when all of the + * found objects aren't moving. This isn't strictly + * necessary as the rest of the loop is structured to + * work in this case, but GCC 7.2.0 with optimization + * greater than 2 generates incorrect code for this... + */ + if (i == AO_SCHEME_NCHUNK) { + chunk_low = chunk_high; +#if DBG_MEM_STATS + loops++; +#endif + continue; + } + /* * Limit amount of chunk array used in mapping moves * to the active region |