package com.foursquare.heapaudit;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.Opcodes;
class HeapNEWINSTANCE extends HeapUtil {
// Allocations by java/lang/Class/newInstance()Ljava/lang/Object; are
// triggered via calls to visitMethodInsn(INVOKEVIRTUAL) where the top of
// the stack contains the name of the class and returns a reference to the
// newly allocated class object.
static void before(boolean debug,
boolean trace,
MethodAdapter mv) {
log(debug,
trace,
mv,
"\tNEWINSTANCE.before");
// STACK: [...|class]
mv.visitLdcInsn(-1);
// STACK: [...|class|count]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|count|class]
mv.visitInsn(Opcodes.DUP);
// STACK: [...|count|class|class]
}
static void after(boolean debug,
boolean trace,
MethodAdapter mv) {
log(debug,
trace,
mv,
"\tNEWINSTANCE.after");
Label cleanup = new Label();
Label finish = new Label();
if (HeapSettings.conditional) {
// STACK: [...|count|class|obj]
visitCheck(mv,
cleanup);
// STACK: [...|count|class|obj]
}
// STACK: [...|count|class|obj]
mv.visitInsn(Opcodes.DUP_X2);
// STACK: [...|obj|count|class|obj]
mv.visitInsn(Opcodes.DUP_X2);
// STACK: [...|obj|obj|count|class|obj]
mv.visitInsn(Opcodes.POP);
// STACK: [...|obj|obj|count|class]
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
"java/lang/Class",
"getName",
"()Ljava/lang/String;");
// STACK: [...|obj|obj|count|type]
mv.visitLdcInsn((long)-1);
// STACK: [...|obj|obj|count|type|size]
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/foursquare/heapaudit/HeapUtil",
"record",
"(Ljava/lang/Object;ILjava/lang/String;J)V");
// STACK: [...|obj]
if (HeapSettings.conditional) {
visitCleanup(mv,
cleanup,
finish);
// STACK: [...|count|class|obj]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|count|obj|class]
mv.visitInsn(Opcodes.POP);
// STACK: [...|count|obj]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|obj|count]
mv.visitInsn(Opcodes.POP);
// STACK: [...|obj]
visitFinish(mv,
finish);
// STACK: [...|obj]
}
}
static void beforeX(boolean debug,
boolean trace,
MethodAdapter mv) {
log(debug,
trace,
mv,
"\tNEWINSTANCE.beforeX");
// STACK: [...|class|count]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|count|class]
mv.visitInsn(Opcodes.DUP2);
// STACK: [...|count|class|count|class]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|count|class|class|count]
}
static void afterY(boolean debug,
boolean trace,
MethodAdapter mv) {
log(debug,
trace,
mv,
"\tNEWINSTANCE.afterY");
Label cleanup = new Label();
Label finish = new Label();
if (HeapSettings.conditional) {
// STACK: [...|count|class|obj]
visitCheck(mv,
cleanup);
// STACK: [...|count|class|obj]
}
// STACK: [...|count|class|obj]
mv.visitInsn(Opcodes.DUP_X2);
// STACK: [...|obj|count|class|obj]
mv.visitInsn(Opcodes.DUP_X2);
// STACK: [...|obj|obj|count|class|obj]
mv.visitInsn(Opcodes.POP);
// STACK: [...|obj|obj|count|class]
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
"java/lang/Class",
"getName",
"()Ljava/lang/String;");
// STACK: [...|obj|obj|count|type]
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/foursquare/heapaudit/HeapUtil",
"record",
"(Ljava/lang/Object;[ILjava/lang/String;)V");
// STACK: [...|obj]
if (HeapSettings.conditional) {
visitCleanup(mv,
cleanup,
finish);
// STACK: [...|count|class|obj]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|count|obj|class]
mv.visitInsn(Opcodes.POP);
// STACK: [...|count|obj]
mv.visitInsn(Opcodes.SWAP);
// STACK: [...|obj|count]
mv.visitInsn(Opcodes.POP);
// STACK: [...|obj]
visitFinish(mv,
finish);
// STACK: [...|obj]
}
}
}