diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index dd5c4c2474b..f82031a051b 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -25,14 +25,12 @@ import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import test.java.lang.invoke.lib.OldInstructionHelper; - +import test.java.lang.invoke.lib.InstructionHelper; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; -import jdk.experimental.bytecode.TypeTag; import java.util.Arrays; import java.util.Objects; @@ -48,12 +46,12 @@ * @test * @key randomness * @summary Test inline types in LWorld. - * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / + * @library /test/lib /test/jdk/java/lang/invoke/common / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @enablePreview * @modules java.base/jdk.internal.value * java.base/jdk.internal.vm.annotation - * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.OldInstructionHelper + * @build test.java.lang.invoke.lib.InstructionHelper * @run main/othervm/timeout=450 compiler.valhalla.inlinetypes.TestLWorld */ @@ -1093,13 +1091,13 @@ public void test34_verifier() { // Test writing constant null to a (flattened) inline type array - private static final MethodHandle setArrayElementNull = OldInstructionHelper.loadCode(MethodHandles.lookup(), + private static final MethodHandle setArrayElementNull = InstructionHelper.buildMethodHandle(MethodHandles.lookup(), "setArrayElementNull", MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class), CODE -> { CODE. - aload_1(). - iload_2(). + aload(1). + iload(2). aconst_null(). aastore(). return_(); @@ -1433,14 +1431,14 @@ public void test43_verifier(RunInfo info) { } // Tests writing an array element with a (statically known) incompatible type - private static final MethodHandle setArrayElementIncompatible = OldInstructionHelper.loadCode(MethodHandles.lookup(), + private static final MethodHandle setArrayElementIncompatible = InstructionHelper.buildMethodHandle(MethodHandles.lookup(), "setArrayElementIncompatible", MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), CODE -> { CODE. - aload_1(). - iload_2(). - aload_3(). + aload(1). + iload(2). + aload(3). aastore(). return_(); }); @@ -4060,14 +4058,14 @@ public void test144_verifier() { } // Tests writing an array element with a (statically known) incompatible type - private static final MethodHandle setArrayElementIncompatibleRef = OldInstructionHelper.loadCode(MethodHandles.lookup(), + private static final MethodHandle setArrayElementIncompatibleRef = InstructionHelper.buildMethodHandle(MethodHandles.lookup(), "setArrayElementIncompatibleRef", MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class), CODE -> { CODE. - aload_1(). - iload_2(). - aload_3(). + aload(1). + iload(2). + aload(3). aastore(). return_(); }); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index a93ec1b10ad..e650a3aa4e0 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, 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 @@ -25,8 +25,7 @@ import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.experimental.bytecode.TypeTag; -import test.java.lang.invoke.lib.OldInstructionHelper; +import test.java.lang.invoke.lib.InstructionHelper; import java.util.Objects; @@ -47,12 +46,12 @@ * @test * @key randomness * @summary Test correct handling of nullable value classes. - * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / + * @library /test/lib /test/jdk/java/lang/invoke/common / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @enablePreview * @modules java.base/jdk.internal.value * java.base/jdk.internal.vm.annotation - * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.OldInstructionHelper + * @build test.java.lang.invoke.lib.InstructionHelper * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestNullableInlineTypes */ @@ -2578,14 +2577,14 @@ public void test92_verifier() { Asserts.assertEQ(test92(), testValue1); } - private static final MethodHandle refCheckCast = OldInstructionHelper.loadCode(MethodHandles.lookup(), + private static final MethodHandle refCheckCast = InstructionHelper.buildMethodHandle(MethodHandles.lookup(), "refCheckCast", MethodType.methodType(MyValue2.class, TestNullableInlineTypes.class, MyValue1.class), CODE -> { CODE. - aload_1(). - checkcast(MyValue2.class). - return_(TypeTag.A); + aload(1). + checkcast(MyValue2.class.describeConstable().orElseThrow()). + areturn(); }); // Test checkcast that only passes with null diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestValueClasses.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestValueClasses.java index 8c6b2c68361..fa1fa4ff790 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestValueClasses.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestValueClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, 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 @@ -25,14 +25,12 @@ import compiler.lib.ir_framework.*; import jdk.test.lib.Asserts; -import jdk.experimental.bytecode.TypeTag; import java.lang.reflect.Method; import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*; import static compiler.valhalla.inlinetypes.InlineTypes.*; -import jdk.internal.value.ValueClass; import jdk.internal.vm.annotation.ImplicitlyConstructible; import jdk.internal.vm.annotation.LooselyConsistentValue; import jdk.internal.vm.annotation.NullRestricted; @@ -41,7 +39,7 @@ * @test * @key randomness * @summary Test correct handling of value classes. - * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common / + * @library /test/lib /test/jdk/java/lang/invoke/common / * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64") * @enablePreview * @modules java.base/jdk.internal.value diff --git a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/OldInstructionHelper.java b/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/OldInstructionHelper.java deleted file mode 100644 index 29acc690936..00000000000 --- a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/OldInstructionHelper.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2010, 2022, 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. - * - * 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 test.java.lang.invoke.lib; - -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; - -import static java.lang.invoke.MethodType.fromMethodDescriptorString; -import static java.lang.invoke.MethodType.methodType; - -/** - * 8308778: Temporarily keep the old bytecode API, but needs removing when Valhalla support is added to classfile API - */ -public class OldInstructionHelper { - - static final BasicTypeHelper BTH = new BasicTypeHelper(); - - 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 = generateClassNameFromLookupClass(l); - return new BasicClassBuilder(className, 55, 0) - .withSuperclass("java/lang/Object") - .withMethod("", "()V", M -> - M.withFlags(Flag.ACC_PUBLIC) - .withCode(TypedCodeBuilder::new, C -> - C.aload_0().invokespecial("java/lang/Object", "", "()V", false).return_() - )); - } - - public static MethodHandle invokedynamic(MethodHandles.Lookup l, - String name, MethodType type, - String bsmMethodName, MethodType bsmType, - Consumer> staticArgs) throws Exception { - byte[] byteArray = classBuilder(l) - .withMethod("m", type.toMethodDescriptorString(), M -> - M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC) - .withCode(TypedCodeBuilder::new, - C -> { - for (int i = 0; i < type.parameterCount(); i++) { - C.load(BTH.tag(cref(type.parameterType(i))), i); - } - C.invokedynamic(name, type.toMethodDescriptorString(), - csym(l.lookupClass()), bsmMethodName, bsmType.toMethodDescriptorString(), - staticArgs); - C.return_(BTH.tag(cref(type.returnType()))); - } - )) - .build(); - Class gc = l.defineClass(byteArray); - return l.findStatic(gc, "m", type); - } - - public static MethodHandle ldcMethodHandle(MethodHandles.Lookup l, - int refKind, Class owner, String name, MethodType type) throws Exception { - return ldc(l, MethodHandle.class, - P -> P.putHandle(refKind, csym(owner), name, type.toMethodDescriptorString())); - } - - public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, - String name, Class type, - String bsmMethodName, MethodType bsmType, - Consumer> staticArgs) throws Exception { - return ldcDynamicConstant(l, name, type, l.lookupClass(), bsmMethodName, bsmType, staticArgs); - } - - public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, - String name, Class type, - Class bsmClass, String bsmMethodName, MethodType bsmType, - Consumer> staticArgs) throws Exception { - return ldcDynamicConstant(l, name, cref(type), csym(bsmClass), bsmMethodName, bsmType.toMethodDescriptorString(), staticArgs); - } - - public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, - String name, String type, - String bsmMethodName, String bsmType, - Consumer> staticArgs) throws Exception { - return ldcDynamicConstant(l, name, type, csym(l.lookupClass()), bsmMethodName, bsmType, staticArgs); - } - - public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, - String name, String type, - String bsmClass, String bsmMethodName, String bsmType, - Consumer> staticArgs) throws Exception { - return ldc(l, type, - P -> P.putDynamicConstant(name, type, - bsmClass, bsmMethodName, bsmType, - staticArgs)); - } - - public static MethodHandle ldc(MethodHandles.Lookup l, - Class type, - Function, Integer> poolFunc) throws Exception { - return ldc(l, cref(type), poolFunc); - } - - public static MethodHandle ldc(MethodHandles.Lookup l, - String type, - Function, Integer> poolFunc) throws Exception { - String methodType = "()" + type; - byte[] byteArray = classBuilder(l) - .withMethod("m", "()" + type, M -> - M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC) - .withCode(TypedCodeBuilder::new, - C -> { - C.ldc(null, (P, v) -> poolFunc.apply(P)); - C.return_(BTH.tag(type)); - } - )) - .build(); - Class gc = l.defineClass(byteArray); - return l.findStatic(gc, "m", fromMethodDescriptorString(methodType, l.lookupClass().getClassLoader())); - } - - public static String csym(Class c) { - return c.getCanonicalName().replace('.', '/'); - } - - 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 methodName, MethodType type, Consumer> builder) { - String className = generateClassNameFromLookupClass(lookup); - return loadCode(lookup, className, methodName, 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); - } - - // Helper method to load code built with "buildCode()" - public static MethodHandle loadCodeBytes(MethodHandles.Lookup lookup, String methodName, MethodType type, byte[] byteCode) { - try { - Class clazz = lookup.defineClass(byteCode); - return lookup.findStatic(clazz, methodName, type); - } catch (Throwable t) { - throw new RuntimeException("Failed to loadCodeBytes \"" + methodName + "\"", t); - } - } - - - 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) { - try { - byte[] byteArray = buildCode(lookup, className, methodName, type, builderFunc, builder); - Class clazz = lookup.defineClass(byteArray); - return resFunc.apply(clazz); - } catch (Throwable e) { - throw new IllegalStateException(e); - } - } - - public static byte[] buildCode(MethodHandles.Lookup lookup, String methodName, MethodType type, Consumer> builder) { - String className = generateClassNameFromLookupClass(lookup); - return buildCode(lookup, className, methodName, type.toMethodDescriptorString(), MethodHandleCodeBuilder::new, builder); - } - - public static , String, byte[], ?>> byte[] buildCode( - MethodHandles.Lookup lookup, String className, String methodName, String type, - Function, String, byte[]>, ? extends C> builderFunc, - Consumer builder) { - - return new IsolatedMethodBuilder(className, lookup) - .withSuperclass(Object.class) - .withMajorVersion(66) - .withMinorVersion(0) - .withFlags(Flag.ACC_PUBLIC, Flag.ACC_IDENTITY) - .withMethod(methodName, type, M -> - M.withFlags(Flag.ACC_STATIC, Flag.ACC_PUBLIC) - .withCode(builderFunc, builder)).build(); - - } - - 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) { - if (c.isArray()) { - return c.descriptorString(); - } - 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) { - return aClass.descriptorString(); - } - - @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/lib/testlibrary/bytecode/jdk/experimental/bytecode/AbstractBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AbstractBuilder.java deleted file mode 100644 index 4e793ef8694..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AbstractBuilder.java +++ /dev/null @@ -1,60 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AnnotationsBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AnnotationsBuilder.java deleted file mode 100644 index 38b5a828dad..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AnnotationsBuilder.java +++ /dev/null @@ -1,338 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AttributeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AttributeBuilder.java deleted file mode 100644 index 80f6bfc8ed0..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/AttributeBuilder.java +++ /dev/null @@ -1,125 +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. - * - * 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); - } -} diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java deleted file mode 100644 index f2d807f1a8e..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicClassBuilder.java +++ /dev/null @@ -1,42 +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. - * - * 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(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 deleted file mode 100644 index b435f663727..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BasicTypeHelper.java +++ /dev/null @@ -1,182 +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. - * - * 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 String type(String s) { - return "L" + s + ";"; - } - - - @Override - public TypeTag tag(String s) { - switch (s.charAt(0)) { - case '[': - 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 '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) { - return (type.startsWith("L") || type.startsWith("Q")) ? type.substring(1, type.length() - 1) : type; - } - - @Override - public String returnType(String s) { - return s.substring(s.indexOf(')') + 1, s.length()); - } - -} diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java deleted file mode 100644 index a79d09b412e..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/BytePoolHelper.java +++ /dev/null @@ -1,758 +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. - * - * 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.MethodHandleInfo; -import java.lang.invoke.MethodType; -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 { - - GrowableByteBuffer pool = new GrowableByteBuffer(); - GrowableByteBuffer bsm_attr = new GrowableByteBuffer(); - //Map indicesMap = new HashMap<>(); - int currentIndex = 1; - 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.symbolToString = symbolToString; - this.typeToString = 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(); - - 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.CONSTANT_UTF8; - o1 = s; - size = 1; - hash = tag.tag | (s.hashCode() << 1); - } - - void setClass(String clazz) { - tag = PoolTag.CONSTANT_CLASS; - o1 = clazz; - size = 1; - hash = tag.tag | (clazz.hashCode() << 1); - } - - void setNameAndType(CharSequence name, String type) { - tag = PoolTag.CONSTANT_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.CONSTANT_INVOKEDYNAMIC; - o1 = bsmIndex; - o2 = name; - o3 = type; - size = 3; - hash = tag.tag | ((bsmIndex | name.hashCode() | type.hashCode()) << 1); - } - - void setDynamicConstant(int bsmIndex, CharSequence name, String type) { - tag = PoolTag.CONSTANT_DYNAMIC; - o1 = bsmIndex; - o2 = name; - o3 = type; - size = 3; - hash = tag.tag | ((bsmIndex | name.hashCode() | type.hashCode()) << 1); - } - - void setString(String s) { - tag = PoolTag.CONSTANT_STRING; - o1 = s; - size = 1; - hash = tag.tag | (s.hashCode() << 1); - } - - void setInteger(Integer i) { - tag = PoolTag.CONSTANT_INTEGER; - o1 = i; - size = 1; - hash = tag.tag | (i.hashCode() << 1); - } - - void setFloat(Float f) { - tag = PoolTag.CONSTANT_FLOAT; - o1 = f; - size = 1; - hash = tag.tag | (f.hashCode() << 1); - } - - void setLong(Long l) { - tag = PoolTag.CONSTANT_LONG; - o1 = l; - size = 1; - hash = tag.tag | (l.hashCode() << 1); - } - - void setDouble(Double d) { - tag = PoolTag.CONSTANT_DOUBLE; - o1 = d; - size = 1; - hash = tag.tag | (d.hashCode() << 1); - } - - void setMethodType(String type) { - tag = PoolTag.CONSTANT_METHODTYPE; - o1 = type; - size = 1; - hash = tag.tag | (type.hashCode() << 1); - } - - void setMethodHandle(int bsmKind, String owner, CharSequence name, String type) { - tag = PoolTag.CONSTANT_METHODHANDLE; - o1 = bsmKind; - o2 = owner; - o3 = name; - o4 = type; - size = 4; - hash = tag.tag | (bsmKind | owner.hashCode() | name.hashCode() | type.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; - } - - 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); - } - - BsmKey dup() { - BsmKey bsmKey = new BsmKey(); - bsmKey.bsmClass = bsmClass; - bsmKey.bsmName = bsmName; - bsmKey.bsmType = bsmType; - bsmKey.bsmArgs = bsmArgs; - bsmKey.hash = hash; - return bsmKey; - } - - @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 putInlineClass(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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_CLASS.tag); - pool.writeChar(utf8_idx); - } - return poolKey.index; - } - - @Override - public int putFieldRef(S owner, CharSequence name, T type) { - return putMemberRef(PoolTag.CONSTANT_FIELDREF, owner, name, type); - } - - @Override - public int putMethodRef(S owner, CharSequence name, T type, boolean isInterface) { - return putMemberRef(isInterface ? PoolTag.CONSTANT_INTERFACEMETHODREF : PoolTag.CONSTANT_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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(poolTag.tag); - pool.writeChar(owner_idx); - pool.writeChar(nameAndType_idx); - } - 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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_INTEGER.tag); - pool.writeInt(i); - } - 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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_FLOAT.tag); - pool.writeFloat(f); - } - 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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_LONG.tag); - pool.writeLong(l); - currentIndex++; - } - 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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_DOUBLE.tag); - pool.writeDouble(d); - currentIndex++; - } - 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 putDynamicConstant(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - return putDynamicConstantInternal(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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_INVOKEDYNAMIC.tag); - pool.writeChar(bsmIndex); - pool.writeChar(nameAndType_idx); - } - return poolKey.index; - } - - private int putDynamicConstantInternal(CharSequence constName, String constType, String bsmClass, CharSequence bsmName, String bsmType, Consumer> staticArgs) { - int bsmIndex = putBsmInternal(bsmClass, bsmName, bsmType, staticArgs); - key.setDynamicConstant(bsmIndex, constName, constType); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int nameAndType_idx = putNameAndType(constName, constType); - poolKey.at(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_DYNAMIC.tag); - pool.writeChar(bsmIndex); - pool.writeChar(nameAndType_idx); - } - 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(); - // TODO the BSM could be a static method on an interface - int bsm_ref = putHandleInternal(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<>(); - - public ByteStaticArgListBuilder add(int i) { - indexes.add(putInt(i)); - return this; - } - public ByteStaticArgListBuilder add(float f) { - indexes.add(putFloat(f)); - return this; - } - public ByteStaticArgListBuilder add(long l) { - indexes.add(putLong(l)); - return this; - } - public ByteStaticArgListBuilder add(double d) { - indexes.add(putDouble(d)); - return this; - } - 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(putHandle(refKind, owner, name, type)); - return this; - } - public ByteStaticArgListBuilder add(Z z, ToIntBiFunction, Z> poolFunc) { - indexes.add(poolFunc.applyAsInt(BytePoolHelper.this, z)); - return this; - } - public ByteStaticArgListBuilder add(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - indexes.add(putDynamicConstant(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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_METHODTYPE.tag); - pool.writeChar(desc_idx); - } - return poolKey.index; - } - - @Override - public int putHandle(int refKind, S owner, CharSequence name, T type) { - return putHandleInternal(refKind, symbolToString.apply(owner), name, typeToString.apply(type), false); - } - - @Override - public int putHandle(int refKind, S owner, CharSequence name, T type, boolean isInterface) { - return putHandleInternal(refKind, symbolToString.apply(owner), name, typeToString.apply(type), isInterface); - } - - private int putHandleInternal(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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_METHODHANDLE.tag); - pool.writeByte(refKind); - pool.writeChar(ref_idx); - } - return poolKey.index; - } - - 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.CONSTANT_FIELDREF; - case 5: // REF_invokeVirtual - case 6: // REF_invokeStatic - case 7: // REF_invokeSpecial - case 8: // REF_newInvokeSpecial - case 9: // REF_invokeInterface - return isInterface ? PoolTag.CONSTANT_INTERFACEMETHODREF : PoolTag.CONSTANT_METHODREF; - default: - throw new IllegalStateException(); - } - } - - @Override - public int putType(T s) { - return putUtf8(typeToString.apply(s)); - } - - public int putUtf8(CharSequence s) { - key.setUtf8(s); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - poolKey.at(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_UTF8.tag); - putUTF8Internal(s); - } - return poolKey.index; - } - - /** - * Puts an UTF8 string into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param s a String whose UTF8 encoded length must be less than 65536. - * @return this byte vector. - */ - void putUTF8Internal(final CharSequence s) { - int charLength = s.length(); - if (charLength > 65535) { - throw new IllegalArgumentException(); - } - // 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; - } - } - } - - /** - * 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. - */ - 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 putString(String s) { - key.setString(s); - PoolKey poolKey = entries.lookup(key); - if (poolKey == null) { - poolKey = key.dup(); - int utf8_index = putUtf8(s); - poolKey.at(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_STRING.tag); - pool.writeChar(utf8_index); - } - return poolKey.index; - } - - 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(currentIndex++); - entries.enter(poolKey); - pool.writeByte(PoolTag.CONSTANT_NAMEANDTYPE.tag); - pool.writeChar(name_idx); - pool.writeChar(type_idx); - } - return poolKey.index; - } - - @Override - public int size() { - return currentIndex - 1; - } - - @Override - public byte[] entries() { - return pool.bytes(); - } - - > 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/ClassBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/ClassBuilder.java deleted file mode 100644 index cc1e6579d2c..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/ClassBuilder.java +++ /dev/null @@ -1,240 +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. - * - * 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(); - } - - /** - * 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.entries(); - 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java deleted file mode 100644 index 25e22ee34e1..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/CodeBuilder.java +++ /dev/null @@ -1,1218 +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. - * - * 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.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 aconst_init(S clazz) { - emitOp(Opcode.ACONST_INIT, clazz); - code.writeChar(poolHelper.putClass(clazz)); - 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); - int poolIdx = poolHelper.putClass(array); - code.writeChar(poolIdx); - return thisBuilder(); - } - - public C checkcast(S target) { - emitOp(Opcode.CHECKCAST); - int poolIdx = poolHelper.putClass(target); - code.writeChar(poolIdx); - return thisBuilder(); - } - - public C instanceof_(S target) { - emitOp(Opcode.INSTANCEOF); - int poolIdx = poolHelper.putClass(target); - code.writeChar(poolIdx); - 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.putDynamicConstant(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(); - } - - //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 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(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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/DeclBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/DeclBuilder.java deleted file mode 100644 index 7e77ae3fe2a..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/DeclBuilder.java +++ /dev/null @@ -1,115 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/FieldBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/FieldBuilder.java deleted file mode 100644 index 688d3addef0..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/FieldBuilder.java +++ /dev/null @@ -1,37 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java deleted file mode 100644 index 7a354159f79..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Flag.java +++ /dev/null @@ -1,65 +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. - * - * 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_IDENTITY(0x0020), - 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_NATIVE(0x0100), - ACC_INLINE(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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/GrowableByteBuffer.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/GrowableByteBuffer.java deleted file mode 100644 index b87228e73d7..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/GrowableByteBuffer.java +++ /dev/null @@ -1,108 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java deleted file mode 100644 index ed8953bbb40..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MacroCodeBuilder.java +++ /dev/null @@ -1,688 +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. - * - * 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: - case Q: - return return_(); - default: - return emitOp(Opcode.IRETURN.at(type)); - } - } - - 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MemberBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MemberBuilder.java deleted file mode 100644 index 45a29d8534e..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MemberBuilder.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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MethodBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MethodBuilder.java deleted file mode 100644 index ee5945808f3..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/MethodBuilder.java +++ /dev/null @@ -1,156 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java deleted file mode 100644 index d87bb0ffd83..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Opcode.java +++ /dev/null @@ -1,258 +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. - * - * 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), - ACONST_INIT(203), - WITHFIELD(204); - - - 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java deleted file mode 100644 index 4ab14782721..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolHelper.java +++ /dev/null @@ -1,83 +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. - * - * 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 putInlineClass(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 putType(T t); - - int putMethodType(T t); - - int putHandle(int refKind, S owner, CharSequence name, T type); - - int putHandle(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 putDynamicConstant(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs); - - int size(); - - E entries(); - - 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolTag.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolTag.java deleted file mode 100644 index bb60e42fb6f..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/PoolTag.java +++ /dev/null @@ -1,53 +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. - * - * 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 PoolTag { - CONSTANT_UTF8(1), - CONSTANT_UNICODE(2), - CONSTANT_INTEGER(3), - CONSTANT_FLOAT(4), - CONSTANT_LONG(5), - CONSTANT_DOUBLE(6), - CONSTANT_CLASS(7), - CONSTANT_STRING(8), - CONSTANT_FIELDREF(9), - CONSTANT_METHODREF(10), - CONSTANT_INTERFACEMETHODREF(11), - CONSTANT_NAMEANDTYPE(12), - CONSTANT_METHODHANDLE(15), - CONSTANT_METHODTYPE(16), - CONSTANT_DYNAMIC(17), - CONSTANT_INVOKEDYNAMIC(18); - - public final int tag; - - PoolTag(int tag) { - this.tag = tag; - } - - static PoolTag from(int tag) { - return values()[tag - 1]; - } -} diff --git a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Type.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Type.java deleted file mode 100644 index cacc3f81dc6..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/Type.java +++ /dev/null @@ -1,28 +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. - * - * 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java deleted file mode 100644 index fedb6043209..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeHelper.java +++ /dev/null @@ -1,126 +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. - * - * 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 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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeTag.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeTag.java deleted file mode 100644 index 52f4f6cfe84..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypeTag.java +++ /dev/null @@ -1,113 +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. - * - * 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), - /** - * Value type - */ - Q("Q", -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/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java b/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java deleted file mode 100644 index 56a291cdf0d..00000000000 --- a/test/jdk/lib/testlibrary/bytecode/jdk/experimental/bytecode/TypedCodeBuilder.java +++ /dev/null @@ -1,1133 +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. - * - * 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.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; - } - } - - public class State { - public final ArrayList stack; - public final Vector locals; - boolean alive; - - State(ArrayList stack, Vector locals) { - this.stack = stack; - this.locals = locals; - } - - 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 && - tag1 != TypeTag.Q && tag2 != TypeTag.Q) { - 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 ACONST_INIT: - 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.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 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 putInlineClass(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 putDynamicConstant(CharSequence constName, T constType, S bsmClass, CharSequence bsmName, T bsmType, Consumer> staticArgs) { - type = constType; - return poolHelper.putDynamicConstant(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 putHandle(int refKind, S owner, CharSequence name, T t) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle")); - return poolHelper.putHandle(refKind, owner, name, t); - } - - @Override - public int putHandle(int refKind, S owner, CharSequence name, T t, boolean isInterface) { - type = typeHelper.type(typeHelper.symbolFrom("java/lang/invoke/MethodHandle")); - return poolHelper.putHandle(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 entries() { - throw new IllegalStateException(); - } - } - - 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); - } -}