Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/functional/Valhalla/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<!-- <src path="${src_lw5}"/> -->
<src path="${transformerListener}" />
<compilerarg line='--add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.value=ALL-UNNAMED' />
<compilerarg line='--enable-preview -source 22'/>
<!-- Also remove this line when running lw5 -->
<compilerarg line='-source 22 -XDenablePrimitiveClasses' />
<classpath>
Expand Down
2 changes: 1 addition & 1 deletion test/functional/Valhalla/playlist.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<variation>-Xnocompressedrefs -Xgcpolicy:gencon</variation>
</variations>
<command>$(JAVA_COMMAND) $(JVM_OPTIONS) \
-Xint \
-Xint --enable-preview \
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED \
--add-exports java.base/jdk.internal.value=ALL-UNNAMED \
-cp $(Q)$(LIB_DIR)$(D)asm.jar$(P)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)ValhallaTests.jar$(Q) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,61 +30,55 @@ public class ValhallaAttributeGenerator extends ClassLoader {

public static Class<?> generateClassWithTwoPreloadAttributes(String name, String[] classList1, String[] classList2) throws Throwable {
byte[] bytes = generateClass(name, ValhallaUtils.ACC_IDENTITY, new Attribute[] {
new PreloadAttribute(classList1),
new PreloadAttribute(classList2)});
new ValhallaUtils.PreloadAttribute(classList1),
new ValhallaUtils.PreloadAttribute(classList2)});
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateClassWithPreloadAttribute(String name, String[] classList) throws Throwable {
byte[] bytes = generateClass(name, ValhallaUtils.ACC_IDENTITY, new Attribute[] {new PreloadAttribute(classList)});
byte[] bytes = generateClass(name, ValhallaUtils.ACC_IDENTITY, new Attribute[] {new ValhallaUtils.PreloadAttribute(classList)});
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateClassWithTwoImplicitCreationAttributes(String name) throws Throwable {
byte[] bytes = generateClass(name, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute(), new ImplicitCreationAttribute()});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute(), new ValhallaUtils.ImplicitCreationAttribute()});
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateNonValueTypeClassWithImplicitCreationAttribute(String name) throws Throwable {
byte[] bytes = generateClass(name, ValhallaUtils.ACC_IDENTITY, new Attribute[] {new ImplicitCreationAttribute()});
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateValidClassWithImplicitCreationAttribute(String name) throws Throwable {
byte[] bytes = generateClass(name, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute()});
byte[] bytes = generateClass(name, ValhallaUtils.ACC_IDENTITY, new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute()});
return generator.defineClass(name, bytes, 0, bytes.length);
}

public static Class<?> generateFieldWithMultipleNullRestrictedAttributes(String className, String fieldClassName) throws Throwable {
/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute()});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute()});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

/* Generate class with field and multiple NullRestricted attributes */
byte[] classBytes = generateIdentityClassWithField(className, 0,
"field", fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute(), new NullRestrictedAttribute()});
"field", fieldClass.descriptorString(), new Attribute[]{new ValhallaUtils.NullRestrictedAttribute(), new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

public static Class<?> generateNullRestrictedAttributeInPrimitiveField(String className) throws Throwable {
/* Generate class with primitive field and a NullRestricted attribute */
byte[] classBytes = generateIdentityClassWithField(className, 0,
"field", "I", new Attribute[]{new NullRestrictedAttribute()});
"field", "I", new Attribute[]{new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

public static Class<?> generateNullRestrictedAttributeInArrayField(String className, String fieldClassName) throws Throwable {
/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set. */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute()});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute()});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

/* Generate class field field that is an array with a NullRestricted attribute */
byte[] classBytes = generateIdentityClassWithField(className, 0,
"field", "[" + fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute()});
"field", "[" + fieldClass.descriptorString(), new Attribute[]{new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

Expand All @@ -93,15 +87,15 @@ public static Class<?> generatePutStaticNullToNullRestrictedField(String classNa

/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set. */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_PUBLIC + ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute()});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute()});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(ValhallaUtils.CLASS_FILE_MAJOR_VERSION, ACC_PUBLIC + ValhallaUtils.ACC_IDENTITY, className, null, "java/lang/Object", null);

/* static field of previously generated field class with NullRestrictd attribute */
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC + ACC_STATIC, fieldName, fieldClass.descriptorString(), null, null);
fieldVisitor.visitAttribute(new NullRestrictedAttribute());
fieldVisitor.visitAttribute(new ValhallaUtils.NullRestrictedAttribute());

/* assign field to null in <clinit> */
MethodVisitor mvClinit = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
Expand Down Expand Up @@ -131,15 +125,15 @@ public static Class<?> generatePutFieldNullToNullRestrictedField(String classNam

/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set. */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_PUBLIC + ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute()});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute()});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(ValhallaUtils.CLASS_FILE_MAJOR_VERSION, ACC_PUBLIC + ValhallaUtils.ACC_IDENTITY, className, null, "java/lang/Object", null);

/* instance field of previously generated field class with NullRestrictd attribute */
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC, fieldName, fieldClass.descriptorString(), null, null);
fieldVisitor.visitAttribute(new NullRestrictedAttribute());
fieldVisitor.visitAttribute(new ValhallaUtils.NullRestrictedAttribute());

/* assign field to null in <init> */
MethodVisitor mvInit = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
Expand All @@ -165,7 +159,7 @@ public static Class<?> generateNullRestrictedAttributeInIdentityClass(boolean is

/* Generate class with field that is an identity class with a NullRestricted attribute */
byte[] classBytes = generateIdentityClassWithField(className, isStatic ? ACC_STATIC : 0,
"field", fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute()});
"field", fieldClass.descriptorString(), new Attribute[]{new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

Expand All @@ -176,19 +170,19 @@ public static Class<?> generateNullRestrictedAttributeInValueClassWithoutIC(bool

/* Generate class with field that has a NullRestricted attribute */
byte[] classBytes = generateIdentityClassWithField(className, isStatic ? ACC_STATIC : 0,
"field", fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute()});
"field", fieldClass.descriptorString(), new Attribute[]{new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

public static Class<?> generateNullRestrictedFieldWhereICHasNoDefaultFlag(boolean isStatic, String className, String fieldClassName) throws Throwable {
/* Generate field class - value type with ImplicitCreation attribute, no flags */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute(0)});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute(0)});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

/* Generate class with field with NullRestricted attribute */
byte[] classBytes = generateIdentityClassWithField(className, isStatic ? ACC_STATIC : 0,
"field", fieldClass.descriptorString(), new Attribute[]{new NullRestrictedAttribute()});
"field", fieldClass.descriptorString(), new Attribute[]{new ValhallaUtils.NullRestrictedAttribute()});
return generator.defineClass(className, classBytes, 0, classBytes.length);
}

Expand All @@ -197,15 +191,15 @@ public static Class<?> generateWithFieldStoreNullToNullRestrictedField(String cl

/* Generate field class - value class with ImplicitCreation attribute and ACC_DEFAULT flag set. */
byte[] fieldClassBytes = generateClass(fieldClassName, ACC_PUBLIC + ACC_FINAL + ValhallaUtils.ACC_VALUE_TYPE,
new Attribute[] {new ImplicitCreationAttribute(ValhallaUtils.ACC_DEFAULT)});
new Attribute[] {new ValhallaUtils.ImplicitCreationAttribute(ValhallaUtils.ACC_DEFAULT)});
Class<?> fieldClass = generator.defineClass(fieldClassName, fieldClassBytes, 0, fieldClassBytes.length);

ClassWriter classWriter = new ClassWriter(0);
classWriter.visit(ValhallaUtils.CLASS_FILE_MAJOR_VERSION, ACC_PUBLIC + ValhallaUtils.ACC_IDENTITY, className, null, "java/lang/Object", null);

/* instance field of previously generated field class with NullRestrictd attribute */
FieldVisitor fieldVisitor = classWriter.visitField(ACC_PUBLIC, fieldName, fieldClass.descriptorString(), null, null);
fieldVisitor.visitAttribute(new NullRestrictedAttribute());
fieldVisitor.visitAttribute(new ValhallaUtils.NullRestrictedAttribute());

MethodVisitor mvInit = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mvInit.visitCode();
Expand Down Expand Up @@ -269,93 +263,4 @@ public static byte[] generateIdentityClassWithField(String name, int fieldFlags,
classWriter.visitEnd();
return classWriter.toByteArray();
}

final static class PreloadAttribute extends Attribute {
private final String[] classes;

public PreloadAttribute(String[] classes) {
super("Preload");
this.classes = classes;
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector b = new ByteVector();

b.putShort(classes.length);

int cpIndex;
for (int i = 0; i < classes.length; i++) {
cpIndex = cw.newClass(classes[i].replace('.', '/'));
b.putShort(cpIndex);
}
return b;
}
}

final static class ImplicitCreationAttribute extends Attribute {
private final int flags;

public ImplicitCreationAttribute() {
super("ImplicitCreation");
/* this is the default flag generated by the compiler for the implicit modifier. */
this.flags = ValhallaUtils.ACC_DEFAULT;
}

public ImplicitCreationAttribute(int flags) {
super("ImplicitCreation");
this.flags = flags;
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector b = new ByteVector();
b.putShort(flags);
return b;
}
}

final static class NullRestrictedAttribute extends Attribute {
public NullRestrictedAttribute() {
super("NullRestricted");
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
return new ByteVector();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ static public void testNonValueTypeClassWithImplicitCreationAttribute() throws T
ValhallaAttributeGenerator.generateNonValueTypeClassWithImplicitCreationAttribute("NonValueTypeImplicitCreationAttribute");
}

/* ImplicitCreation smoke test. The attribute doesn't do anything in the vm right now, make sure
* it passes class validation.
*/
@Test
static public void testValueTypeClassWithImplicitCreationAttribute() throws Throwable {
ValhallaAttributeGenerator.generateValidClassWithImplicitCreationAttribute("ValueTypeClassWithImplicitCreationAttribute");
}

/* There must be no more than one NullRestricted attribute in the attributes table of a field_info structure */
@Test(expectedExceptions = java.lang.ClassFormatError.class, expectedExceptionsMessageRegExp = ".*Multiple NullRestricted attributes present.*")
static public void testMultipleNullRestrictedAttributes() throws Throwable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
*******************************************************************************/
package org.openj9.test.lworld;

import org.objectweb.asm.*;

public class ValhallaUtils {
/**
* Currently value type is built on JDK22, so use java file major version 66 for now.
Expand All @@ -40,4 +42,92 @@ public class ValhallaUtils {
static final int ACC_DEFAULT = 0x1;
static final int ACC_NON_ATOMIC = 0x2;

final static class PreloadAttribute extends Attribute {
private final String[] classes;

public PreloadAttribute(String[] classes) {
super("Preload");
this.classes = classes;
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector b = new ByteVector();

b.putShort(classes.length);

int cpIndex;
for (int i = 0; i < classes.length; i++) {
cpIndex = cw.newClass(classes[i].replace('.', '/'));
b.putShort(cpIndex);
}
return b;
}
}

final static class ImplicitCreationAttribute extends Attribute {
private final int flags;

public ImplicitCreationAttribute() {
super("ImplicitCreation");
/* this is the default flag generated by the compiler for the implicit modifier. */
this.flags = ValhallaUtils.ACC_DEFAULT;
}

public ImplicitCreationAttribute(int flags) {
super("ImplicitCreation");
this.flags = flags;
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector b = new ByteVector();
b.putShort(flags);
return b;
}
}

final static class NullRestrictedAttribute extends Attribute {
public NullRestrictedAttribute() {
super("NullRestricted");
}

public Label[] getLabels() {
return null;
}

public boolean isCodeAttribute() {
return false;
}

public boolean isUnknown() {
return true;
}

public ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
return new ByteVector();
}
}
}
Loading