altos/scheme: Work around gcc 7.2.0 optimization bug in memory manager
authorKeith Packard <keithp@keithp.com>
Mon, 18 Dec 2017 10:12:04 +0000 (02:12 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 18 Dec 2017 10:12:04 +0000 (02:12 -0800)
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>
src/scheme/ao_scheme_mem.c

index 3659d3ec4a7fa331312bc96f856183c071c148aa..94275451b10419fefbaa4e0e3be317a47b9e0752 100644 (file)
@@ -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