[gclist] GCBench "benchmark" problem

Boehm, Hans hans_boehm@hp.com
Mon, 7 May 2001 14:22:01 -0700

I found what's essentially a bug in the GCBench benchmark

The main program includes something like: 

	Node longLivedTree;

	longLivedTree = new ...
	Populate(..., longLivedTree);

	... do stuff that allocates a lot ...

	if (longLivedTree == null || ...) ...

The  longLivedTree == null  check was intended to ensure that longLivedTree
remains live.  But it doesn't always do that.

The problem is that it's too easy to conclude statically that longLivedTree
!= null, either based on the fact that it is the result of new, or based on
the fact that Populate dereferences it.  I caught gcc -O3 apparently doing
the latter (?) for the C version.

As far as I can tell, at least the HotSpot 1.3 client compiler didn't pick
up on this.  I'm not sure about other JVMs, though I suspect others would
have noticed this problem if they had.

This is clearly not an ideal benchmark.  However it still seems to be useful
for sanity checks and ballpark cross-language comparisons.  And it's better
than allocate-drop loops.  And unlike more realistic benchmarks, it's
possible to completely understand its behavior, so that issues like this
can actually be identified.

Thus I propose to "fix" it by changing the final test to

 longLivedTree.left.right == null

and calling the result version 3.  (Only the multithreaded variant has a
version 2.)

This shouldn't affect the running time of the benchmark appreciably, unless
it was being overoptimized before.  My guess is that it will make this sort
of optimization far less likely.  (Since the program has no input a
sufficiently agreessive partial evaluator could always optimize the whole
thing away, but ...)

Does anybody know of an optimizer that would still eliminate this test?