@Override public void nodeDispatch(String suffix, int divide, int start, int end) { MethodVisitor mv; mv = cw.visitMethod(ACC_PRIVATE, name() + suffix, signature(), null, null); mv.visitCode(); Label startLabel = new Label(); mv.visitLabel(startLabel); final int powerOfTwo = Integer.numberOfTrailingZeros(divide); int sStart = start >> powerOfTwo; int sEnd = end >> powerOfTwo; int left = end - (sEnd << powerOfTwo); if (left > 0) { sEnd++; } Label[] labels = newLabels(sEnd - sStart); Label defaultLabel = new Label(); mv.visitVarInsn(ILOAD, argIndex()); int sub = leafStart(); if (sub != 0) { AsmUtils.addIndex(mv, sub); mv.visitInsn(ISUB); } AsmUtils.addIndex(mv, powerOfTwo); mv.visitInsn(ISHR); mv.visitVarInsn(ISTORE, maxArgIndex() + 1); mv.visitVarInsn(ILOAD, maxArgIndex() + 1); mv.visitTableSwitchInsn(sStart, sEnd - 1, defaultLabel, labels); for (int i = sStart; i < sEnd; i++) { int estart = i << powerOfTwo; int eend = Math.min(end, (i + 1) << powerOfTwo); mv.visitLabel(labels[i - sStart]); if (i == start) { mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } loadArguments(mv); mv.visitMethodInsn( INVOKESPECIAL, classType, name() + (divide / maxMethodSize) + "n" + estart + "t" + eend, signature(), false); if (isVoid()) { if (i < (sEnd - 1)) { mv.visitJumpInsn(GOTO, defaultLabel); } } else { mv.visitInsn(ARETURN); } } mv.visitLabel(defaultLabel); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); if (isVoid()) { mv.visitInsn(RETURN); } else { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } Label endLabel = new Label(); mv.visitLabel(endLabel); appendDebugInfo(mv, startLabel, endLabel); mv.visitMaxs(6, 5); mv.visitEnd(); }
private static <T> void appendInit( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, CellSetter<T>[] setters, ClassWriter cw, String targetType, String classType, int maxSize) { MethodVisitor mv; // constructor { mv = cw.visitMethod( ACC_PUBLIC, "<init>", "(" + AsmUtils.toDeclaredLType(Instantiator.class) + AsmUtils.toDeclaredLType(DelayedCellSetter[].class) + AsmUtils.toDeclaredLType(CellSetter[].class) + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContext.class) + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class) + ")V", "(" + "L" + AsmUtils.toType(Instantiator.class) + "<L" + AsmUtils.toType(CsvMapperCellHandler.class) + "<L" + targetType + ";>;L" + targetType + ";>;" + "[L" + DELAYED_CELL_SETTER_TYPE + "<L" + targetType + ";*>;" + "[L" + CELL_SETTER_TYPE + "<L" + targetType + ";>;" + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + AsmUtils.toDeclaredLType(ParsingContext.class) + "L" + AsmUtils.toType(FieldMapperErrorHandler.class) + "<L" + AsmUtils.toType(CsvColumnKey.class) + ";>;" + ")V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ARRAYLENGTH); mv.visitVarInsn(ALOAD, 5); mv.visitVarInsn(ALOAD, 6); mv.visitMethodInsn( INVOKESPECIAL, CSV_CELL_MAPPER_TYPE, "<init>", "(" + AsmUtils.toDeclaredLType(Instantiator.class) + AsmUtils.toDeclaredLType(CsvColumnKey[].class) + "I" + "I" + AsmUtils.toDeclaredLType(ParsingContext.class) + AsmUtils.toDeclaredLType(FieldMapperErrorHandler.class) + ")V", false); ShardingHelper.shard( delayedCellSetters.length, maxSize, new ShardingHelper.ShardCallBack() { @Override public void leafDispatch(String suffix, int start, int end) {} @Override public void nodeDispatch(String suffix, int divide, int start, int end) {} }); for (int i = 0; i < delayedCellSetters.length; i++) { if (delayedCellSetters[i] != null) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); AsmUtils.addIndex(mv, i); mv.visitInsn(AALOAD); mv.visitFieldInsn( PUTFIELD, classType, "delayedCellSetter" + i, AsmUtils.toDeclaredLType(DELAYED_CELL_SETTER_TYPE)); } } for (int i = 0; i < setters.length; i++) { if (setters[i] != null) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 3); AsmUtils.addIndex(mv, i); mv.visitInsn(AALOAD); mv.visitFieldInsn( PUTFIELD, classType, "setter" + i, AsmUtils.toDeclaredLType(CELL_SETTER_TYPE)); } } mv.visitInsn(RETURN); mv.visitMaxs(7, 7); mv.visitEnd(); } }