I like it, except for the scanning the cache at flip time.  Instead of:
	if (cache[hash(ptr)] != ptr) {
		*writelist++ = cache[hash(ptr)];
		cache[hash(ptr)] = ptr;
	}
how about:
	if (cache[hash(ptr)] != ptr) {
		cache[hash(ptr)] = ptr;
		*writelist++ = ptr;
	}
This way the cache just needs to be zeroed at flip time, and it
doesn't take any more instructions.
-William