[Kaffe] new stack trace patch.

Alex Nicolaou anicolao at mud.cgl.uwaterloo.ca
Tue Feb 9 06:02:47 PST 1999


Maxim Kizub wrote:
> 
> Hello.
> 
> I think, it's a bit unrelated to kaffe, but can you explain
> your problem?
> 
> If you wish to have work-by-contract emulation - why you do
> not use a compiler/preprocessor that has this feature?
> I know at least three of them.

Since the company I was working at was just experimenting with Java for
commercial development, they were unwilling to take too many risks at
once. Pure Java was our mandate and our goal, so a preprocessor (of any
kind) was considered undesirable.

> In my expirience (I use stack traces to find out the
> method that called a specified one) - the parsing of
> stack trace is _extremly_ slow operation.
> A program that will offten use code like your will
> be virtually impossible to debug, because all time
> will be spended on trace output parsing...

Well, technically we weren't parsing the stack trace but just extracting
it into a string to use as part of the key for recovering the variable.
So it wasn't so bad in terms of speed, and after all it's only the debug
version. I'm very unconcerned about the speed of the debug version when
everyone is using PPro 200 or 300 Mhz machines and the shipping software
is supposed to target 133 Mhz Pentiums.
 
> Also, what's wrong with additional local variables?
> Your code will be used with jit? I think, native
> instructions speed is not related to position of
> local variable - all of them are accessed
> in the same way, unlike 5 first slots in JVM bytecode.

Native speed may be unrelated to the position of local variables
(although this is not assured) but is likely to be related to the
*number* of local variables. Depending, of course, on how the JIT is
implemented and what the target platform is. On SPARC, for example, both
the number and position of the locals is likely to affect the JIT
performance on a JIT implemented in the obvious way (using the local
variable registers that the processor provides, of which there are only
8). 

Whether there is or isn't an impact is something we didn't seriously
assess. What I knew for sure was that we didn't want any efficiency loss
in the finished app because of code that was there for debugging, and
the solution we chose guarantees that by allowing us to strip all
debugging code from the production build, yeilding a 2 to 15 times
speedup depending on the piece of code. A 15x slowdown seems to me to be
a very small price to pay for this style of programming; in my current
project (different company) I have found almost every bug by the
triggering of an assertion failure. It's basically zero effort
debugging.

alex 


> Alex Nicolaou wrote:
> >
> > Patrick Tullmann wrote:
> > >
> > > > Personally, I consider any code that relies on parsing stack traces
> > > > highly bogus.
> > >
> > > I second that.  Since stack trace parsing is obviously somewhat
> > > VM-dependent it shouldn't be too hard to add a
> > > kaffe.util.StackTraceConverter or something for getting the
> > > information you're really interested in.  That or just revisit the
> > > "need" for stack trace parsing...
> >
> > Since two people have now commented on how using the stack trace is
> > bogus, I figure I could at least say what we were using it for. In
> > Eiffel, there's a great assertion construct called "old", which you can
> > use to compare the value of a variable to its value when the function
> > was entered. To give a trivial example, the pop() routine of a stack
> > class would have the following postcondition: size == old size - 1,
> > since pop removes one item from the stack.
> >
> > We wanted to implement this for Java. Of course these assertions get
> > stripped out at production compile time, and of course the code didn't
> > rely on stack traces for any of its normal function. The stack trace
> > plus the current thread plus the variable whose old value was being
> > stored made a sensible unique key for finding the variable again at the
> > end of the function. So, in Java, the pop() example would look something
> > like
> >
> > .. pop() {
> >     Debug.StoreInt( "size", size );
> >     // do the pop
> >     Debug.Postcondition(size - 1 == Debug.getInt( "size" ));
> > }
> >
> > Off-hand, I can't think of a thread-safe way of implementing this that
> > doesn't use stack traces and doesn't introduce extra local variables.
> > Since we didn't want to use a C pre-processor on our Java code,
> > introducing extra locals didn't seem like a good option. (We did have to
> > resort to a Java preprocessor to remove all code inside a Debug.*()
> > method call.)
> >
> > In general, knowing the stack trace programmatically is a great way to
> > do certain debugging tasks, and the fact that there's no stack trace
> > object that can be used to inspect it from running code is clearly an
> > oversight in the design of the exception objects, which are too deeply
> > embedded in the VM and don't provide a sufficient interface to Java code
> > for their functionality.


More information about the kaffe mailing list