package com.foursquare.heapaudit; import org.objectweb.asm.Label; import org.objectweb.asm.MethodAdapter; import org.objectweb.asm.Opcodes; class HeapNEWARRAY extends HeapUtil { // Allocations by NEWARRAY are triggered via calls to visitIntInsn where the // top of the stack contains the number of elements in the array and returns // a reference to the newly allocated array object. static void before(boolean debug, boolean trace, MethodAdapter mv, int operand) { log(debug, trace, mv, "\tNEWARRAY.before(" + types[operand] + ")"); // STACK: [...|count] mv.visitInsn(Opcodes.DUP); // STACK: [...|count|count] } static void after(boolean debug, boolean trace, MethodAdapter mv, int operand) { log(debug, trace, mv, "\tNEWARRAY.after(" + types[operand] + ")"); Label cleanup = new Label(); Label finish = new Label(); if (HeapSettings.conditional) { // STACK: [...|count|obj] visitCheck(mv, cleanup); // STACK: [...|count|obj] } // STACK: [...|count|obj] mv.visitInsn(Opcodes.DUP_X1); // STACK: [...|obj|count|obj] mv.visitInsn(Opcodes.SWAP); // STACK: [...|obj|obj|count] mv.visitLdcInsn(types[operand]); // 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|obj] mv.visitInsn(Opcodes.SWAP); // STACK: [...|obj|count] mv.visitInsn(Opcodes.POP); // STACK: [...|obj] visitFinish(mv, finish); // STACK: [...|obj] } } // Mappings from primitive type opcode to friendly name. private static final String[] types = new String[] { "INVALID0", "INVALID1", "INVALID2", "INVALID3", "Z", "C", "F", "D", "B", "S", "I", "J" }; }