diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/AbstractBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/AbstractBuilder.java deleted file mode 100644 index be5727f257d..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/AbstractBuilder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Base builder. - * - * @param the type of the symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of this builder - */ -public class AbstractBuilder> { - /** - * The helper to build the constant pool. - */ - protected final PoolHelper poolHelper; - - /** - * The helper to use to manipulate type descriptors. - */ - protected final TypeHelper typeHelper; - - /** - * Create a builder. - * - * @param poolHelper the helper to build the constant pool - * @param typeHelper the helper to use to manipulate type descriptors - */ - AbstractBuilder(PoolHelper poolHelper, TypeHelper typeHelper) { - this.poolHelper = poolHelper; - this.typeHelper = typeHelper; - } - - @SuppressWarnings("unchecked") - D thisBuilder() { - return (D) this; - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/AnnotationsBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/AnnotationsBuilder.java deleted file mode 100644 index 2df226bc508..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/AnnotationsBuilder.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.function.Consumer; -import java.util.function.ToIntBiFunction; - -public class AnnotationsBuilder extends AbstractBuilder> { - - GrowableByteBuffer annoAttribute; - int nannos; - - AnnotationsBuilder(PoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - this.annoAttribute = new GrowableByteBuffer(); - annoAttribute.writeChar(0); - } - - public enum Kind { - RUNTIME_VISIBLE, - RUNTIME_INVISIBLE; - } - - enum Tag { - B('B'), - C('C'), - D('D'), - F('F'), - I('I'), - J('J'), - S('S'), - Z('Z'), - STRING('s'), - ENUM('e'), - CLASS('c'), - ANNO('@'), - ARRAY('['); - - char tagChar; - - Tag(char tagChar) { - this.tagChar = tagChar; - } - } - - AnnotationsBuilder withAnnotation(T annoType, Consumer annotationBuilder) { - annoAttribute.writeChar(poolHelper.putType(annoType)); - int offset = annoAttribute.offset; - annoAttribute.writeChar(0); - if (annotationBuilder != null) { - AnnotationElementBuilder _builder = new AnnotationElementBuilder(); - int nelems = _builder.withElements(annotationBuilder); - patchCharAt(offset, nelems); - } - nannos++; - return this; - } - - byte[] build() { - patchCharAt(0, nannos); - return annoAttribute.bytes(); - } - - private void patchCharAt(int offset, int newChar) { - int prevOffset = annoAttribute.offset; - try { - annoAttribute.offset = offset; - annoAttribute.writeChar(newChar); - } finally { - annoAttribute.offset = prevOffset; - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - static Consumer NO_BUILDER = - new Consumer() { - @Override - public void accept(Object o) { - //do nothing - } - }; - - public class AnnotationElementBuilder { - - int nelems; - - public AnnotationElementBuilder withString(String name, String s) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writeStringValue(s); - return this; - } - - private void writeStringValue(String s) { - annoAttribute.writeByte(Tag.STRING.tagChar); - annoAttribute.writeChar(poolHelper.putUtf8(s)); - nelems++; - } - - public AnnotationElementBuilder withClass(String name, T s) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writeClassValue(s); - return this; - } - - private void writeClassValue(T s) { - annoAttribute.writeByte(Tag.CLASS.tagChar); - annoAttribute.writeChar(poolHelper.putType(s)); - nelems++; - } - - public AnnotationElementBuilder withEnum(String name, T enumType, int constant) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writeEnumValue(enumType, constant); - return this; - } - - private void writeEnumValue(T enumType, int constant) { - annoAttribute.writeByte(Tag.ENUM.tagChar); - annoAttribute.writeChar(poolHelper.putType(enumType)); - annoAttribute.writeChar(constant); - nelems++; - } - - public AnnotationElementBuilder withAnnotation(String name, T annoType, Consumer annotationBuilder) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writeAnnotationValue(annoType, annotationBuilder); - return this; - } - - private void writeAnnotationValue(T annoType, Consumer annotationBuilder) { - annoAttribute.writeByte(Tag.ANNO.tagChar); - annoAttribute.writeChar(poolHelper.putType(annoType)); - int offset = annoAttribute.offset; - annoAttribute.writeChar(0); - int nelems = withNestedElements(annotationBuilder); - patchCharAt(offset, nelems); - this.nelems++; - } - - public AnnotationElementBuilder withPrimitive(String name, char c) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.C, (int)c, PoolHelper::putInt); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, short s) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.S, (int)s, PoolHelper::putInt); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, byte b) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.B, (int)b, PoolHelper::putInt); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, int i) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.I, i, PoolHelper::putInt); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, float f) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.F, f, PoolHelper::putFloat); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, long l) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.J, l, PoolHelper::putLong); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, double d) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.D, d, PoolHelper::putDouble); - return this; - } - - public AnnotationElementBuilder withPrimitive(String name, boolean b) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - writePrimitiveValue(Tag.Z, b ? 1 : 0, PoolHelper::putInt); - return this; - } - - private void writePrimitiveValue(Tag tag, Z value, ToIntBiFunction, Z> poolFunc) { - annoAttribute.writeByte(tag.tagChar); - annoAttribute.writeChar(poolFunc.applyAsInt(poolHelper, value)); - nelems++; - } - - AnnotationElementBuilder withStrings(String name, String... ss) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(ss.length); - for (String s : ss) { - writeStringValue(s); - } - return this; - } - - @SuppressWarnings("unchecked") - AnnotationElementBuilder withClasses(String name, T... cc) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(cc.length); - for (T c : cc) { - writeClassValue(c); - } - return this; - } - - AnnotationElementBuilder withEnums(String name, T enumType, int... constants) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(constants.length); - for (int c : constants) { - writeEnumValue(enumType, c); - } - return this; - } - - @SuppressWarnings("unchecked") - public AnnotationElementBuilder withAnnotations(String name, T annoType, Consumer... annotationBuilders) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(annotationBuilders.length); - for (Consumer annotationBuilder : annotationBuilders) { - writeAnnotationValue(annoType, annotationBuilder); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, char... cc) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(cc.length); - for (char c : cc) { - writePrimitiveValue(Tag.C, (int)c, PoolHelper::putInt); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, short... ss) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(ss.length); - for (short s : ss) { - writePrimitiveValue(Tag.S, (int)s, PoolHelper::putInt); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, byte... bb) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(bb.length); - for (byte b : bb) { - writePrimitiveValue(Tag.B, (int)b, PoolHelper::putInt); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, int... ii) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(ii.length); - for (int i : ii) { - writePrimitiveValue(Tag.I, i, PoolHelper::putInt); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, float... ff) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(ff.length); - for (float f : ff) { - writePrimitiveValue(Tag.F, f, PoolHelper::putFloat); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, long... ll) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(ll.length); - for (long l : ll) { - writePrimitiveValue(Tag.J, l, PoolHelper::putLong); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, double... dd) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(dd.length); - for (double d : dd) { - writePrimitiveValue(Tag.D, d, PoolHelper::putDouble); - } - return this; - } - - public AnnotationElementBuilder withPrimitives(String name, boolean... bb) { - annoAttribute.writeChar(poolHelper.putUtf8(name)); - annoAttribute.writeChar(bb.length); - for (boolean b : bb) { - writePrimitiveValue(Tag.Z, b ? 1 : 0, PoolHelper::putInt); - } - return this; - } - - int withNestedElements(Consumer annotationBuilder) { - return withElements(new AnnotationElementBuilder(), annotationBuilder); - } - - int withElements(Consumer annotationBuilder) { - return withElements(this, annotationBuilder); - } - - private int withElements(AnnotationElementBuilder builder, Consumer annotationBuilder) { - annotationBuilder.accept(builder); - return builder.nelems; - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/AttributeBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/AttributeBuilder.java deleted file mode 100644 index f2c423ca1f5..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/AttributeBuilder.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Base builder for attribute containing class file entities. - * - * @param the type of the symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of this builder - */ - public class AttributeBuilder> - extends AbstractBuilder { - - /** - * The number of attributes. - */ - protected int nattrs; - - /** - * The attributes represented as bytes. - */ - protected GrowableByteBuffer attributes = new GrowableByteBuffer(); - - /** - * Create an attribute builder. - * - * @param poolHelper the helper to build the constant pool - * @param typeHelper the helper to use to manipulate type descriptors - */ - public AttributeBuilder(PoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - } - - /** - * Add a class file Attribute. Defined as: - *
-     * {@code   attribute_info {
-     *     u2 attribute_name_index;
-     *     u4 attribute_length;
-     *     u1 info[attribute_length];
-     *   }}
-     * 
- * - * @param name the attribute name - * @param bytes the bytes of the attribute info - * @return this builder, for chained calls - */ - public D withAttribute(CharSequence name, byte[] bytes) { - attributes.writeChar(poolHelper.putUtf8(name)); - attributes.writeInt(bytes.length); - attributes.writeBytes(bytes); - nattrs++; - return thisBuilder(); - } - - /** - * Add a class file Attribute, using a writer. Defined as: - *
-     * {@code   attribute_info {
-     *     u2 attribute_name_index;
-     *     u4 attribute_length;
-     *     u1 info[attribute_length];
-     *   }}
-     * 
- * - * @param the type of the object representing the attribute - * @param name the attribute name - * @param attr the representation of the attribute - * @param attrWriter the writer which transform the attribute representation into bytes - * @return this builder, for chained calls - */ - public D withAttribute(CharSequence name, Z attr, AttributeWriter attrWriter) { - attributes.writeChar(poolHelper.putUtf8(name)); - int offset = attributes.offset; - attributes.writeInt(0); - attrWriter.write(attr, poolHelper, attributes); - int len = attributes.offset - offset - 4; - attributes.withOffset(offset, buf -> buf.writeInt(len)); - nattrs++; - return thisBuilder(); - } - - /** - * Writer for transforming attribute representations to bytes - * - * @param the type of symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of the object representing the attribute - */ - public interface AttributeWriter { - - /** - * Write an attribute representation into a byte buffer. - * - * @param attr the representation of the attribute - * @param poolHelper the constant pool helper - * @param buf the buffer to collect the bytes - */ - void write(A attr, PoolHelper poolHelper, GrowableByteBuffer buf); - } - - /** - * Add a source file attribute. - * - * @param sourceFile name of the source file - * @return this builder, for chained calls - */ - public D withSourceFile(String sourceFile) { - GrowableByteBuffer a = new GrowableByteBuffer(); - a.writeChar(poolHelper.putUtf8(sourceFile)); - return withAttribute("SourceFile", a.bytes()); - } - - /** - * Add a linenumber table attribute. - * - * @param pcln pairs of start_pc and linenumber - * @return this builder, for chained calls - */ - public D withLineNumberTable(int... pcln) { - GrowableByteBuffer a = new GrowableByteBuffer(); - if (pcln.length % 2 != 0) { - throw new IllegalArgumentException("Unmatched start_pc/linenumber pair"); - } - a.writeChar(pcln.length / 2); - for (int v : pcln) { - a.writeChar(v); - } - return withAttribute("LineNumberTable", a.bytes()); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/BasicClassBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/BasicClassBuilder.java deleted file mode 100644 index 993a4abc518..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/BasicClassBuilder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -public class BasicClassBuilder extends ClassBuilder { - - public BasicClassBuilder(String thisClass, int majorVersion, int minorVersion) { - this(); - withMinorVersion(minorVersion); - withMajorVersion(majorVersion); - withThisClass(thisClass); - } - - public BasicClassBuilder() { - this(new BytePoolHelper<>(s->s, s->s), new BasicTypeHelper()); - } - - public BasicClassBuilder(BytePoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java b/src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java deleted file mode 100644 index e53204c8de6..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.Iterator; - -/** - * Helper to create and manipulate type descriptors, where type descriptors - * are represented as JVM type descriptor strings and symbols are represented - * as name strings - */ -public class BasicTypeHelper implements TypeHelper { - - @Override - public String elemtype(String s) { - if (!s.startsWith("[")) { - throw new IllegalStateException(); - } - return s.substring(1); - } - - @Override - public String arrayOf(String s) { - return "[" + s; - } - - @Override - public boolean isValue(String t) { - return t.charAt(0) == 'Q' && t.endsWith(";"); - } - - @Override - public String type(String s) { - return "L" + s + ";"; - } - - @Override - public String valueType(String s) { - return "Q" + s + ";"; - } - - @Override - public TypeTag tag(String s) { - switch (s.charAt(0)) { - case '[': - case 'Q': - case 'L': - return TypeTag.A; - case 'B': - case 'C': - case 'Z': - case 'S': - case 'I': - return TypeTag.I; - case 'F': - return TypeTag.F; - case 'J': - return TypeTag.J; - case 'D': - return TypeTag.D; - case 'V': - return TypeTag.V; - default: - if (s == nullType()) { - return TypeTag.A; - } - throw new IllegalStateException("Bad type: " + s); - } - } - - @Override - public String nullType() { - // Needed in TypedCodeBuilder; ACONST_NULL pushes a 'null' onto the stack, - // and stack maps handle null differently - return ""; - } - - @Override - public String commonSupertype(String t1, String t2) { - if (t1.equals(t2)) { - return t1; - } else { - try { - Class c1 = from(t1); - Class c2 = from(t2); - if (c1.isAssignableFrom(c2)) { - return t1; - } else if (c2.isAssignableFrom(c1)) { - return t2; - } else { - return "Ljava/lang/Object;"; - } - } catch (Exception e) { - return null; - } - } - } - - public Class from(String desc) throws ReflectiveOperationException { - if (desc.startsWith("[")) { - return Class.forName(desc.replaceAll("/", ".")); - } else { - return Class.forName(symbol(desc).replaceAll("/", ".")); - } - } - - @Override - public Iterator parameterTypes(String s) { - //TODO: gracefully non-method types - return new Iterator() { - int ch = 1; - - @Override - public boolean hasNext() { - return s.charAt(ch) != ')'; - } - - @Override - public String next() { - char curr = s.charAt(ch); - switch (curr) { - case 'C': - case 'B': - case 'S': - case 'I': - case 'J': - case 'F': - case 'D': - case 'Z': - ch++; - return String.valueOf(curr); - case '[': - ch++; - return "[" + next(); - case 'Q': - case 'L': - StringBuilder builder = new StringBuilder(); - while (curr != ';') { - builder.append(curr); - curr = s.charAt(++ch); - } - builder.append(';'); - ch++; - return builder.toString(); - default: - throw new AssertionError("cannot parse string: " + s); - } - } - }; - } - - @Override - public String symbolFrom(String s) { - return s; - } - - @Override - public String fromTag(TypeTag tag) { - return tag.name(); - } - - @Override - public String symbol(String type) { - if (type.startsWith("L") || type.startsWith("Q")) { - return type.substring(1, type.length() - 1); - } else { - return type; - } - } - - @Override - public String returnType(String s) { - return s.substring(s.indexOf(')') + 1, s.length()); - } - -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolBuilder.java deleted file mode 100644 index 9a499f6ca04..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolBuilder.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Low-level internal constant pool builder. - */ -class BytePoolBuilder implements PoolBuilder { - - GrowableByteBuffer pool = new GrowableByteBuffer(); - int currentIndex = 1; - - @Override - public int putClass(int utf8_idx) { - pool.writeByte(PoolTag.CLASS.tag); - pool.writeChar(utf8_idx); - return currentIndex++; - } - - @Override - public int putFieldRef(int owner_idx, int nameAndType_idx) { - return putMemberRef(PoolTag.FIELDREF, owner_idx, nameAndType_idx); - } - - @Override - public int putMethodRef(int owner_idx, int nameAndType_idx, boolean isInterface) { - return putMemberRef((isInterface ? PoolTag.INTERFACEMETHODREF : PoolTag.METHODREF), - owner_idx, nameAndType_idx); - } - - @Override - public int putMemberRef(PoolTag tag, int owner_idx, int nameAndType_idx) { - pool.writeByte(tag.tag); - pool.writeChar(owner_idx); - pool.writeChar(nameAndType_idx); - return currentIndex++; - } - - @Override - public int putInt(int i) { - pool.writeByte(PoolTag.INTEGER.tag); - pool.writeInt(i); - return currentIndex++; - } - - @Override - public int putFloat(float f) { - pool.writeByte(PoolTag.FLOAT.tag); - pool.writeFloat(f); - return currentIndex++; - } - - @Override - public int putLong(long l) { - pool.writeByte(PoolTag.LONG.tag); - pool.writeLong(l); - int inx = currentIndex; - currentIndex += 2; - return inx; - } - - @Override - public int putDouble(double d) { - pool.writeByte(PoolTag.DOUBLE.tag); - pool.writeDouble(d); - int inx = currentIndex; - currentIndex += 2; - return inx; - } - - @Override - public int putInvokeDynamic(int bsmIndex, int nameAndType_idx) { - pool.writeByte(PoolTag.INVOKEDYNAMIC.tag); - pool.writeChar(bsmIndex); - pool.writeChar(nameAndType_idx); - return currentIndex++; - } - - @Override - public int putConstantDynamic(int bsmIndex, int nameAndType_idx) { - pool.writeByte(PoolTag.CONSTANTDYNAMIC.tag); - pool.writeChar(bsmIndex); - pool.writeChar(nameAndType_idx); - return currentIndex++; - } - - @Override - public int putMethodType(int desc_idx) { - pool.writeByte(PoolTag.METHODTYPE.tag); - pool.writeChar(desc_idx); - return currentIndex++; - } - - @Override - public int putMethodHandle(int refKind, int ref_idx) { - pool.writeByte(PoolTag.METHODHANDLE.tag); - pool.writeByte(refKind); - pool.writeChar(ref_idx); - return currentIndex++; - } - - @Override - public int putString(int utf8_index) { - pool.writeByte(PoolTag.STRING.tag); - pool.writeChar(utf8_index); - return currentIndex++; - } - - @Override - public int putNameAndType(int name_idx, int type_idx) { - pool.writeByte(PoolTag.NAMEANDTYPE.tag); - pool.writeChar(name_idx); - pool.writeChar(type_idx); - return currentIndex++; - } - - @Override - public int putUtf8(CharSequence s) { - int charLength = s.length(); - if (charLength > 65535) { - throw new IllegalArgumentException(); - } - pool.writeByte(PoolTag.UTF8.tag); - // optimistic algorithm: instead of computing the byte length and then - // serializing the string (which requires two loops), we assume the byte - // length is equal to char length (which is the most frequent case), and - // we start serializing the string right away. During the serialization, - // if we find that this assumption is wrong, we continue with the - // general method. - pool.writeChar(charLength); - for (int i = 0; i < charLength; ++i) { - char c = s.charAt(i); - if (c >= '\001' && c <= '\177') { - pool.writeByte((byte) c); - } else { - encodeUTF8(s, i, 65535); - break; - } - } - return currentIndex++; - } - - /** - * 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. - */ - private void encodeUTF8(final CharSequence 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 byteLengthFinal = byteLength; - pool.withOffset(pool.offset - i - 2, buf -> buf.writeChar(byteLengthFinal)); - for (int j = i; j < charLength; ++j) { - c = s.charAt(j); - if (c >= '\001' && c <= '\177') { - pool.writeChar((byte) c); - } else if (c > '\u07FF') { - pool.writeChar((byte) (0xE0 | c >> 12 & 0xF)); - pool.writeChar((byte) (0x80 | c >> 6 & 0x3F)); - pool.writeChar((byte) (0x80 | c & 0x3F)); - } else { - pool.writeChar((byte) (0xC0 | c >> 6 & 0x1F)); - pool.writeChar((byte) (0x80 | c & 0x3F)); - } - } - } - - @Override - public int size() { - return currentIndex - 1; - } - - @Override - public byte[] representation() { - return pool.bytes(); - } - -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolHelper.java b/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolHelper.java deleted file mode 100644 index 7fdc481ef35..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/BytePoolHelper.java +++ /dev/null @@ -1,795 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandleInfo; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.ToIntBiFunction; - -/** - * A helper for building and tracking constant pools whose entries are - * represented as byte arrays. - * - * @param the type of the symbol representation - * @param the type of type descriptors representation - */ -public class BytePoolHelper implements PoolHelper { - - final BytePoolBuilder builder; - GrowableByteBuffer bsm_attr = new GrowableByteBuffer(); - //Map indicesMap = new HashMap<>(); - int currentBsmIndex = 0; - - KeyMap entries = new KeyMap<>(); - KeyMap bootstraps = new KeyMap<>(); - PoolKey key = new PoolKey(); - BsmKey bsmKey = new BsmKey(); - - Function symbolToString; - Function typeToString; - - public BytePoolHelper(Function symbolToString, Function typeToString) { - this(new BytePoolBuilder(), symbolToString, typeToString); - } - - BytePoolHelper(BytePoolBuilder builder, Function symbolToString, Function typeToString) { - this.builder = builder; - this.symbolToString = symbolToString; - this.typeToString = typeToString; - } - - public static BytePoolHelper immutable(Consumer> cpBuild, - Function symbolToString, Function typeToString) { - return new ImmutableBytePoolHelper<>(cpBuild, symbolToString, typeToString); - } - - static class KeyMap> { - - @SuppressWarnings("unchecked") - K[] table = (K[])new AbstractKey[0x10]; - int nelems; - - public void enter(K e) { - if (nelems * 3 >= (table.length - 1) * 2) - dble(); - int hash = getIndex(e); - K old = table[hash]; - if (old == null) { - nelems++; - } - e.next = old; - table[hash] = e; - } - - protected K lookup(K other) { - K e = table[getIndex(other)]; - while (e != null && !e.equals(other)) - e = e.next; - return e; - } - - /** - * Look for slot in the table. - * We use open addressing with double hashing. - */ - int getIndex(K e) { - int hashMask = table.length - 1; - int h = e.hashCode(); - int i = h & hashMask; - // The expression below is always odd, so it is guaranteed - // to be mutually prime with table.length, a power of 2. - int x = hashMask - ((h + (h >> 16)) << 1); - for (; ; ) { - K e2 = table[i]; - if (e2 == null) - return i; - else if (e.hash == e2.hash) - return i; - i = (i + x) & hashMask; - } - } - - @SuppressWarnings("unchecked") - private void dble() { - K[] oldtable = table; - table = (K[])new AbstractKey[oldtable.length * 2]; - int n = 0; - for (int i = oldtable.length; --i >= 0; ) { - K e = oldtable[i]; - if (e != null) { - table[getIndex(e)] = e; - n++; - } - } - // We don't need to update nelems for shared inherited scopes, - // since that gets handled by leave(). - nelems = n; - } - } - - public static abstract class AbstractKey> { - int hash; - int index = -1; - K next; - - abstract K dup(); - - @Override - public abstract boolean equals(Object o); - - @Override - public int hashCode() { - return hash; - } - - void at(int index) { - this.index = index; - } - } - - public static class PoolKey extends AbstractKey { - PoolTag tag; - Object o1; - Object o2; - Object o3; - Object o4; - int size = -1; - - void setUtf8(CharSequence s) { - tag = PoolTag.UTF8; - o1 = s; - size = 1; - hash = tag.tag | (s.hashCode() << 1); - } - - void setClass(String clazz) { - tag = PoolTag.CLASS; - o1 = clazz; - size = 1; - hash = tag.tag | (clazz.hashCode() << 1); - } - - void setNameAndType(CharSequence name, String type) { - tag = PoolTag.NAMEANDTYPE; - o1 = name; - o2 = type; - size = 2; - hash = tag.tag | ((name.hashCode() | type.hashCode()) << 1); - } - - void setMemberRef(PoolTag poolTag, String owner, CharSequence name, String type) { - tag = poolTag; - o1 = owner; - o2 = name; - o3 = type; - size = 3; - hash = tag.tag | ((owner.hashCode() | name.hashCode() | type.hashCode()) << 1); - } - - void setInvokeDynamic(int bsmIndex, CharSequence name, String type) { - tag = PoolTag.INVOKEDYNAMIC; - o1 = bsmIndex; - o2 = name; - o3 = type; - size = 3; - hash = tag.tag | ((bsmIndex | name.hashCode() | type.hashCode()) << 1); - } - - void setConstantDynamic(int bsmIndex, CharSequence name, String type) { - tag = PoolTag.INVOKEDYNAMIC; - o1 = bsmIndex; - o2 = name; - o3 = type; - size = 3; - hash = tag.tag | ((bsmIndex | name.hashCode() | type.hashCode()) << 1); - } - - void setString(String s) { - tag = PoolTag.STRING; - o1 = s; - size = 1; - hash = tag.tag | (s.hashCode() << 1); - } - - void setInteger(Integer i) { - tag = PoolTag.INTEGER; - o1 = i; - size = 1; - hash = tag.tag | (i.hashCode() << 1); - } - - void setFloat(Float f) { - tag = PoolTag.FLOAT; - o1 = f; - size = 1; - hash = tag.tag | (f.hashCode() << 1); - } - - void setLong(Long l) { - tag = PoolTag.LONG; - o1 = l; - size = 1; - hash = tag.tag | (l.hashCode() << 1); - } - - void setDouble(Double d) { - tag = PoolTag.DOUBLE; - o1 = d; - size = 1; - hash = tag.tag | (d.hashCode() << 1); - } - - void setMethodType(String type) { - tag = PoolTag.METHODTYPE; - o1 = type; - size = 1; - hash = tag.tag | (type.hashCode() << 1); - } - - void setMethodType(MethodType mt) { - tag = PoolTag.METHODTYPE; - o1 = mt; - size = 1; - hash = tag.tag | (mt.hashCode() << 1); - } - - void setMethodHandle(int bsmKind, String owner, CharSequence name, String type) { - tag = PoolTag.METHODHANDLE; - o1 = bsmKind; - o2 = owner; - o3 = name; - o4 = type; - size = 4; - hash = tag.tag | (bsmKind | owner.hashCode() | name.hashCode() | type.hashCode() << 1); - } - - void setMethodHandle(MethodHandle mh) { - tag = PoolTag.METHODHANDLE; - o1 = mh; - size = 1; - hash = tag.tag | (mh.hashCode() << 1); - } - - @Override - public boolean equals(Object obj) { - PoolKey that = (PoolKey) obj; - if (tag != that.tag) return false; - switch (size) { - case 1: - if (!o1.equals(that.o1)) { - return false; - } - break; - case 2: - if (!o2.equals(that.o2) || !o1.equals(that.o1)) { - return false; - } - break; - case 3: - if (!o3.equals(that.o3) || !o2.equals(that.o2) || !o1.equals(that.o1)) { - return false; - } - break; - case 4: - if (!o4.equals(that.o4) || !o3.equals(that.o3) || !o2.equals(that.o2) || !o1.equals(that.o1)) { - return false; - } - break; - } - return true; - } - - @Override - PoolKey dup() { - PoolKey poolKey = new PoolKey(); - poolKey.tag = tag; - poolKey.size = size; - poolKey.hash = hash; - poolKey.o1 = o1; - poolKey.o2 = o2; - poolKey.o3 = o3; - poolKey.o4 = o4; - return poolKey; - } - } - - static class BsmKey extends AbstractKey { - String bsmClass; - CharSequence bsmName; - String bsmType; - List bsmArgs; - - void set(String bsmClass, CharSequence bsmName, String bsmType, List bsmArgs) { - this.bsmClass = bsmClass; - this.bsmName = bsmName; - this.bsmType = bsmType; - this.bsmArgs = bsmArgs; - hash = bsmClass.hashCode() | bsmName.hashCode() | bsmType.hashCode() | Objects.hash(bsmArgs); - } - - @Override - BsmKey dup() { - BsmKey bsmKey = new BsmKey(); - bsmKey.bsmClass = bsmClass; - bsmKey.bsmName = bsmName; - bsmKey.bsmType = bsmType; - bsmKey.bsmArgs = bsmArgs; - bsmKey.hash = hash; - return bsmKey; - } - - //TODO: missing hashCode() - - @Override - public boolean equals(Object obj) { - if (obj instanceof BsmKey) { - BsmKey that = (BsmKey)obj; - return Objects.equals(bsmClass, that.bsmClass) && - Objects.equals(bsmName, that.bsmName) && - Objects.equals(bsmType, that.bsmType) && - Objects.deepEquals(bsmArgs, that.bsmArgs); - } else { - return false; - } - } - } - - @Override - public int putClass(S symbol) { - return putClassInternal(symbolToString.apply(symbol)); - } - - @Override - public int putValueClass(S symbol) { - return putClassInternal("Q" + symbolToString.apply(symbol) + ";"); - } - - private int putClassInternal(String symbol) { - key.setClass(symbol); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int utf8_idx = putUtf8(symbol); - poolKey.at(builder.putClass(utf8_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putFieldRef(S owner, CharSequence name, T type) { - return putMemberRef(PoolTag.FIELDREF, owner, name, type); - } - - @Override - public int putMethodRef(S owner, CharSequence name, T type, boolean isInterface) { - return putMemberRef(isInterface ? PoolTag.INTERFACEMETHODREF : PoolTag.METHODREF, - owner, name, type); - } - - int putMemberRef(PoolTag poolTag, S owner, CharSequence name, T type) { - return putMemberRefInternal(poolTag, symbolToString.apply(owner), name, typeToString.apply(type)); - } - - int putMemberRefInternal(PoolTag poolTag, String owner, CharSequence name, String type) { - key.setMemberRef(poolTag, owner, name, type); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int owner_idx = putClassInternal(owner); - int nameAndType_idx = putNameAndType(name, type); - poolKey.at(builder.putMemberRef(poolTag, owner_idx, nameAndType_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putInt(int i) { - key.setInteger(i); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putInt(i)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putFloat(float f) { - key.setFloat(f); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putFloat(f)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putLong(long l) { - key.setLong(l); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putLong(l)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putDouble(double d) { - key.setDouble(d); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putDouble(d)); - entries.enter(poolKey); - } - return poolKey.index; - } - - - @Override - public int putInvokeDynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - return putInvokeDynamicInternal(invokedName, typeToString.apply(invokedType), symbolToString.apply(bsmClass), bsmName, typeToString.apply(bsmType), staticArgs); - } - - @Override - public int putConstantDynamic(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - return putConstantDynamicInternal(constName, typeToString.apply(constType), symbolToString.apply(bsmClass), bsmName, typeToString.apply(bsmType), staticArgs); - } - - private int putInvokeDynamicInternal(CharSequence invokedName, String invokedType, String bsmClass, CharSequence bsmName, String bsmType, Consumer> staticArgs) { - int bsmIndex = putBsmInternal(bsmClass, bsmName, bsmType, staticArgs); - key.setInvokeDynamic(bsmIndex, invokedName, invokedType); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int nameAndType_idx = putNameAndType(invokedName, invokedType); - poolKey.at(builder.putInvokeDynamic(bsmIndex, nameAndType_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - private int putConstantDynamicInternal(CharSequence constName, String constType, String bsmClass, CharSequence bsmName, String bsmType, Consumer> staticArgs) { - int bsmIndex = putBsmInternal(bsmClass, bsmName, bsmType, staticArgs); - key.setConstantDynamic(bsmIndex, constName, constType); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int nameAndType_idx = putNameAndType(constName, constType); - poolKey.at(builder.putConstantDynamic(bsmIndex, nameAndType_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - private int putBsmInternal(String bsmClass, CharSequence bsmName, String bsmType, Consumer> staticArgs) { - ByteStaticArgListBuilder staticArgsBuilder = new ByteStaticArgListBuilder(); - staticArgs.accept(staticArgsBuilder); - List static_idxs = staticArgsBuilder.indexes; - bsmKey.set(bsmClass, bsmName, bsmType, static_idxs); - BsmKey poolKey = bootstraps.lookup(bsmKey); - if (poolKey == null) { - poolKey = bsmKey.dup(); - int bsm_ref = putMethodHandleInternal(MethodHandleInfo.REF_invokeStatic, bsmClass, bsmName, bsmType, false); - poolKey.at(currentBsmIndex++); - bootstraps.enter(poolKey); - bsm_attr.writeChar(bsm_ref); - bsm_attr.writeChar(static_idxs.size()); - for (int i : static_idxs) { - bsm_attr.writeChar(i); - } - } - return poolKey.index; - } - //where - class ByteStaticArgListBuilder implements StaticArgListBuilder { - - List indexes = new ArrayList<>(); - - @Override - public ByteStaticArgListBuilder add(int i) { - indexes.add(putInt(i)); - return this; - } - @Override - public ByteStaticArgListBuilder add(float f) { - indexes.add(putFloat(f)); - return this; - } - @Override - public ByteStaticArgListBuilder add(long l) { - indexes.add(putLong(l)); - return this; - } - @Override - public ByteStaticArgListBuilder add(double d) { - indexes.add(putDouble(d)); - return this; - } - @Override - public ByteStaticArgListBuilder add(String s) { - indexes.add(putString(s)); - return this; - } - @Override - public StaticArgListBuilder add(int refKind, S owner, CharSequence name, T type) { - indexes.add(putMethodHandle(refKind, owner, name, type)); - return this; - } - @Override - public ByteStaticArgListBuilder add(Z z, ToIntBiFunction, Z> poolFunc) { - indexes.add(poolFunc.applyAsInt(BytePoolHelper.this, z)); - return this; - } - @Override - public ByteStaticArgListBuilder add(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - indexes.add(putConstantDynamic(constName, constType, bsmClass, bsmName, bsmType, staticArgs)); - return this; - } - } - - @Override - public int putMethodType(T s) { - return putMethodTypeInternal(typeToString.apply(s)); - } - - private int putMethodTypeInternal(String s) { - key.setMethodType(s); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int desc_idx = putUtf8(s); - poolKey.at(builder.putMethodType(desc_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putMethodHandle(int refKind, S owner, CharSequence name, T type) { - return putMethodHandle(refKind, owner, name, type, false); - } - - @Override - public int putMethodHandle(int refKind, S owner, CharSequence name, T type, boolean isInterface) { - return putMethodHandleInternal(refKind, symbolToString.apply(owner), name, typeToString.apply(type), isInterface); - } - - private int putMethodHandleInternal(int refKind, String owner, CharSequence name, String type, boolean isInterface) { - key.setMethodHandle(refKind, owner, name, type); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int ref_idx = putMemberRefInternal(fromKind(refKind, isInterface), owner, name, type); - poolKey.at(builder.putMethodHandle(refKind, ref_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putValue(Object v) { - if (v instanceof Class) { - return putClassInternal(((Class) v).getName().replaceAll("\\.", "/")); - } else if (v instanceof String) { - key.setString((String) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int utf8_index = putUtf8((String) v); - poolKey.at(builder.putString(utf8_index)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof Integer) { - key.setInteger((Integer) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putInt((Integer) v)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof Float) { - key.setFloat((Float) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putFloat((Float) v)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof Double) { - key.setDouble((Double) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putDouble((Double) v)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof Long) { - key.setLong((Long) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putLong((Long) v)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof MethodHandle) { - key.setMethodHandle((MethodHandle) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - MethodHandle mh = (MethodHandle) v; - Member member = memberFromHandle(mh); - // ## TODO - String type = null; // type from handle - int refKind = 0; // kind for member - PoolTag tag = null; // tag for member - int ref_idx = putMemberRefInternal(tag, - member.getDeclaringClass().getSimpleName(), - member.getName(), - type); - poolKey.at(builder.putMethodHandle(refKind, ref_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } else if (v instanceof MethodType) { - key.setMethodType((MethodType) v); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - MethodType mt = (MethodType) v; - int desc_idx = putUtf8(mt.toMethodDescriptorString()); - poolKey.at(builder.putMethodType(desc_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } else { - throw new UnsupportedOperationException("Unsupported object class: " + v.getClass().getName()); - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private Member memberFromHandle(MethodHandle mh) { - Class[] targets = new Class[]{Method.class, Field.class, Constructor.class}; - for (Class target : targets) { - try { - return MethodHandles.reflectAs(target, mh); - } catch (ClassCastException ex) { - //swallow - } - } - throw new UnsupportedOperationException("Cannot crack method handle!"); - } - - PoolTag fromKind(int bsmKind, boolean isInterface) { - switch (bsmKind) { - case 1: // REF_getField - case 2: // REF_getStatic - case 3: // REF_putField - case 4: // REF_putStatic - return PoolTag.FIELDREF; - case 5: // REF_invokeVirtual - case 7: // REF_invokeSpecial - case 8: // REF_newInvokeSpecial - return PoolTag.METHODREF; - case 6: // REF_invokeStatic - case 9: // REF_invokeInterface - return isInterface ? PoolTag.INTERFACEMETHODREF : PoolTag.METHODREF; - default: - throw new IllegalStateException(); - } - } - - @Override - public int putType(T s) { - return putUtf8(typeToString.apply(s)); - } - - @Override - public int putUtf8(CharSequence s) { - key.setUtf8(s); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(builder.putUtf8(s)); - entries.enter(poolKey); - } - return poolKey.index; - } - - @Override - public int putString(String s) { - key.setString(s); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int utf8_index = putUtf8(s); - poolKey.at(builder.putString(utf8_index)); - entries.enter(poolKey); - } - return poolKey.index; - } - - public int putNameAndType(CharSequence name, String type) { - key.setNameAndType(name, type); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int name_idx = putUtf8(name); - int type_idx = putUtf8(type); - poolKey.at(builder.putNameAndType(name_idx, type_idx)); - entries.enter(poolKey); - } - return poolKey.index; - } - - /** - * @return the count of constant pool indicies. - */ - @Override - public int size() { - return builder.size(); - } - - /** - * @return the size in bytes of all constant pool entries. - */ - @Override - public byte[] representation() { - return builder.representation(); - } - - > void addAttributes(ClassBuilder cb) { - if (currentBsmIndex > 0) { - GrowableByteBuffer bsmAttrBuf = new GrowableByteBuffer(); - bsmAttrBuf.writeChar(currentBsmIndex); - bsmAttrBuf.writeBytes(bsm_attr); - cb.withAttribute("BootstrapMethods", bsmAttrBuf.bytes()); - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/ClassBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/ClassBuilder.java deleted file mode 100644 index 6665b477f36..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/ClassBuilder.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.function.Consumer; - -/** - * Base class builder. The base of higher level class builders. - * - * @param the type of symbol representation - * @param the type of type descriptors representation - * @param the type of this builder - */ -public class ClassBuilder> - extends DeclBuilder { - - /** - * The helper to use to manipulate type descriptors. - */ - protected TypeHelper typeHelper; - - /** - * The symbol for the class being built. - */ - protected S thisClass; - - /** - * The super-interfaces of the class being built.. - */ - protected GrowableByteBuffer interfaces = new GrowableByteBuffer(); - - /** - * The fields of the class being built. - */ - protected GrowableByteBuffer fields = new GrowableByteBuffer(); - - /** - * The methods of the class being built. - */ - protected GrowableByteBuffer methods = new GrowableByteBuffer(); - - int majorVersion; - int minorVersion; - int flags; - int superclass; - int nmethods, nfields, ninterfaces; - - /** - * Create a class builder. - * - * @param poolHelper the helper to build the constant pool - * @param typeHelper the helper to use to manipulate type descriptors - */ - public ClassBuilder(BytePoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - this.typeHelper = typeHelper; - } - - /** - * Set the minor class file version. - * - * @param minorVersion the minor version number - * @return this builder, for chained calls - */ - public C withMinorVersion(int minorVersion) { - this.minorVersion = minorVersion; - return thisBuilder(); - } - - /** - * Set the major class file version. - * - * @param majorVersion the major version number - * @return this builder, for chained calls - */ - public C withMajorVersion(int majorVersion) { - this.majorVersion = majorVersion; - return thisBuilder(); - } - - /** - * Set the class symbol - * - * @param thisClass the class symbol - * @return this builder, for chained calls - */ - public C withThisClass(S thisClass) { - this.thisClass = thisClass; - return thisBuilder(); - } - - /** - * Set the class access flags - * - * @param flags an array of {@code Flag} - * @return this builder, for chained calls - */ - @Override - public C withFlags(Flag... flags) { - for (Flag f : flags) { - this.flags |= f.flag; - } - return thisBuilder(); - } - - /** - * Set the superclass - * - * @param sup the superclass symbol - * @return this builder, for chained calls - */ - public C withSuperclass(S sup) { - this.superclass = poolHelper.putClass(sup); - return thisBuilder(); - } - - /** - * Add a super interface. - * - * @param sup an interface symbol - * @return this builder, for chained calls - */ - public C withSuperinterface(S sup) { - this.interfaces.writeChar(poolHelper.putClass(sup)); - ninterfaces++; - return thisBuilder(); - } - - /** - * Add a field. - * - * @param name the name of the field - * @param type the type descriptor of the field - * @return this builder, for chained calls - */ - public final C withField(CharSequence name, T type) { - return withField(name, type, FB -> { - }); - } - - /** - * Add a field. - * - * @param name the name of the field - * @param type the type descriptor of the field - * @param fieldConfig access to the {@code FieldBuilder} to allow clients to - * adjust flags, annotations and bytecode attributes on the field declaration - * @return this builder, for chained calls - */ - public C withField(CharSequence name, T type, Consumer> fieldConfig) { - FieldBuilder F = new FieldBuilder<>(name, type, poolHelper, typeHelper); - fieldConfig.accept(F); - F.build(fields); - nfields++; - return thisBuilder(); - } - - /** - * Add a method - * - * @param name the name of the method - * @param type the type descriptor of the method - * @return this builder, for chained calls - */ - public final C withMethod(CharSequence name, T type) { - return withMethod(name, type, MB -> { - }); - } - - /** - * Add a method - * - * @param name the name of the method - * @param type the type descriptor of the method - * @param methodConfig access to the {@code MethodBuilder} to allow clients to - * adjust flags, annotations and bytecode attributes on the method declaration - * @return this builder, for chained calls - */ - public C withMethod(CharSequence name, T type, Consumer> methodConfig) { - MethodBuilder M = new MethodBuilder<>(thisClass, name, type, poolHelper, typeHelper); - methodConfig.accept(M); - M.build(methods); - nmethods++; - return thisBuilder(); - } - - /** - * Add a source file attribute. - * - * @param sourceFile name of the source file - * @return this builder, for chained calls - */ - public C withSourceFile(String sourceFile) { - GrowableByteBuffer a = new GrowableByteBuffer(); - a.writeChar(poolHelper.putUtf8(sourceFile)); - return withAttribute("SourceFile", a.bytes()); - } - - /** - * Build the constant pool into a byte array. - * - * @return a representation of this constant pool as a byte array - */ - @SuppressWarnings("unchecked") - public byte[] build() { - ((BytePoolHelper)poolHelper).addAttributes(this); - addAnnotations(); - int thisClassIdx = poolHelper.putClass(thisClass); - byte[] poolBytes = poolHelper.representation(); - GrowableByteBuffer buf = new GrowableByteBuffer(); - buf.writeInt(0xCAFEBABE); - buf.writeChar(minorVersion); - buf.writeChar(majorVersion); - buf.writeChar(poolHelper.size() + 1); - buf.writeBytes(poolBytes); - buf.writeChar(flags); - buf.writeChar(thisClassIdx); - buf.writeChar(superclass); - buf.writeChar(ninterfaces); - if (ninterfaces > 0) { - buf.writeBytes(interfaces); - } - buf.writeChar(nfields); - buf.writeBytes(fields); - buf.writeChar(nmethods); - buf.writeBytes(methods); - buf.writeChar(nattrs); - buf.writeBytes(attributes); - return buf.bytes(); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/CodeBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/CodeBuilder.java deleted file mode 100644 index 6a5b1f14e2f..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/CodeBuilder.java +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import jdk.experimental.bytecode.PoolHelper.StaticArgListBuilder; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.util.Iterator; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.ToIntFunction; - -/** - * Builder for class file code attributes. A code attribute is defined: - *
- * {@code
- * Code_attribute {
- *    u2 attribute_name_index;
- *    u4 attribute_length;
- *    u2 max_stack;
- *    u2 max_locals;
- *    u4 code_length;
- *    u1 code[code_length];
- *    u2 exception_table_length;
- *    {   u2 start_pc;
- *        u2 end_pc;
- *        u2 handler_pc;
- *        u2 catch_type;
- *    } exception_table[exception_table_length];
- *    u2 attributes_count;
- *    attribute_info attributes[attributes_count];
- * } }
- * 
- * - * @param the type of symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of this code builder - */ -public class CodeBuilder> extends AttributeBuilder { - - protected GrowableByteBuffer code = new GrowableByteBuffer(); - GrowableByteBuffer catchers = new GrowableByteBuffer(); - GrowableByteBuffer stackmaps = new GrowableByteBuffer(); - MethodBuilder methodBuilder; - int ncatchers; - int stacksize = -1; - int localsize = -1; - int nstackmaps = 0; - - public enum JumpMode { - NARROW, - WIDE; - } - - CodeBuilder(MethodBuilder methodBuilder) { - super(methodBuilder.poolHelper, methodBuilder.typeHelper); - this.methodBuilder = methodBuilder; - } - - public C getstatic(S owner, CharSequence name, T type) { - emitOp(Opcode.GETSTATIC, type); - code.writeChar(poolHelper.putFieldRef(owner, name, type)); - return thisBuilder(); - } - - public C putstatic(S owner, CharSequence name, T type) { - emitOp(Opcode.PUTSTATIC, type); - code.writeChar(poolHelper.putFieldRef(owner, name, type)); - return thisBuilder(); - } - - public C getfield(S owner, CharSequence name, T type) { - emitOp(Opcode.GETFIELD, type); - code.writeChar(poolHelper.putFieldRef(owner, name, type)); - return thisBuilder(); - } - - public C putfield(S owner, CharSequence name, T type) { - emitOp(Opcode.PUTFIELD, type); - code.writeChar(poolHelper.putFieldRef(owner, name, type)); - return thisBuilder(); - } - - public C withfield(S owner, CharSequence name, T type) { - emitOp(Opcode.WITHFIELD, type); - code.writeChar(poolHelper.putFieldRef(owner, name, type)); - return thisBuilder(); - } - - public C invokevirtual(S owner, CharSequence name, T type, boolean isInterface) { - emitOp(Opcode.INVOKEVIRTUAL, type); - code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface)); - return thisBuilder(); - } - - public C invokespecial(S owner, CharSequence name, T type, boolean isInterface) { - emitOp(Opcode.INVOKESPECIAL, type); - code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface)); - return thisBuilder(); - } - - public C invokestatic(S owner, CharSequence name, T type, boolean isInterface) { - emitOp(Opcode.INVOKESTATIC, type); - code.writeChar(poolHelper.putMethodRef(owner, name, type, isInterface)); - return thisBuilder(); - } - - public C invokeinterface(S owner, CharSequence name, T type) { - emitOp(Opcode.INVOKEINTERFACE, type); - code.writeChar(poolHelper.putMethodRef(owner, name, type, true)); - int nargs = 1; - Iterator it = typeHelper.parameterTypes(type); - while (it.hasNext()) { - nargs += typeHelper.tag(it.next()).width; - } - code.writeByte(nargs); - code.writeByte(0); - return thisBuilder(); - } - - public C invokedynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - emitOp(Opcode.INVOKEDYNAMIC, invokedType); - code.writeChar(poolHelper.putInvokeDynamic(invokedName, invokedType, bsmClass, bsmName, bsmType, staticArgs)); - code.writeChar(0); //padding - return thisBuilder(); - } - - public C new_(S clazz) { - emitOp(Opcode.NEW, clazz); - code.writeChar(poolHelper.putClass(clazz)); - return thisBuilder(); - } - - public C defaultvalue(S target) { - emitOp(Opcode.DEFAULTVALUE, target); - code.writeChar(poolHelper.putClass(target)); - return thisBuilder(); - } - - public C newarray(TypeTag tag) { - emitOp(Opcode.NEWARRAY, tag); - int newarraycode = tag.newarraycode; - if (newarraycode == -1) { - throw new IllegalStateException("Bad tag " + tag); - } - code.writeByte(newarraycode); - return thisBuilder(); - } - - public C anewarray(S array) { - emitOp(Opcode.ANEWARRAY, array); - code.writeChar(poolHelper.putClass(array)); - return thisBuilder(); - } - - public C anewvaluearray(S array) { - emitOp(Opcode.ANEWARRAY, array); - code.writeChar(poolHelper.putValueClass(array)); - return thisBuilder(); - } - - public C checkcast(S target) { - emitOp(Opcode.CHECKCAST); - code.writeChar(poolHelper.putClass(target)); - return thisBuilder(); - } - - public C checkvaluecast(S target) { - emitOp(Opcode.CHECKCAST); - code.writeChar(poolHelper.putValueClass(target)); - return thisBuilder(); - } - - public C instanceof_(S target) { - emitOp(Opcode.INSTANCEOF); - code.writeChar(poolHelper.putClass(target)); - return thisBuilder(); - } - - public C multianewarray(S array, byte dims) { - emitOp(Opcode.MULTIANEWARRAY, new Object[]{array, dims}); - code.writeChar(poolHelper.putClass(array)).writeByte(dims); - return thisBuilder(); - } - - public C ldc(int i) { - return ldc(pool -> pool.putInt(i), false); - } - - public C ldc(long l) { - return ldc(pool -> pool.putLong(l), true); - } - - public C ldc(float f) { - return ldc(pool -> pool.putFloat(f), false); - } - - public C ldc(double d) { - return ldc(pool -> pool.putDouble(d), true); - } - - public C ldc(String s) { - return ldc(pool -> pool.putString(s), false); - } - - public C ldc(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - boolean fat = typeHelper.tag(constType).width() == 2; - return ldc(pool -> pool.putConstantDynamic(constName, constType, bsmClass, bsmName, bsmType, staticArgs), fat); - } - - public C ldc(Z z, BiFunction, Z, Integer> poolFunc) { - return ldc(pool -> poolFunc.apply(pool, z), false); - } - - - protected C ldc(ToIntFunction> indexFunc, boolean fat) { - // @@@ This should probably be abstract - int index = indexFunc.applyAsInt(poolHelper); - return ldc(index, null, fat); - } - - protected final C ldc(int index, T type, boolean fat) { - if (fat) { - emitOp(Opcode.LDC2_W, type); - code.writeChar(index); - } else if (index > 63) { - emitOp(Opcode.LDC_W, type); - code.writeChar(index); - } else { - emitOp(Opcode.LDC, type); - code.writeByte(index); - } - return thisBuilder(); - } - - public C ldc(MethodHandle o) { - return ldc(o, false); - } - - public C ldc(MethodType o) { - return ldc(o, false); - } - - public C ldc(Object o) { - emitOp(Opcode.LDC, o); - code.writeByte(poolHelper.putValue(o)); - return thisBuilder(); - } - - public C ldc_w(Object o) { - emitOp(Opcode.LDC_W, o); - code.writeChar(poolHelper.putValue(o)); - return thisBuilder(); - } - - public C ldc2_w(Object o) { - emitOp(Opcode.LDC2_W, o); - code.writeChar(poolHelper.putValue(o)); - return thisBuilder(); - } - - private final C ldc(Object o, boolean fat) { - int idx = poolHelper.putValue(o); - if (fat) { - return ldc2_w(o); - } else if (idx > 63) { - return ldc_w(o); - } else { - return ldc(o); - } - } - - //other non-CP dependent opcodes - public C areturn() { - return emitOp(Opcode.ARETURN); - } - - public C ireturn() { - return emitOp(Opcode.IRETURN); - } - - public C freturn() { - return emitOp(Opcode.FRETURN); - } - - public C lreturn() { - return emitOp(Opcode.LRETURN); - } - - public C dreturn() { - return emitOp(Opcode.DRETURN); - } - - public C return_() { - return emitOp(Opcode.RETURN); - } - - protected C emitWideIfNeeded(Opcode opcode, int n) { - boolean wide = n > Byte.MAX_VALUE; - if (wide) { - wide(); - } - emitOp(opcode, n); - if (wide) { - code.writeChar(n); - } else { - code.writeByte(n); - } - return thisBuilder(); - } - - protected C emitWideIfNeeded(Opcode opcode, int n, int v) { - boolean wide = n > Byte.MAX_VALUE || v > Byte.MAX_VALUE; - if (wide) { - wide(); - } - emitOp(opcode, n); - if (wide) { - code.writeChar(n).writeChar(v); - } else { - code.writeByte(n).writeByte(v); - } - return thisBuilder(); - } - - public TypedBuilder typed(TypeTag typeTag) { - return typed(typeTag, _unused -> new TypedBuilder()); - } - - protected TB typed(TypeTag typeTag, Function typedBuilderFunc) { - emitOp(Opcode.TYPED); - code.writeChar(poolHelper.putType(typeHelper.fromTag(typeTag))); - return typedBuilderFunc.apply(typeTag); - } - - public class TypedBuilder { - public C aload_0() { - return CodeBuilder.this.aload_0(); - } - - public C aload_1() { - return CodeBuilder.this.aload_1(); - } - - public C aload_2() { - return CodeBuilder.this.aload_2(); - } - - public C aload_3() { - return CodeBuilder.this.aload_3(); - } - - public C aload(int n) { - return CodeBuilder.this.aload(n); - } - - public C astore_0() { - return CodeBuilder.this.astore_0(); - } - - public C astore_1() { - return CodeBuilder.this.astore_1(); - } - - public C astore_2() { - return CodeBuilder.this.astore_2(); - } - - public C astore_3() { - return CodeBuilder.this.astore_3(); - } - - public C astore(int n) { - return CodeBuilder.this.astore(n); - } - - public C aaload() { - return CodeBuilder.this.aaload(); - } - - public C aastore() { - return CodeBuilder.this.aastore(); - } - - public C areturn() { - return CodeBuilder.this.areturn(); - } - - public C anewarray(S s) { - return CodeBuilder.this.anewarray(s); - } - - public C anewvaluearray(S s) { - return CodeBuilder.this.anewvaluearray(s); - } - - public C aconst_null() { - return CodeBuilder.this.aconst_null(); - } - - public C if_acmpeq(short target) { - return CodeBuilder.this.if_acmpeq(target); - } - - public C if_acmpne(short target) { - return CodeBuilder.this.if_acmpeq(target); - } - } - - public C aload(int i) { - return emitWideIfNeeded(Opcode.ALOAD, i); - } - - public C iload(int i) { - return emitWideIfNeeded(Opcode.ILOAD, i); - } - - public C fload(int i) { - return emitWideIfNeeded(Opcode.FLOAD, i); - } - - public C lload(int i) { - return emitWideIfNeeded(Opcode.LLOAD, i); - } - - public C dload(int i) { - return emitWideIfNeeded(Opcode.DLOAD, i); - } - - public C aload_0() { - return emitOp(Opcode.ALOAD_0); - } - - public C iload_0() { - return emitOp(Opcode.ILOAD_0); - } - - public C fload_0() { - return emitOp(Opcode.FLOAD_0); - } - - public C lload_0() { - return emitOp(Opcode.LLOAD_0); - } - - public C dload_0() { - return emitOp(Opcode.DLOAD_0); - } - - public C aload_1() { - return emitOp(Opcode.ALOAD_1); - } - - public C iload_1() { - return emitOp(Opcode.ILOAD_1); - } - - public C fload_1() { - return emitOp(Opcode.FLOAD_1); - } - - public C lload_1() { - return emitOp(Opcode.LLOAD_1); - } - - public C dload_1() { - return emitOp(Opcode.DLOAD_1); - } - - public C aload_2() { - return emitOp(Opcode.ALOAD_2); - } - - public C iload_2() { - return emitOp(Opcode.ILOAD_2); - } - - public C fload_2() { - return emitOp(Opcode.FLOAD_2); - } - - public C lload_2() { - return emitOp(Opcode.LLOAD_2); - } - - public C dload_2() { - return emitOp(Opcode.DLOAD_2); - } - - public C aload_3() { - return emitOp(Opcode.ALOAD_3); - } - - public C iload_3() { - return emitOp(Opcode.ILOAD_3); - } - - public C fload_3() { - return emitOp(Opcode.FLOAD_3); - } - - public C lload_3() { - return emitOp(Opcode.LLOAD_3); - } - - public C dload_3() { - return emitOp(Opcode.DLOAD_3); - } - - public C astore(int i) { - return emitWideIfNeeded(Opcode.ASTORE, i); - } - - public C istore(int i) { - return emitWideIfNeeded(Opcode.ISTORE, i); - } - - public C fstore(int i) { - return emitWideIfNeeded(Opcode.FSTORE, i); - } - - public C lstore(int i) { - return emitWideIfNeeded(Opcode.LSTORE, i); - } - - public C dstore(int i) { - return emitWideIfNeeded(Opcode.DSTORE, i); - } - - public C astore_0() { - return emitOp(Opcode.ASTORE_0); - } - - public C istore_0() { - return emitOp(Opcode.ISTORE_0); - } - - public C fstore_0() { - return emitOp(Opcode.FSTORE_0); - } - - public C lstore_0() { - return emitOp(Opcode.LSTORE_0); - } - - public C dstore_0() { - return emitOp(Opcode.DSTORE_0); - } - - public C astore_1() { - return emitOp(Opcode.ASTORE_1); - } - - public C istore_1() { - return emitOp(Opcode.ISTORE_1); - } - - public C fstore_1() { - return emitOp(Opcode.FSTORE_1); - } - - public C lstore_1() { - return emitOp(Opcode.LSTORE_1); - } - - public C dstore_1() { - return emitOp(Opcode.DSTORE_1); - } - - public C astore_2() { - return emitOp(Opcode.ASTORE_2); - } - - public C istore_2() { - return emitOp(Opcode.ISTORE_2); - } - - public C fstore_2() { - return emitOp(Opcode.FSTORE_2); - } - - public C lstore_2() { - return emitOp(Opcode.LSTORE_2); - } - - public C dstore_2() { - return emitOp(Opcode.DSTORE_2); - } - - public C astore_3() { - return emitOp(Opcode.ASTORE_3); - } - - public C istore_3() { - return emitOp(Opcode.ISTORE_3); - } - - public C fstore_3() { - return emitOp(Opcode.FSTORE_3); - } - - public C lstore_3() { - return emitOp(Opcode.LSTORE_3); - } - - public C dstore_3() { - return emitOp(Opcode.DSTORE_3); - } - - //... - - public C iaload() { - return emitOp(Opcode.IALOAD); - } - - public C laload() { - return emitOp(Opcode.LALOAD); - } - - public C faload() { - return emitOp(Opcode.FALOAD); - } - - public C daload() { - return emitOp(Opcode.DALOAD); - } - - public C aaload() { - return emitOp(Opcode.AALOAD); - } - - public C baload() { - return emitOp(Opcode.BALOAD); - } - - public C caload() { - return emitOp(Opcode.CALOAD); - } - - public C saload() { - return emitOp(Opcode.SALOAD); - } - - public C iastore() { - return emitOp(Opcode.IASTORE); - } - - public C lastore() { - return emitOp(Opcode.LASTORE); - } - - public C fastore() { - return emitOp(Opcode.FASTORE); - } - - public C dastore() { - return emitOp(Opcode.DASTORE); - } - - public C aastore() { - return emitOp(Opcode.AASTORE); - } - - public C bastore() { - return emitOp(Opcode.BASTORE); - } - - public C castore() { - return emitOp(Opcode.CASTORE); - } - - public C sastore() { - return emitOp(Opcode.SASTORE); - } - - public C nop() { - return emitOp(Opcode.NOP); - } - - public C aconst_null() { - return emitOp(Opcode.ACONST_NULL); - } - - public C iconst_0() { - return emitOp(Opcode.ICONST_0); - } - - public C iconst_1() { - return emitOp(Opcode.ICONST_1); - } - - public C iconst_2() { - return emitOp(Opcode.ICONST_2); - } - - public C iconst_3() { - return emitOp(Opcode.ICONST_3); - } - - public C iconst_4() { - return emitOp(Opcode.ICONST_4); - } - - public C iconst_5() { - return emitOp(Opcode.ICONST_5); - } - - public C iconst_m1() { - return emitOp(Opcode.ICONST_M1); - } - - public C lconst_0() { - return emitOp(Opcode.LCONST_0); - } - - public C lconst_1() { - return emitOp(Opcode.LCONST_1); - } - - public C fconst_0() { - return emitOp(Opcode.FCONST_0); - } - - public C fconst_1() { - return emitOp(Opcode.FCONST_1); - } - - public C fconst_2() { - return emitOp(Opcode.FCONST_2); - } - - public C dconst_0() { - return emitOp(Opcode.DCONST_0); - } - - public C dconst_1() { - return emitOp(Opcode.DCONST_1); - } - - public C sipush(int s) { - emitOp(Opcode.SIPUSH); - code.writeChar(s); - return thisBuilder(); - } - - public C bipush(int b) { - emitOp(Opcode.BIPUSH); - code.writeByte(b); - return thisBuilder(); - } - - public C pop() { - return emitOp(Opcode.POP); - } - - public C pop2() { - return emitOp(Opcode.POP2); - } - - public C dup() { - return emitOp(Opcode.DUP); - } - - public C dup_x1() { - return emitOp(Opcode.DUP_X1); - } - - public C dup_x2() { - return emitOp(Opcode.DUP_X2); - } - - public C dup2() { - return emitOp(Opcode.DUP2); - } - - public C dup2_x1() { - return emitOp(Opcode.DUP2_X1); - } - - public C dup2_x2() { - return emitOp(Opcode.DUP2_X2); - } - - public C swap() { - return emitOp(Opcode.SWAP); - } - - public C iadd() { - return emitOp(Opcode.IADD); - } - - public C ladd() { - return emitOp(Opcode.LADD); - } - - public C fadd() { - return emitOp(Opcode.FADD); - } - - public C dadd() { - return emitOp(Opcode.DADD); - } - - public C isub() { - return emitOp(Opcode.ISUB); - } - - public C lsub() { - return emitOp(Opcode.LSUB); - } - - public C fsub() { - return emitOp(Opcode.FSUB); - } - - public C dsub() { - return emitOp(Opcode.DSUB); - } - - public C imul() { - return emitOp(Opcode.IMUL); - } - - public C lmul() { - return emitOp(Opcode.LMUL); - } - - public C fmul() { - return emitOp(Opcode.FMUL); - } - - public C dmul() { - return emitOp(Opcode.DMUL); - } - - public C idiv() { - return emitOp(Opcode.IDIV); - } - - public C ldiv() { - return emitOp(Opcode.LDIV); - } - - public C fdiv() { - return emitOp(Opcode.FDIV); - } - - public C ddiv() { - return emitOp(Opcode.DDIV); - } - - public C irem() { - return emitOp(Opcode.IREM); - } - - public C lrem() { - return emitOp(Opcode.LREM); - } - - public C frem() { - return emitOp(Opcode.FREM); - } - - public C drem() { - return emitOp(Opcode.DREM); - } - - public C ineg() { - return emitOp(Opcode.INEG); - } - - public C lneg() { - return emitOp(Opcode.LNEG); - } - - public C fneg() { - return emitOp(Opcode.FNEG); - } - - public C dneg() { - return emitOp(Opcode.DNEG); - } - - public C ishl() { - return emitOp(Opcode.ISHL); - } - - public C lshl() { - return emitOp(Opcode.LSHL); - } - - public C ishr() { - return emitOp(Opcode.ISHR); - } - - public C lshr() { - return emitOp(Opcode.LSHR); - } - - public C iushr() { - return emitOp(Opcode.IUSHR); - } - - public C lushr() { - return emitOp(Opcode.LUSHR); - } - - public C iand() { - return emitOp(Opcode.IAND); - } - - public C land() { - return emitOp(Opcode.LAND); - } - - public C ior() { - return emitOp(Opcode.IOR); - } - - public C lor() { - return emitOp(Opcode.LOR); - } - - public C ixor() { - return emitOp(Opcode.IXOR); - } - - public C lxor() { - return emitOp(Opcode.LXOR); - } - - public C iinc(int index, int val) { - return emitWideIfNeeded(Opcode.IINC, index, val); - } - - public C i2l() { - return emitOp(Opcode.I2L); - } - - public C i2f() { - return emitOp(Opcode.I2F); - } - - public C i2d() { - return emitOp(Opcode.I2D); - } - - public C l2i() { - return emitOp(Opcode.L2I); - } - - public C l2f() { - return emitOp(Opcode.L2F); - } - - public C l2d() { - return emitOp(Opcode.L2D); - } - - public C f2i() { - return emitOp(Opcode.F2I); - } - - public C f2l() { - return emitOp(Opcode.F2L); - } - - public C f2d() { - return emitOp(Opcode.F2D); - } - - public C d2i() { - return emitOp(Opcode.D2I); - } - - public C d2l() { - return emitOp(Opcode.D2L); - } - - public C d2f() { - return emitOp(Opcode.D2F); - } - - public C i2b() { - return emitOp(Opcode.I2B); - } - - public C i2c() { - return emitOp(Opcode.I2C); - } - - public C i2s() { - return emitOp(Opcode.I2S); - } - - public C lcmp() { - return emitOp(Opcode.LCMP); - } - - public C fcmpl() { - return emitOp(Opcode.FCMPL); - } - - public C fcmpg() { - return emitOp(Opcode.FCMPG); - } - - public C dcmpl() { - return emitOp(Opcode.DCMPL); - } - - public C dcmpg() { - return emitOp(Opcode.DCMPG); - } - - public C ifeq(short target) { - return emitNarrowJumpOp(Opcode.IFEQ, target); - } - - public C ifne(short target) { - return emitNarrowJumpOp(Opcode.IFNE, target); - } - - public C iflt(short target) { - return emitNarrowJumpOp(Opcode.IFLT, target); - } - - public C ifge(short target) { - return emitNarrowJumpOp(Opcode.IFGE, target); - } - - public C ifgt(short target) { - return emitNarrowJumpOp(Opcode.IFGT, target); - } - - public C ifle(short target) { - return emitNarrowJumpOp(Opcode.IFLE, target); - } - - public C if_icmpeq(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPEQ, target); - } - - public C if_icmpne(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPNE, target); - } - - public C if_icmplt(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPLT, target); - } - - public C if_icmpge(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPGE, target); - } - - public C if_icmpgt(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPGT, target); - } - - public C if_icmple(short target) { - return emitNarrowJumpOp(Opcode.IF_ICMPLE, target); - } - - public C if_acmpeq(short target) { - return emitNarrowJumpOp(Opcode.IF_ACMPEQ, target); - } - - public C if_acmpne(short target) { - return emitNarrowJumpOp(Opcode.IF_ACMPNE, target); - } - - public C goto_(short target) { - return emitNarrowJumpOp(Opcode.GOTO_, target); - } - - public C jsr(short target) { - return emitNarrowJumpOp(Opcode.JSR, target); - } - - public C ret(int index) { - return emitWideIfNeeded(Opcode.RET, index); - } - - public C tableswitch(int low, int high, int defaultTarget, int... targets) { - if (high - low + 1 != targets.length) throw new IllegalStateException("Bad targets length"); - emitOp(Opcode.TABLESWITCH); - //padding - int start = code.offset; - if ((start % 4) != 0) { - //add padding - for (int i = 0; i < 4 - (start % 4); i++) { - code.writeByte(0); - } - } - code.writeInt(defaultTarget) - .writeInt(low) - .writeInt(high); - for (int target : targets) { - code.writeInt(target); - } - return thisBuilder(); - } - - public C lookupswitch(int defaultTarget, int... npairs) { - if (npairs.length % 2 != 0) throw new IllegalStateException("Bad npairs length"); - emitOp(Opcode.LOOKUPSWITCH); - //padding - int start = code.offset; - for (int i = 0; i < (4 - (start % 4)); i++) { - code.writeByte(0); - } - code.writeInt(defaultTarget) - .writeInt(npairs.length / 2); - for (int i = 0; i < npairs.length; i += 2) { - code.writeInt(npairs[i]); - code.writeInt(npairs[i + 1]); - } - return thisBuilder(); - } - - public C arraylength() { - return emitOp(Opcode.ARRAYLENGTH); - } - - public C athrow() { - return emitOp(Opcode.ATHROW); - } - - public C monitorenter() { - return emitOp(Opcode.MONITORENTER); - } - - public C monitorexit() { - return emitOp(Opcode.MONITOREXIT); - } - - public C wide() { - return emitOp(Opcode.WIDE); - } - - public C if_null(short offset) { - return emitNarrowJumpOp(Opcode.IF_NULL, offset); - } - - public C if_nonnull(short offset) { - return emitNarrowJumpOp(Opcode.IF_NONNULL, offset); - } - - public C goto_w(int target) { - return emitWideJumpOp(Opcode.GOTO_W, target); - } - - public C jsr_w(int target) { - return emitWideJumpOp(Opcode.JSR_W, target); - } - - public C withCatch(S type, int start, int end, int offset) { - catchers.writeChar(start); - catchers.writeChar(end); - catchers.writeChar(offset); - catchers.writeChar(type != null ? poolHelper.putClass(type) : 0); - ncatchers++; - return thisBuilder(); - } - - public C withLocalSize(int localsize) { - this.localsize = localsize; - return thisBuilder(); - } - - public C withStackSize(int stacksize) { - this.stacksize = stacksize; - return thisBuilder(); - } - - protected int localsize() { - return localsize; - } - - void build(GrowableByteBuffer buf) { - buf.writeChar(stacksize); //max stack size - buf.writeChar(localsize()); //max locals - buf.writeInt(code.offset); - buf.writeBytes(code); - buf.writeChar(ncatchers); - buf.writeBytes(catchers); - buf.writeChar(nattrs); //attributes - buf.writeBytes(attributes); - } - - byte[] build() { - GrowableByteBuffer buf = new GrowableByteBuffer(); - build(buf); - return buf.bytes(); - } - - protected C emitNarrowJumpOp(Opcode opcode, short target) { - emitOp(opcode); - emitOffset(code, JumpMode.NARROW, target); - return thisBuilder(); - } - - protected C emitWideJumpOp(Opcode opcode, int target) { - emitOp(opcode); - emitOffset(code, JumpMode.WIDE, target); - return thisBuilder(); - } - - protected C emitOp(Opcode opcode) { - return emitOp(opcode, null); - } - - protected C emitOp(Opcode opcode, Object optPoolValue) { - code.writeByte(opcode.code); - return thisBuilder(); - } - - protected void emitOffset(GrowableByteBuffer buf, JumpMode jumpMode, int offset) { - if (jumpMode == JumpMode.NARROW) { - buf.writeChar((short) offset); - } else { - buf.writeInt(offset); - } - } - - int offset() { - return code.offset; - } - - /*** stackmap support ***/ - - /** - * The tags and constants used in compressed stackmap. - */ - static final int SAME_FRAME_SIZE = 64; - static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247; - static final int SAME_FRAME_EXTENDED = 251; - static final int FULL_FRAME = 255; - static final int MAX_LOCAL_LENGTH_DIFF = 4; - - @SuppressWarnings("unchecked") - private void writeStackMapType(T t) { - if (t == null) { - stackmaps.writeByte(0); - } else { - switch (typeHelper.tag(t)) { - case B: - case C: - case S: - case I: - case Z: - stackmaps.writeByte(1); - break; - case F: - stackmaps.writeByte(2); - break; - case D: - stackmaps.writeByte(3); - break; - case J: - stackmaps.writeByte(4); - break; - case A: - if (t == typeHelper.nullType()) { - stackmaps.writeByte(5); //null - } else { - //TODO: uninit this, top? - stackmaps.writeByte(7); - stackmaps.writeChar(typeHelper.isValue(t) ? - poolHelper.putValueClass(typeHelper.symbol(t)) : poolHelper.putClass(typeHelper.symbol(t))); - } - break; - default: - throw new IllegalStateException("Bad type"); - } - } - } - - public void sameFrame(int offsetDelta) { - int frameType = (offsetDelta < SAME_FRAME_SIZE) ? - offsetDelta : SAME_FRAME_EXTENDED; - stackmaps.writeByte(frameType); - if (frameType == SAME_FRAME_EXTENDED) { - stackmaps.writeChar(offsetDelta); - } - } - - public void sameLocals1StackItemFrame(int offsetDelta, T stackItem) { - int frameType = (offsetDelta < SAME_FRAME_SIZE) ? - (SAME_FRAME_SIZE + offsetDelta) : SAME_LOCALS_1_STACK_ITEM_EXTENDED; - stackmaps.writeByte(frameType); - if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) { - stackmaps.writeChar(offsetDelta); - } - writeStackMapType(stackItem); - } - - public void appendFrame(int offsetDelta, int prevLocalsSize, List locals) { - int frameType = SAME_FRAME_EXTENDED + (locals.size() - prevLocalsSize); - stackmaps.writeByte(frameType); - stackmaps.writeChar(offsetDelta); - for (int i = prevLocalsSize; i < locals.size(); i++) { - writeStackMapType(locals.get(i)); - } - } - - public void chopFrame(int offsetDelta, int droppedVars) { - int frameType = SAME_FRAME_EXTENDED - droppedVars; - stackmaps.writeByte(frameType); - stackmaps.writeChar(offsetDelta); - } - - public void fullFrame(int offsetDelta, List locals, List stackItems) { - stackmaps.writeByte(FULL_FRAME); - stackmaps.writeChar(offsetDelta); - stackmaps.writeChar(locals.size()); - for (T local : locals) { - writeStackMapType(local); - } - - stackmaps.writeChar(stackItems.size()); - for (T stackType : stackItems) { - writeStackMapType(stackType); - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/DeclBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/DeclBuilder.java deleted file mode 100644 index 899c20cbdb4..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/DeclBuilder.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.function.Consumer; - -/** - * Declaration (class, class member, ...) builder. - * - * @param the type of symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of this builder - */ -public class DeclBuilder> - extends AttributeBuilder { - - /** - * The access flags of the declaration, as bit flags. - */ - protected int flags; - - AnnotationsBuilder runtimeInvisibleAnnotations; - AnnotationsBuilder runtimeVisibleAnnotations; - - /** - * Create a declaration builder, - * - * @param poolHelper the helper to build the constant pool - * @param typeHelper the helper to use to manipulate type descriptors - */ - DeclBuilder(PoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - } - - /** - * Specify the class file flags for this declaration. - * - * @param flags the flags as {@code Flag} objects - * @return this builder, for chained calls - */ - public D withFlags(Flag... flags) { - for (Flag f : flags) { - this.flags |= f.flag; - } - return thisBuilder(); - } - - /** - * Specify, via bits, the class file flags for this declaration. - * - * @param flags the flags as bit settings - * @return this builder, for chained calls - */ - public D withFlags(int flags) { - withFlags(Flag.parse(flags)); - return thisBuilder(); - } - - public D withAnnotation(AnnotationsBuilder.Kind kind, T annoType) { - getAnnotations(kind).withAnnotation(annoType, null); - return thisBuilder(); - } - - public D withAnnotation(AnnotationsBuilder.Kind kind, T annoType, Consumer.AnnotationElementBuilder> annotations) { - getAnnotations(kind).withAnnotation(annoType, annotations); - return thisBuilder(); - } - - private AnnotationsBuilder getAnnotations(AnnotationsBuilder.Kind kind) { - switch (kind) { - case RUNTIME_INVISIBLE: - if (runtimeInvisibleAnnotations == null) { - runtimeInvisibleAnnotations = new AnnotationsBuilder<>(poolHelper, typeHelper); - } - return runtimeInvisibleAnnotations; - case RUNTIME_VISIBLE: - if (runtimeVisibleAnnotations == null) { - runtimeVisibleAnnotations = new AnnotationsBuilder<>(poolHelper, typeHelper); - } - return runtimeVisibleAnnotations; - } - throw new IllegalStateException(); - } - - void addAnnotations() { - if (runtimeVisibleAnnotations != null) { - withAttribute("RuntimeVisibleAnnotations", runtimeVisibleAnnotations.build()); - } - if (runtimeInvisibleAnnotations != null) { - withAttribute("RuntimeInvisibleAnnotations", runtimeVisibleAnnotations.build()); - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/FieldBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/FieldBuilder.java deleted file mode 100644 index a4954e6ae6a..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/FieldBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Field builder. - * - * @param the type of symbol representation - * @param the type of type descriptor representation - * @param the type of pool entries - */ -public class FieldBuilder extends MemberBuilder> { - public FieldBuilder(CharSequence name, T type, PoolHelper poolHelper, TypeHelper typeHelper) { - super(name, type, poolHelper, typeHelper); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/Flag.java b/src/java.base/share/classes/jdk/experimental/bytecode/Flag.java deleted file mode 100644 index 9eac26b1f3e..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/Flag.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.EnumSet; - -public enum Flag { - ACC_PUBLIC(0x0001), - ACC_PROTECTED(0x0004), - ACC_PRIVATE(0x0002), - ACC_INTERFACE(0x0200), - ACC_ENUM(0x4000), - ACC_ANNOTATION(0x2000), - ACC_SUPER(0x0020), - ACC_ABSTRACT(0x0400), - ACC_VOLATILE(0x0040), - ACC_TRANSIENT(0x0080), - ACC_SYNTHETIC(0x1000), - ACC_STATIC(0x0008), - ACC_FINAL(0x0010), - ACC_SYNCHRONIZED(0x0020), - ACC_BRIDGE(0x0040), - ACC_VARARGS(0x0080), - ACC_INLINE(0x0100), - ACC_NATIVE(0x0100), - ACC_STRICT(0x0800); - - public int flag; - - Flag(int flag) { - this.flag = flag; - } - - static Flag[] parse(int flagsMask) { - EnumSet flags = EnumSet.noneOf(Flag.class); - for (Flag f : Flag.values()) { - if ((f.flag & flagsMask) != 0) { - flags.add(f); - } - } - return flags.stream().toArray(Flag[]::new); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/GrowableByteBuffer.java b/src/java.base/share/classes/jdk/experimental/bytecode/GrowableByteBuffer.java deleted file mode 100644 index d24d8b482a3..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/GrowableByteBuffer.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.function.Consumer; - -public class GrowableByteBuffer { - - public GrowableByteBuffer() { - } - - byte[] elems = new byte[64]; - int offset = 0; - - public GrowableByteBuffer writeByte(int b) { - return writeBytes(1, b); - } - - public GrowableByteBuffer writeChar(int x) { - return writeBytes(2, x); - } - - public GrowableByteBuffer writeInt(int x) { - return writeBytes(4, x); - } - - public GrowableByteBuffer writeFloat(float x) { - return writeInt(Float.floatToIntBits(x)); - } - - public GrowableByteBuffer writeLong(long x) { - return writeBytes(8, x); - } - - public GrowableByteBuffer writeDouble(double x) { - writeLong(Double.doubleToLongBits(x)); - return this; - } - - public GrowableByteBuffer writeBytes(byte[] barr) { - expandIfNeeded(barr.length); - System.arraycopy(barr, 0, elems, offset, barr.length); - offset += barr.length; - return this; - } - - public GrowableByteBuffer writeBytes(GrowableByteBuffer bb) { - expandIfNeeded(bb.offset); - System.arraycopy(bb.elems, 0, elems, offset, bb.offset); - offset += bb.offset; - return this; - } - - public GrowableByteBuffer withOffset(int offset, Consumer actions) { - int prevOffset = this.offset; - this.offset = offset; - actions.accept(this); - this.offset = prevOffset; - return this; - } - - private GrowableByteBuffer writeBytes(int size, long x) { - expandIfNeeded(size); - for (int i = 0; i < size; i++) { - elems[offset++] = (byte) ((x >> 8 * (size - i - 1)) & 0xFF); - } - return this; - } - - void expandIfNeeded(int increment) { - if (offset + increment > elems.length) { - int newsize = elems.length * 2; - while (offset + increment > newsize) { - newsize *= 2; - } - byte[] newelems = new byte[newsize]; - System.arraycopy(elems, 0, newelems, 0, offset); - elems = newelems; - } - } - - public byte[] bytes() { - byte[] bytes = new byte[offset]; - System.arraycopy(elems, 0, bytes, 0, offset); - return bytes; - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/ImmutableBytePoolHelper.java b/src/java.base/share/classes/jdk/experimental/bytecode/ImmutableBytePoolHelper.java deleted file mode 100644 index a997bdbbc6b..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/ImmutableBytePoolHelper.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.experimental.bytecode; - -import jdk.experimental.bytecode.Pool.Class_info; -import jdk.experimental.bytecode.Pool.Double_info; -import jdk.experimental.bytecode.Pool.Fieldref_info; -import jdk.experimental.bytecode.Pool.Float_info; -import jdk.experimental.bytecode.Pool.Integer_info; -import jdk.experimental.bytecode.Pool.InterfaceMethodref_info; -import jdk.experimental.bytecode.Pool.InvokeDynamic_info; -import jdk.experimental.bytecode.Pool.Long_info; -import jdk.experimental.bytecode.Pool.MethodHandle_info; -import jdk.experimental.bytecode.Pool.MethodType_info; -import jdk.experimental.bytecode.Pool.Methodref_info; -import jdk.experimental.bytecode.Pool.NameAndType_info; -import jdk.experimental.bytecode.Pool.String_info; -import jdk.experimental.bytecode.Pool.Utf8_info; -import jdk.experimental.bytecode.Pool.PoolInfo; -import java.util.ArrayList; -import java.util.function.Consumer; -import java.util.function.Function; - -import static jdk.experimental.bytecode.Pool.*; -import jdk.experimental.bytecode.Pool.PoolInfoAndIndex; - -/** - * A helper for explicitly building immutable constant pools with a defined - * order. - */ -class ImmutableBytePoolHelper extends BytePoolHelper { - - private final BuiltPool icpool; - - public ImmutableBytePoolHelper(Consumer> cpBuild, - Function symbolToString, Function typeToString) { - super(null /* already built */, symbolToString, typeToString); - this.icpool = new BuiltPool(cpBuild); - // go through the constant pool installing all the entries in the - // helper's map. - for (PoolInfoAndIndex pii : icpool.entriesAndIndicies()) { - PoolInfo info = pii.info; - PoolKey poolKey = new PoolKey(); - try { - switch (info.getTag()) { - case STRING_TAG: { - String_info si = (String_info) info; - poolKey.setString(si.getString()); - break; - } - case INTEGER_TAG: - poolKey.setInteger(((Integer_info) info).value); - break; - case FLOAT_TAG: - poolKey.setFloat(((Float_info) info).value); - break; - case DOUBLE_TAG: - poolKey.setDouble(((Double_info) info).value); - break; - case LONG_TAG: - poolKey.setLong(((Long_info) info).value); - break; - case CLASS_TAG: { - Class_info ci = (Class_info) info; - poolKey.setClass(ci.getName()); - break; - } - case FIELDREF_TAG: { - Fieldref_info fr = (Fieldref_info) info; - NameAndType_info nat = fr.getNameAndTypeInfo(); - poolKey.setMemberRef(PoolTag.FIELDREF, fr.getClassName(), nat.getName(), nat.getType()); - break; - } - case METHODREF_TAG: { - Methodref_info mr = (Methodref_info) info; - NameAndType_info nat = mr.getNameAndTypeInfo(); - poolKey.setMemberRef(PoolTag.METHODREF, mr.getClassName(), nat.getName(), nat.getType()); - break; - } - case INTERFACEMETHODREF_TAG: { - InterfaceMethodref_info mr = (InterfaceMethodref_info) info; - NameAndType_info nat = mr.getNameAndTypeInfo(); - poolKey.setMemberRef(PoolTag.INTERFACEMETHODREF, mr.getClassName(), nat.getName(), nat.getType()); - break; - } - case METHODTYPE_TAG: { - MethodType_info mt = (MethodType_info) info; - poolKey.setMethodType(mt.getType()); - break; - } - case METHODHANDLE_TAG: { - MethodHandle_info mh = (MethodHandle_info) info; - PoolInfo rinfo = icpool.get(mh.reference_index); - String owner; - NameAndType_info nat; - switch (rinfo.getTag()) { - case FIELDREF_TAG: - Fieldref_info fr = (Fieldref_info) rinfo; - owner = fr.getClassName(); - nat = fr.getNameAndTypeInfo(); - break; - case METHODREF_TAG: - Methodref_info mr = (Methodref_info) rinfo; - owner = mr.getClassName(); - nat = mr.getNameAndTypeInfo(); - break; - case INTERFACEMETHODREF_TAG: - InterfaceMethodref_info imr = (InterfaceMethodref_info) rinfo; - owner = imr.getClassName(); - nat = imr.getNameAndTypeInfo(); - break; - default: - throw new IllegalStateException(rinfo.toString()); - } - poolKey.setMethodHandle(mh.reference_kind, owner, nat.getName(), nat.getType()); - break; - } - case NAMEANDTYPE_TAG: { - NameAndType_info nat = (NameAndType_info) info; - poolKey.setNameAndType(nat.getName(), nat.getType()); - break; - } - case UTF8_TAG: { - Utf8_info u = (Utf8_info) info; - poolKey.setUtf8(u.value); - break; - } - case INVOKEDYNAMIC_TAG: { - InvokeDynamic_info idi = (InvokeDynamic_info) info; - NameAndType_info nat = (NameAndType_info) icpool.get(idi.name_and_type_index); - PoolInfo bsm = icpool.get(idi.bootstrap_method_attr_index); - // idi.bootstrap_method_attr_index, idi.name_and_type_index); - throw new UnsupportedOperationException("InvokeDynamic " + idi); - } - case MODULE_TAG: { - throw new UnsupportedOperationException("Module " + info); - } - case PACKAGE_TAG: { - throw new UnsupportedOperationException("Package " + info); - } - default: - throw new IllegalStateException("unsupported pool entry: " + info); - } - } catch (PoolException ex) { - } - poolKey.at(pii.index); - entries.enter(poolKey); - } - } - - /** - * @return the count of constant pool indicies. - */ - @Override - public int size() { - return icpool.builder.size(); - } - - /** - * @return the size in bytes of all constant pool entries. - */ - @Override - public byte[] representation() { - return icpool.builder.representation(); - } - - /** - * Build the byte array representation of the constant pool, and at the - * same time build as an array of PoolInfo objects. - */ - private static class BuiltPool extends Pool { - - final ArrayList infos = new ArrayList<>(); - final IBCPB builder; - - BuiltPool(Consumer> cpBuild) { - this.builder = new IBCPB(); - cpBuild.accept(builder); - } - - @Override - protected PoolInfo getSafe(int index) { - return infos.get(index); - } - - @Override - public int size() { - return infos.size(); - } - - private class IBCPB extends BytePoolBuilder { - - @Override - public int putClass(int utf8_idx) { - int id = super.putClass(utf8_idx); - return put(id, new Class_info(utf8_idx)); - } - - @Override - public int putMemberRef(PoolTag tag, int owner_idx, int nameAndType_idx) { - int id = super.putMemberRef(tag, owner_idx, nameAndType_idx); - switch (tag) { - case FIELDREF: - return put(id, new Fieldref_info(owner_idx, nameAndType_idx)); - case METHODREF: - return put(id, new Methodref_info(owner_idx, nameAndType_idx)); - case INTERFACEMETHODREF: - return put(id, new InterfaceMethodref_info(owner_idx, nameAndType_idx)); - default: - throw new IllegalArgumentException("tag: " + tag); - } - } - - @Override - public int putInt(int i) { - int id = super.putInt(i); - return put(id, new Integer_info(i)); - } - - @Override - public int putFloat(float f) { - int id = super.putFloat(f); - return put(id, new Float_info(f)); - } - - @Override - public int putLong(long l) { - int id = super.putLong(l); - return put(id, new Long_info(l)); - } - - @Override - public int putDouble(double d) { - int id = super.putDouble(d); - return put(id, new Double_info(d)); - } - - @Override - public int putInvokeDynamic(int bsmIndex, int nameAndType_idx) { - int id = super.putInvokeDynamic(bsmIndex, nameAndType_idx); - return put(id, new InvokeDynamic_info(bsmIndex, nameAndType_idx)); - } - - @Override - public int putConstantDynamic(int bsmIndex, int nameAndType_idx) { - int id = super.putConstantDynamic(bsmIndex, nameAndType_idx); - throw new UnsupportedOperationException(); - } - - @Override - public int putMethodType(int desc_idx) { - int id = super.putMethodType(desc_idx); - return put(id, new MethodType_info(desc_idx)); - } - - @Override - public int putMethodHandle(int refKind, int ref_idx) { - int id = super.putMethodHandle(refKind, ref_idx); - return put(id, new MethodHandle_info(refKind, ref_idx)); - } - - @Override - public int putString(int utf8_index) { - int id = super.putString(utf8_index); - return put(id, new String_info(utf8_index)); - } - - @Override - public int putNameAndType(int name_idx, int type_idx) { - int id = super.putNameAndType(name_idx, type_idx); - return put(id, new NameAndType_info(name_idx, type_idx)); - } - - @Override - public int putUtf8(CharSequence s) { - int id = super.putUtf8(s); - return put(id, new Utf8_info(s.toString())); - } - - private int put(int id, PoolInfo info) { - // fill gaps with nulls - int fill = id - infos.size(); - for (int i = 0; i < fill; ++i) { - infos.add(null); - } - infos.add(info); - return id; - } - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/IsolatedMethodBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/IsolatedMethodBuilder.java deleted file mode 100644 index d49aef4044e..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/IsolatedMethodBuilder.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; - -public class IsolatedMethodBuilder extends MethodBuilder, String, Object[]> { - - public IsolatedMethodBuilder(Lookup lookup, String name, String type) { - super(null, name, type, new IsolatedMethodPoolHelper(lookup), null); - } - - static class IsolatedMethodPoolHelper implements PoolHelper, String, Object[]> { - Map constants = new HashMap<>(); - Lookup lookup; - - private IsolatedMethodPoolHelper(Lookup lookup) { - this.lookup = lookup; - } - - @Override - public int putClass(Class symbol) { - return putIfAbsent(symbol); - } - - @Override - public int putValueClass(Class symbol) { - return putIfAbsent(symbol); - } - - @Override - public int putFieldRef(Class owner, CharSequence name, String type) { - try { - Field f = owner.getDeclaredField(name.toString()); //TODO: we should unreflect for a var handle - return putIfAbsent(lookup.unreflectGetter(f)); - } catch (Throwable ex) { - ex.printStackTrace(); - return -1; - } - } - - @Override - public int putMethodRef(Class owner, CharSequence name, String type, boolean isInterface) { - try { - Method m = owner.getDeclaredMethod(name.toString()); //we should unreflect according to method vs. constructor - //and static vs. private etc. - return putIfAbsent(lookup.unreflect(m)); - } catch (Throwable ex) { - ex.printStackTrace(); - return -1; - } - } - - @Override - public int putInt(int i) { - return putIfAbsent(i); - } - - @Override - public int putFloat(float f) { - return putIfAbsent(f); - } - - @Override - public int putLong(long l) { - return putIfAbsent(l); - } - - @Override - public int putDouble(double d) { - return putIfAbsent(d); - } - - @Override - public int putString(String s) { - return putIfAbsent(s); - } - - @Override - public int putValue(Object v) { - return 0; // ??? - } - - @Override - public int putInvokeDynamic(CharSequence invokedName, String invokedType, Class bsmClass, CharSequence bsmName, String bsmType, Consumer, String, Object[]>> staticArgs) { - return 0; //??? - } - - @Override - public int putConstantDynamic(CharSequence constName, String constType, Class bsmClass, CharSequence bsmName, String bsmType, Consumer, String, Object[]>> staticArgs) { - return 0; //??? - } - - @Override - public int putMethodHandle(int refKind, Class owner, CharSequence name, String type) { - return putMethodHandle(refKind, owner, name, type, false); - } - - @Override - public int putMethodHandle(int refKind, Class owner, CharSequence name, String type, boolean isInterface) { - return 0; //??? - } - - @Override - public int putMethodType(String s) { - return 0; //??? - } - - @Override - public int putUtf8(CharSequence s) { - return putIfAbsent(s); - } - - @Override - public int putType(String s) { - return putIfAbsent(s); - } - - @Override - public int size() { - return constants.size(); - } - - @Override - public Object[] representation() { - return constants.keySet().toArray(); - } - - int putIfAbsent(Object o) { - int nextIndex = constants.size() + 1; - Object res = constants.putIfAbsent(o, nextIndex); - return res == null ? - nextIndex : (Integer)res; - } - } - - public Object[] entries() { - return poolHelper.representation(); - } - - @Override - public byte[] build() { - byte[] arr = super.build(); - int codelength_offset = 2 + 2 + 2 + 2 + - 2 + 4 + 2 + 2; - int code_offset = codelength_offset + 4; - int length = ByteBuffer.wrap(arr).getInt(codelength_offset); - byte[] opcodes = new byte[length]; - System.arraycopy(arr, code_offset, opcodes, 0, length); - return opcodes; - } - - public static void main(String[] args) { - IsolatedMethodBuilder imb = new IsolatedMethodBuilder(MethodHandles.lookup(), "foo", "(java/lang/String;)I"); - imb.withCode(C -> - C.aload_0() - .invokevirtual(String.class, "length", "()I", false) - .ireturn()); - byte[] opcodes = imb.build(); - System.out.println(Arrays.toString(opcodes)); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/MacroCodeBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/MacroCodeBuilder.java deleted file mode 100644 index 7303b833028..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/MacroCodeBuilder.java +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.function.Consumer; - -public class MacroCodeBuilder> extends CodeBuilder { - - JumpMode jumpMode = JumpMode.NARROW; - - Map labels = new HashMap<>(); - List pendingJumps = new LinkedList<>(); - - class PendingJump { - CharSequence label; - int pc; - - PendingJump(CharSequence label, int pc) { - this.label = label; - this.pc = pc; - } - - boolean resolve(CharSequence label, int offset) { - if (this.label.equals(label)) { - //patch offset - code.withOffset(pc + 1, buf -> emitOffset(buf, jumpMode, offset - pc)); - return true; - } else { - return false; - } - } - } - - public enum InvocationKind { - INVOKESTATIC, - INVOKEVIRTUAL, - INVOKESPECIAL, - INVOKEINTERFACE; - } - - public enum FieldAccessKind { - STATIC, - INSTANCE; - } - - public enum CondKind { - EQ(0), - NE(1), - LT(2), - GE(3), - GT(4), - LE(5); - - int offset; - - CondKind(int offset) { - this.offset = offset; - } - - public CondKind negate() { - switch (this) { - case EQ: - return NE; - case NE: - return EQ; - case LT: - return GE; - case GE: - return LT; - case GT: - return LE; - case LE: - return GT; - default: - throw new IllegalStateException("Unknown cond"); - } - } - } - - static class WideJumpException extends RuntimeException { - static final long serialVersionUID = 42L; - } - - public MacroCodeBuilder(MethodBuilder methodBuilder) { - super(methodBuilder); - } - - public C load(TypeTag type, int n) { - switch (n) { - case 0: - return emitOp(Opcode.ILOAD_0.at(type, 4)); - case 1: - return emitOp(Opcode.ILOAD_1.at(type, 4)); - case 2: - return emitOp(Opcode.ILOAD_2.at(type, 4)); - case 3: - return emitOp(Opcode.ILOAD_3.at(type, 4)); - default: - return emitWideIfNeeded(Opcode.ILOAD.at(type), n); - } - } - - public C store(TypeTag type, int n) { - switch (n) { - case 0: - return emitOp(Opcode.ISTORE_0.at(type, 4)); - case 1: - return emitOp(Opcode.ISTORE_1.at(type, 4)); - case 2: - return emitOp(Opcode.ISTORE_2.at(type, 4)); - case 3: - return emitOp(Opcode.ISTORE_3.at(type, 4)); - default: - return emitWideIfNeeded(Opcode.ISTORE.at(type), n); - } - } - - public C arrayload(TypeTag type) { - return emitOp(Opcode.IALOAD.at(type)); - } - - public C arraystore(TypeTag type, int n) { - return emitOp(Opcode.IASTORE.at(type)); - } - - public C const_(int i) { - switch (i) { - case -1: - return iconst_m1(); - case 0: - return iconst_0(); - case 1: - return iconst_1(); - case 2: - return iconst_2(); - case 3: - return iconst_3(); - case 4: - return iconst_4(); - case 5: - return iconst_5(); - default: - if (i > 0 && i <= Byte.MAX_VALUE) { - return bipush(i); - } else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) { - return sipush(i); - } else { - return ldc(i); - } - } - } - - public C const_(long l) { - if (l == 0) { - return lconst_0(); - } else if (l == 1) { - return lconst_1(); - } else { - return ldc(l); - } - } - - public C const_(float f) { - if (f == 0) { - return fconst_0(); - } else if (f == 1) { - return fconst_1(); - } else if (f == 2) { - return fconst_2(); - } else { - return ldc(f); - } - } - - public C const_(double d) { - if (d == 0) { - return dconst_0(); - } else if (d == 1) { - return dconst_1(); - } else { - return ldc(d); - } - } - - public C getfield(FieldAccessKind fak, S owner, CharSequence name, T type) { - switch (fak) { - case INSTANCE: - return getfield(owner, name, type); - case STATIC: - return getstatic(owner, name, type); - default: - throw new IllegalStateException(); - } - } - - public C putfield(FieldAccessKind fak, S owner, CharSequence name, T type) { - switch (fak) { - case INSTANCE: - return putfield(owner, name, type); - case STATIC: - return putstatic(owner, name, type); - default: - throw new IllegalStateException(); - } - } - - public C invoke(InvocationKind ik, S owner, CharSequence name, T type, boolean isInterface) { - switch (ik) { - case INVOKESTATIC: - return invokestatic(owner, name, type, isInterface); - case INVOKEVIRTUAL: - return invokevirtual(owner, name, type, isInterface); - case INVOKESPECIAL: - return invokespecial(owner, name, type, isInterface); - case INVOKEINTERFACE: - if (!isInterface) throw new AssertionError(); - return invokeinterface(owner, name, type); - default: - throw new IllegalStateException(); - } - } - - public C add(TypeTag type) { - return emitOp(Opcode.IADD.at(type)); - } - - public C sub(TypeTag type) { - return emitOp(Opcode.ISUB.at(type)); - } - - public C mul(TypeTag type) { - return emitOp(Opcode.IMUL.at(type)); - } - - public C div(TypeTag type) { - return emitOp(Opcode.IDIV.at(type)); - } - - public C rem(TypeTag type) { - return emitOp(Opcode.IREM.at(type)); - } - - public C neg(TypeTag type) { - return emitOp(Opcode.INEG.at(type)); - } - - public C shl(TypeTag type) { - return emitOp(Opcode.ISHL.at(type)); - } - - public C shr(TypeTag type) { - return emitOp(Opcode.ISHR.at(type)); - } - - public C ushr(TypeTag type) { - return emitOp(Opcode.ISHR.at(type)); - } - - public C and(TypeTag type) { - return emitOp(Opcode.IAND.at(type)); - } - - public C or(TypeTag type) { - return emitOp(Opcode.IOR.at(type)); - } - - public C xor(TypeTag type) { - return emitOp(Opcode.IXOR.at(type)); - } - - public C return_(TypeTag type) { - switch (type) { - case V: - return return_(); - default: - return emitOp(Opcode.IRETURN.at(type)); - } - } - - @Override - public LabelledTypedBuilder typed(TypeTag typeTag) { - return super.typed(typeTag, _unused -> new LabelledTypedBuilder()); - } - - public class LabelledTypedBuilder extends TypedBuilder { - public C if_acmpeq(CharSequence target) { - return ifcmp(TypeTag.A, CondKind.EQ, target); - } - - public C if_acmpne(CharSequence target) { - return ifcmp(TypeTag.A, CondKind.NE, target); - } - } - - public C conv(TypeTag from, TypeTag to) { - switch (from) { - case B: - case C: - case S: - switch (to) { - case J: - return i2l(); - case F: - return i2f(); - case D: - return i2d(); - } - break; - case I: - switch (to) { - case J: - return i2l(); - case F: - return i2f(); - case D: - return i2d(); - case B: - return i2b(); - case C: - return i2c(); - case S: - return i2s(); - } - break; - case J: - switch (to) { - case I: - return l2i(); - case F: - return l2f(); - case D: - return l2d(); - } - break; - case F: - switch (to) { - case I: - return f2i(); - case J: - return f2l(); - case D: - return f2d(); - } - break; - case D: - switch (to) { - case I: - return d2i(); - case J: - return d2l(); - case F: - return d2f(); - } - break; - } - //no conversion is necessary - do nothing! - return thisBuilder(); - } - - public C if_null(CharSequence label) { - return emitCondJump(Opcode.IF_NULL, Opcode.IF_NONNULL, label); - } - - public C if_nonnull(CharSequence label) { - return emitCondJump(Opcode.IF_NONNULL, Opcode.IF_NULL, label); - } - - public C ifcmp(TypeTag type, CondKind cond, CharSequence label) { - switch (type) { - case I: - return emitCondJump(Opcode.IF_ICMPEQ, cond, label); - case A: - return emitCondJump(Opcode.IF_ACMPEQ, cond, label); - case J: - return lcmp().emitCondJump(Opcode.IFEQ, cond, label); - case D: - return dcmpg().emitCondJump(Opcode.IFEQ, cond, label); - case F: - return fcmpg().emitCondJump(Opcode.IFEQ, cond, label); - default: - throw new IllegalArgumentException("Bad cmp type"); - } - } - - public C goto_(CharSequence label) { - emitOp(jumpMode == JumpMode.NARROW ? Opcode.GOTO_ : Opcode.GOTO_W); - emitOffset(code, jumpMode, labelOffset(label)); - return thisBuilder(); - } - - protected int labelOffset(CharSequence label) { - int pc = code.offset - 1; - Integer labelPc = labels.get(label); - if (labelPc == null) { - addPendingJump(label, pc); - } - return labelPc == null ? 0 : (labelPc - pc); - } - - public C label(CharSequence s) { - int pc = code.offset; - Object old = labels.put(s, pc); - if (old != null) { - throw new IllegalStateException("label already exists"); - } - resolveJumps(s, pc); - return thisBuilder(); - } - - //FIXME: address this jumpy mess - i.e. offset and state update work against each other! - public C emitCondJump(Opcode opcode, CondKind ck, CharSequence label) { - return emitCondJump(opcode.at(ck), opcode.at(ck.negate()), label); - } - - public C emitCondJump(Opcode pos, Opcode neg, CharSequence label) { - if (jumpMode == JumpMode.NARROW) { - emitOp(pos); - emitOffset(code, jumpMode, labelOffset(label)); - } else { - emitOp(neg); - emitOffset(code, JumpMode.NARROW, 8); - goto_w(labelOffset(label)); - } - return thisBuilder(); - } - - void addPendingJump(CharSequence label, int pc) { - pendingJumps.add(new PendingJump(label, pc)); - } - - void resolveJumps(CharSequence label, int pc) { - Iterator jumpsIt = pendingJumps.iterator(); - while (jumpsIt.hasNext()) { - PendingJump jump = jumpsIt.next(); - if (jump.resolve(label, pc)) { - jumpsIt.remove(); - } - } - } - - @Override - protected void emitOffset(GrowableByteBuffer buf, JumpMode jumpMode, int offset) { - if (jumpMode == JumpMode.NARROW && (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE)) { - throw new WideJumpException(); - } - super.emitOffset(buf, jumpMode, offset); - } - - public C jsr(CharSequence label) { - emitOp(jumpMode == JumpMode.NARROW ? Opcode.JSR : Opcode.JSR_W); - emitOffset(code, jumpMode, labelOffset(label)); - return thisBuilder(); - } - - @SuppressWarnings("unchecked") - public C withTry(Consumer tryBlock, Consumer catchBlocks) { - int start = code.offset; - tryBlock.accept((C) this); - int end = code.offset; - CatchBuilder catchBuilder = makeCatchBuilder(start, end); - catchBlocks.accept(catchBuilder); - catchBuilder.build(); - return thisBuilder(); - } - - void clear() { - code.offset = 0; - catchers.offset = 0; - ncatchers = 0; - labels.clear(); - pendingJumps = null; - } - - protected CatchBuilder makeCatchBuilder(int start, int end) { - return new CatchBuilder(start, end); - } - - public class CatchBuilder { - int start, end; - - String endLabel = labelName(); - - Map> catchers = new LinkedHashMap<>(); - public Consumer finalizer; - List pendingGaps = new ArrayList<>(); - - public CatchBuilder(int start, int end) { - this.start = start; - this.end = end; - } - - public CatchBuilder withCatch(S exc, Consumer catcher) { - catchers.put(exc, catcher); - return this; - } - - public CatchBuilder withFinally(Consumer finalizer) { - this.finalizer = finalizer; - return this; - } - - @SuppressWarnings("unchecked") - void build() { - if (finalizer != null) { - finalizer.accept((C) MacroCodeBuilder.this); - } - goto_(endLabel); - for (Map.Entry> catcher_entry : catchers.entrySet()) { - emitCatch(catcher_entry.getKey(), catcher_entry.getValue()); - } - if (finalizer != null) { - emitFinalizer(); - } - resolveJumps(endLabel, code.offset); - } - - @SuppressWarnings("unchecked") - protected void emitCatch(S exc, Consumer catcher) { - int offset = code.offset; - MacroCodeBuilder.this.withCatch(exc, start, end, offset); - catcher.accept((C) MacroCodeBuilder.this); - if (finalizer != null) { - int startFinalizer = code.offset; - finalizer.accept((C) MacroCodeBuilder.this); - pendingGaps.add(startFinalizer); - pendingGaps.add(code.offset); - } - goto_(endLabel); - } - - @SuppressWarnings("unchecked") - protected void emitFinalizer() { - int offset = code.offset; - pop(); - for (int i = 0; i < pendingGaps.size(); i += 2) { - MacroCodeBuilder.this.withCatch(null, pendingGaps.get(i), pendingGaps.get(i + 1), offset); - } - MacroCodeBuilder.this.withCatch(null, start, end, offset); - finalizer.accept((C) MacroCodeBuilder.this); - } - -// @SuppressWarnings("unchecked") -// CatchBuilder withCatch(S exc, Consumer catcher) { -// int offset = code.offset; -// MacroCodeBuilder.this.withCatch(exc, start, end, offset); -// catcher.accept((C)MacroCodeBuilder.this); -// return this; -// } -// -// @SuppressWarnings("unchecked") -// CatchBuilder withFinally(Consumer catcher) { -// int offset = code.offset; -// MacroCodeBuilder.this.withCatch(null, start, end, offset); -// catcher.accept((C)MacroCodeBuilder.this); -// return this; -// } - } - - @SuppressWarnings("unchecked") - public C switch_(Consumer consumer) { - int start = code.offset; - SwitchBuilder sb = makeSwitchBuilder(); - consumer.accept(sb); - int nlabels = sb.cases.size(); - switch (sb.switchCode()) { - case LOOKUPSWITCH: { - int[] lookupOffsets = new int[nlabels * 2]; - int i = 0; - for (Integer v : sb.cases.keySet()) { - lookupOffsets[i] = v; - i += 2; - } - lookupswitch(0, lookupOffsets); - //backpatch lookup - int curr = code.offset - (8 * nlabels) - 8; - int defaultOffset = code.offset - start; - code.withOffset(curr, buf -> emitOffset(buf, JumpMode.WIDE, defaultOffset)); - sb.defaultCase.accept((C) this); - curr += 12; - for (Consumer case_ : sb.cases.values()) { - int offset = code.offset; - code.withOffset(curr, buf -> emitOffset(buf, JumpMode.WIDE, offset - start)); - case_.accept((C) this); - curr += 8; - } - break; - } - case TABLESWITCH: { - int[] tableOffsets = new int[sb.hi - sb.lo + 1]; - tableswitch(sb.lo, sb.hi, 0, tableOffsets); - //backpatch table - int curr = code.offset - (4 * tableOffsets.length) - 12; - int defaultOffset = code.offset - start; - code.withOffset(curr, buf -> emitOffset(buf, JumpMode.WIDE, defaultOffset)); - sb.defaultCase.accept((C) this); - curr += 12; - int lastCasePc = -1; - for (int i = sb.lo; i <= sb.hi; i++) { - Consumer case_ = sb.cases.get(i); - if (case_ != null) { - lastCasePc = code.offset; - case_.accept((C) this); - } - int offset = lastCasePc - start; - code.withOffset(curr, buf -> emitOffset(buf, JumpMode.WIDE, offset)); - curr += 4; - } - } - } - resolveJumps(sb.endLabel, code.offset); - return thisBuilder(); - } - - private static int labelCount = 0; - - String labelName() { - return "label" + labelCount++; - } - - protected SwitchBuilder makeSwitchBuilder() { - return new SwitchBuilder(); - } - - public class SwitchBuilder { - Map> cases = new TreeMap<>(); - int lo = Integer.MAX_VALUE; - int hi = Integer.MIN_VALUE; - String endLabel = labelName(); - - public Consumer defaultCase; - - @SuppressWarnings("unchecked") - public SwitchBuilder withCase(int value, Consumer case_, boolean fallthrough) { - if (value > hi) { - hi = value; - } - if (value < lo) { - lo = value; - } - if (!fallthrough) { - Consumer prevCase = case_; - case_ = C -> { - prevCase.accept(C); - C.goto_(endLabel); - }; - } - cases.put(value, case_); - return this; - } - - @SuppressWarnings("unchecked") - public SwitchBuilder withDefault(Consumer defaultCase) { - if (this.defaultCase != null) { - throw new IllegalStateException("default already set"); - } - this.defaultCase = defaultCase; - return this; - } - - Opcode switchCode() { - int nlabels = cases.size(); - // Determine whether to issue a tableswitch or a lookupswitch - // instruction. - long table_space_cost = 4 + ((long) hi - lo + 1); // words - long lookup_space_cost = 3 + 2 * (long) nlabels; - return - nlabels > 0 && - table_space_cost <= lookup_space_cost - ? - Opcode.TABLESWITCH : Opcode.LOOKUPSWITCH; - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/MemberBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/MemberBuilder.java deleted file mode 100644 index cf32a320a14..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/MemberBuilder.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Class member builder. - * - * @param the type of symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - * @param the type of this builder - */ -public class MemberBuilder> extends DeclBuilder { - - CharSequence name; - T desc; - - /** - * Create a member builder. - * - * @param name the name of the class member - * @param type the type descriptor of the class member - * @param poolHelper the helper to build the constant pool - * @param typeHelper the helper to use to manipulate type descriptors - */ - MemberBuilder(CharSequence name, T type, PoolHelper poolHelper, TypeHelper typeHelper) { - super(poolHelper, typeHelper); - this.name = name; - this.desc = type; - } - - /** - * Build the member. - * - * @param buf the {@code GrowableByteBuffer} to build the member into - */ - protected void build(GrowableByteBuffer buf) { - addAnnotations(); - buf.writeChar(flags); - buf.writeChar(poolHelper.putUtf8(name)); - buf.writeChar(poolHelper.putType(desc)); - buf.writeChar(nattrs); - buf.writeBytes(attributes); - } - - /** - * Build the member. - * - * @return a byte array representation of the member - */ - protected byte[] build() { - GrowableByteBuffer buf = new GrowableByteBuffer(); - addAnnotations(); - build(buf); - return buf.bytes(); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/MethodBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/MethodBuilder.java deleted file mode 100644 index b48fe1a7400..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/MethodBuilder.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import jdk.experimental.bytecode.CodeBuilder.JumpMode; - -import java.util.Iterator; -import java.util.function.Consumer; -import java.util.function.Function; - -public class MethodBuilder extends MemberBuilder> { - - S thisClass; - ParameterAnnotationsBuilder runtimeVisibleParameterAnnotations; - ParameterAnnotationsBuilder runtimeInvisibleParameterAnnotations; - - public MethodBuilder(S thisClass, CharSequence name, T type, PoolHelper pool, TypeHelper typeHelper) { - super(name, type, pool, typeHelper); - this.thisClass = thisClass; - } - - public > MethodBuilder withCode(Function, ? extends C> func, - Consumer code) { - C codeBuilder = func.apply(this); - int start = attributes.offset; - try { - code.accept(codeBuilder); - } catch (MacroCodeBuilder.WideJumpException ex) { - //wide jumps! Redo the code - ((MacroCodeBuilder) codeBuilder).jumpMode = JumpMode.WIDE; - ((MacroCodeBuilder) codeBuilder).clear(); - code.accept(codeBuilder); - } - - attributes.writeChar(poolHelper.putUtf8("Code")); - attributes.writeInt(0); - codeBuilder.build(attributes); - int length = attributes.offset - start; - //avoid using lambda here - int prevOffset = attributes.offset; - try { - attributes.offset = start + 2; - attributes.writeInt(length - 6); - } finally { - attributes.offset = prevOffset; - } - nattrs++; - return this; - } - - public MethodBuilder withCode(Consumer> code) { - return withCode(CodeBuilder::new, code); - } - - @SuppressWarnings({"varargs", "unchecked"}) - public MethodBuilder withExceptions(S... exceptions) { - attributes.writeChar(poolHelper.putUtf8("Exceptions")); - attributes.writeInt(2 + (2 * exceptions.length)); - attributes.writeChar(exceptions.length); - for (S exception : exceptions) { - attributes.writeChar(poolHelper.putClass(exception)); - } - nattrs++; - return this; - } - - public MethodBuilder withParameterAnnotation(AnnotationsBuilder.Kind kind, int nparam, T annoType) { - getParameterAnnotations(kind).builders[nparam].withAnnotation(annoType, null); - return this; - } - - public MethodBuilder withParameterAnnotation(AnnotationsBuilder.Kind kind, int nparam, T annoType, Consumer.AnnotationElementBuilder> annotations) { - getParameterAnnotations(kind).builders[nparam].withAnnotation(annoType, annotations); - return this; - } - - private ParameterAnnotationsBuilder getParameterAnnotations(AnnotationsBuilder.Kind kind) { - switch (kind) { - case RUNTIME_INVISIBLE: - if (runtimeInvisibleParameterAnnotations == null) { - runtimeInvisibleParameterAnnotations = new ParameterAnnotationsBuilder(); - } - return runtimeInvisibleParameterAnnotations; - case RUNTIME_VISIBLE: - if (runtimeVisibleParameterAnnotations == null) { - runtimeVisibleParameterAnnotations = new ParameterAnnotationsBuilder(); - } - return runtimeVisibleParameterAnnotations; - } - throw new IllegalStateException(); - } - - class ParameterAnnotationsBuilder { - - GrowableByteBuffer parameterAnnos = new GrowableByteBuffer(); - - @SuppressWarnings({"unchecked", "rawtypes"}) - AnnotationsBuilder[] builders = new AnnotationsBuilder[nparams()]; - - ParameterAnnotationsBuilder() { - for (int i = 0; i < builders.length; i++) { - builders[i] = new AnnotationsBuilder<>(poolHelper, typeHelper); - } - } - - byte[] build() { - parameterAnnos.writeByte(builders.length); - for (AnnotationsBuilder builder : builders) { - parameterAnnos.writeBytes(builder.build()); - } - return parameterAnnos.bytes(); - } - - int nparams() { - Iterator paramsIt = typeHelper.parameterTypes(desc); - int nparams = 0; - while (paramsIt.hasNext()) { - paramsIt.next(); - nparams++; - } - return nparams; - } - } - - @Override - void addAnnotations() { - super.addAnnotations(); - if (runtimeInvisibleParameterAnnotations != null) { - withAttribute("RuntimeInvisibleParameterAnnotations", runtimeInvisibleParameterAnnotations.build()); - } - if (runtimeVisibleParameterAnnotations != null) { - withAttribute("RuntimeVisibleParameterAnnotations", runtimeVisibleParameterAnnotations.build()); - } - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/Opcode.java b/src/java.base/share/classes/jdk/experimental/bytecode/Opcode.java deleted file mode 100644 index 69ce28e1c5d..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/Opcode.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import jdk.experimental.bytecode.MacroCodeBuilder.CondKind; - -public enum Opcode { - - NOP(0), - ACONST_NULL(1), - ICONST_M1(2), - ICONST_0(3), - ICONST_1(4), - ICONST_2(5), - ICONST_3(6), - ICONST_4(7), - ICONST_5(8), - LCONST_0(9), - LCONST_1(10), - FCONST_0(11), - FCONST_1(12), - FCONST_2(13), - DCONST_0(14), - DCONST_1(15), - BIPUSH(16), - SIPUSH(17), - LDC(18), - LDC_W(19), - LDC2_W(20), - ILOAD(21), - LLOAD(22), - FLOAD(23), - DLOAD(24), - ALOAD(25), - ILOAD_0(26), - ILOAD_1(27), - ILOAD_2(28), - ILOAD_3(29), - LLOAD_0(30), - LLOAD_1(31), - LLOAD_2(32), - LLOAD_3(33), - FLOAD_0(34), - FLOAD_1(35), - FLOAD_2(36), - FLOAD_3(37), - DLOAD_0(38), - DLOAD_1(39), - DLOAD_2(40), - DLOAD_3(41), - ALOAD_0(42), - ALOAD_1(43), - ALOAD_2(44), - ALOAD_3(45), - IALOAD(46), - LALOAD(47), - FALOAD(48), - DALOAD(49), - AALOAD(50), - BALOAD(51), - CALOAD(52), - SALOAD(53), - ISTORE(54), - LSTORE(55), - FSTORE(56), - DSTORE(57), - ASTORE(58), - ISTORE_0(59), - ISTORE_1(60), - ISTORE_2(61), - ISTORE_3(62), - LSTORE_0(63), - LSTORE_1(64), - LSTORE_2(65), - LSTORE_3(66), - FSTORE_0(67), - FSTORE_1(68), - FSTORE_2(69), - FSTORE_3(70), - DSTORE_0(71), - DSTORE_1(72), - DSTORE_2(73), - DSTORE_3(74), - ASTORE_0(75), - ASTORE_1(76), - ASTORE_2(77), - ASTORE_3(78), - IASTORE(79), - LASTORE(80), - FASTORE(81), - DASTORE(82), - AASTORE(83), - BASTORE(84), - CASTORE(85), - SASTORE(86), - POP(87), - POP2(88), - DUP(89), - DUP_X1(90), - DUP_X2(91), - DUP2(92), - DUP2_X1(93), - DUP2_X2(94), - SWAP(95), - IADD(96), - LADD(97), - FADD(98), - DADD(99), - ISUB(100), - LSUB(101), - FSUB(102), - DSUB(103), - IMUL(104), - LMUL(105), - FMUL(106), - DMUL(107), - IDIV(108), - LDIV(109), - FDIV(110), - DDIV(111), - IREM(112), - LREM(113), - FREM(114), - DREM(115), - INEG(116), - LNEG(117), - FNEG(118), - DNEG(119), - ISHL(120), - LSHL(121), - ISHR(122), - LSHR(123), - IUSHR(124), - LUSHR(125), - IAND(126), - LAND(127), - IOR(128), - LOR(129), - IXOR(130), - LXOR(131), - IINC(132), - I2L(133), - I2F(134), - I2D(135), - L2I(136), - L2F(137), - L2D(138), - F2I(139), - F2L(140), - F2D(141), - D2I(142), - D2L(143), - D2F(144), - I2B(145), - I2C(146), - I2S(147), - LCMP(148), - FCMPL(149), - FCMPG(150), - DCMPL(151), - DCMPG(152), - IFEQ(153), - IFNE(154), - IFLT(155), - IFGE(156), - IFGT(157), - IFLE(158), - IF_ICMPEQ(159), - IF_ICMPNE(160), - IF_ICMPLT(161), - IF_ICMPGE(162), - IF_ICMPGT(163), - IF_ICMPLE(164), - IF_ACMPEQ(165), - IF_ACMPNE(166), - GOTO_(167), - JSR(168), - RET(169), - TABLESWITCH(170), - LOOKUPSWITCH(171), - IRETURN(172), - LRETURN(173), - FRETURN(174), - DRETURN(175), - ARETURN(176), - RETURN(177), - GETSTATIC(178), - PUTSTATIC(179), - GETFIELD(180), - PUTFIELD(181), - INVOKEVIRTUAL(182), - INVOKESPECIAL(183), - INVOKESTATIC(184), - INVOKEINTERFACE(185), - INVOKEDYNAMIC(186), - NEW(187), - NEWARRAY(188), - ANEWARRAY(189), - ARRAYLENGTH(190), - ATHROW(191), - CHECKCAST(192), - INSTANCEOF(193), - MONITORENTER(194), - MONITOREXIT(195), - WIDE(196), - MULTIANEWARRAY(197), - IF_NULL(198), - IF_NONNULL(199), - GOTO_W(200), - JSR_W(201), - DEFAULTVALUE(203), - WITHFIELD(204), - TYPED(212); - - int code; - - Opcode(int code) { - this.code = code; - } - - protected Opcode at(TypeTag type) { - return at(type, 1); - } - - protected Opcode at(CondKind cond) { - return at(cond.offset, 1); - } - - protected Opcode at(TypeTag type, int multiplier) { - return at(type.offset, multiplier); - } - - private Opcode at(int offset, int multiplier) { - if (offset < 0) throw new AssertionError(); - return Opcode.values()[code + (multiplier * offset)]; - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/Pool.java b/src/java.base/share/classes/jdk/experimental/bytecode/Pool.java deleted file mode 100644 index 6a2b2fb173c..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/Pool.java +++ /dev/null @@ -1,981 +0,0 @@ -/* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; - -/** - * See JVMS, section 4. - * - * Representation of a Constant Pool, where subclasses of PoolInfo represent the - * entries. Concrete implementations provide access to pool entries by index. - */ -public abstract class Pool { - - public static final int CLASS_TAG = 7; - public static final int CONSTANTDYNAMIC_TAG = 17; - public static final int DOUBLE_TAG = 6; - public static final int FIELDREF_TAG = 9; - public static final int FLOAT_TAG = 4; - public static final int INTEGER_TAG = 3; - public static final int INTERFACEMETHODREF_TAG = 11; - public static final int INVOKEDYNAMIC_TAG = 18; - public static final int LONG_TAG = 5; - public static final int METHODHANDLE_TAG = 15; - public static final int METHODREF_TAG = 10; - public static final int METHODTYPE_TAG = 16; - public static final int MODULE_TAG = 19; - public static final int NAMEANDTYPE_TAG = 12; - public static final int PACKAGE_TAG = 20; - public static final int STRING_TAG = 8; - public static final int UNICODE_TAG = 2; - public static final int UTF8_TAG = 1; - - protected abstract PoolInfo getSafe(int index); - - public abstract int size(); - - public PoolInfo get(int index) throws InvalidIndex { - if (index <= 0 || index >= size()) - throw new InvalidIndex(index); - PoolInfo info = getSafe(index); - if (info == null) { - // this occurs for indices referencing the "second half" of an - // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long - throw new InvalidIndex(index); - } - return info; - } - - public int byteLength() { - int length = 2; - for (int i = 1; i < size();) { - PoolInfo cpInfo = getSafe(i); - length += cpInfo.byteLength(); - i += cpInfo.size(); - } - return length; - } - - public Iterable entries() { - return () -> new Iterator() { - - @Override - public boolean hasNext() { - return next < size; - } - - @Override - public PoolInfo next() { - PoolInfo pi = getSafe(next); - switch (pi.getTag()) { - case DOUBLE_TAG: - case LONG_TAG: - next += 2; - break; - default: - next += 1; - } - return pi; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private int next = 1; - private final int size = size(); - - }; - } - - public Iterable entriesAndIndicies() { - return () -> new Iterator() { - - @Override - public boolean hasNext() { - return next < size; - } - - @Override - public PoolInfoAndIndex next() { - int i = next; - PoolInfo pi = getSafe(i); - switch (pi.getTag()) { - case DOUBLE_TAG: - case LONG_TAG: - next += 2; - break; - default: - next += 1; - } - return new PoolInfoAndIndex(pi, i); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private int next = 1; - private final int size = size(); - - }; - } - - - public class PoolInfoAndIndex { - public final PoolInfo info; - public final int index; - PoolInfoAndIndex(PoolInfo info, int index) { - this.info = info; - this.index = index; - } - } - - private PoolInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry { - PoolInfo info = get(index); - if (info.getTag() != expected_type) { - throw new UnexpectedEntry(index, expected_type, info.getTag()); - } - return info; - } - - public Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry { - return ((Utf8_info) get(index, UTF8_TAG)); - } - - public Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry { - return ((Class_info) get(index, CLASS_TAG)); - } - - public Module_info getModuleInfo(int index) throws InvalidIndex, UnexpectedEntry { - return ((Module_info) get(index, MODULE_TAG)); - } - - public NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry { - return ((NameAndType_info) get(index, NAMEANDTYPE_TAG)); - } - - public Package_info getPackageInfo(int index) throws InvalidIndex, UnexpectedEntry { - return ((Package_info) get(index, PACKAGE_TAG)); - } - - public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry { - return getUTF8Info(index).value; - } - - public int getUTF8Index(String value) throws EntryNotFound { - for (int i = 1; i < size(); i++) { - PoolInfo info = getSafe(i); - if (info instanceof Utf8_info && - ((Utf8_info) info).value.equals(value)) - return i; - } - throw new EntryNotFound(value); - } - - public interface Visitor { - - R visitClass(Class_info info, P p); - - R visitDouble(Double_info info, P p); - - R visitFieldref(Fieldref_info info, P p); - - R visitFloat(Float_info info, P p); - - R visitInteger(Integer_info info, P p); - - R visitInterfaceMethodref(InterfaceMethodref_info info, P p); - - R visitInvokeDynamic(InvokeDynamic_info info, P p); - - R visitLong(Long_info info, P p); - - R visitMethodref(Methodref_info info, P p); - - R visitMethodHandle(MethodHandle_info info, P p); - - R visitMethodType(MethodType_info info, P p); - - R visitModule(Module_info info, P p); - - R visitNameAndType(NameAndType_info info, P p); - - R visitPackage(Package_info info, P p); - - R visitString(String_info info, P p); - - R visitUtf8(Utf8_info info, P p); - } - - public abstract class PoolInfo { - - public Pool getPool() { - return Pool.this; - } - - public abstract int getTag(); - - /** - * @return The number of slots in the constant pool used by this entry. - * 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. - */ - public int size() { - return 1; - } - - public abstract int byteLength(); - - public abstract R accept(Visitor visitor, D data); - } - - public abstract class RefPoolInfo extends PoolInfo { - - protected RefPoolInfo(int tag, int class_index, int name_and_type_index) { - this.tag = tag; - this.class_index = class_index; - this.name_and_type_index = name_and_type_index; - } - - @Override - public int getTag() { - return tag; - } - - @Override - public int byteLength() { - return 5; - } - - public Class_info getClassInfo() throws PoolException { - return Pool.this.getClassInfo(class_index); - } - - public String getClassName() throws PoolException { - return Pool.this.getClassInfo(class_index).getName(); - } - - public NameAndType_info getNameAndTypeInfo() throws PoolException { - return Pool.this.getNameAndTypeInfo(name_and_type_index); - } - - public final int tag; - public final int class_index; - public final int name_and_type_index; - } - - public class Class_info extends PoolInfo { - - public Class_info(int name_index) { - this.name_index = name_index; - } - - @Override - public int getTag() { - return CLASS_TAG; - } - - @Override - public int byteLength() { - return 3; - } - - /** - * Get the raw value of the class referenced by this constant pool - * entry.This will either be the name of the class, in internal form, or - * a descriptor for an array class. - * - * @return the raw value of the class - * @throws PoolException - */ - public String getName() throws PoolException { - return getUTF8Value(name_index); - } - - /** - * If this constant pool entry identifies either a class or interface - * type, or a possibly multi-dimensional array of a class of interface - * type, return the name of the class or interface in internal - * form.Otherwise, (i.e. if this is a possibly multi-dimensional array - * of a primitive type), return null. - * - * @return the base class or interface name - * @throws PoolException - */ - public String getBaseName() throws PoolException { - String name = getName(); - if (name.startsWith("[")) { - int index = name.indexOf("[L"); - if (index == -1) - index = name.indexOf("[Q"); - if (index == -1) { - return null; - } - return name.substring(index + 2, name.length() - 1); - } else { - return name; - } - } - - public int getDimensionCount() throws PoolException { - String name = getName(); - int count = 0; - while (name.charAt(count) == '[') { - count++; - } - return count; - } - - @Override - public String toString() { - return "CONSTANT_Class_info[name_index: " + name_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitClass(this, data); - } - - public final int name_index; - } - - public class Double_info extends PoolInfo { - - public Double_info(double value) { - this.value = value; - } - - @Override - public int getTag() { - return DOUBLE_TAG; - } - - @Override - public int byteLength() { - return 9; - } - - @Override - public int size() { - return 2; - } - - @Override - public String toString() { - return "CONSTANT_Double_info[value: " + value + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitDouble(this, data); - } - - public final double value; - } - - public class Fieldref_info extends RefPoolInfo { - - public Fieldref_info(int class_index, int name_and_type_index) { - super(FIELDREF_TAG, class_index, name_and_type_index); - } - - @Override - public String toString() { - return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitFieldref(this, data); - } - } - - public class Float_info extends PoolInfo { - - public Float_info(float value) { - this.value = value; - } - - @Override - public int getTag() { - return FLOAT_TAG; - } - - @Override - public int byteLength() { - return 5; - } - - @Override - public String toString() { - return "CONSTANT_Float_info[value: " + value + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitFloat(this, data); - } - - public final float value; - } - - public class Integer_info extends PoolInfo { - - public Integer_info(int value) { - this.value = value; - } - - @Override - public int getTag() { - return INTEGER_TAG; - } - - @Override - public int byteLength() { - return 5; - } - - @Override - public String toString() { - return "CONSTANT_Integer_info[value: " + value + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitInteger(this, data); - } - - public final int value; - } - - public class InterfaceMethodref_info extends RefPoolInfo { - - public InterfaceMethodref_info(int class_index, int name_and_type_index) { - super(INTERFACEMETHODREF_TAG, class_index, name_and_type_index); - } - - @Override - public String toString() { - return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitInterfaceMethodref(this, data); - } - } - - public class InvokeDynamic_info extends PoolInfo { - - public InvokeDynamic_info(int bootstrap_method_index, int name_and_type_index) { - this.bootstrap_method_attr_index = bootstrap_method_index; - this.name_and_type_index = name_and_type_index; - } - - @Override - public int getTag() { - return INVOKEDYNAMIC_TAG; - } - - @Override - public int byteLength() { - return 5; - } - - @Override - public String toString() { - return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitInvokeDynamic(this, data); - } - - public NameAndType_info getNameAndTypeInfo() throws PoolException { - return Pool.this.getNameAndTypeInfo(name_and_type_index); - } - - public final int bootstrap_method_attr_index; - public final int name_and_type_index; - } - - public class Long_info extends PoolInfo { - - public Long_info(long value) { - this.value = value; - } - - @Override - public int getTag() { - return LONG_TAG; - } - - @Override - public int size() { - return 2; - } - - @Override - public int byteLength() { - return 9; - } - - @Override - public String toString() { - return "CONSTANT_Long_info[value: " + value + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitLong(this, data); - } - - public final long value; - } - - public class MethodHandle_info extends PoolInfo { - - public MethodHandle_info(int ref_kind, int member_index) { - this.reference_kind = ref_kind; - this.reference_index = member_index; - } - - @Override - public int getTag() { - return METHODHANDLE_TAG; - } - - @Override - public int byteLength() { - return 4; - } - - @Override - public String toString() { - return "CONSTANT_MethodHandle_info[ref_kind: " + RefKind.getRefkind(reference_kind) + ", member_index: " + reference_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitMethodHandle(this, data); - } - - public RefPoolInfo getRefPoolInfo() throws PoolException { - int expected = METHODREF_TAG; - int actual = Pool.this.get(reference_index).getTag(); - // allow these tag types also: - switch (actual) { - case FIELDREF_TAG: - case INTERFACEMETHODREF_TAG: - expected = actual; - } - return (RefPoolInfo) Pool.this.get(reference_index, expected); - } - - public final int reference_kind; - public final int reference_index; - } - - public class MethodType_info extends PoolInfo { - - public MethodType_info(int signature_index) { - this.descriptor_index = signature_index; - } - - @Override - public int getTag() { - return METHODTYPE_TAG; - } - - @Override - public int byteLength() { - return 3; - } - - @Override - public String toString() { - return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitMethodType(this, data); - } - - public String getType() throws PoolException { - return Pool.this.getUTF8Value(descriptor_index); - } - - public final int descriptor_index; - } - - public class Methodref_info extends RefPoolInfo { - - public Methodref_info(int class_index, int name_and_type_index) { - super(METHODREF_TAG, class_index, name_and_type_index); - } - - @Override - public String toString() { - return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitMethodref(this, data); - } - } - - public class Module_info extends PoolInfo { - - public Module_info(int name_index) { - this.name_index = name_index; - } - - @Override - public int getTag() { - return MODULE_TAG; - } - - @Override - public int byteLength() { - return 3; - } - - /** - * Get the raw value of the module name referenced by this constant pool - * entry. This will be the name of the module. - * - * @return the raw value of the module name - */ - public String getName() throws PoolException { - return Pool.this.getUTF8Value(name_index); - } - - @Override - public String toString() { - return "CONSTANT_Module_info[name_index: " + name_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitModule(this, data); - } - - public final int name_index; - } - - public class NameAndType_info extends PoolInfo { - - public NameAndType_info(int name_index, int type_index) { - this.name_index = name_index; - this.type_index = type_index; - } - - @Override - public int getTag() { - return NAMEANDTYPE_TAG; - } - - @Override - public int byteLength() { - return 5; - } - - public String getName() throws PoolException { - return Pool.this.getUTF8Value(name_index); - } - - public String getType() throws PoolException { - return Pool.this.getUTF8Value(type_index); - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitNameAndType(this, data); - } - - @Override - public String toString() { - return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]"; - } - - public final int name_index; - public final int type_index; - } - - public class Package_info extends PoolInfo { - - public Package_info(int name_index) { - this.name_index = name_index; - } - - @Override - public int getTag() { - return PACKAGE_TAG; - } - - @Override - public int byteLength() { - return 3; - } - - /** - * Get the raw value of the package name referenced by this constant - * pool entry.This will be the name of the package, in internal form. - * - * @return the raw value of the module name - * @throws jdk.experimental.bytecode.classfile.ConstantPoolException - */ - public String getName() throws PoolException { - return Pool.this.getUTF8Value(name_index); - } - - @Override - public String toString() { - return "CONSTANT_Package_info[name_index: " + name_index + "]"; - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitPackage(this, data); - } - - public final int name_index; - } - - public class String_info extends PoolInfo { - - public String_info(int string_index) { - this.string_index = string_index; - } - - @Override - public int getTag() { - return STRING_TAG; - } - - @Override - public int byteLength() { - return 3; - } - - public String getString() throws PoolException { - return Pool.this.getUTF8Value(string_index); - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitString(this, data); - } - - @Override - public String toString() { - return "CONSTANT_String_info[class_index: " + string_index + "]"; - } - - public final int string_index; - } - - public class Utf8_info extends PoolInfo { - - public Utf8_info(String value) { - this.value = value; - } - - @Override - public int getTag() { - return UTF8_TAG; - } - - @Override - public int byteLength() { - class SizeOutputStream extends OutputStream { - - @Override - public void write(int b) { - size++; - } - int size; - } - SizeOutputStream sizeOut = new SizeOutputStream(); - DataOutputStream out = new DataOutputStream(sizeOut); - try { - out.writeUTF(value); - } catch (IOException ignore) { - } - return 1 + sizeOut.size; - } - - @Override - public String toString() { - if (value.length() < 32 && isPrintableAscii(value)) { - return "CONSTANT_Utf8_info[value: \"" + value + "\"]"; - } else { - return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]"; - } - } - - @Override - public R accept(Visitor visitor, D data) { - return visitor.visitUtf8(this, data); - } - - public final String value; - } - - public static enum RefKind { - GETFIELD_REF(1), - GETSTATIC_REF(2), - PUTFIELD_REF(3), - PUTSTATIC_REF(4), - INVOKEVIRTUAL_REF(5), - INVOKESTATIC_REF(6), - INVOKESPECIAL_REF(7), - NEWINVOKESPECIAL_REF(8), - INVOKEINTERFACE_REF(9); - - public final int tag; - - RefKind(int tag) { - this.tag = tag; - } - - public static RefKind getRefkind(int tag) { - switch (tag) { - case 1: - return GETFIELD_REF; - case 2: - return GETSTATIC_REF; - case 3: - return PUTFIELD_REF; - case 4: - return PUTSTATIC_REF; - case 5: - return INVOKEVIRTUAL_REF; - case 6: - return INVOKESTATIC_REF; - case 7: - return INVOKESPECIAL_REF; - case 8: - return NEWINVOKESPECIAL_REF; - case 9: - return INVOKEINTERFACE_REF; - default: - return null; - } - } - } - - static boolean isPrintableAscii(String s) { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c < 32 || c >= 127) { - return false; - } - } - return true; - } - - public static class InvalidIndex extends PoolException { - - private static final long serialVersionUID = -4350294289300939730L; - - public InvalidIndex(int index) { - super(index); - } - - @Override - public String getMessage() { - // i18n - return "invalid index #" + index; - } - } - - public static class UnexpectedEntry extends PoolException { - - private static final long serialVersionUID = 6986335935377933211L; - - public UnexpectedEntry(int index, int expected_tag, int found_tag) { - super(index); - this.expected_tag = expected_tag; - this.found_tag = found_tag; - } - - @Override - public String getMessage() { - // i18n? - return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag; - } - - public final int expected_tag; - public final int found_tag; - } - - public static class InvalidEntry extends PoolException { - - private static final long serialVersionUID = 1000087545585204447L; - - public InvalidEntry(int index, int tag) { - super(index); - this.tag = tag; - } - - @Override - public String getMessage() { - // i18n? - return "unexpected tag at #" + index + ": " + tag; - } - - public final int tag; - } - - public static class EntryNotFound extends PoolException { - - private static final long serialVersionUID = 2885537606468581850L; - - public EntryNotFound(Object value) { - super(-1); - this.value = value; - } - - @Override - public String getMessage() { - // i18n? - return "value not found: " + value; - } - - public final Object value; - } - -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/PoolBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/PoolBuilder.java deleted file mode 100644 index 3452768c8ec..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/PoolBuilder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/** - * Interface for low-level building of constant pool. Indicies are used rather - * than strings and thus component parts aren't added automatically. - * - * @param the type of the constant pool representation that is built - */ -public interface PoolBuilder { - - int putClass(int utf8_idx); - - int putConstantDynamic(int bsmIndex, int nameAndType_idx); - - int putDouble(double d); - - int putFieldRef(int owner_idx, int nameAndType_idx); - - int putFloat(float f); - - int putMethodHandle(int refKind, int ref_idx); - - int putInt(int i); - - int putInvokeDynamic(int bsmIndex, int nameAndType_idx); - - int putLong(long l); - - int putMemberRef(PoolTag tag, int owner_idx, int nameAndType_idx); - - int putMethodRef(int owner_idx, int nameAndType_idx, boolean isInterface); - - int putMethodType(int desc_idx); - - int putNameAndType(int name_idx, int type_idx); - - int putString(int utf8_index); - - int putUtf8(CharSequence s); - - /** - * - * @return count of constant pool indicies - */ - int size(); - - /** - * - * @return the representation of the constant pool - */ - R representation(); - -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/PoolException.java b/src/java.base/share/classes/jdk/experimental/bytecode/PoolException.java deleted file mode 100644 index e1a3dc05095..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/PoolException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -/* - * Base constant pool exception. - */ -public class PoolException extends Exception { - private static final long serialVersionUID = -2324397349644754565L; - public PoolException(int index) { - this.index = index; - } - - public final int index; -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/PoolHelper.java b/src/java.base/share/classes/jdk/experimental/bytecode/PoolHelper.java deleted file mode 100644 index e4b74aa0dbe..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/PoolHelper.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.function.Consumer; -import java.util.function.ToIntBiFunction; - -/** - * An interface for building and tracking constant pools. - * - * @param the type of the symbol representation - * @param the type of type descriptors representation - * @param the type of pool entries - */ -public interface PoolHelper { - int putClass(S symbol); - - int putValueClass(S symbol); - - int putFieldRef(S owner, CharSequence name, T type); - - int putMethodRef(S owner, CharSequence name, T type, boolean isInterface); - - int putUtf8(CharSequence s); - - int putInt(int i); - - int putFloat(float f); - - int putLong(long l); - - int putDouble(double d); - - int putString(String s); - - int putValue(Object v); - - int putType(T t); - - int putMethodType(T t); - - int putMethodHandle(int refKind, S owner, CharSequence name, T type); - - int putMethodHandle(int refKind, S owner, CharSequence name, T type, boolean isInterface); - - int putInvokeDynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs); - - int putConstantDynamic(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs); - - int size(); - - R representation(); - - interface StaticArgListBuilder { - StaticArgListBuilder add(int i); - StaticArgListBuilder add(float f); - StaticArgListBuilder add(long l); - StaticArgListBuilder add(double d); - StaticArgListBuilder add(String s); - StaticArgListBuilder add(int refKind, S owner, CharSequence name, T type); - StaticArgListBuilder add(Z z, ToIntBiFunction, Z> poolFunc); - StaticArgListBuilder add(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgList); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/PoolTag.java b/src/java.base/share/classes/jdk/experimental/bytecode/PoolTag.java deleted file mode 100644 index 5e8bb1accd9..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/PoolTag.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import static jdk.experimental.bytecode.Pool.*; - -public enum PoolTag { - UTF8 (UTF8_TAG), - UNICODE (UNICODE_TAG), - INTEGER (INTEGER_TAG), - FLOAT (FLOAT_TAG), - LONG (LONG_TAG), - DOUBLE (DOUBLE_TAG), - CLASS (CLASS_TAG), - STRING (STRING_TAG), - FIELDREF (FIELDREF_TAG), - METHODREF (METHODREF_TAG), - INTERFACEMETHODREF (INTERFACEMETHODREF_TAG), - NAMEANDTYPE (NAMEANDTYPE_TAG), - METHODHANDLE (METHODHANDLE_TAG), - METHODTYPE (METHODTYPE_TAG), - CONSTANTDYNAMIC (CONSTANTDYNAMIC_TAG), - INVOKEDYNAMIC (INVOKEDYNAMIC_TAG), - MODULE (MODULE_TAG), - PACKAGE (PACKAGE_TAG); - - public final int tag; - - PoolTag(int tag) { - this.tag = tag; - } - - static PoolTag from(int tag) { - return values()[tag - 1]; - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/Type.java b/src/java.base/share/classes/jdk/experimental/bytecode/Type.java deleted file mode 100644 index 706ef105bd0..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/Type.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -public interface Type { - TypeTag getTag(); -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/TypeHelper.java b/src/java.base/share/classes/jdk/experimental/bytecode/TypeHelper.java deleted file mode 100644 index daa5476a6e4..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/TypeHelper.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.util.Iterator; - -/** - * Helper to create and manipulate type descriptors of T. - * - * @param the type of symbols - * @param the type of type descriptors - */ -public interface TypeHelper { - /** - * Return the type descriptor of an element given the type - * descriptor of an array. - * - * @param t the type descriptor of the array - * @return the element type - */ - T elemtype(T t); - - /** - * Return the type descriptor of an array given the type descriptor - * of an element. - * - * @param t the type descriptor of the element - * @return the type descriptor of the array - */ - T arrayOf(T t); - - /** - * Return an iterator over the type descriptors of the parameters of a - * method. - * - * @param t the method type descriptor - * @return an iterator over the type descriptors of the parameters - */ - Iterator parameterTypes(T t); - - /** - * Return the type descriptor of a {@code TypeTag}. - * - * @param tag the {@code TypeTag} of a primitive type - * @return the type descriptor of the primitive type - */ - T fromTag(TypeTag tag); - - /** - * Return the return type descriptor of a method. - * - * @param t the method type descriptor - * @return the return type descriptor - */ - T returnType(T t); - - /** - * Return the type descriptor for a symbol. - * - * @param s the symbol - * @return the type descriptor - */ - T type(S s); - - /** - * Return true if the parameter is a value type. - * - * @param t the type descreiptor - * @return true if the given type is a value type - */ - boolean isValue(T t); - - /** - * For a symbol that corresponds to a value type, return the type descriptor. - * - * @param s the symbol - * @return the type descriptor - */ - default T valueType(S s) { - return type(s); - } - - /** - * Return the symbol corresponding to a type descriptor. - * - * @param type the type descriptor - * @return the symbol - */ - S symbol(T type); - - /** - * Return the {@code TypeTag} corresponding to a type descriptor. Reference - * types return {@code TypeTag.A}. - * - * @param t a type descriptor - * @return the corresponding {@code TypeTag} - */ - TypeTag tag(T t); - - /** - * Return the symbol corresponding to a JVM type descriptor string. - * - * @param s a JVM type descriptor string - * @return the corresponding symbol - */ - S symbolFrom(String s); - - /** - * Return the common supertype descriptor of two type descriptors. - * - * @param t1 a type descriptor - * @param t2 a type descriptor - * @return the common supertype descriptor - */ - T commonSupertype(T t1, T t2); - - /** - * Return the type descriptor for the null type. - * - * @return the type descriptor for the null type - */ - T nullType(); -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/TypeTag.java b/src/java.base/share/classes/jdk/experimental/bytecode/TypeTag.java deleted file mode 100644 index 5abacf52fec..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/TypeTag.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -public enum TypeTag implements Type { - /** - * byte - */ - B("B", 0, 1, 8), - /** - * short - */ - S("S", 0, 1, 9), - /** - * int - */ - I("I", 0, 1, 10), - /** - * float - */ - F("F", 2, 1, 6), - /** - * long - */ - J("J", 1, 2, 11), - /** - * double - */ - D("D", 3, 2, 7), - /** - * Reference type - */ - A("A", 4, 1, -1), - /** - * char - */ - C("C", 0, 1, 5), - /** - * boolean - */ - Z("Z", 0, 1, 4), - /** - * void - */ - V("V", -1, -1, -1); - - String typeStr; - int offset; - int width; - int newarraycode; - - TypeTag(String typeStr, int offset, int width, int newarraycode) { - this.typeStr = typeStr; - this.offset = offset; - this.width = width; - this.newarraycode = newarraycode; - } - - static TypeTag commonSupertype(TypeTag t1, TypeTag t2) { - if (t1.isIntegral() && t2.isIntegral()) { - int p1 = t1.ordinal(); - int p2 = t2.ordinal(); - return (p1 <= p2) ? t2 : t1; - } else { - return null; - } - } - - public int width() { - return width; - } - - boolean isIntegral() { - switch (this) { - case B: - case S: - case I: - return true; - default: - return false; - } - } - - @Override - public TypeTag getTag() { - return this; - } -} diff --git a/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java b/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java deleted file mode 100644 index 53e2b40bb35..00000000000 --- a/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.bytecode; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Vector; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.function.ToIntFunction; - -public class TypedCodeBuilder> extends MacroCodeBuilder { - - State lastStackMapState; - int lastStackMapPc = -1; - Map lvarOffsets = new HashMap<>(); - protected State state; - int depth = 0; - int currLocalOffset = 0; - - class StatefulPendingJump extends PendingJump { - - State state; - - StatefulPendingJump(CharSequence label, int pc, State state) { - super(label, pc); - this.state = state; - } - - @Override - boolean resolve(CharSequence label, int pc) { - boolean b = super.resolve(label, pc); - if (b) { - TypedCodeBuilder.this.state = TypedCodeBuilder.this.state.merge(state); - } - return b; - } - } - - class LocalVarInfo { - CharSequence name; - int offset; - int depth; - TypeTag type; - - LocalVarInfo(CharSequence name, int offset, int depth, TypeTag type) { - this.name = name; - this.offset = offset; - this.depth = depth; - this.type = type; - } - } - - public TypedCodeBuilder(MethodBuilder methodBuilder) { - super(methodBuilder); - T t = methodBuilder.desc; - state = new State(); - if ((methodBuilder.flags & Flag.ACC_STATIC.flag) == 0) { - T clazz = typeHelper.type(methodBuilder.thisClass); - state.load(clazz, currLocalOffset++); //TODO: uninit?? - } - Iterator paramsIt = typeHelper.parameterTypes(t); - while (paramsIt.hasNext()) { - T p = paramsIt.next(); - state.load(p, currLocalOffset); - currLocalOffset += typeHelper.tag(p).width; - } - lastStackMapState = state.dup(); - stacksize = state.stack.size(); - localsize = state.locals.size(); - } - - @Override - protected C emitOp(Opcode opcode, Object optPoolValue) { - updateState(opcode, optPoolValue); - return super.emitOp(opcode, optPoolValue); - } - - @Override - protected SwitchBuilder makeSwitchBuilder() { - return new TypedSwitchBuilder(); - } - - class TypedSwitchBuilder extends SwitchBuilder { - - @Override - public SwitchBuilder withCase(int value, Consumer case_, boolean fallthrough) { - super.withCase(value, c -> { - withLocalScope(() -> { - State prevState = state; - state = prevState.dup(); - emitStackMap(c.offset()); - case_.accept(c); - state = prevState; - }); - }, fallthrough); - return this; - } - - @Override - public SwitchBuilder withDefault(Consumer defaultCase) { - super.withDefault(c -> { - withLocalScope(() -> { - State prevState = state; - state = prevState.dup(); - emitStackMap(c.offset()); - defaultCase.accept(c); - state = prevState; - }); - }); - return this; - } - } - - @Override - public StatefulTypedBuilder typed(TypeTag tag) { - return super.typed(tag, StatefulTypedBuilder::new); - } - - public class StatefulTypedBuilder extends LabelledTypedBuilder { - - TypeTag tag; - - StatefulTypedBuilder(TypeTag tag) { - this.tag = tag; - } - - @Override - public C astore_0() { - return storeAndUpdate(super::astore_0); - } - - @Override - public C astore_1() { - return storeAndUpdate(super::astore_1); - } - - @Override - public C astore_2() { - return storeAndUpdate(super::astore_2); - } - - @Override - public C astore_3() { - return storeAndUpdate(super::astore_3); - } - - @Override - public C astore(int n) { - return storeAndUpdate(() -> super.astore(n)); - } - - @Override - public C aastore() { - return storeAndUpdate(super::aastore); - } - - @Override - public C areturn() { - state.pop(tag); - state.push(typeHelper.nullType()); - return super.areturn(); - } - - @Override - public C anewarray(S s) { - super.anewarray(s); - state.pop(); - state.push(typeHelper.arrayOf(typeHelper.type(s))); - return thisBuilder(); - } - - @Override - public C anewvaluearray(S s) { - super.anewvaluearray(s); - state.pop(); - state.push(typeHelper.arrayOf(typeHelper.valueType(s))); - return thisBuilder(); - } - - @Override - public C aconst_null() { - super.aconst_null(); - state.pop(); - state.push(tag); - return thisBuilder(); - } - - public C if_acmpeq(CharSequence label) { - return jumpAndUpdate(() -> super.if_acmpeq(label)); - } - - public C if_acmpne(CharSequence label) { - return jumpAndUpdate(() -> super.if_acmpne(label)); - } - - private C storeAndUpdate(Supplier op) { - state.pop(tag); - state.push(typeHelper.nullType()); - return op.get(); - } - - private C jumpAndUpdate(Supplier op) { - state.pop(tag); - state.pop(tag); - state.push(typeHelper.nullType()); - state.push(typeHelper.nullType()); - return op.get(); - } - } - - public class State { - public final ArrayList stack; - public final Vector locals; - boolean alive; - - State(ArrayList stack, Vector locals) { - this.stack = stack; - this.locals = locals; - this.alive = true; - } - - State() { - this(new ArrayList<>(), new Vector<>()); - } - - void push(TypeTag tag) { - switch (tag) { - case A: - case V: - throw new IllegalStateException("Bad type tag"); - default: - push(typeHelper.fromTag(tag)); - } - } - - void push(T t) { - stack.add(t); - if (width(t) == 2) { - stack.add(null); - } - if (stack.size() > stacksize) { - stacksize = stack.size(); - } - } - - T peek() { - return stack.get(stack.size() - 1); - } - - T tosType() { - T tos = peek(); - if (tos == null) { - //double slot - tos = stack.get(stack.size() - 2); - } - return tos; - } - - T popInternal() { - return stack.remove(stack.size() - 1); - } - - @SuppressWarnings("unchecked") - T pop() { - if (stack.size() == 0 || peek() == null) throw new IllegalStateException(); - return popInternal(); - } - - T pop2() { - T o = stack.get(stack.size() - 2); - TypeTag t = typeHelper.tag(o); - if (t.width != 2) throw new IllegalStateException(); - popInternal(); - popInternal(); - return o; - } - - T pop(TypeTag t) { - return (t.width() == 2) ? - pop2() : pop(); - } - - void load(TypeTag tag, int index) { - if (tag == TypeTag.A) throw new IllegalStateException("Bad type tag"); - load(typeHelper.fromTag(tag), index); - } - - void load(T t, int index) { - ensureDefined(index); - locals.set(index, t); - if (width(t) == 2) { - locals.add(null); - } - if (locals.size() > localsize) { - localsize = locals.size(); - } - } - - void ensureDefined(int index) { - if (index >= locals.size()) { - locals.setSize(index + 1); - } - } - - State dup() { - State newState = new State(new ArrayList<>(stack), new Vector<>(locals)); - return newState; - } - - State merge(State that) { - if (!alive) { return that; } - if (that.stack.size() != stack.size()) { - throw new IllegalStateException("Bad stack size at merge point"); - } - for (int i = 0; i < stack.size(); i++) { - T t1 = stack.get(i); - T t2 = that.stack.get(i); - stack.set(i, merge(t1, t2, "Bad stack type at merge point")); - } - int nlocals = locals.size() > that.locals.size() ? that.locals.size() : locals.size(); - for (int i = 0; i < nlocals; i++) { - T t1 = locals.get(i); - T t2 = that.locals.get(i); - locals.set(i, merge(t1, t2, "Bad local type at merge point")); - } - if (locals.size() > nlocals) { - for (int i = nlocals; i < locals.size(); i++) { - locals.remove(i); - } - } - return this; - } - - T merge(T t1, T t2, String msg) { - if (t1 == null && t2 == null) { - return t1; - } - T res; - TypeTag tag1 = typeHelper.tag(t1); - TypeTag tag2 = typeHelper.tag(t2); - if (tag1 != TypeTag.A && tag2 != TypeTag.A) { - res = typeHelper.fromTag(TypeTag.commonSupertype(tag1, tag2)); - } else if (t1 == typeHelper.nullType()) { - res = t2; - } else if (t2 == typeHelper.nullType()) { - res = t1; - } else { - res = typeHelper.commonSupertype(t1, t2); - } - if (res == null) { - throw new IllegalStateException(msg); - } - return res; - } - - @Override - public String toString() { - return String.format("[locals = %s, stack = %s]", locals, stack); - } - } - - int width(T o) { - return o == typeHelper.nullType() ? - TypeTag.A.width() : - typeHelper.tag(o).width; - } - - @SuppressWarnings("unchecked") - public void updateState(Opcode op, Object optValue) { - switch (op) { - case AALOAD: - state.pop(); - state.push(typeHelper.elemtype(state.pop())); - break; - case GOTO_: - state.alive = false; - break; - case NOP: - case IINC: - case INEG: - case LNEG: - case FNEG: - case DNEG: - break; - case ACONST_NULL: - state.push(typeHelper.nullType()); - break; - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - state.push(TypeTag.I); - break; - case LCONST_0: - case LCONST_1: - state.push(TypeTag.J); - break; - case FCONST_0: - case FCONST_1: - case FCONST_2: - state.push(TypeTag.F); - break; - case DCONST_0: - case DCONST_1: - state.push(TypeTag.D); - break; - case ILOAD_0: - case FLOAD_0: - case ALOAD_0: - case LLOAD_0: - case DLOAD_0: - state.push(state.locals.get(0)); - break; - case ILOAD_1: - case FLOAD_1: - case ALOAD_1: - case LLOAD_1: - case DLOAD_1: - state.push(state.locals.get(1)); - break; - case ILOAD_2: - case FLOAD_2: - case ALOAD_2: - case LLOAD_2: - case DLOAD_2: - state.push(state.locals.get(2)); - break; - case ILOAD_3: - case FLOAD_3: - case ALOAD_3: - case LLOAD_3: - case DLOAD_3: - state.push(state.locals.get(3)); - break; - case ILOAD: - case FLOAD: - case ALOAD: - case LLOAD: - case DLOAD: - state.push(state.locals.get((Integer) optValue)); - break; - case IALOAD: - case BALOAD: - case CALOAD: - case SALOAD: - state.pop(); - state.pop(); - state.push(TypeTag.I); - break; - case LALOAD: - state.pop(); - state.pop(); - state.push(TypeTag.J); - break; - case FALOAD: - state.pop(); - state.pop(); - state.push(TypeTag.F); - break; - case DALOAD: - state.pop(); - state.pop(); - state.push(TypeTag.D); - break; - case ISTORE_0: - case FSTORE_0: - case ASTORE_0: - state.load(state.pop(), 0); - break; - case ISTORE_1: - case FSTORE_1: - case ASTORE_1: - state.load(state.pop(), 1); - break; - case ISTORE_2: - case FSTORE_2: - case ASTORE_2: - state.load(state.pop(), 2); - break; - case ISTORE_3: - case FSTORE_3: - case ASTORE_3: - state.load(state.pop(), 3); - break; - case ISTORE: - case FSTORE: - case ASTORE: - state.load(state.pop(), (int) optValue); - break; - case LSTORE_0: - case DSTORE_0: - state.load(state.pop2(), 0); - break; - case LSTORE_1: - case DSTORE_1: - state.load(state.pop2(), 1); - break; - case LSTORE_2: - case DSTORE_2: - state.load(state.pop2(), 2); - break; - case LSTORE_3: - case DSTORE_3: - state.load(state.pop2(), 3); - break; - case LSTORE: - case DSTORE: - state.load(state.pop2(), (int) optValue); - break; - case POP: - case LSHR: - case LSHL: - case LUSHR: - state.pop(); - break; - case ARETURN: - case IRETURN: - case FRETURN: - state.pop(); - break; - case ATHROW: - state.pop(); - break; - case POP2: - state.pop2(); - break; - case LRETURN: - case DRETURN: - state.pop2(); - break; - case DUP: - state.push(state.peek()); - break; - case RETURN: - break; - case ARRAYLENGTH: - state.pop(); - state.push(TypeTag.I); - break; - case ISUB: - case IADD: - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - state.pop(); - state.pop(); - state.push(TypeTag.I); - break; - case AASTORE: - state.pop(); - state.pop(); - state.pop(); - break; - case LAND: - case LOR: - case LXOR: - case LREM: - case LDIV: - case LMUL: - case LSUB: - case LADD: - state.pop2(); - state.pop2(); - state.push(TypeTag.J); - break; - case LCMP: - state.pop2(); - state.pop2(); - state.push(TypeTag.I); - break; - case L2I: - state.pop2(); - state.push(TypeTag.I); - break; - case I2L: - state.pop(); - state.push(TypeTag.J); - break; - case I2F: - state.pop(); - state.push(TypeTag.F); - break; - case I2D: - state.pop(); - state.push(TypeTag.D); - break; - case L2F: - state.pop2(); - state.push(TypeTag.F); - break; - case L2D: - state.pop2(); - state.push(TypeTag.D); - break; - case F2I: - state.pop(); - state.push(TypeTag.I); - break; - case F2L: - state.pop(); - state.push(TypeTag.J); - break; - case F2D: - state.pop(); - state.push(TypeTag.D); - break; - case D2I: - state.pop2(); - state.push(TypeTag.I); - break; - case D2L: - state.pop2(); - state.push(TypeTag.J); - break; - case D2F: - state.pop2(); - state.push(TypeTag.F); - break; - case TABLESWITCH: - case LOOKUPSWITCH: - state.pop(); - break; - case DUP_X1: { - T val1 = state.pop(); - T val2 = state.pop(); - state.push(val1); - state.push(val2); - state.push(val1); - break; - } - case BASTORE: - state.pop(); - state.pop(); - state.pop(); - break; - case I2B: - case I2C: - case I2S: - break; - case FMUL: - case FADD: - case FSUB: - case FDIV: - case FREM: - state.pop(); - state.pop(); - state.push(TypeTag.F); - break; - case CASTORE: - case IASTORE: - case FASTORE: - case SASTORE: - state.pop(); - state.pop(); - state.pop(); - break; - case LASTORE: - case DASTORE: - state.pop2(); - state.pop(); - state.pop(); - break; - case DUP2: - if (state.peek() != null) { - //form 1 - T value1 = state.pop(); - T value2 = state.pop(); - state.push(value2); - state.push(value1); - state.push(value2); - state.push(value1); - } else { - //form 2 - T value = state.pop2(); - state.push(value); - state.push(value); - } - break; - case DUP2_X1: - if (state.peek() != null) { - T value1 = state.pop(); - T value2 = state.pop(); - T value3 = state.pop(); - state.push(value2); - state.push(value1); - state.push(value3); - state.push(value2); - state.push(value1); - } else { - T value1 = state.pop2(); - T value2 = state.pop(); - state.push(value1); - state.push(value2); - state.push(value1); - } - break; - case DUP2_X2: - if (state.peek() != null) { - T value1 = state.pop(); - T value2 = state.pop(); - if (state.peek() != null) { - // form 1 - T value3 = state.pop(); - T value4 = state.pop(); - state.push(value2); - state.push(value1); - state.push(value4); - state.push(value3); - state.push(value2); - state.push(value1); - } else { - // form 3 - T value3 = state.pop2(); - state.push(value2); - state.push(value1); - state.push(value3); - state.push(value2); - state.push(value1); - } - } else { - T value1 = state.pop2(); - if (state.peek() != null) { - // form 2 - T value2 = state.pop(); - T value3 = state.pop(); - state.push(value1); - state.push(value3); - state.push(value2); - state.push(value1); - } else { - // form 4 - T value2 = state.pop2(); - state.push(value1); - state.push(value2); - state.push(value1); - } - } - break; - case DUP_X2: { - T value1 = state.pop(); - if (state.peek() != null) { - // form 1 - T value2 = state.pop(); - T value3 = state.pop(); - state.push(value1); - state.push(value3); - state.push(value2); - state.push(value1); - } else { - // form 2 - T value2 = state.pop2(); - state.push(value1); - state.push(value2); - state.push(value1); - } - } - break; - case FCMPL: - case FCMPG: - state.pop(); - state.pop(); - state.push(TypeTag.I); - break; - case DCMPL: - case DCMPG: - state.pop2(); - state.pop2(); - state.push(TypeTag.I); - break; - case SWAP: { - T value1 = state.pop(); - T value2 = state.pop(); - state.push(value1); - state.push(value2); - break; - } - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - state.pop2(); - state.pop2(); - state.push(TypeTag.D); - break; - case RET: - break; - case WIDE: - // must be handled by the caller. - return; - case MONITORENTER: - case MONITOREXIT: - state.pop(); - break; - case NEW: - case DEFAULTVALUE: - state.push(typeHelper.type((S) optValue)); - break; - case NEWARRAY: - state.pop(); - state.push(typeHelper.arrayOf(typeHelper.fromTag((TypeTag) optValue))); - break; - case ANEWARRAY: - state.pop(); - state.push(typeHelper.arrayOf(typeHelper.type((S)optValue))); - break; - case MULTIANEWARRAY: - for (int i = 0; i < (byte) ((Object[]) optValue)[1]; i++) { - state.pop(); - } - state.push(typeHelper.type((S) ((Object[]) optValue)[0])); - break; - case INVOKEINTERFACE: - case INVOKEVIRTUAL: - case INVOKESPECIAL: - case INVOKESTATIC: - case INVOKEDYNAMIC: - processInvoke(op, (T) optValue); - break; - case GETSTATIC: - state.push((T) optValue); - break; - case GETFIELD: - state.pop(); - state.push((T) optValue); - break; - case PUTSTATIC: { - TypeTag tag = typeHelper.tag((T) optValue); - if (tag.width == 1) { - state.pop(); - } else { - state.pop2(); - } - break; - } - case PUTFIELD: { - TypeTag tag = typeHelper.tag((T) optValue); - if (tag.width == 1) { - state.pop(); - } else { - state.pop2(); - } - state.pop(); - break; - } - case WITHFIELD: { - TypeTag tag = typeHelper.tag((T) optValue); - if (tag.width == 1) { - state.pop(); - } else { - state.pop2(); - } - break; - } - case BIPUSH: - case SIPUSH: - state.push(TypeTag.I); - break; - case LDC: - case LDC_W: - case LDC2_W: - state.push((T)optValue); - break; - case IF_ACMPEQ: - case IF_ICMPEQ: - case IF_ACMPNE: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ICMPLT: - case IF_ICMPNE: - state.pop(); - state.pop(); - break; - case IF_NONNULL: - case IF_NULL: - case IFEQ: - case IFGE: - case IFGT: - case IFLE: - case IFLT: - case IFNE: - state.pop(); - break; - case INSTANCEOF: - state.pop(); - state.push(TypeTag.Z); - break; - case TYPED: - case CHECKCAST: - break; - - default: - throw new UnsupportedOperationException("Unsupported opcode: " + op); - } - } - - void processInvoke(Opcode opcode, T invokedType) { - Iterator paramsIt = typeHelper.parameterTypes(invokedType); - while (paramsIt.hasNext()) { - T t = paramsIt.next(); - TypeTag tag = typeHelper.tag(t); - if (tag.width == 2) { - state.popInternal(); - state.popInternal(); - } else { - state.popInternal(); - } - } - if (opcode != Opcode.INVOKESTATIC && opcode != Opcode.INVOKEDYNAMIC) { - state.pop(); //receiver - } - T retType = typeHelper.returnType(invokedType); - TypeTag retTag = typeHelper.tag(retType); - if (retTag != TypeTag.V) - state.push(retType); - } - - @Override - protected C ldc(ToIntFunction> indexFunc, boolean fat) { - LdcPoolHelper ldcPoolHelper = new LdcPoolHelper(); - int index = indexFunc.applyAsInt(ldcPoolHelper); - fat = typeHelper.tag(ldcPoolHelper.type).width() == 2; - return super.ldc(index, ldcPoolHelper.type, fat); - } - //where - class LdcPoolHelper implements PoolHelper { - - T type; - - @Override - public int putClass(S symbol) { - type = typeHelper.type(symbol); - return poolHelper.putClass(symbol); - } - - @Override - public int putValueClass(S symbol) { - throw new IllegalStateException(); - } - - @Override - public int putInt(int i) { - type = typeHelper.fromTag(TypeTag.I); - return poolHelper.putInt(i); - } - - @Override - public int putFloat(float f) { - type = typeHelper.fromTag(TypeTag.F); - return poolHelper.putFloat(f); - } - - @Override - public int putLong(long l) { - type = typeHelper.fromTag(TypeTag.J); - return poolHelper.putLong(l); - } - - @Override - public int putDouble(double d) { - type = typeHelper.fromTag(TypeTag.D); - return poolHelper.putDouble(d); - } - - @Override - public int putString(String s) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/String")); - return poolHelper.putString(s); - } - - @Override - public int putValue(Object v) { - type = typeTag(v); - return poolHelper.putValue(v); - } - - @Override - public int putConstantDynamic(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - type = constType; - return poolHelper.putConstantDynamic(constName, constType, bsmClass, bsmName, bsmType, staticArgs); - } - - @Override - public int putFieldRef(S owner, CharSequence name, T type) { - throw new IllegalStateException(); - } - - @Override - public int putMethodRef(S owner, CharSequence name, T type, boolean isInterface) { - throw new IllegalStateException(); - } - - @Override - public int putUtf8(CharSequence s) { - throw new IllegalStateException(); - } - - @Override - public int putType(T t) { - throw new IllegalStateException(); - } - - @Override - public int putMethodType(T t) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType")); - return poolHelper.putMethodType(t); - } - - @Override - public int putMethodHandle(int refKind, S owner, CharSequence name, T t) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle")); - return poolHelper.putMethodHandle(refKind, owner, name, t); - } - - @Override - public int putMethodHandle(int refKind, S owner, CharSequence name, T t, boolean isInterface) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle")); - return poolHelper.putMethodHandle(refKind, owner, name, t, isInterface); - } - - @Override - public int putInvokeDynamic(CharSequence invokedName, T invokedType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - throw new IllegalStateException(); - } - - @Override - public int size() { - throw new IllegalStateException(); - } - - @Override - public E representation() { - throw new IllegalStateException(); - } - - private T typeTag(Object o) { - if (o instanceof Double) { - return typeHelper.fromTag(TypeTag.D); - } else if (o instanceof Long) { - return typeHelper.fromTag(TypeTag.J); - } else if (o instanceof Float) { - return typeHelper.fromTag(TypeTag.F); - } else if (o instanceof Integer) { - return typeHelper.fromTag(TypeTag.I); - } else if (o instanceof Class) { - return typeHelper.type(typeHelper.symbolFrom("java/lang/Class")); - } else if (o instanceof String) { - return typeHelper.type(typeHelper.symbolFrom("java/lang/String")); - } else if (o instanceof MethodHandle) { - return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle")); - } else if (o instanceof MethodType) { - return typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodType")); - } else { - throw new IllegalStateException("Unsupported object class: " + o.getClass().getName()); - } - } - } - - public C load(int index) { - return load(typeHelper.tag(state.locals.get(index)), index); - } - - public C store(int index) { - return store(typeHelper.tag(state.tosType()), index); - } - - @Override - public C withLocalSize(int localsize) { - throw new IllegalStateException("Local size automatically computed"); - } - - @Override - public C withStackSize(int stacksize) { - throw new IllegalStateException("Stack size automatically computed"); - } - - public C withLocal(CharSequence name, T type) { - int offset = currLocalOffset; - TypeTag tag = typeHelper.tag(type); - lvarOffsets.put(name, new LocalVarInfo(name, offset, depth, tag)); - state.load(type, offset); - currLocalOffset += tag.width; - return thisBuilder(); - } - - public C load(CharSequence local) { - return load(lvarOffsets.get(local).offset); - } - - public C store(CharSequence local) { - return store(lvarOffsets.get(local).offset); - } - - @Override - public C withTry(Consumer tryBlock, Consumer catchBlocks) { - return super.withTry(c -> { - withLocalScope(() -> { - tryBlock.accept(c); - }); - }, catchBlocks); - } - - @Override - protected CatchBuilder makeCatchBuilder(int start, int end) { - return new TypedCatchBuilder(start, end); - } - - class TypedCatchBuilder extends CatchBuilder { - - State initialState = state.dup(); - - TypedCatchBuilder(int start, int end) { - super(start, end); - } - - @Override - protected void emitCatch(S exc, Consumer catcher) { - withLocalScope(() -> { - state.push(typeHelper.type(exc)); - emitStackMap(code.offset); - super.emitCatch(exc, catcher); - state = initialState; - }); - } - - @Override - protected void emitFinalizer() { - withLocalScope(() -> { - state.push(typeHelper.type(typeHelper.symbolFrom("java/lang/Throwable"))); - emitStackMap(code.offset); - super.emitFinalizer(); - }); - } - } - - protected void withLocalScope(Runnable runnable) { - int prevDepth = depth; - try { - depth++; - runnable.run(); - } finally { - Iterator> lvarIt = lvarOffsets.entrySet().iterator(); - while (lvarIt.hasNext()) { - LocalVarInfo lvi = lvarIt.next().getValue(); - if (lvi.depth == depth) { - int width = lvi.type.width; - currLocalOffset -= width; - lvarIt.remove(); - } - } - depth = prevDepth; - } - } - - @Override - void addPendingJump(CharSequence label, int pc) { - pendingJumps.add(new StatefulPendingJump(label, pc, state.dup())); - } - - @Override - void resolveJumps(CharSequence label, int pc) { - super.resolveJumps(label, pc); - emitStackMap(pc); - } - - //TODO: optimize stackmap generation by avoiding intermediate classes - protected void emitStackMap(int pc) { - //stack map generation - if (pc > lastStackMapPc) { - writeStackMapFrame(pc); - lastStackMapState = state.dup(); - lastStackMapPc = pc; - nstackmaps++; - } - } - - @Override - void build(GrowableByteBuffer buf) { - if (stacksize == -1) { - throw new IllegalStateException("Bad stack size"); - } - if (localsize == -1) { - throw new IllegalStateException("Bad locals size"); - } - if (nstackmaps > 0) { - GrowableByteBuffer stackmapsAttr = new GrowableByteBuffer(); - stackmapsAttr.writeChar(nstackmaps); - stackmapsAttr.writeBytes(stackmaps); - withAttribute("StackMapTable", stackmapsAttr.bytes()); - } - super.build(buf); - } - - /** - * Compare this frame with the previous frame and produce - * an entry of compressed stack map frame. - */ - void writeStackMapFrame(int pc) { - List locals = state.locals; - List stack = state.stack; - List prev_locals = lastStackMapState.locals; - int offset_delta = lastStackMapPc == -1 ? pc : pc - lastStackMapPc - 1; - if (stack.size() == 1) { - if (locals.size() == prev_locals.size() && prev_locals.equals(locals)) { - sameLocals1StackItemFrame(offset_delta, stack.get(stack.size() - 1)); - return; - } - } else if (stack.size() == 0) { - int diff_length = prev_locals.size() - locals.size(); - if (diff_length == 0) { - sameFrame(offset_delta); - return; - } else if (-MAX_LOCAL_LENGTH_DIFF < diff_length && diff_length < 0) { - appendFrame(offset_delta, prev_locals.size(), locals); - return; - } else if (0 < diff_length && diff_length < MAX_LOCAL_LENGTH_DIFF) { - chopFrame(offset_delta, diff_length); - return; - } - } - fullFrame(offset_delta, locals, stack); - } -} diff --git a/src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java b/src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java deleted file mode 100644 index b34babe7adf..00000000000 --- a/src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.experimental.value; - -import jdk.experimental.bytecode.BytePoolHelper; -import jdk.experimental.bytecode.BasicTypeHelper; -import jdk.experimental.bytecode.ClassBuilder; -import jdk.experimental.bytecode.CodeBuilder; -import jdk.experimental.bytecode.Flag; -import jdk.experimental.bytecode.MethodBuilder; -import jdk.experimental.bytecode.TypeHelper; -import jdk.experimental.bytecode.TypeTag; -import jdk.experimental.bytecode.TypedCodeBuilder; -import jdk.experimental.value.MethodHandleBuilder.IsolatedMethodBuilder.IsolatedMethodPoolHelper; -import jdk.internal.misc.Unsafe; -import sun.security.action.GetPropertyAction; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UncheckedIOException; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.invoke.MethodType; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Utility class for building method handles. - */ -public class MethodHandleBuilder { - - static final Unsafe UNSAFE = Unsafe.getUnsafe(); - - public static final boolean ENABLE_POOL_PATCHES; - public static final String DUMP_CLASS_FILES_DIR; - - static { - Properties props = GetPropertyAction.privilegedGetProperties(); - ENABLE_POOL_PATCHES = Boolean.parseBoolean( - props.getProperty("valhalla.enablePoolPatches")); - DUMP_CLASS_FILES_DIR = props.getProperty("valhalla.DUMP_CLASS_FILES_DIR"); - } - - public static MethodHandle loadCode(Lookup lookup, String name, MethodType type, Consumer> builder) { - return loadCode(lookup, name, name, type, builder); - } - - public static MethodHandle loadCode(Lookup lookup, String className, String methodName, MethodType type, Consumer> builder) { - String descriptor = type.toMethodDescriptorString(); - return loadCode(lookup, className, methodName, descriptor, MethodHandleCodeBuilder::new, - clazz -> { - try { - return lookup.findStatic(clazz, methodName, MethodType.fromMethodDescriptorString(descriptor, lookup.lookupClass().getClassLoader())); - } catch (ReflectiveOperationException ex) { - throw new IllegalStateException(ex); - } - }, - builder); - } - - protected static , String, byte[], ?>> Z loadCode( - Lookup lookup, String className, String methodName, String type, - Function, String, byte[]>, ? extends C> builderFunc, - Function, Z> resFunc, Consumer builder) { - - IsolatedMethodBuilder isolatedMethodBuilder = new IsolatedMethodBuilder(className, lookup); - isolatedMethodBuilder - .withSuperclass(Object.class) - .withMajorVersion(60) - .withMinorVersion(0) - .withFlags(Flag.ACC_PUBLIC) - .withMethod(methodName, type, M -> - M.withFlags(Flag.ACC_STATIC, Flag.ACC_PUBLIC) - .withCode(builderFunc, builder)); - - try { - byte[] barr = isolatedMethodBuilder.build(); - maybeDump(className, barr); - Class clazz = UNSAFE.defineAnonymousClass(lookup.lookupClass(), barr, isolatedMethodBuilder.patches()); - UNSAFE.ensureClassInitialized(clazz); - return resFunc.apply(clazz); - } catch (Throwable e) { - throw new IllegalStateException(e); - } - } - - public static class IsolatedMethodBuilder extends ClassBuilder, String, IsolatedMethodBuilder> { - - private static final Class THIS_CLASS = new Object() { }.getClass(); - - public IsolatedMethodBuilder(String clazz, Lookup lookup) { - super(ENABLE_POOL_PATCHES ? - new IsolatedMethodPatchingPoolHelper(clazz) : - new IsolatedMethodPoolHelper(clazz), - new IsolatedMethodTypeHelper(lookup)); - withThisClass(THIS_CLASS); - } - - public Class thisClass() { - return THIS_CLASS; - } - - Object[] patches() { - return ((IsolatedMethodPoolHelper)poolHelper).patches(); - } - - static String classToInternalName(Class c) { - return c.getName().replace('.', '/'); - } - - static class IsolatedMethodTypeHelper implements TypeHelper, String> { - - BasicTypeHelper basicTypeHelper = new BasicTypeHelper(); - Lookup lookup; - - IsolatedMethodTypeHelper(Lookup lookup) { - this.lookup = lookup; - } - - @Override - public String elemtype(String s) { - return basicTypeHelper.elemtype(s); - } - - @Override - public String arrayOf(String s) { - return basicTypeHelper.arrayOf(s); - } - - @Override - public Iterator parameterTypes(String s) { - return basicTypeHelper.parameterTypes(s); - } - - @Override - public String fromTag(TypeTag tag) { - return basicTypeHelper.fromTag(tag); - } - - @Override - public String returnType(String s) { - return basicTypeHelper.returnType(s); - } - - @Override - public String type(Class aClass) { - if (aClass.isArray()) { - return classToInternalName(aClass); - } else { - return (aClass.isInlineClass() ? "Q" : "L") + classToInternalName(aClass) + ";"; - } - } - - @Override - public boolean isValue(String desc) { - Class aClass = symbol(desc); - return aClass != null && aClass.isInlineClass(); - } - - @Override - public Class symbol(String desc) { - try { - if (desc.startsWith("[")) { - return Class.forName(desc.replaceAll("/", "."), true, lookup.lookupClass().getClassLoader()); - } else { - return Class.forName(basicTypeHelper.symbol(desc).replaceAll("/", "."), true, lookup.lookupClass().getClassLoader()); - } - } catch (ReflectiveOperationException ex) { - throw new AssertionError(ex); - } - } - - @Override - public TypeTag tag(String s) { - return basicTypeHelper.tag(s); - } - - @Override - public Class symbolFrom(String s) { - return symbol(s); - } - - @Override - public String commonSupertype(String t1, String t2) { - return basicTypeHelper.commonSupertype(t1, t2); - } - - @Override - public String nullType() { - return basicTypeHelper.nullType(); - } - } - - static class IsolatedMethodPoolHelper extends BytePoolHelper, String> { - final String clazz; - - IsolatedMethodPoolHelper(String clazz) { - super(c -> from(c, clazz), s->s); - this.clazz = clazz; - } - - Object[] patches() { - return null; - } - - static String from(Class c, String clazz) { - return c == THIS_CLASS ? clazz.replace('.', '/') - : classToInternalName(c); - } - } - - @Override - public byte[] build() { - return super.build(); - } - } - - static class IsolatedMethodPatchingPoolHelper extends IsolatedMethodPoolHelper { - - public IsolatedMethodPatchingPoolHelper(String clazz) { - super(clazz); - } - - Map cpPatches = new HashMap<>(); - int cph = 0; // for counting constant placeholders - - static class CpPatch { - - final int index; - final String placeholder; - final Object value; - - CpPatch(int index, String placeholder, Object value) { - this.index = index; - this.placeholder = placeholder; - this.value = value; - } - - public String toString() { - return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value; - } - } - - @Override - public int putValue(Object v) { - if (v instanceof String || v instanceof Integer || v instanceof Float || v instanceof Double || v instanceof Long) { - return super.putValue(v); - } - assert (!v.getClass().isPrimitive()) : v; - return patchPoolEntry(v); // CP patching support - } - - int patchPoolEntry(Object v) { - String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++; - if (cpPatches.containsKey(cpPlaceholder)) { - throw new InternalError("observed CP placeholder twice: " + cpPlaceholder); - } - // insert placeholder in CP and remember the patch - int index = super.putValue(cpPlaceholder); // TODO check if already in the constant pool - cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, v)); - return index; - } - - @Override - Object[] patches() { - int size = size(); - Object[] res = new Object[size]; - for (CpPatch p : cpPatches.values()) { - if (p.index >= size) - throw new InternalError("bad cp patch index"); - res[p.index] = p.value; - } - return res; - } - - private static String debugString(Object arg) { - // @@@ Cannot crack open a MH like with InvokerByteCodeGenerator.debugString - return arg.toString(); - } - } - - public static class MethodHandleCodeBuilder> extends TypedCodeBuilder, String, byte[], T> { - - BasicTypeHelper basicTypeHelper = new BasicTypeHelper(); - - public MethodHandleCodeBuilder(jdk.experimental.bytecode.MethodBuilder, String, byte[]> methodBuilder) { - super(methodBuilder); - } - - TypeTag getTagType(String s) { - return basicTypeHelper.tag(s); - } - - public T ifcmp(String s, CondKind cond, CharSequence label) { - return super.ifcmp(getTagType(s), cond, label); - } - - public T return_(String s) { - return super.return_(getTagType(s)); - } - } - - static void maybeDump(final String className, final byte[] classFile) { - if (DUMP_CLASS_FILES_DIR != null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public Void run() { - String dumpName = className.replace('.','/'); - Path dumpFile = Paths.get(DUMP_CLASS_FILES_DIR, dumpName + ".class"); - try { - Files.createDirectories(dumpFile.getParent()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - - System.out.println("dump: " + dumpFile); - try (OutputStream os = Files.newOutputStream(dumpFile)) { - os.write(classFile); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - return null; - } - }); - } - } -} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java index fa56e428572..f468e7fa23e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestC1.java @@ -28,14 +28,12 @@ import java.lang.reflect.Method; import java.util.Arrays; -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; /* * @test * @key randomness * @summary Various tests that are specific for C1. - * @modules java.base/jdk.experimental.value * @library /testlibrary /test/lib /compiler/whitebox / * @requires os.simpleArch == "x64" * @compile -XDallowWithFieldOperator TestC1.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java index 0445cc66c03..dcfe99bc45c 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestGetfieldChains.java @@ -29,14 +29,12 @@ import java.nio.file.NoSuchFileException; import java.util.Arrays; -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; /* * @test * @key randomness * @summary Verify that chains of getfields on flattened fields are correctly optimized - * @modules java.base/jdk.experimental.value * @library /testlibrary /test/lib /compiler/whitebox / * @requires os.simpleArch == "x64" * @compile TestGetfieldChains.java NamedRectangle.java Rectangle.java Point.java GetfieldChains.jcod diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index d12f104f671..b26a17dbd01 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -27,15 +27,15 @@ import java.lang.reflect.Method; import java.util.Arrays; -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; +import test.java.lang.invoke.lib.InstructionHelper; /* * @test * @key randomness * @summary Test inline types in LWorld. - * @modules java.base/jdk.experimental.value - * @library /testlibrary /test/lib /compiler/whitebox / + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common /testlibrary /compiler/whitebox / + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @compile TestLWorld.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform @@ -1047,7 +1047,7 @@ public void test34_verifier(boolean warmup) { // Test writing constant null to a (flattened) inline type array - private static final MethodHandle setArrayElementNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), + private static final MethodHandle setArrayElementNull = InstructionHelper.loadCode(MethodHandles.lookup(), "setArrayElementNull", MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class), CODE -> { @@ -1374,7 +1374,7 @@ public void test43_verifier(boolean warmup) { } // Tests writing an array element with a (statically known) incompatible type - private static final MethodHandle setArrayElementIncompatible = MethodHandleBuilder.loadCode(MethodHandles.lookup(), + private static final MethodHandle setArrayElementIncompatible = InstructionHelper.loadCode(MethodHandles.lookup(), "setArrayElementIncompatible", MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), CODE -> { diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java index b1859d36356..22069dda612 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorldProfiling.java @@ -30,7 +30,6 @@ * @test * @key randomness * @summary Test inline type specific profiling - * @modules java.base/jdk.experimental.value * @library /testlibrary /test/lib /compiler/whitebox / * @requires (os.simpleArch == "x64") * @compile TestLWorldProfiling.java diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java index 0b9c59fabbf..fdd27859432 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNativeClone.java @@ -25,7 +25,6 @@ * @test * @bug 8209702 * @summary Verify that the native clone intrinsic handles inline types. - * @modules java.base/jdk.experimental.value * @library /test/lib * @run main/othervm -Xbatch -XX:-UseTypeProfile * -XX:CompileCommand=compileonly,compiler.valhalla.inlinetypes.MyValue::* @@ -40,7 +39,6 @@ import java.lang.invoke.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; inline class MyValue { @@ -49,30 +47,12 @@ inline class MyValue { public MyValue(int x) { this.x = x; } + } public class TestNativeClone { - private static final MethodHandle cloneValue = MethodHandleBuilder.loadCode(MethodHandles.lookup(), - "MyValue", - MethodType.methodType(Object.class, MyValue.class), - CODE -> { - CODE. - aload_0(). - invokevirtual(Object.class, "clone", "()Ljava/lang/Object;", false). - areturn(); - }); - - public static void test1(MyValue vt) throws Throwable { - try { - cloneValue.invoke(vt); - throw new RuntimeException("No exception thrown"); - } catch (CloneNotSupportedException e) { - // Expected - } - } - - public static void test2(Method clone, Object obj) { + public static void test1(Method clone, Object obj) { try { clone.invoke(obj); } catch (InvocationTargetException e) { @@ -90,8 +70,7 @@ public static void main(String[] args) throws Throwable { Method clone = Object.class.getDeclaredMethod("clone"); clone.setAccessible(true); for (int i = 0; i < 20_000; ++i) { - test1(vt); - test2(clone, vt); + test1(clone, vt); } } } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java index 03731dffe44..40abc9dd944 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestWithfieldC1.java @@ -28,14 +28,12 @@ import java.lang.reflect.Method; import java.util.Arrays; -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; /* * @test * @key randomness * @summary Verify that C1 performs escape analysis before optimizing withfield bytecode to putfield. - * @modules java.base/jdk.experimental.value * @library /testlibrary /test/lib /compiler/whitebox / * @requires os.simpleArch == "x64" * @compile -XDallowWithFieldOperator TestWithfieldC1.java diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/CreationErrorTest.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/CreationErrorTest.java index 53c6ee87fbb..3028ad39a51 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/CreationErrorTest.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/CreationErrorTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.*; import static jdk.test.lib.Asserts.*; +import test.java.lang.invoke.lib.InstructionHelper; import jdk.experimental.bytecode.MacroCodeBuilder; import jdk.experimental.bytecode.MacroCodeBuilder.CondKind; @@ -41,19 +42,15 @@ import jdk.test.lib.Platform; import jdk.test.lib.Utils; -import jdk.experimental.value.MethodHandleBuilder; - import javax.tools.*; /** * @test CreationErrorTest * @summary Test data movement with inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run main/othervm -Xint -Xmx128m -XX:-ShowMessageBoxOnError - * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=false + * -XX:+UnlockDiagnosticVMOptions * runtime.valhalla.inlinetypes.CreationErrorTest */ @@ -75,7 +72,7 @@ public static void main(String[] args) { } static void testErroneousObjectCreation() { - MethodHandle testNewOnInlineClass = MethodHandleBuilder.loadCode( + MethodHandle testNewOnInlineClass = InstructionHelper.loadCode( LOOKUP, "testNewOnInlineClass", MethodType.methodType(boolean.class), @@ -97,7 +94,7 @@ static void testErroneousObjectCreation() { // Note: this test might become obsolete if defaultvalue is extended to accept identity classes static void testErroneousValueCreation() { - MethodHandle testDefaultvalueOnIdentityClass = MethodHandleBuilder.loadCode( + MethodHandle testDefaultvalueOnIdentityClass = InstructionHelper.loadCode( LOOKUP, "testDefaultValueOnIdentityClass", MethodType.methodType(boolean.class), diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/FlattenableSemanticTest.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/FlattenableSemanticTest.java index 045455b3b2b..53db5a934bc 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/FlattenableSemanticTest.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/FlattenableSemanticTest.java @@ -22,17 +22,12 @@ */ package runtime.valhalla.inlinetypes; -import java.lang.invoke.*; - -import jdk.experimental.value.MethodHandleBuilder; import jdk.test.lib.Asserts; /* * @test * @summary Flattenable field semantic test - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value * @library /test/lib * @compile -XDallowWithFieldOperator Point.java JumboInline.java * @compile -XDallowWithFieldOperator FlattenableSemanticTest.java diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineOops.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineOops.java index ddd8df3ae1b..7552d6ad4c4 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineOops.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineOops.java @@ -30,16 +30,14 @@ import static jdk.test.lib.Asserts.*; import jdk.test.lib.Utils; import sun.hotspot.WhiteBox; - -import jdk.experimental.value.MethodHandleBuilder; +import test.java.lang.invoke.lib.InstructionHelper; /** * @test InlineOops_int_Serial * @requires vm.gc.Serial * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -53,9 +51,8 @@ * @test InlineOops_int_G1 * @requires vm.gc.G1 * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -69,9 +66,8 @@ * @test InlineOops_int_Parallel * @requires vm.gc.Parallel * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -85,9 +81,8 @@ * @test InlineOops_int_Z * @requires vm.gc.Z * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -102,9 +97,8 @@ * @test InlineOops_comp_serial * @requires vm.gc.Serial * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -118,9 +112,8 @@ * @test InlineOops_comp_G1 * @requires vm.gc.G1 * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -134,9 +127,8 @@ * @test InlineOops_comp_Parallel * @requires vm.gc.Parallel * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -150,9 +142,8 @@ * @test InlineOops_comp_Z * @requires vm.gc.Z * @summary Test embedding oops into Inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator Person.java * @compile -XDallowWithFieldOperator InlineOops.java * @run driver ClassFileInstaller sun.hotspot.WhiteBox @@ -410,7 +401,7 @@ public static void testOverGc() { doGc(); // VT on stack and lvt, null refs, see if GC flies - MethodHandle moveValueThroughStackAndLvt = MethodHandleBuilder.loadCode( + MethodHandle moveValueThroughStackAndLvt = InstructionHelper.loadCode( LOOKUP, "gcOverPerson", MethodType.methodType(vtClass, vtClass), @@ -677,7 +668,7 @@ public static void testFrameOopsDefault(Object[][] oopMaps) { // Slots 1=oopMaps // OopMap Q=RRR (.name .description .someNotes) try { - MethodHandleBuilder.loadCode( + InstructionHelper.loadCode( LOOKUP, "exerciseVBytecodeExprStackWithDefault", mt, CODE->{ CODE @@ -717,7 +708,7 @@ public static void testFrameOopsRefs(String name, String description, String not int fooArraySlot = 0; int oopMapsSlot = 1; try { - MethodHandleBuilder.loadCode(LOOKUP, "exerciseVBytecodeExprStackWithRefs", mt, + InstructionHelper.loadCode(LOOKUP, "exerciseVBytecodeExprStackWithRefs", mt, CODE->{ CODE .aload(fooArraySlot) diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypesTest.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypesTest.java index 162cc28d308..c06637f05f4 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypesTest.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/InlineTypesTest.java @@ -41,16 +41,14 @@ import jdk.test.lib.Platform; import jdk.test.lib.Utils; -import jdk.experimental.value.MethodHandleBuilder; - import javax.tools.*; +import test.java.lang.invoke.lib.InstructionHelper; /** * @test InlineTypesTest * @summary Test data movement with inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator TestValue1.java TestValue2.java TestValue3.java TestValue4.java InlineTypesTest.java * @run main/othervm -Xint -Xmx128m -XX:-ShowMessageBoxOnError * -XX:+ExplicitGCInvokesConcurrent @@ -103,7 +101,7 @@ public static void main(String[] args) { static void testExecutionStackToLocalVariable(Class inlineClass) throws Throwable { String sig = "()Q" + inlineClass.getName() + ";"; final String signature = sig.replace('.', '/'); - MethodHandle fromExecStackToLocalVar = MethodHandleBuilder.loadCode( + MethodHandle fromExecStackToLocalVar = InstructionHelper.loadCode( LOOKUP, "execStackToLocalVar", MethodType.methodType(boolean.class), @@ -148,7 +146,7 @@ static void testExecutionStackToFields(Class inlineClass, Class containerC final String fieldQSignature = "Q" + inlineClass.getName().replace('.', '/') + ";"; final String fieldLSignature = "L" + inlineClass.getName().replace('.', '/') + "$ref;"; System.out.println(methodSignature); - MethodHandle fromExecStackToFields = MethodHandleBuilder.loadCode( + MethodHandle fromExecStackToFields = InstructionHelper.loadCode( LOOKUP, "execStackToFields", MethodType.methodType(boolean.class), @@ -219,7 +217,7 @@ static void testExecutionStackToInlineArray(Class inlineClass, Class conta final String signature = sig.replace('.', '/'); final String arraySignature = "[L" + inlineClass.getName().replace('.', '/') + ";"; System.out.println(arraySignature); - MethodHandle fromExecStackToInlineArray = MethodHandleBuilder.loadCode( + MethodHandle fromExecStackToInlineArray = InstructionHelper.loadCode( LOOKUP, "execStackToInlineArray", MethodType.methodType(boolean.class), diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/ObjectMethods.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/ObjectMethods.java index 9bd1a63f17e..22dd64e3d68 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/ObjectMethods.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/ObjectMethods.java @@ -24,14 +24,13 @@ import java.lang.invoke.*; -import jdk.experimental.value.MethodHandleBuilder; +import test.java.lang.invoke.lib.InstructionHelper; /* * @test ObjectMethods * @summary Check object method implemented by the VM behave with inline types - * @modules java.base/jdk.experimental.bytecode - * java.base/jdk.experimental.value - * @library /test/lib + * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @compile -XDallowWithFieldOperator ObjectMethods.java * @run main/othervm -Xint -XX:+UseCompressedClassPointers runtime.valhalla.inlinetypes.ObjectMethods * @run main/othervm -Xint -XX:-UseCompressedClassPointers runtime.valhalla.inlinetypes.ObjectMethods @@ -134,15 +133,15 @@ static void checkSynchronized(Object val) { static void checkMonitorExit(Object val) { boolean sawImse = false; try { - MethodHandleBuilder.loadCode(MethodHandles.lookup(), - "mismatchedMonitorExit", - MethodType.methodType(Void.TYPE, Object.class), - CODE->{ - CODE - .aload(0) - .monitorexit() - .return_(); - }).invokeExact(val); + InstructionHelper.loadCode(MethodHandles.lookup(), + "mismatchedMonitorExit", + MethodType.methodType(Void.TYPE, Object.class), + CODE->{ + CODE + .aload(0) + .monitorexit() + .return_(); + }).invokeExact(val); throw new IllegalStateException("Unreachable code, reached"); } catch (Throwable t) { if (t instanceof IllegalMonitorStateException) { diff --git a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java b/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java index 8cfce0ac4c8..90a72d86f5c 100644 --- a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java +++ b/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java @@ -25,14 +25,21 @@ import jdk.experimental.bytecode.BasicClassBuilder; import jdk.experimental.bytecode.BasicTypeHelper; +import jdk.experimental.bytecode.BytePoolHelper; +import jdk.experimental.bytecode.ClassBuilder; +import jdk.experimental.bytecode.CodeBuilder; import jdk.experimental.bytecode.Flag; +import jdk.experimental.bytecode.MethodBuilder; import jdk.experimental.bytecode.PoolHelper; import jdk.experimental.bytecode.TypedCodeBuilder; +import jdk.experimental.bytecode.TypeHelper; +import jdk.experimental.bytecode.TypeTag; import java.io.FileOutputStream; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.util.Iterator; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; @@ -46,8 +53,12 @@ public class InstructionHelper { static final AtomicInteger COUNT = new AtomicInteger(); + static String generateClassNameFromLookupClass(MethodHandles.Lookup l) { + return l.lookupClass().getCanonicalName().replace('.', '/') + "$Code_" + COUNT.getAndIncrement(); + } + static BasicClassBuilder classBuilder(MethodHandles.Lookup l) { - String className = l.lookupClass().getCanonicalName().replace('.', '/') + "$Code_" + COUNT.getAndIncrement(); + String className = generateClassNameFromLookupClass(l); return new BasicClassBuilder(className, 55, 0) .withSuperclass("java/lang/Object") .withMethod("", "()V", M -> @@ -83,7 +94,7 @@ public static MethodHandle invokedynamic(MethodHandles.Lookup l, public static MethodHandle ldcMethodHandle(MethodHandles.Lookup l, int refKind, Class owner, String name, MethodType type) throws Exception { return ldc(l, MethodHandle.class, - P -> P.putMethodHandle(refKind, csym(owner), name, type.toMethodDescriptorString())); + P -> P.putHandle(refKind, csym(owner), name, type.toMethodDescriptorString())); } public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, @@ -112,7 +123,7 @@ public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, String bsmClass, String bsmMethodName, String bsmType, Consumer> staticArgs) throws Exception { return ldc(l, type, - P -> P.putConstantDynamic(name, type, + P -> P.putDynamicConstant(name, type, bsmClass, bsmMethodName, bsmType, staticArgs)); } @@ -148,4 +159,195 @@ public static String csym(Class c) { public static String cref(Class c) { return methodType(c).toMethodDescriptorString().substring(2); } + + + // loadCode(MethodHandles.Lookup, String, MethodType, Consumer>) et al... + + public static MethodHandle loadCode(MethodHandles.Lookup lookup, String name, MethodType type, Consumer> builder) { + String className = generateClassNameFromLookupClass(lookup); + return loadCode(lookup, className, name, type, builder); + } + + public static MethodHandle loadCode(MethodHandles.Lookup lookup, String className, String methodName, MethodType type, Consumer> builder) { + String descriptor = type.toMethodDescriptorString(); + return loadCode(lookup, className, methodName, descriptor, MethodHandleCodeBuilder::new, + clazz -> { + try { + return lookup.findStatic(clazz, methodName, MethodType.fromMethodDescriptorString(descriptor, lookup.lookupClass().getClassLoader())); + } catch (ReflectiveOperationException ex) { + throw new IllegalStateException(ex); + } + }, + builder); + } + + + private static , String, byte[], ?>> Z loadCode( + MethodHandles.Lookup lookup, String className, String methodName, String type, + Function, String, byte[]>, ? extends C> builderFunc, + Function, Z> resFunc, Consumer builder) { + + IsolatedMethodBuilder isolatedMethodBuilder = new IsolatedMethodBuilder(className, lookup); + isolatedMethodBuilder + .withSuperclass(Object.class) + .withMajorVersion(60) + .withMinorVersion(0) + .withFlags(Flag.ACC_PUBLIC) + .withMethod(methodName, type, M -> + M.withFlags(Flag.ACC_STATIC, Flag.ACC_PUBLIC) + .withCode(builderFunc, builder)); + + try { + byte[] byteArray = isolatedMethodBuilder.build(); + Class clazz = lookup.defineClass(byteArray); + return resFunc.apply(clazz); + } catch (Throwable e) { + throw new IllegalStateException(e); + } + } + + private static class IsolatedMethodBuilder extends ClassBuilder, String, IsolatedMethodBuilder> { + + private static final Class THIS_CLASS = new Object() { }.getClass(); + + private IsolatedMethodBuilder(String clazz, MethodHandles.Lookup lookup) { + super(new IsolatedMethodPoolHelper(clazz), + new IsolatedMethodTypeHelper(lookup)); + withThisClass(THIS_CLASS); + } + + public Class thisClass() { + return THIS_CLASS; + } + + static String classToInternalName(Class c) { + return c.getName().replace('.', '/'); + } + + private static class IsolatedMethodTypeHelper implements TypeHelper, String> { + + BasicTypeHelper basicTypeHelper = new BasicTypeHelper(); + MethodHandles.Lookup lookup; + + private IsolatedMethodTypeHelper(MethodHandles.Lookup lookup) { + this.lookup = lookup; + } + + @Override + public String elemtype(String s) { + return basicTypeHelper.elemtype(s); + } + + @Override + public String arrayOf(String s) { + return basicTypeHelper.arrayOf(s); + } + + @Override + public Iterator parameterTypes(String s) { + return basicTypeHelper.parameterTypes(s); + } + + @Override + public String fromTag(TypeTag tag) { + return basicTypeHelper.fromTag(tag); + } + + @Override + public String returnType(String s) { + return basicTypeHelper.returnType(s); + } + + @Override + public String type(Class aClass) { + if (aClass.isArray()) { + return classToInternalName(aClass); + } else { + return (aClass.isInlineClass() ? "Q" : "L") + classToInternalName(aClass) + ";"; + } + } + + @Override + public boolean isInlineClass(String desc) { + Class aClass = symbol(desc); + return aClass != null && aClass.isInlineClass(); + } + + @Override + public Class symbol(String desc) { + try { + if (desc.startsWith("[")) { + return Class.forName(desc.replaceAll("/", "."), true, lookup.lookupClass().getClassLoader()); + } else { + return Class.forName(basicTypeHelper.symbol(desc).replaceAll("/", "."), true, lookup.lookupClass().getClassLoader()); + } + } catch (ReflectiveOperationException ex) { + throw new AssertionError(ex); + } + } + + @Override + public TypeTag tag(String s) { + return basicTypeHelper.tag(s); + } + + @Override + public Class symbolFrom(String s) { + return symbol(s); + } + + @Override + public String commonSupertype(String t1, String t2) { + return basicTypeHelper.commonSupertype(t1, t2); + } + + @Override + public String nullType() { + return basicTypeHelper.nullType(); + } + } + + private static class IsolatedMethodPoolHelper extends BytePoolHelper, String> { + final String clazz; + + private IsolatedMethodPoolHelper(String clazz) { + super(c -> from(c, clazz), s->s); + this.clazz = clazz; + } + + static String from(Class c, String clazz) { + return c == THIS_CLASS ? clazz.replace('.', '/') + : classToInternalName(c); + } + } + + @Override + public byte[] build() { + return super.build(); + } + } + + public static class MethodHandleCodeBuilder> extends TypedCodeBuilder, String, byte[], T> { + + BasicTypeHelper basicTypeHelper = new BasicTypeHelper(); + + public MethodHandleCodeBuilder(jdk.experimental.bytecode.MethodBuilder, String, byte[]> methodBuilder) { + super(methodBuilder); + } + + TypeTag getTagType(String s) { + return basicTypeHelper.tag(s); + } + + public T ifcmp(String s, CondKind cond, CharSequence label) { + return super.ifcmp(getTagType(s), cond, label); + } + + public T return_(String s) { + return super.return_(getTagType(s)); + } + } + + + } diff --git a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java index 570fa1c127f..4707060c3cd 100644 --- a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java +++ b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test bootstrap methods throwing an exception - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng BootstrapMethodJumboArgsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 BootstrapMethodJumboArgsTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMException.java b/test/jdk/java/lang/invoke/condy/CondyBSMException.java index 4e6ec9af0cd..c9d2f9a12f0 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMException.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMException.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test bootstrap methods throwing an exception - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyBSMException * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMException */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java index e450c12554c..86a68049790 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 8199875 * @summary Test basic invocation of bootstrap methods - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyBSMInvocation * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java index 1138de86074..c3e14877863 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test invalid name in name and type - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyBSMValidationTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java index d3527709b3c..fb32bec7834 100644 --- a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java +++ b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java @@ -25,7 +25,8 @@ * @test * @bug 8186046 * @summary Test for an interface using condy with default overpass methods - * @modules java.base/jdk.experimental.bytecode + * @library /lib/testlibrary/bytecode + * @build jdk.experimental.bytecode.BasicClassBuilder * @run testng CondyInterfaceWithOverpassMethods * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyInterfaceWithOverpassMethods */ diff --git a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java index 99f9b3e5916..b7d6999fb4d 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test invalid name in name and type - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyNameValidationTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNameValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java index be512191fca..dc25639e058 100644 --- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java +++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java @@ -25,8 +25,8 @@ * @test * @bug 8186211 * @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder * @run testng CondyRepeatFailedResolution * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyRepeatFailedResolution */ diff --git a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java index 3a1da76f1ab..b6d343ab8dc 100644 --- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java @@ -25,7 +25,8 @@ * @test * @bug 8186046 * @summary Test for condy BSMs returning primitive values or null - * @modules java.base/jdk.experimental.bytecode + * @library /lib/testlibrary/bytecode + * @build jdk.experimental.bytecode.BasicClassBuilder * @run testng CondyReturnPrimitiveTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyReturnPrimitiveTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java index e93580ec472..f2f8bcc00f3 100644 --- a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test bootstrap arguments for condy - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyStaticArgumentsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyStaticArgumentsTest */ @@ -109,7 +108,7 @@ public void testBasicArgs() throws Throwable { .add("something", PoolHelper::putString) .add("(IJFD)V", PoolHelper::putMethodType) .add(mhi, (P, Z) -> { - return P.putMethodHandle(mhi.getReferenceKind(), "CondyStaticArgumentsTest", mhi.getName(), bi.descriptor); + return P.putHandle(mhi.getReferenceKind(), "CondyStaticArgumentsTest", mhi.getName(), bi.descriptor); })); Assert.assertEquals(mh.invoke(), "constant-name-String-1-2-3.0-4.0-Number-something-(int,long,float,double)void-11"); @@ -148,7 +147,7 @@ static String condyWithCondy(MethodHandles.Lookup l, String name, Class type, static int bigDecimalPoolHelper(String value, String mc, PoolHelper P) { BSMInfo bi = BSMInfo.of("bigDecimal"); - return P.putConstantDynamic("big-decimal", "Ljava/math/BigDecimal;", InstructionHelper.csym(L.lookupClass()), bi.methodName, bi.descriptor, + return P.putDynamicConstant("big-decimal", "Ljava/math/BigDecimal;", InstructionHelper.csym(L.lookupClass()), bi.methodName, bi.descriptor, S -> S.add(value, PoolHelper::putString) .add(mc, (P2, s) -> { return mathContextPoolHelper(s, P2); @@ -157,7 +156,7 @@ static int bigDecimalPoolHelper(String value, String mc, PoolHelper int mathContextPoolHelper(String mc, PoolHelper P) { BSMInfo bi = BSMInfo.of("mathContext"); - return P.putConstantDynamic(mc, "Ljava/math/MathContext;", InstructionHelper.csym(L.lookupClass()), bi.methodName, bi.descriptor, + return P.putDynamicConstant(mc, "Ljava/math/MathContext;", InstructionHelper.csym(L.lookupClass()), bi.methodName, bi.descriptor, S -> { }); } diff --git a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java index 251b34ebe75..eebd440c864 100644 --- a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java @@ -25,8 +25,8 @@ * @test * @bug 8186046 * @summary Test invalid name in name and type - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyTypeValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java index e820dfa9355..2ea242f45f3 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Stress test ldc to ensure HotSpot correctly manages oop maps - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyWithGarbageTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWithGarbageTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyWrongType.java b/test/jdk/java/lang/invoke/condy/CondyWrongType.java index b204d38afeb..0966ab86599 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java +++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 * @summary Test bootstrap methods returning the wrong type - * @library /java/lang/invoke/common - * @modules java.base/jdk.experimental.bytecode - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng CondyWrongType * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWrongType */ diff --git a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java index 04ca8023f5a..91880c18ed5 100644 --- a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java +++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java @@ -25,9 +25,8 @@ * @test * @bug 8186046 8195694 * @summary Test dynamic constant bootstraps - * @modules java.base/jdk.experimental.bytecode - * @library /java/lang/invoke/common - * @build test.java.lang.invoke.lib.InstructionHelper + * @library /lib/testlibrary/bytecode /java/lang/invoke/common + * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper * @run testng ConstantBootstrapsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 ConstantBootstrapsTest */ @@ -160,13 +159,14 @@ public void testGetStaticSelf() throws Throwable { assertEquals(handle.invoke(), BigInteger.ZERO); } + public void testInvoke() throws Throwable { var handle = InstructionHelper.ldcDynamicConstant( L, "_", List.class, ConstantBootstraps.class, "invoke", lookupMT(Object.class, MethodHandle.class, Object[].class), S -> { S.add("", (P, Z) -> { - return P.putMethodHandle(MethodHandleInfo.REF_invokeStatic, "java/util/List", "of", + return P.putHandle(MethodHandleInfo.REF_invokeStatic, "java/util/List", "of", MethodType.methodType(List.class, Object[].class).toMethodDescriptorString(), true); }); @@ -181,7 +181,7 @@ public void testInvokeAsType() throws Throwable { ConstantBootstraps.class, "invoke", lookupMT(Object.class, MethodHandle.class, Object[].class), S -> { S.add("", (P, Z) -> { - return P.putMethodHandle(MethodHandleInfo.REF_invokeStatic, "java/lang/Integer", "valueOf", + return P.putHandle(MethodHandleInfo.REF_invokeStatic, "java/lang/Integer", "valueOf", MethodType.methodType(Integer.class, String.class).toMethodDescriptorString(), false); }); @@ -197,7 +197,7 @@ public void testInvokeAsTypeVariableArity() throws Throwable { ConstantBootstraps.class, "invoke", lookupMT(Object.class, MethodHandle.class, Object[].class), S -> { S.add("", (P, Z) -> { - return P.putMethodHandle(MethodHandleInfo.REF_invokeStatic, "java/util/List", "of", + return P.putHandle(MethodHandleInfo.REF_invokeStatic, "java/util/List", "of", MethodType.methodType(List.class, Object[].class).toMethodDescriptorString(), true); }); diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java index 0449628cb61..f2d807f1a8e 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java @@ -32,6 +32,10 @@ public BasicClassBuilder(String thisClass, int majorVersion, int minorVersion) { withThisClass(thisClass); } + public BasicClassBuilder(BytePoolHelper poolHelper, TypeHelper typeHelper) { + super(poolHelper, typeHelper); + } + public BasicClassBuilder() { super(new BytePoolHelper<>(s->s, s->s), new BasicTypeHelper()); } diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicTypeHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicTypeHelper.java index 42d5e6335b2..d66ceb1e9f1 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicTypeHelper.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicTypeHelper.java @@ -45,16 +45,27 @@ public String arrayOf(String s) { return "[" + s; } + @Override + public boolean isInlineClass(String t) { + return t.charAt(0) == 'Q' && t.endsWith(";"); + } + @Override public String type(String s) { return "L" + s + ";"; } + @Override + public String valueType(String s) { + return "Q" + s + ";"; + } + @Override public TypeTag tag(String s) { switch (s.charAt(0)) { case '[': case 'L': + case 'Q': return TypeTag.A; case 'B': case 'C': @@ -70,9 +81,10 @@ public TypeTag tag(String s) { return TypeTag.D; case 'V': return TypeTag.V; - case 'Q': - return TypeTag.Q; default: + if (s == nullType()) { + return TypeTag.A; + } throw new IllegalStateException("Bad type: " + s); } } diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java index 6461cdfb8f1..a79d09b412e 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java @@ -24,6 +24,7 @@ package jdk.experimental.bytecode; import java.lang.invoke.MethodHandleInfo; +import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -336,6 +337,11 @@ public int putClass(S symbol) { return putClassInternal(symbolToString.apply(symbol)); } + @Override + public int putInlineClass(S symbol) { + return putClassInternal("Q" + symbolToString.apply(symbol) + ";"); + } + private int putClassInternal(String symbol) { key.setClass(symbol); PoolKey poolKey = entries.lookup(key); diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java index d16cd138fff..01057d6ce45 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java @@ -99,14 +99,14 @@ public C getfield(S owner, CharSequence name, T type) { return thisBuilder(); } - public C vgetfield(S owner, CharSequence name, T type) { - emitOp(Opcode.VGETFIELD, type); + public C putfield(S owner, CharSequence name, T type) { + emitOp(Opcode.PUTFIELD, type); code.writeChar(poolHelper.putFieldRef(owner, name, type)); return thisBuilder(); } - public C putfield(S owner, CharSequence name, T type) { - emitOp(Opcode.PUTFIELD, type); + public C withfield(S owner, CharSequence name, T type) { + emitOp(Opcode.WITHFIELD, type); code.writeChar(poolHelper.putFieldRef(owner, name, type)); return thisBuilder(); } @@ -155,15 +155,9 @@ public C new_(S clazz) { return thisBuilder(); } - public C vnew_(S clazz, CharSequence name, T desc) { - emitOp(Opcode.VNEW, clazz); - code.writeChar(poolHelper.putMethodRef(clazz, name, desc, false)); - return thisBuilder(); - } - - public C vnewarray(S array) { - emitOp(Opcode.VNEWARRAY, array); - code.writeChar(poolHelper.putClass(array)); + public C defaultvalue(S clazz) { + emitOp(Opcode.DEFAULTVALUE, clazz); + code.writeChar(poolHelper.putClass(clazz)); return thisBuilder(); } @@ -201,24 +195,6 @@ public C multianewarray(S array, byte dims) { return thisBuilder(); } - public C multivnewarray(S array, byte dims) { - emitOp(Opcode.MULTIVNEWARRAY, new Object[]{array, dims}); - code.writeChar(poolHelper.putClass(array)).writeByte(dims); - return thisBuilder(); - } - - public C vbox(S target) { - emitOp(Opcode.VBOX, target); - code.writeChar(poolHelper.putClass(target)); - return thisBuilder(); - } - - public C vunbox(S target) { - emitOp(Opcode.VUNBOX, target); - code.writeChar(poolHelper.putClass(target)); - return thisBuilder(); - } - public C ldc(int i) { return ldc(pool -> pool.putInt(i), false); } @@ -293,10 +269,6 @@ public C return_() { return emitOp(Opcode.RETURN); } - public C vreturn() { - return emitOp(Opcode.VRETURN); - } - protected C emitWideIfNeeded(Opcode opcode, int n) { boolean wide = n > Byte.MAX_VALUE; if (wide) { @@ -325,90 +297,6 @@ protected C emitWideIfNeeded(Opcode opcode, int n, int v) { return thisBuilder(); } - public TypedBuilder typed(TypeTag typeTag) { - return typed(typeTag, _unused -> new TypedBuilder()); - } - - protected TB typed(TypeTag typeTag, Function typedBuilderFunc) { - emitOp(Opcode.TYPED); - code.writeChar(poolHelper.putType(typeHelper.fromTag(typeTag))); - return typedBuilderFunc.apply(typeTag); - } - - public class TypedBuilder { - public C aload_0() { - return CodeBuilder.this.aload_0(); - } - - public C aload_1() { - return CodeBuilder.this.aload_1(); - } - - public C aload_2() { - return CodeBuilder.this.aload_2(); - } - - public C aload_3() { - return CodeBuilder.this.aload_3(); - } - - public C aload(int n) { - return CodeBuilder.this.aload(n); - } - - public C astore_0() { - return CodeBuilder.this.astore_0(); - } - - public C astore_1() { - return CodeBuilder.this.astore_1(); - } - - public C astore_2() { - return CodeBuilder.this.astore_2(); - } - - public C astore_3() { - return CodeBuilder.this.astore_3(); - } - - public C astore(int n) { - return CodeBuilder.this.astore(n); - } - - public C aaload() { - return CodeBuilder.this.aaload(); - } - - public C aastore() { - return CodeBuilder.this.aastore(); - } - - public C areturn() { - return CodeBuilder.this.areturn(); - } - - public C anewarray(S s) { - return CodeBuilder.this.anewarray(s); - } - - public C aconst_null() { - return CodeBuilder.this.aconst_null(); - } - - public C if_acmpeq(short target) { - return CodeBuilder.this.if_acmpeq(target); - } - - public C if_acmpne(short target) { - return CodeBuilder.this.if_acmpeq(target); - } - } - - public C vload(int i) { - return emitWideIfNeeded(Opcode.VLOAD, i); - } - public C aload(int i) { return emitWideIfNeeded(Opcode.ALOAD, i); } @@ -509,10 +397,6 @@ public C dload_3() { return emitOp(Opcode.DLOAD_3); } - public C vstore(int i) { - return emitWideIfNeeded(Opcode.VSTORE, i); - } - public C astore(int i) { return emitWideIfNeeded(Opcode.ASTORE, i); } @@ -631,10 +515,6 @@ public C daload() { return emitOp(Opcode.DALOAD); } - public C vaload() { - return emitOp(Opcode.VALOAD); - } - public C aaload() { return emitOp(Opcode.AALOAD); } @@ -667,10 +547,6 @@ public C dastore() { return emitOp(Opcode.DASTORE); } - public C vastore() { - return emitOp(Opcode.VASTORE); - } - public C aastore() { return emitOp(Opcode.AASTORE); } @@ -1280,7 +1156,8 @@ private void writeStackMapType(T t) { } else { //TODO: uninit this, top? stackmaps.writeByte(7); - stackmaps.writeChar(poolHelper.putClass(typeHelper.symbol(t))); + stackmaps.writeChar(typeHelper.isInlineClass(t) ? + poolHelper.putInlineClass(typeHelper.symbol(t)) : poolHelper.putClass(typeHelper.symbol(t))); } break; default: diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java index 47da97ab1a6..3dd647cc209 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java @@ -43,6 +43,7 @@ public enum Flag { ACC_BRIDGE(0x0040), ACC_VARARGS(0x0080), ACC_NATIVE(0x0100), + ACC_INLINE(0x0100), ACC_STRICT(0x0800); public int flag; diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/IsolatedMethodBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/IsolatedMethodBuilder.java index 7d84af52263..9b7ea90b1b8 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/IsolatedMethodBuilder.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/IsolatedMethodBuilder.java @@ -53,6 +53,11 @@ public int putClass(Class symbol) { return putIfAbsent(symbol); } + @Override + public int putInlineClass(Class symbol) { + return putIfAbsent(symbol); + } + @Override public int putFieldRef(Class owner, CharSequence name, String type) { try { diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java index 4cd50cc8789..ed8953bbb40 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java @@ -115,40 +115,32 @@ public MacroCodeBuilder(MethodBuilder methodBuilder) { } public C load(TypeTag type, int n) { - if (type == TypeTag.Q) { - return vload(n); - } else { - switch (n) { - case 0: - return emitOp(Opcode.ILOAD_0.at(type, 4)); - case 1: - return emitOp(Opcode.ILOAD_1.at(type, 4)); - case 2: - return emitOp(Opcode.ILOAD_2.at(type, 4)); - case 3: - return emitOp(Opcode.ILOAD_3.at(type, 4)); - default: - return emitWideIfNeeded(Opcode.ILOAD.at(type), n); - } + switch (n) { + case 0: + return emitOp(Opcode.ILOAD_0.at(type, 4)); + case 1: + return emitOp(Opcode.ILOAD_1.at(type, 4)); + case 2: + return emitOp(Opcode.ILOAD_2.at(type, 4)); + case 3: + return emitOp(Opcode.ILOAD_3.at(type, 4)); + default: + return emitWideIfNeeded(Opcode.ILOAD.at(type), n); } } public C store(TypeTag type, int n) { - if (type == TypeTag.Q) { - return vstore(n); - } else { - switch (n) { - case 0: - return emitOp(Opcode.ISTORE_0.at(type, 4)); - case 1: - return emitOp(Opcode.ISTORE_1.at(type, 4)); - case 2: - return emitOp(Opcode.ISTORE_2.at(type, 4)); - case 3: - return emitOp(Opcode.ISTORE_3.at(type, 4)); - default: - return emitWideIfNeeded(Opcode.ISTORE.at(type), n); - } + switch (n) { + case 0: + return emitOp(Opcode.ISTORE_0.at(type, 4)); + case 1: + return emitOp(Opcode.ISTORE_1.at(type, 4)); + case 2: + return emitOp(Opcode.ISTORE_2.at(type, 4)); + case 3: + return emitOp(Opcode.ISTORE_3.at(type, 4)); + default: + return emitWideIfNeeded(Opcode.ISTORE.at(type), n); } } @@ -308,29 +300,13 @@ public C xor(TypeTag type) { public C return_(TypeTag type) { switch (type) { case V: - return return_(); case Q: - return vreturn(); + return return_(); default: return emitOp(Opcode.IRETURN.at(type)); } } - @Override - public LabelledTypedBuilder typed(TypeTag typeTag) { - return super.typed(typeTag, _unused -> new LabelledTypedBuilder()); - } - - public class LabelledTypedBuilder extends TypedBuilder { - public C if_acmpeq(CharSequence target) { - return ifcmp(TypeTag.A, CondKind.EQ, target); - } - - public C if_acmpne(CharSequence target) { - return ifcmp(TypeTag.A, CondKind.NE, target); - } - } - public C conv(TypeTag from, TypeTag to) { switch (from) { case B: diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java index d3fa013e650..6dcc3367f0c 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java @@ -229,18 +229,9 @@ public enum Opcode { IF_NONNULL(199), GOTO_W(200), JSR_W(201), - VLOAD(203), - VSTORE(204), - VALOAD(205), - VASTORE(206), - VNEW(207), - VNEWARRAY(208), - MULTIVNEWARRAY(209), - VRETURN(210), - VGETFIELD(211), - TYPED(212), - VBOX(216), - VUNBOX(217); + DEFAULTVALUE(203), + WITHFIELD(204); + int code; diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java index d85579635e1..4ab14782721 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java @@ -36,6 +36,8 @@ public interface PoolHelper { int putClass(S symbol); + int putInlineClass(S symbol); + int putFieldRef(S owner, CharSequence name, T type); int putMethodRef(S owner, CharSequence name, T type, boolean isInterface); diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java index fedb6043209..11250cb1541 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java @@ -83,6 +83,24 @@ */ T type(S s); + /** + * Return true if the parameter is a value type. + * + * @param t the type descreiptor + * @return true if the given type is a value type + */ + boolean isInlineClass(T t); + + /** + * For a symbol that corresponds to a value type, return the type descriptor. + * + * @param s the symbol + * @return the type descriptor + */ + default T valueType(S s) { + return type(s); + } + /** * Return the symbol corresponding to a type descriptor. * diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java index dc82ad67af3..407bcff3658 100644 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java +++ b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java @@ -137,95 +137,6 @@ public SwitchBuilder withDefault(Consumer defaultCase) { } } - @Override - public StatefulTypedBuilder typed(TypeTag tag) { - return super.typed(tag, StatefulTypedBuilder::new); - } - - public class StatefulTypedBuilder extends LabelledTypedBuilder { - - TypeTag tag; - - StatefulTypedBuilder(TypeTag tag) { - this.tag = tag; - } - - @Override - public C astore_0() { - return storeAndUpdate(super::astore_0); - } - - @Override - public C astore_1() { - return storeAndUpdate(super::astore_1); - } - - @Override - public C astore_2() { - return storeAndUpdate(super::astore_2); - } - - @Override - public C astore_3() { - return storeAndUpdate(super::astore_3); - } - - @Override - public C astore(int n) { - return storeAndUpdate(() -> super.astore(n)); - } - - @Override - public C aastore() { - return storeAndUpdate(super::aastore); - } - - @Override - public C areturn() { - state.pop(tag); - state.push(typeHelper.nullType()); - return super.areturn(); - } - - @Override - public C anewarray(S s) { - super.anewarray(s); - state.pop(); - state.push(typeHelper.arrayOf(typeHelper.type(s))); - return thisBuilder(); - } - - @Override - public C aconst_null() { - super.aconst_null(); - state.pop(); - state.push(tag); - return thisBuilder(); - } - - public C if_acmpeq(CharSequence label) { - return jumpAndUpdate(() -> super.if_acmpeq(label)); - } - - public C if_acmpne(CharSequence label) { - return jumpAndUpdate(() -> super.if_acmpne(label)); - } - - private C storeAndUpdate(Supplier op) { - state.pop(tag); - state.push(typeHelper.nullType()); - return op.get(); - } - - private C jumpAndUpdate(Supplier op) { - state.pop(tag); - state.pop(tag); - state.push(typeHelper.nullType()); - state.push(typeHelper.nullType()); - return op.get(); - } - } - public class State { public final ArrayList stack; public final Vector locals; @@ -386,7 +297,6 @@ int width(T o) { @SuppressWarnings("unchecked") public void updateState(Opcode op, Object optValue) { switch (op) { - case VALOAD: case AALOAD: state.pop(); state.push(typeHelper.elemtype(state.pop())); @@ -395,6 +305,7 @@ public void updateState(Opcode op, Object optValue) { state.alive = false; break; case NOP: + case IINC: case INEG: case LNEG: case FNEG: @@ -458,7 +369,6 @@ public void updateState(Opcode op, Object optValue) { case ALOAD: case LLOAD: case DLOAD: - case VLOAD: state.push(state.locals.get((Integer) optValue)); break; case IALOAD: @@ -507,7 +417,6 @@ public void updateState(Opcode op, Object optValue) { case ISTORE: case FSTORE: case ASTORE: - case VSTORE: state.load(state.pop(), (int) optValue); break; case LSTORE_0: @@ -536,7 +445,6 @@ public void updateState(Opcode op, Object optValue) { case LUSHR: state.pop(); break; - case VRETURN: case ARETURN: case IRETURN: case FRETURN: @@ -576,7 +484,6 @@ public void updateState(Opcode op, Object optValue) { state.pop(); state.push(TypeTag.I); break; - case VASTORE: case AASTORE: state.pop(); state.pop(); @@ -823,8 +730,8 @@ public void updateState(Opcode op, Object optValue) { case MONITOREXIT: state.pop(); break; - case VNEW: case NEW: + case DEFAULTVALUE: state.push(typeHelper.type((S) optValue)); break; case NEWARRAY: @@ -835,13 +742,6 @@ public void updateState(Opcode op, Object optValue) { state.pop(); state.push(typeHelper.arrayOf(typeHelper.arrayOf(typeHelper.type((S)optValue)))); break; - case VNEWARRAY: - case VBOX: - case VUNBOX: - state.pop(); - state.push(typeHelper.type((S) optValue)); - break; - case MULTIVNEWARRAY: case MULTIANEWARRAY: for (int i = 0; i < (byte) ((Object[]) optValue)[1]; i++) { state.pop(); @@ -858,7 +758,6 @@ public void updateState(Opcode op, Object optValue) { case GETSTATIC: state.push((T) optValue); break; - case VGETFIELD: case GETFIELD: state.pop(); state.push((T) optValue); @@ -882,6 +781,15 @@ public void updateState(Opcode op, Object optValue) { state.pop(); break; } + case WITHFIELD: { + TypeTag tag = typeHelper.tag((T) optValue); + if (tag.width == 1) { + state.pop(); + } else { + state.pop2(); + } + break; + } case BIPUSH: case SIPUSH: state.push(TypeTag.I); @@ -916,7 +824,6 @@ public void updateState(Opcode op, Object optValue) { state.pop(); state.push(TypeTag.Z); break; - case TYPED: case CHECKCAST: break; @@ -964,6 +871,11 @@ public int putClass(S symbol) { return poolHelper.putClass(symbol); } + @Override + public int putInlineClass(S symbol) { + throw new IllegalStateException(); + } + @Override public int putInt(int i) { type = typeHelper.fromTag(TypeTag.I);