another limit check bug

Matthew Fluet fluet@CS.Cornell.EDU
Mon, 26 Nov 2001 11:13:46 -0500 (EST)


I don't think this has anything to do with Henry's problem, but I think
there is a bug in the LimitCheck macro for the ccodegen:

#define LimitCheck(frameSize, ret, b, other)
	do {
		declareFirst;

		if (GC_EVERY_CHECK
		or (GC_FIRST_CHECK and gc_first)
		or frontier + (b) > gcState.limit
		or (other)) {
			do {
				uint	bytes = b;

				InvokeRuntime
					(GC_gc(&gcState, bytes,
						GC_EVERY_CHECK or
						(GC_FIRST_CHECK and
						__FILE__, __LINE__),
					frameSize, ret);
			} while (frontier + (b) > gcState.limit)
			clearFirst;
		}
		assert(gcState.stackBottom <= stackTop + WORD_SIZE);
	} while (0)

There is one uint bytes = b declaration per LimitCheck.  So, I could
imagine two threads, with a variable sized array allocation:

Thread A: checks for 4000 bytes for an array, fails, sets b = 4000,
          invokes gc
Thread B: uses up heap, gets to the same array allocation,
          checks for 400 bytes for an array, fails, sets b = 400,
          invokes gc
Thread A: returns from gc, which got 400 bytes, does the while test with
          b = 400, so succeeds, then goes on to allocate 4000 bytes.

I think this clinches a per thread bytesNeeded and moving the while loop
into the GC_gc function.