Bug 29665 - Inconsistant stack height
Summary: Inconsistant stack height
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P1 normal (vote)
Target Milestone: ---   Edit
Assignee: Erik Hilsdale CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-01-16 15:18 EST by Robert Wenner CLA
Modified: 2003-04-24 16:13 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Wenner CLA 2003-01-16 15:18:00 EST
Using AspectJ1.1b4 running the following program crashes it with this message:
"Inconsistent stack height 0 != 2". While reducing my original program to the
minimum example below I had also stack height 0 != 1, but I guess that is
related, so I didn't reproduce it (mail me if this you need this, too).

mport java.lang.reflect.Method;

public class StackError {
	public static void main(String args[]) {}

	void assertTrue(String msg, boolean b) {}

	public void testEqualsNull() {
		StackError one = new StackError();
		StackError two = new StackError();
		assertTrue("equal", one.equals(two));	// does not work
		boolean yes = one.equals(two);			// works
	}
	
	public boolean equals(Object other) {
		return true;
	}
}

aspect EqualsContract {
	pointcut equalsCall(Object thisOne, Object otherOne):
		target(Object+) && 
 
	target(thisOne) &&
		call(public boolean equals(Object+)) &&
		args(otherOne) &&
		!within(EqualsContract);
	
	boolean around(Object thisOne, Object otherOne):
	equalsCall(thisOne, otherOne) {
		boolean result = proceed(thisOne, otherOne);
		Class cls = thisOne.getClass();
		String name = cls.getName();
		boolean hasHashCode = false;
		try {
			Method m = cls.getDeclaredMethod("hashCode", null);
			String lookFor = "public int " + name + ".hashCode()";
			hasHashCode = lookFor.equals(m.toString());
		}
		catch (NoSuchMethodException nsme) {}
		return result;
	}
}


The program does not crash if you comment out the line indicated with the "does
not work" comment. Note the line below that (comment "works") does work.
Comment 1 Jim Hugunin CLA 2003-01-16 18:37:25 EST
This looks like a bug in the implementation of around advice inlining 
(available for the first time in this release).  You should try compiling with 
-XnoInline to see if this works-around the bug.
Comment 2 Robert Wenner CLA 2003-01-16 19:05:16 EST
As Jim Hugunin suggested the problem does not occur if I use -xnoInline
Comment 3 Jim Hugunin CLA 2003-04-10 19:54:45 EDT
Erik, can you please move this to a P1 or P2 major bug to make sure we don't 
miss it for 1.1final?  Now that it's assigned to you I can't make that kind of 
change.
Comment 4 Jim Hugunin CLA 2003-04-22 18:03:01 EDT
This is now fixed in the current tree with a test in bugs/StackError.java.

The problem is that the body of the around method was being inlined into a 
location where the stack height was not zero.  This had a bad interaction with 
the exception handler in the around advice that will remove everything on the 
stack and replace it with the exception that was raised.

The simple fix was to switch to using the closure style of around advice 
whenever the around body has an exception handler and the join point is in 
stack (rather than frame) context.

A much better fix would be to add one more level of indirection by putting the 
around advice in a method to avoid these stack issues.  This will require 
significant bytecode work and since it is just a performance optimization, it 
is unlikely to happen until after 1.1.0.

Erik, please take a look at these fixes and if you're happy with them, mark 
the bug as fixed.
Comment 5 Erik Hilsdale CLA 2003-04-24 16:13:55 EDT
the fix is conservative and correct, exactly right for this stage of development.