Community
Participate
Working Groups
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.
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.
As Jim Hugunin suggested the problem does not occur if I use -xnoInline
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.
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.
the fix is conservative and correct, exactly right for this stage of development.