Stack size for @AllArgs fixed
This commit is contained in:
+38
-14
@@ -36,6 +36,7 @@ public class InterceptionInstrumenter {
|
||||
private static final Pattern ANYTHING = Pattern.compile(".*");
|
||||
private static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||
|
||||
//private final boolean dumpInstrumentedMethods = true;
|
||||
private final boolean dumpInstrumentedMethods = false;
|
||||
|
||||
private final Map<String, ClassMatcher> classPatterns = new LinkedHashMap<String, ClassMatcher>();
|
||||
@@ -181,7 +182,6 @@ public class InterceptionInstrumenter {
|
||||
Type.getInternalName(method.getDeclaringClass()),
|
||||
method.getName(),
|
||||
Type.getMethodDescriptor(method),
|
||||
method.getParameterTypes().length,
|
||||
thisParameterIndex,
|
||||
methodNameParameterIndex,
|
||||
methodDescParameterIndex,
|
||||
@@ -279,18 +279,22 @@ public class InterceptionInstrumenter {
|
||||
final List<MethodData> exitData = new ArrayList<MethodData>();
|
||||
final List<MethodData> enterData = new ArrayList<MethodData>();
|
||||
|
||||
int maxParamCount = 0;
|
||||
org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc);
|
||||
|
||||
int maxStackDepth = 0;
|
||||
for (MethodInstrumenter instrumenter : applicableInstrumenters) {
|
||||
for (MethodData methodData : instrumenter.getEnterData()) {
|
||||
if (maxParamCount < stackDepth(methodData)) {
|
||||
maxParamCount = stackDepth(methodData);
|
||||
int depth = stackDepth(methodData, methodBeingInstrumented);
|
||||
if (maxStackDepth < depth) {
|
||||
maxStackDepth = depth;
|
||||
}
|
||||
enterData.add(methodData);
|
||||
}
|
||||
|
||||
for (MethodData methodData : instrumenter.getExitData()) {
|
||||
if (maxParamCount < stackDepth(methodData)) {
|
||||
maxParamCount = stackDepth(methodData);
|
||||
int depth = stackDepth(methodData, methodBeingInstrumented);
|
||||
if (maxStackDepth < depth) {
|
||||
maxStackDepth = depth;
|
||||
}
|
||||
exitData.add(methodData);
|
||||
}
|
||||
@@ -304,7 +308,7 @@ public class InterceptionInstrumenter {
|
||||
|
||||
final boolean isConstructor = "<init>".equals(name);
|
||||
|
||||
final int finalMaxParamCount = maxParamCount;
|
||||
final int finalMaxStackDepth = maxStackDepth;
|
||||
return new MethodVisitorWithUniversalHandler(ASM4, mv) {
|
||||
|
||||
private InstructionAdapter ia = null;
|
||||
@@ -319,8 +323,7 @@ public class InterceptionInstrumenter {
|
||||
|
||||
@Override
|
||||
public void visitMaxs(int maxStack, int maxLocals) {
|
||||
int maxInstrumentedStack = finalMaxParamCount + 1; // +1 for returned value on the stack
|
||||
super.visitMaxs(Math.max(maxStack, maxInstrumentedStack), maxLocals);
|
||||
super.visitMaxs(Math.max(maxStack, finalMaxStackDepth), maxLocals);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -362,10 +365,16 @@ public class InterceptionInstrumenter {
|
||||
};
|
||||
}
|
||||
|
||||
private int stackDepth(MethodData methodData) {
|
||||
// array + index + value
|
||||
int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 3 : 0;
|
||||
return methodData.getParameterCount() + 1 /*receiver*/ + allArgsStackDepth;
|
||||
private int stackDepth(MethodData methodData, org.jetbrains.asm4.commons.Method methodBeingInstrumented) {
|
||||
org.jetbrains.asm4.commons.Method method = getAsmMethod(methodData);
|
||||
// array * 2 (dup) + index + value (may be long/double)
|
||||
int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 5 : 0;
|
||||
// receiver + return value must be kept on the stack OR exception, so we have to reserve at least 1
|
||||
int totalSize = 1 + Math.max(methodBeingInstrumented.getReturnType().getSize(), 1);
|
||||
for (Type type : method.getArgumentTypes()) {
|
||||
totalSize += type.getSize();
|
||||
}
|
||||
return totalSize + allArgsStackDepth + method.getReturnType().getSize();
|
||||
}
|
||||
|
||||
private void checkMultipleMatches(MethodInstrumenter instrumenter, String name, String desc) {
|
||||
@@ -398,6 +407,10 @@ public class InterceptionInstrumenter {
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
private static org.jetbrains.asm4.commons.Method getAsmMethod(MethodData methodData) {
|
||||
return new org.jetbrains.asm4.commons.Method(methodData.getName(), methodData.getDesc());
|
||||
}
|
||||
|
||||
private static void invokeMethod(
|
||||
int access,
|
||||
String instrumentedMethodName,
|
||||
@@ -410,7 +423,9 @@ public class InterceptionInstrumenter {
|
||||
ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc());
|
||||
ia.checkcast(field.getRuntimeType());
|
||||
|
||||
int parameterCount = methodData.getParameterCount();
|
||||
org.jetbrains.asm4.commons.Method asmMethod = getAsmMethod(methodData);
|
||||
|
||||
int parameterCount = asmMethod.getArgumentTypes().length;
|
||||
if (parameterCount > 0) {
|
||||
Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc);
|
||||
boolean isStatic = (access & ACC_STATIC) != 0;
|
||||
@@ -457,6 +472,15 @@ public class InterceptionInstrumenter {
|
||||
}
|
||||
}
|
||||
ia.invokevirtual(methodData.getDeclaringClass(), methodData.getName(), methodData.getDesc());
|
||||
Type type = asmMethod.getReturnType();
|
||||
if (type.getSort() != Type.VOID) {
|
||||
if (type.getSize() == 1) {
|
||||
ia.pop();
|
||||
}
|
||||
else {
|
||||
ia.pop2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyBoxingIfNeeded(InstructionAdapter ia, Type type) {
|
||||
|
||||
-1
@@ -18,7 +18,6 @@ package org.jetbrains.jet.preloading.instrumentation;
|
||||
|
||||
interface MethodData extends MemberData {
|
||||
FieldData getOwnerField();
|
||||
int getParameterCount();
|
||||
|
||||
// -1 for no @This parameter
|
||||
int getThisParameterIndex();
|
||||
|
||||
-8
@@ -18,7 +18,6 @@ package org.jetbrains.jet.preloading.instrumentation;
|
||||
|
||||
public class MethodDataImpl extends MemberDataImpl implements MethodData {
|
||||
private final FieldData ownerField;
|
||||
private final int parameterCount;
|
||||
private final int thisParameterIndex;
|
||||
private final int methodNameParameterIndex;
|
||||
private final int methodDescParameterIndex;
|
||||
@@ -29,7 +28,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData {
|
||||
String declaringClass,
|
||||
String name,
|
||||
String desc,
|
||||
int parameterCount,
|
||||
int thisParameterIndex,
|
||||
int methodNameParameterIndex,
|
||||
int methodDescParameterIndex,
|
||||
@@ -37,7 +35,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData {
|
||||
) {
|
||||
super(declaringClass, name, desc);
|
||||
this.ownerField = ownerField;
|
||||
this.parameterCount = parameterCount;
|
||||
this.thisParameterIndex = thisParameterIndex;
|
||||
this.methodNameParameterIndex = methodNameParameterIndex;
|
||||
this.methodDescParameterIndex = methodDescParameterIndex;
|
||||
@@ -49,11 +46,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData {
|
||||
return ownerField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterCount() {
|
||||
return parameterCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThisParameterIndex() {
|
||||
return thisParameterIndex;
|
||||
|
||||
Reference in New Issue
Block a user