private void dupStackElementBeforeSignatureArgs(final String sig) {
    final Label beginScopeLabel = new Label();
    final Label endScopeLabel = new Label();
    super.visitLabel(beginScopeLabel);

    Type[] argTypes = Type.getArgumentTypes(sig);
    int[] args = new int[argTypes.length];

    for (int i = argTypes.length - 1; i >= 0; --i) {
      args[i] = newLocal(argTypes[i], beginScopeLabel, endScopeLabel);
      super.visitVarInsn(argTypes[i].getOpcode(Opcodes.ISTORE), args[i]);
    }
    super.visitInsn(Opcodes.DUP);
    for (int i = 0; i < argTypes.length; ++i) {
      int op = argTypes[i].getOpcode(Opcodes.ILOAD);
      super.visitVarInsn(op, args[i]);
      if (op == Opcodes.ALOAD) {
        super.visitInsn(Opcodes.ACONST_NULL);
        super.visitVarInsn(Opcodes.ASTORE, args[i]);
      }
    }
    super.visitLabel(endScopeLabel);
  }
Reflection-based allocation (@see java.lang.reflect.Array#newInstance) is triggered with a
static method call (INVOKESTATIC), so we hook it here. Class initialization is triggered with a
constructor call (INVOKESPECIAL) so we hook that here too as a proxy for the new bytecode which
leaves an uninitialized object on the stack that we're not allowed to touch. {@link
java.lang.Object#clone} is also a call to INVOKESPECIAL, and is hooked here. {@link
java.lang.Class#newInstance} and {@link java.lang.reflect.Constructor#newInstance} are both
INVOKEVIRTUAL calls, so they are hooked here, as well.
src/main/java/com/google/monitoring/runtime/instrumentation/AllocationMethodAdapter.java