[kaffe] stack limits in kaffe

Patrick Tullmann tullmann@cs.utah.edu
Fri, 26 Apr 2002 18:30:15 -0600


I've been running into some StackOverflowErrors with Kaffe.  So, I
wrote a simple Java app (attached below) which has a recursive
function recurse until a StackOverflowError is thrown, it then prints
the depth at which it crashed.  I then ran it against several versions
of Kaffe, Sun's JDK1.4, and Sun's JDK1.3

For each run the first line is the "size" of the main stack, the
second is the "size" of a new thread's stack.  (These can be different
because the main thread usually runs with the underlying OSen's
automagically growable stack.)  The "size" is measured in number of
stack frames for a method with very few stack slots (I think it uses
two from the javap -c output of the method).


For JDK1.4:
Overflowed at 62005
Overflowed at 14007

For JDK1.4 -Xint: 
Overflowed at 41836
Overflowed at 9337

For JDK1.3:
Overflowed at 60255
Overflowed at 84390

For JDK1.3 -Xint:
Overflowed at 45734
Overflowed at 45938

Looks like they reduced the default stack size in JDK1.4 for new
threads...  (-Xint means run with the interpreter only).


For Kaffe jit3, --disable-debug, CFLAGS="-O4":
Overflowed at 20040
Overflowed at 579

For Kaffe jit3, <neither enable or disable debug>
Overflowed at 20039
Overflowed at 576

For Kaffe jit3, --enable-debug:
Overflowed at 20040
Overflowed at 576

For Kaffe intrp, --disable-debug CFLAGS="-O4":
Overflowed at 1743
Overflowed at 87

For Kaffe intrp, <neither enable/disable debug>:
Overflowed at 755
Overflowed at 33

For Kaffe intrp, --enable-debug:
Overflowed at 572
Overflowed at 24

Frankly, I'm amazed the Kaffe "intrp --enable-debug" version manages
to run anything at all!  New threads only have 24 stack frames!

This is with Kaffe's unix-jthreads on a Linux/x86 box with the OS
stack limit set to 4Mb.  In jthreads, new thread stacks are 64K, with
an 8K buffer used to detect stack overflow (so really there is only
56K of space, and 1K or so of that is used by the thread
initialization code).  That means the debugging interpreter is using
almost 2K per java method??  That can't be right...

So, if anyone is looking for something to work on, cleaning up the
interpreter's stack usage might be a good project.  :)

-Pat

----- ----- ---- ---  ---  --   -    -      -         -               -
Pat Tullmann                                       tullmann@cs.utah.edu
		This space unintentionally left blank.


/**
 * See how big the main stack and a newly-created thread's stack can get.
 *
 * @author Pat Tullmann <pat@tullmann.org>
 */
public class StackSizer
{
	private static final int MAX_RECURSION_DEPTH = 100000;

	public static void main(String[] args)
	{
		// See if the main thread has a fixed stack size
		findStackSize(MAX_RECURSION_DEPTH);

		// See if a new thread has a fixed stack size
		new Thread(new Runnable() {
				public void run()
				{
					findStackSize(MAX_RECURSION_DEPTH);
				}
			}).start();
	}

	private static class MyOverflow
		extends Exception
	{
		public int depth;

		public MyOverflow(int d, StackOverflowError soe)
		{
			super();
			this.depth = d;
		}
	}


	private static void findStackSize(int max)
	{
		try
		{
			findStackSize(0, max);
		}
		catch (MyOverflow mo)
		{
			System.err.println("Overflowed at " +mo.depth);
		}
	}

	
	private static void findStackSize(int current, int max)
		throws MyOverflow
	{
		try
		{
			if (current < max)
				findStackSize(++current, max);
		}
		catch (StackOverflowError soe)
		{
			// Do the printing up where there is some room on the stack!
			throw new MyOverflow(current, soe);
		}
	}
}