diff --git a/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java b/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java index bb09e68697..0e71478170 100644 --- a/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java +++ b/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java @@ -13,14 +13,15 @@ package org.aspectj.runtime.reflect; -import java.util.Stack; - import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.reflect.SourceLocation; import org.aspectj.runtime.internal.AroundClosure; +import java.util.ArrayList; +import java.util.List; + class JoinPointImpl implements ProceedingJoinPoint { static class StaticPartImpl implements JoinPoint.StaticPart { String kind; @@ -137,48 +138,38 @@ public final String toLongString() { } // To proceed we need a closure to proceed on. Generated code - // will either be using arc or arcs but not both. arcs being non-null - // indicates it is in use (even if an empty stack) + // will either be using arc or arcs but not both. private AroundClosure arc = null; - private Stack arcs = null; + private final List arcs = new ArrayList<>(); + private int currentArcIndex = -1; public void set$AroundClosure(AroundClosure arc) { this.arc = arc; } - public void stack$AroundClosure(AroundClosure arc) { + public synchronized void stack$AroundClosure(AroundClosure arc) { // If input parameter arc is null this is the 'unlink' call from AroundClosure - if (arcs == null) { - arcs = new Stack<>(); - } - if (arc==null) { - this.arcs.pop(); - } else { - this.arcs.push(arc); + if (arc != null) { + this.arcs.add(arc); + currentArcIndex++; } - } + } - public Object proceed() throws Throwable { + public synchronized Object proceed() throws Throwable { // when called from a before advice, but be a no-op - if (arcs == null) { - if (arc == null) { - return null; - } else { - return arc.run(arc.getState()); - } + if (currentArcIndex < 0) { + return arc == null ? null : arc.run(arc.getState()); } else { - return arcs.peek().run(arcs.peek().getState()); + final AroundClosure ac = arcs.get(currentArcIndex--); + final Object result = ac.run(ac.getState()); + currentArcIndex++; + return result; } } - public Object proceed(Object[] adviceBindings) throws Throwable { + public synchronized Object proceed(Object[] adviceBindings) throws Throwable { // when called from a before advice, but be a no-op - AroundClosure ac = null; - if (arcs == null) { - ac = arc; - } else { - ac = arcs.peek(); - } + AroundClosure ac = currentArcIndex < 0 ? arc : arcs.get(currentArcIndex); if (ac == null) { return null; @@ -254,7 +245,10 @@ public Object proceed(Object[] adviceBindings) throws Throwable { // state[i] = adviceBindings[formalIndex]; // } // } - return ac.run(state); + currentArcIndex--; + final Object result = ac.run(state); + currentArcIndex++; + return result; } }