--- old/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Fri May 30 13:40:19 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java Fri May 30 13:40:19 2014 @@ -785,11 +785,29 @@ if (innerClasses == null) { innerClasses = new ByteVector(); } - ++innerClassesCount; - innerClasses.putShort(name == null ? 0 : newClass(name)); - innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); - innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); - innerClasses.putShort(access); + // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the + // constant_pool table which represents a class or interface C that is + // not a package member must have exactly one corresponding entry in the + // classes array". To avoid duplicates we keep track in the intVal field + // of the Item of each CONSTANT_Class_info entry C whether an inner + // class entry has already been added for C (this field is unused for + // class entries, and changing its value does not change the hashcode + // and equality tests). If so we store the index of this inner class + // entry (plus one) in intVal. This hack allows duplicate detection in + // O(1) time. + Item nameItem = newClassItem(name); + if (nameItem.intVal == 0) { + ++innerClassesCount; + innerClasses.putShort(nameItem.index); + innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); + innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); + innerClasses.putShort(access); + nameItem.intVal = innerClassesCount; + } else { + // Compare the inner classes entry nameItem.intVal - 1 with the + // arguments of this method and throw an exception if there is a + // difference? + } } @Override --- old/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java Fri May 30 13:40:21 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java Fri May 30 13:40:21 2014 @@ -1455,16 +1455,20 @@ | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); } else { // if u and t are array types, but not with the same element - // type, merge(u,t)=java/lang/Object - v = OBJECT | cw.addType("java/lang/Object"); + // type, merge(u,t) = dim(u) - 1 | java/lang/Object + int vdim = ELEMENT_OF + (u & DIM); + v = vdim | OBJECT | cw.addType("java/lang/Object"); } } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { // if t is any other reference or array type, the merged type - // is Object, or min(dim(u), dim(t)) | java/lang/Object is u - // and t have different array dimensions - int tdim = t & DIM; - int udim = u & DIM; - v = (udim != tdim ? Math.min(tdim, udim) : 0) | OBJECT + // is min(udim, tdim) | java/lang/Object, where udim is the + // array dimension of u, minus 1 if u is an array type with a + // primitive element type (and similarly for tdim). + int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 + : ELEMENT_OF) + (t & DIM); + int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 + : ELEMENT_OF) + (u & DIM); + v = Math.min(tdim, udim) | OBJECT | cw.addType("java/lang/Object"); } else { // if t is any other type, merge(u,t)=TOP --- old/src/share/classes/jdk/internal/org/objectweb/asm/Item.java Fri May 30 13:40:22 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/Item.java Fri May 30 13:40:22 2014 @@ -237,9 +237,10 @@ this.strVal2 = strVal2; this.strVal3 = strVal3; switch (type) { + case ClassWriter.CLASS: + this.intVal = 0; // intVal of a class must be zero, see visitInnerClass case ClassWriter.UTF8: case ClassWriter.STR: - case ClassWriter.CLASS: case ClassWriter.MTYPE: case ClassWriter.TYPE_NORMAL: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); --- old/src/share/classes/jdk/internal/org/objectweb/asm/Label.java Fri May 30 13:40:24 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/Label.java Fri May 30 13:40:23 2014 @@ -502,7 +502,7 @@ void addToSubroutine(final long id, final int nbSubroutines) { if ((status & VISITED) == 0) { status |= VISITED; - srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1]; + srcAndRefPositions = new int[nbSubroutines / 32 + 1]; } srcAndRefPositions[(int) (id >>> 32)] |= (int) id; } --- old/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Fri May 30 13:40:25 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Fri May 30 13:40:25 2014 @@ -1430,6 +1430,14 @@ @Override public void visitMaxs(final int maxStack, final int maxLocals) { + if (resize) { + // replaces the temporary jump opcodes introduced by Label.resolve. + if (ClassReader.RESIZE) { + resizeInstructions(); + } else { + throw new RuntimeException("Method code too large!"); + } + } if (ClassReader.FRAMES && compute == FRAMES) { // completes the control flow graph with exception handler blocks Handler handler = firstHandler; @@ -1987,43 +1995,43 @@ stackMap.putByte(v); } } else { - StringBuffer buf = new StringBuffer(); + StringBuilder sb = new StringBuilder(); d >>= 28; while (d-- > 0) { - buf.append('['); + sb.append('['); } if ((t & Frame.BASE_KIND) == Frame.OBJECT) { - buf.append('L'); - buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); - buf.append(';'); + sb.append('L'); + sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); + sb.append(';'); } else { switch (t & 0xF) { case 1: - buf.append('I'); + sb.append('I'); break; case 2: - buf.append('F'); + sb.append('F'); break; case 3: - buf.append('D'); + sb.append('D'); break; case 9: - buf.append('Z'); + sb.append('Z'); break; case 10: - buf.append('B'); + sb.append('B'); break; case 11: - buf.append('C'); + sb.append('C'); break; case 12: - buf.append('S'); + sb.append('S'); break; default: - buf.append('J'); + sb.append('J'); } } - stackMap.putByte(7).putShort(cw.newClass(buf.toString())); + stackMap.putByte(7).putShort(cw.newClass(sb.toString())); } } } @@ -2051,14 +2059,6 @@ if (classReaderOffset != 0) { return 6 + classReaderLength; } - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - if (ClassReader.RESIZE) { - resizeInstructions(); - } else { - throw new RuntimeException("Method code too large!"); - } - } int size = 8; if (code.length > 0) { if (code.length > 65536) { @@ -2715,49 +2715,50 @@ } } - // recomputes the stack map frames - if (frameCount > 0) { - if (compute == FRAMES) { - frameCount = 0; - stackMap = null; - previousFrame = null; - frame = null; - Frame f = new Frame(); - f.owner = labels; - Type[] args = Type.getArgumentTypes(descriptor); - f.initInputFrame(cw, access, args, maxLocals); - visitFrame(f); - Label l = labels; - while (l != null) { - /* - * here we need the original label position. getNewOffset - * must therefore never have been called for this label. - */ - u = l.position - 3; - if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) { - getNewOffset(allIndexes, allSizes, l); - // TODO update offsets in UNINITIALIZED values - visitFrame(l.frame); - } - l = l.successor; - } - } else { + // updates the stack map frame labels + if (compute == FRAMES) { + Label l = labels; + while (l != null) { /* - * Resizing an existing stack map frame table is really hard. - * Not only the table must be parsed to update the offets, but - * new frames may be needed for jump instructions that were - * inserted by this method. And updating the offsets or - * inserting frames can change the format of the following - * frames, in case of packed frames. In practice the whole table - * must be recomputed. For this the frames are marked as - * potentially invalid. This will cause the whole class to be - * reread and rewritten with the COMPUTE_FRAMES option (see the - * ClassWriter.toByteArray method). This is not very efficient - * but is much easier and requires much less code than any other - * method I can think of. + * Detects the labels that are just after an IF instruction that + * has been resized with the IFNOT GOTO_W pattern. These labels + * are now the target of a jump instruction (the IFNOT + * instruction). Note that we need the original label position + * here. getNewOffset must therefore never have been called for + * this label. */ - cw.invalidFrames = true; + u = l.position - 3; + if (u >= 0 && resize[u]) { + l.status |= Label.TARGET; + } + getNewOffset(allIndexes, allSizes, l); + l = l.successor; } + // Update the offsets in the uninitialized types + for (i = 0; i < cw.typeTable.length; ++i) { + Item item = cw.typeTable[i]; + if (item != null && item.type == ClassWriter.TYPE_UNINIT) { + item.intVal = getNewOffset(allIndexes, allSizes, 0, + item.intVal); + } + } + // The stack map frames are not serialized yet, so we don't need + // to update them. They will be serialized in visitMaxs. + } else if (frameCount > 0) { + /* + * Resizing an existing stack map frame table is really hard. Not + * only the table must be parsed to update the offets, but new + * frames may be needed for jump instructions that were inserted by + * this method. And updating the offsets or inserting frames can + * change the format of the following frames, in case of packed + * frames. In practice the whole table must be recomputed. For this + * the frames are marked as potentially invalid. This will cause the + * whole class to be reread and rewritten with the COMPUTE_FRAMES + * option (see the ClassWriter.toByteArray method). This is not very + * efficient but is much easier and requires much less code than any + * other method I can think of. + */ + cw.invalidFrames = true; } // updates the exception handler block labels Handler h = firstHandler; --- old/src/share/classes/jdk/internal/org/objectweb/asm/Type.java Fri May 30 13:40:27 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/Type.java Fri May 30 13:40:26 2014 @@ -585,11 +585,11 @@ case DOUBLE: return "double"; case ARRAY: - StringBuffer b = new StringBuffer(getElementType().getClassName()); + StringBuilder sb = new StringBuilder(getElementType().getClassName()); for (int i = getDimensions(); i > 0; --i) { - b.append("[]"); + sb.append("[]"); } - return b.toString(); + return sb.toString(); case OBJECT: return new String(buf, off, len).replace('/', '.'); default: --- old/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Fri May 30 13:40:28 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Fri May 30 13:40:28 2014 @@ -1089,7 +1089,7 @@ @Deprecated public void invokestatic(final String owner, final String name, final String desc) { - if (api < Opcodes.ASM5) { + if (api >= Opcodes.ASM5) { invokestatic(owner, name, desc, false); return; } --- old/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java Fri May 30 13:40:29 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/commons/Method.java Fri May 30 13:40:29 2014 @@ -205,7 +205,7 @@ } String returnType = method.substring(0, space); String methodName = method.substring(space + 1, start - 1).trim(); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append('('); int p; do { @@ -229,7 +229,7 @@ return type; } - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); int index = 0; while ((index = type.indexOf("[]", index) + 1) > 0) { sb.append('['); --- old/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Fri May 30 13:40:31 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java Fri May 30 13:40:30 2014 @@ -147,17 +147,17 @@ } Type[] args = Type.getArgumentTypes(desc); - StringBuffer s = new StringBuffer("("); + StringBuilder sb = new StringBuilder("("); for (int i = 0; i < args.length; i++) { - s.append(mapDesc(args[i].getDescriptor())); + sb.append(mapDesc(args[i].getDescriptor())); } Type returnType = Type.getReturnType(desc); if (returnType == Type.VOID_TYPE) { - s.append(")V"); - return s.toString(); + sb.append(")V"); + return sb.toString(); } - s.append(')').append(mapDesc(returnType.getDescriptor())); - return s.toString(); + sb.append(')').append(mapDesc(returnType.getDescriptor())); + return sb.toString(); } public Object mapValue(Object value) { --- old/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Fri May 30 13:40:32 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java Fri May 30 13:40:32 2014 @@ -239,7 +239,9 @@ if (computeSVUID) { this.name = name; this.access = access; - this.interfaces = Arrays.copyOf(interfaces, interfaces.length); + this.interfaces = new String[interfaces.length]; + System.arraycopy(interfaces, 0, this.interfaces, 0, + interfaces.length); } super.visit(version, access, name, signature, superName, interfaces); --- old/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Fri May 30 13:40:34 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Fri May 30 13:40:33 2014 @@ -351,6 +351,7 @@ } @Override + @SuppressWarnings("serial") public AnnotationVisitor visitAnnotationDefault() { return new AnnotationNode(new ArrayList(0) { @Override --- old/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java Fri May 30 13:40:35 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/AnalyzerException.java Fri May 30 13:40:35 2014 @@ -66,6 +66,7 @@ * @author Bing Ran * @author Eric Bruneton */ +@SuppressWarnings("serial") public class AnalyzerException extends Exception { public final AbstractInsnNode node; --- old/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java Fri May 30 13:40:37 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/Frame.java Fri May 30 13:40:36 2014 @@ -754,14 +754,14 @@ */ @Override public String toString() { - StringBuffer b = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for (int i = 0; i < getLocals(); ++i) { - b.append(getLocal(i)); + sb.append(getLocal(i)); } - b.append(' '); + sb.append(' '); for (int i = 0; i < getStackSize(); ++i) { - b.append(getStack(i).toString()); + sb.append(getStack(i).toString()); } - return b.toString(); + return sb.toString(); } } --- old/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Fri May 30 13:40:38 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Fri May 30 13:40:38 2014 @@ -206,7 +206,6 @@ } text.add("import java.util.*;\n"); text.add("import jdk.internal.org.objectweb.asm.*;\n"); - text.add("import jdk.internal.org.objectweb.asm.attrs.*;\n"); text.add("public class " + simpleName + "Dump implements Opcodes {\n\n"); text.add("public static byte[] dump () throws Exception {\n\n"); text.add("ClassWriter cw = new ClassWriter(0);\n"); --- old/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Fri May 30 13:40:39 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java Fri May 30 13:40:39 2014 @@ -298,26 +298,26 @@ for (int j = 0; j < method.instructions.size(); ++j) { method.instructions.get(j).accept(mv); - StringBuffer s = new StringBuffer(); + StringBuilder sb = new StringBuilder(); Frame f = frames[j]; if (f == null) { - s.append('?'); + sb.append('?'); } else { for (int k = 0; k < f.getLocals(); ++k) { - s.append(getShortName(f.getLocal(k).toString())) + sb.append(getShortName(f.getLocal(k).toString())) .append(' '); } - s.append(" : "); + sb.append(" : "); for (int k = 0; k < f.getStackSize(); ++k) { - s.append(getShortName(f.getStack(k).toString())) + sb.append(getShortName(f.getStack(k).toString())) .append(' '); } } - while (s.length() < method.maxStack + method.maxLocals + 1) { - s.append(' '); + while (sb.length() < method.maxStack + method.maxLocals + 1) { + sb.append(' '); } pw.print(Integer.toString(j + 100000).substring(1)); - pw.print(" " + s + " : " + t.text.get(t.text.size() - 1)); + pw.print(" " + sb + " : " + t.text.get(t.text.size() - 1)); } for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { method.tryCatchBlocks.get(j).accept(mv); --- old/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Fri May 30 13:40:41 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Fri May 30 13:40:41 2014 @@ -443,7 +443,7 @@ } buf.append(tab); - appendAccess(access); + appendAccess(access & ~Opcodes.ACC_VOLATILE); if ((access & Opcodes.ACC_NATIVE) != 0) { buf.append("native "); } --- old/src/share/classes/jdk/internal/org/objectweb/asm/version.txt Fri May 30 13:40:42 2014 +++ new/src/share/classes/jdk/internal/org/objectweb/asm/version.txt Fri May 30 13:40:42 2014 @@ -1,12 +1,12 @@ Path: . -Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-03-12 +Working Copy Root Path: /hudson/jobs/objectweb-pull/workspace/asm-svn-2014-05-27 URL: file:///svnroot/asm/trunk/asm Repository Root: file:///svnroot/asm Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9 -Revision: 1721 +Revision: 1748 Node Kind: directory Schedule: normal Last Changed Author: ebruneton -Last Changed Rev: 1721 -Last Changed Date: 2014-03-02 17:25:35 +0100 (Sun, 02 Mar 2014) +Last Changed Rev: 1747 +Last Changed Date: 2014-05-24 10:22:13 +0200 (Sat, 24 May 2014)