diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
index 89eb6d4b640..98de3231a86 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ByteVector.java
@@ -259,41 +259,68 @@ public class ByteVector {
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else {
- int byteLength = i;
- for (int j = i; j < charLength; ++j) {
- c = s.charAt(j);
- if (c >= '\001' && c <= '\177') {
- byteLength++;
- } else if (c > '\u07FF') {
- byteLength += 3;
- } else {
- byteLength += 2;
- }
- }
- if (byteLength > 65535) {
- throw new IllegalArgumentException();
- }
- data[length] = (byte) (byteLength >>> 8);
- data[length + 1] = (byte) byteLength;
- if (length + 2 + byteLength > data.length) {
- length = len;
- enlarge(2 + byteLength);
- data = this.data;
- }
- for (int j = i; j < charLength; ++j) {
- c = s.charAt(j);
- if (c >= '\001' && c <= '\177') {
- data[len++] = (byte) c;
- } else if (c > '\u07FF') {
- data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
- data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
- data[len++] = (byte) (0x80 | c & 0x3F);
- } else {
- data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
- data[len++] = (byte) (0x80 | c & 0x3F);
- }
- }
- break;
+ length = len;
+ return encodeUTF8(s, i, 65535);
+ }
+ }
+ length = len;
+ return this;
+ }
+
+ /**
+ * Puts an UTF8 string into this byte vector. The byte vector is
+ * automatically enlarged if necessary. The string length is encoded in two
+ * bytes before the encoded characters, if there is space for that (i.e. if
+ * this.length - i - 2 >= 0).
+ *
+ * @param s
+ * the String to encode.
+ * @param i
+ * the index of the first character to encode. The previous
+ * characters are supposed to have already been encoded, using
+ * only one byte per character.
+ * @param maxByteLength
+ * the maximum byte length of the encoded string, including the
+ * already encoded characters.
+ * @return this byte vector.
+ */
+ ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
+ int charLength = s.length();
+ int byteLength = i;
+ char c;
+ for (int j = i; j < charLength; ++j) {
+ c = s.charAt(j);
+ if (c >= '\001' && c <= '\177') {
+ byteLength++;
+ } else if (c > '\u07FF') {
+ byteLength += 3;
+ } else {
+ byteLength += 2;
+ }
+ }
+ if (byteLength > maxByteLength) {
+ throw new IllegalArgumentException();
+ }
+ int start = length - i - 2;
+ if (start >= 0) {
+ data[start] = (byte) (byteLength >>> 8);
+ data[start + 1] = (byte) byteLength;
+ }
+ if (length + byteLength - i > data.length) {
+ enlarge(byteLength - i);
+ }
+ int len = length;
+ for (int j = i; j < charLength; ++j) {
+ c = s.charAt(j);
+ if (c >= '\001' && c <= '\177') {
+ data[len++] = (byte) c;
+ } else if (c > '\u07FF') {
+ data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
+ data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
+ data[len++] = (byte) (0x80 | c & 0x3F);
+ } else {
+ data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
+ data[len++] = (byte) (0x80 | c & 0x3F);
}
}
length = len;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
index ab9dcd0dce4..66e8e7e3f11 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java
@@ -716,7 +716,8 @@ public class ClassWriter extends ClassVisitor {
sourceFile = newUTF8(file);
}
if (debug != null) {
- sourceDebug = new ByteVector().putUTF8(debug);
+ sourceDebug = new ByteVector().encodeUTF8(debug, 0,
+ Integer.MAX_VALUE);
}
}
@@ -857,7 +858,7 @@ public class ClassWriter extends ClassVisitor {
}
if (sourceDebug != null) {
++attributeCount;
- size += sourceDebug.length + 4;
+ size += sourceDebug.length + 6;
newUTF8("SourceDebugExtension");
}
if (enclosingMethodOwner != 0) {
@@ -946,9 +947,9 @@ public class ClassWriter extends ClassVisitor {
out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
}
if (sourceDebug != null) {
- int len = sourceDebug.length - 2;
+ int len = sourceDebug.length;
out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
- out.putByteArray(sourceDebug.data, 2, len);
+ out.putByteArray(sourceDebug.data, 0, len);
}
if (enclosingMethodOwner != 0) {
out.putShort(newUTF8("EnclosingMethod")).putInt(4);
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
index 78953ce4f87..e32a13af942 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/Frame.java
@@ -99,8 +99,8 @@ final class Frame {
* stack types. VALUE depends on KIND. For LOCAL types, it is an index in
* the input local variable types. For STACK types, it is a position
* relatively to the top of input frame stack. For BASE types, it is either
- * one of the constants defined in FrameVisitor, or for OBJECT and
- * UNINITIALIZED types, a tag and an index in the type table.
+ * one of the constants defined below, or for OBJECT and UNINITIALIZED
+ * types, a tag and an index in the type table.
*
* Output frames can contain types of any kind and with a positive or
* negative dimension (and even unassigned types, represented by 0 - which
@@ -537,7 +537,7 @@ final class Frame {
/**
* The types that are initialized in the basic block. A constructor
* invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
- * every occurrence of this type in the local variables and in the
+ * every occurence of this type in the local variables and in the
* operand stack. This cannot be done during the first phase of the
* algorithm since, during this phase, the local variables and the operand
* stack are not completely computed. It is therefore necessary to store the
@@ -1446,6 +1446,7 @@ final class Frame {
// if t is the NULL type, merge(u,t)=u, so there is no change
return false;
} else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
+ // if t and u have the same dimension and same base kind
if ((u & BASE_KIND) == OBJECT) {
// if t is also a reference type, and if u and t have the
// same dimension merge(u,t) = dim(t) | common parent of the
@@ -1458,9 +1459,13 @@ final class Frame {
v = OBJECT | cw.addType("java/lang/Object");
}
} else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
- // if t is any other reference or array type,
- // merge(u,t)=java/lang/Object
- v = OBJECT | cw.addType("java/lang/Object");
+ // 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
+ | cw.addType("java/lang/Object");
} else {
// if t is any other type, merge(u,t)=TOP
v = TOP;
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
index e914d45134e..b761babb138 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java
@@ -240,6 +240,7 @@ public class AnalyzerAdapter extends MethodVisitor {
locals.add(types[i].getInternalName());
}
}
+ maxLocals = locals.size();
}
@Override
@@ -519,12 +520,12 @@ public class AnalyzerAdapter extends MethodVisitor {
// ------------------------------------------------------------------------
private Object get(final int local) {
- maxLocals = Math.max(maxLocals, local);
+ maxLocals = Math.max(maxLocals, local + 1);
return local < locals.size() ? locals.get(local) : Opcodes.TOP;
}
private void set(final int local, final Object type) {
- maxLocals = Math.max(maxLocals, local);
+ maxLocals = Math.max(maxLocals, local + 1);
while (local >= locals.size()) {
locals.add(Opcodes.TOP);
}
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
index 2ba917cb6a3..7acfff532f5 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java
@@ -556,6 +556,8 @@ public class InsnList {
AbstractInsnNode prev;
+ AbstractInsnNode remove;
+
InsnListIterator(int index) {
if (index == size()) {
next = null;
@@ -577,12 +579,22 @@ public class InsnList {
AbstractInsnNode result = next;
prev = result;
next = result.next;
+ remove = result;
return result;
}
public void remove() {
- InsnList.this.remove(prev);
- prev = prev.prev;
+ if (remove != null) {
+ if (remove == next) {
+ next = next.next;
+ } else {
+ prev = prev.prev;
+ }
+ InsnList.this.remove(remove);
+ remove = null;
+ } else {
+ throw new IllegalStateException();
+ }
}
public boolean hasPrevious() {
@@ -593,6 +605,7 @@ public class InsnList {
AbstractInsnNode result = prev;
next = result;
prev = result.prev;
+ remove = result;
return result;
}
@@ -619,6 +632,7 @@ public class InsnList {
public void add(Object o) {
InsnList.this.insertBefore(next, (AbstractInsnNode) o);
prev = (AbstractInsnNode) o;
+ remove = null;
}
public void set(Object o) {
diff --git a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
index b6e2075de8b..dfd58a0fe1f 100644
--- a/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
+++ b/jdk/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java
@@ -351,7 +351,6 @@ public class MethodNode extends MethodVisitor {
}
@Override
- @SuppressWarnings("serial") // Anonymous class
public AnnotationVisitor visitAnnotationDefault() {
return new AnnotationNode(new ArrayList