diff --git a/buildenv/docker/mkdocker.sh b/buildenv/docker/mkdocker.sh index 69b8532a35c..b2594d0d46b 100644 --- a/buildenv/docker/mkdocker.sh +++ b/buildenv/docker/mkdocker.sh @@ -35,7 +35,6 @@ usage() { echo " --criu include CRIU" echo " --cuda include CUDA header files" echo " --dist=... specify the Linux distribution (e.g. centos, ubuntu)" - echo " --freemarker include freemarker.jar" echo " --gitcache={yes|no} generate the git cache (default: yes)" echo " --jdk=... specify which JDKs can be built (default: all)" echo " --print write the Dockerfile to stdout (default; overrides '--build')" @@ -68,7 +67,6 @@ cuda_tag= dist=unspecified engine=docker engine_specified=0 -freemarker=no gen_git_cache=yes jdk_versions=all registry= @@ -108,9 +106,6 @@ parse_options() { --dist=*) dist="${arg#*=}" ;; - --freemarker) - freemarker=yes - ;; --gitcache=*) gen_git_cache="${arg#*=}" ;; @@ -680,16 +675,6 @@ set_user() { echo "USER $user" } -install_freemarker() { - echo "" - local freemarker_version=2.3.8 - echo "# Download and extract freemarker.jar to /home/$user/freemarker.jar." - echo "RUN cd /home/$user \\" - echo " && $wget_O freemarker.tar.gz https://sourceforge.net/projects/freemarker/files/freemarker/$freemarker_version/freemarker-$freemarker_version.tar.gz/download \\" - echo " && tar -xzf freemarker.tar.gz freemarker-$freemarker_version/lib/freemarker.jar --strip-components=2 \\" - echo " && rm -f freemarker.tar.gz" -} - bootjdk_dirs() { local version for version in $@ ; do @@ -893,9 +878,6 @@ fi create_user if [ "x$cuda_tag" != x ] ; then install_cuda -fi -if [ $freemarker = yes ] ; then - install_freemarker fi install_cmake install_python diff --git a/buildenv/jenkins/variables/defaults.yml b/buildenv/jenkins/variables/defaults.yml index efc13c9e10a..bebda57bc7c 100644 --- a/buildenv/jenkins/variables/defaults.yml +++ b/buildenv/jenkins/variables/defaults.yml @@ -138,7 +138,7 @@ jitserver: # OpenSSL #========================================# openssl: - extra_getsource_options: '-openssl-branch=openssl-3.5.2' + extra_getsource_options: '-openssl-branch=openssl-3.5.4' extra_configure_options: '--with-openssl=fetched' #========================================# # OpenSSL Bundling @@ -332,7 +332,7 @@ aarch64_linux: 11: 'linux-aarch64-normal-server-release' node_labels: build: 'ci.role.build && hw.arch.aarch64 && sw.tool.docker' - docker_image: 'adoptopenjdk/centos7_build_image@sha256:14254361f71a38b80d7f405c9de762fda780060589c070411b2c205b6ee26974' + docker_image: 'adoptopenjdk/centos7_build_image' build_env: vars: all: 'CC=/usr/local/gcc10/bin/gcc-10.3 CXX=/usr/local/gcc10/bin/g++-10.3' diff --git a/buildspecs/j9.flags b/buildspecs/j9.flags index eb0331b6df3..f408585bff2 100644 --- a/buildspecs/j9.flags +++ b/buildspecs/j9.flags @@ -1834,6 +1834,10 @@ Only available on zOS Enables support for Project Valhalla L-World Flattenable Value Types No support for Project Valhalla L-World Flattenable Value Types + + Enables support for Project Valhalla Strict Fields + No support for Project Valhalla Strict Fields + Support for PHP interpreter. No support for PHP. diff --git a/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/J9FlagsXMLParser.java b/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/J9FlagsXMLParser.java index 6f89762698e..1795f3be817 100644 --- a/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/J9FlagsXMLParser.java +++ b/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/J9FlagsXMLParser.java @@ -27,92 +27,71 @@ import java.util.HashMap; import java.util.Map; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; - /** - * Used to create mapping between flags ids and their equivalent cNames in the j9.flags file - * - * @author lpnguyen + * Used to create mapping between flags ids and their equivalent cNames in the j9.flags file. * + * @author lpnguyen */ -public class J9FlagsXMLParser -{ - public static final String[] knownNames = {"JIT", "JNI", "INL", "AOT", "Arg0EA"}; - - private final XMLHandler handler; - - public J9FlagsXMLParser(File xmlFile) throws SAXException, IOException - { - this.handler = new XMLHandler(); - - XMLReader reader = XMLReaderFactory.createXMLReader(); - - reader.setContentHandler(handler); - reader.setErrorHandler(handler); - - reader.parse(new InputSource(new FileReader(xmlFile))); +public final class J9FlagsXMLParser { - } - - public Map getCNameToFlagIdMap() { - return handler.getCNameToIdMap(); - } - - private static class XMLHandler extends DefaultHandler implements ContentHandler - { - final Map cNameToFlagId = new HashMap(); - - public Map getCNameToIdMap() { - return cNameToFlagId; - } - - private String cName(String id) - { + private static final String[] knownNames = { "JIT", "JNI", "INL", "AOT", "Arg0EA" }; + + private static final class XMLHandler extends DefaultHandler implements ContentHandler { + + private static String cName(String id) { boolean addUnderscore = false; - boolean knownNameFound = false; - - StringBuffer cName = new StringBuffer(id.length()); - - for (int index = 0; index < id.length(); index++) { + int idLength = id.length(); + StringBuilder cName = new StringBuilder(idLength); + + outer: for (int index = 0; index < idLength; index++) { if (addUnderscore) { cName.append("_"); addUnderscore = false; } - - knownNameFound = false; - for (int j = 0; j < knownNames.length; j++) { - String known = knownNames[j]; + + for (String known : knownNames) { if (id.startsWith(known, index)) { cName.append(known); - index = index + known.length(); + index += known.length(); addUnderscore = true; - knownNameFound = true; - break; + continue outer; } } - - if (!knownNameFound) { - if ((!Character.isUpperCase(id.charAt(index))) && (index < id.length()-1) && Character.isUpperCase(id.charAt(index+1))) { - addUnderscore = true; - } - cName.append(Character.toUpperCase(id.charAt(index))); + + char nextChar = id.charAt(index); + if ((index < idLength - 1) && !Character.isUpperCase(nextChar)) { + addUnderscore = Character.isUpperCase(id.charAt(index + 1)); } + cName.append(Character.toUpperCase(nextChar)); } - + return cName.toString(); } + private final Map cNameToFlagId; + + XMLHandler() { + super(); + this.cNameToFlagId = new HashMap<>(); + } + + Map getCNameToIdMap() { + return cNameToFlagId; + } + @Override - public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException - { + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if (qName.equals("flag")) { String id = atts.getValue("id"); if (null != cNameToFlagId.put(cName(id), id)) { @@ -122,22 +101,40 @@ public void startElement(String uri, String localName, String qName, Attributes } @Override - public void endElement(String uri, String localName, String qName) throws SAXException - { - + public void endElement(String uri, String localName, String qName) throws SAXException { + // do nothing } - + @Override - public void error(SAXParseException arg0) throws SAXException - { - throw arg0; + public void error(SAXParseException exception) throws SAXException { + throw exception; } - + @Override - public void warning(SAXParseException arg0) throws SAXException - { + public void warning(SAXParseException exception) throws SAXException { System.err.println("Warning parsing XML"); - arg0.printStackTrace(); + exception.printStackTrace(); } } + + private final XMLHandler handler; + + public J9FlagsXMLParser(File xmlFile) throws SAXException, IOException { + SAXParser parser; + + try { + parser = SAXParserFactory.newInstance().newSAXParser(); + } catch (ParserConfigurationException e) { + throw new SAXException(e); + } + + this.handler = new XMLHandler(); + + parser.parse(new InputSource(new FileReader(xmlFile)), handler); + } + + public Map getCNameToFlagIdMap() { + return handler.getCNameToIdMap(); + } + } diff --git a/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/StructureXMLParser.java b/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/StructureXMLParser.java index 9a76c883216..b561d05c32a 100644 --- a/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/StructureXMLParser.java +++ b/debugtools/DDR_Autoblob/src/com/ibm/j9ddr/autoblob/xmlparser/StructureXMLParser.java @@ -34,14 +34,16 @@ import java.util.Set; import java.util.Stack; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.XMLReaderFactory; import com.ibm.j9ddr.autoblob.CTypeParser; import com.ibm.j9ddr.autoblob.datamodel.ClassType; @@ -56,102 +58,77 @@ import com.ibm.j9ddr.autoblob.datamodel.UnionType; import com.ibm.j9ddr.autoblob.datamodel.UserDefinedType; import com.ibm.j9ddr.autoblob.linenumbers.ILineNumberConverter; - +import com.ibm.j9ddr.autoblob.xmlparser.StructureXMLParser.XMLHandler; /** - * Class that reads the XML produced by the EDG-based + * Class that reads the XML produced by the EDG-based * extract_structures tool. - * - * @author andhall * + * @author andhall */ -public class StructureXMLParser implements ITypeCollection -{ +public class StructureXMLParser implements ITypeCollection { + public static final String CLASS_TAG = "class"; - public static final String BASE_CLASS_TAG = "base_class"; - public static final String UNION_TAG = "union"; - public static final String TYPEDEF_TAG = "typedef"; - public static final String ENUM_TAG = "enum"; - public static final String ENUM_CONSTANT_TAG = "constant"; - public static final String NAMESPACE_TAG = "namespace"; - public static final String STRUCT_TAG = "struct"; - public static final String FIELD_TAG = "field"; - public static final String TYPES_TAG = "types"; - public static final String ENUM_CONSTANT_VALUE_ATTRIBUTE = "value"; - public static final String TYPE_NAME_ATTRIBUTE = "name"; - public static final String TYPE_LINE_ATTRIBUTE = "line"; - public static final String FIELD_NAME_ATTRIBUTE = "name"; - public static final String TYPE_COMPLETE_ATTRIBUTE = "complete"; - public static final String FIELD_TYPE_ATTRIBUTE = "type"; - public static final String FIELD_LINE_ATTRIBUTE = "line"; - public static final String TYPEDEF_ALIASES_ATTRIBUTE = "aliases"; - public static final String TYPES_LANGUAGE_ATTRIBUTE = "language"; - public static final String ANONYMOUS_TYPE_ATTRIBUTE = "anonymous_type"; - public static final String ANONYMOUS_TYPE_ID_ATTRIBUTE = "anonymous_type_id"; - + private final XMLHandler handler; - - public StructureXMLParser(File xmlFile, ILineNumberConverter lineNumberConverter) throws SAXException, IOException - { + + public StructureXMLParser(File xmlFile, ILineNumberConverter lineNumberConverter) throws SAXException, IOException { + SAXParser parser; + + try { + parser = SAXParserFactory.newInstance().newSAXParser(); + } catch (ParserConfigurationException e) { + throw new SAXException(e); + } + this.handler = new XMLHandler(lineNumberConverter); - - XMLReader reader = XMLReaderFactory.createXMLReader(); - - reader.setContentHandler(handler); - reader.setErrorHandler(handler); - - reader.parse(new InputSource(new FileReader(xmlFile))); + + parser.parse(new InputSource(new FileReader(xmlFile)), handler); handler.fixUpFieldTypes(); } - - public Map getTypedefs() - { + + public Map getTypedefs() { return Collections.unmodifiableMap(handler.typedefsByName); } - - public Set getStructures() - { - return Collections.unmodifiableSet(new HashSet(handler.structsByName.values())); + + public Set getStructures() { + return Collections.unmodifiableSet(new HashSet<>(handler.structsByName.values())); } - - public Set getUnions() - { - return Collections.unmodifiableSet(new HashSet(handler.unionsByName.values())); + + public Set getUnions() { + return Collections.unmodifiableSet(new HashSet<>(handler.unionsByName.values())); } - - public Set getEnums() - { - return Collections.unmodifiableSet(new HashSet(handler.enumsByName.values())); + + public Set getEnums() { + return Collections.unmodifiableSet(new HashSet<>(handler.enumsByName.values())); } - - public List getTopScopeAnonymousEnums() - { + + public List getTopScopeAnonymousEnums() { return Collections.unmodifiableList(handler.topScopeAnonymousEnums); } - - public UserDefinedType findType(String name) - { + + public UserDefinedType findType(String name) { if (handler.structsByName.containsKey(name)) { return handler.structsByName.get(name); } else if (handler.enumsByName.containsKey(name)) { @@ -164,212 +141,214 @@ public UserDefinedType findType(String name) return null; } } - - private static class XMLHandler extends DefaultHandler implements ContentHandler - { - final Map typedefsByName = new HashMap(); - final Map structsByName = new HashMap(); - final Map enumsByName = new HashMap(); - final Map unionsByName = new HashMap(); - static final Map primitiveTypesByName = new HashMap(); - - final Map anonymousStructsById = new HashMap(); - final Map anonymousEnumsById = new HashMap(); - final Map anonymousUnionsById = new HashMap(); - - final List topScopeAnonymousEnums = new LinkedList(); - - private static final String[] primitiveTypes = new String[]{ - "bool", - "byte", - "short", - "int", - "long", - "long long", - "unsigned byte", - "unsigned short", - "unsigned int", - "unsigned long", - "unsigned long long", - "signed byte", - "signed short", - "signed int", - "signed long", - "signed long long", - "float", - "double", - "char", - "unsigned char", - "signed char" - }; - + + static final class XMLHandler extends DefaultHandler implements ContentHandler { + + private static final Map primitiveTypesByName; + static { + final String[] primitiveTypes = new String[] { + "bool", + "byte", + "short", + "int", + "long", + "long long", + "unsigned byte", + "unsigned short", + "unsigned int", + "unsigned long", + "unsigned long long", + "signed byte", + "signed short", + "signed int", + "signed long", + "signed long long", + "float", + "double", + "char", + "unsigned char", + "signed char" + }; + + Map map = new HashMap<>(); + for (String primitiveType : primitiveTypes) { - primitiveTypesByName.put(primitiveType, new Type(primitiveType)); + map.put(primitiveType, new Type(primitiveType)); } + + primitiveTypesByName = map; } - - private final ILineNumberConverter converter; - - /* State variables */ - - private Stack typeStack = new Stack(); - - //Stack of runnables to be executed every time a tag closes. Will cope very badly with broken XML. - private final Stack deferredWorkStack = new Stack(); - - private static final Runnable NO_OP = new Runnable() { + private static final Runnable NO_OP = new Runnable() { + @Override public void run() { - }}; - + // do nothing + } + }; + + final Map typedefsByName = new HashMap<>(); + final Map structsByName = new HashMap<>(); + final Map enumsByName = new HashMap<>(); + final Map unionsByName = new HashMap<>(); + + final Map anonymousStructsById = new HashMap<>(); + final Map anonymousEnumsById = new HashMap<>(); + final Map anonymousUnionsById = new HashMap<>(); + + final List topScopeAnonymousEnums = new LinkedList<>(); + + private final ILineNumberConverter converter; + + /* State variables. */ + + private Stack typeStack = new Stack<>(); + + /* Stack of runnables to be executed every time a tag closes. Will cope very badly with broken XML. */ + private final Stack deferredWorkStack = new Stack<>(); + private final Runnable POP_TYPE_STACK = new Runnable() { - public void run() - { + @Override + public void run() { typeStack.pop(); } }; - + private boolean isCPlusPlus; - - XMLHandler(ILineNumberConverter converter) - { + + XMLHandler(ILineNumberConverter converter) { this.converter = converter; } - - //C++ has a single namespace for structs, classes, enums and typedefs - so EDG doesn't bother specifying struct J9JavaVM * - //for example, it just puts J9JavaVM *. The DDR structure reader relies on the type prefix, so we have to add it back in - public void fixUpFieldTypes() - { - if (! isCPlusPlus) { - return; + + /* C++ has a single namespace for structs, classes, enums and typedefs + * - so EDG doesn't bother specifying struct J9JavaVM *, for example, + * it just puts J9JavaVM *. The DDR structure reader relies on the type + * prefix, so we have to add it back. + */ + public void fixUpFieldTypes() { + if (isCPlusPlus) { + fixUpFields(structsByName.values()); + fixUpFields(unionsByName.values()); } - - fixUpFields(structsByName.values()); - fixUpFields(unionsByName.values()); } - private void fixUpFields(Collection values) - { - for (RecordType r : values) { - for (Declaration dec : r.getEntries()) { + private void fixUpFields(Collection types) { + for (RecordType type : types) { + for (Declaration dec : type.getEntries()) { String fixedUpType = resolveCPlusPlusTypeName(dec.getType().getFullName()); - + dec.overrideTypeString(fixedUpType); } } } - - private String resolveCPlusPlusTypeName(String typeName) - { + + private String resolveCPlusPlusTypeName(String typeName) { CTypeParser parser = new CTypeParser(typeName); - - Type t = getCPlusPlusType(parser.getCoreType(), -1); - - return parser.getPrefix() + t.getFullName() + parser.getSuffix(); + + Type type = getCPlusPlusType(parser.getCoreType(), -1); + + return parser.getPrefix() + type.getFullName() + parser.getSuffix(); } @Override - public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException - { - //Every tag must add an entry to deferredWorkStack (even if it's NO_OP) + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + /* Every tag must add an entry to deferredWorkStack (even if it's NO_OP). */ if (qName.equals(TYPES_TAG)) { String language = atts.getValue(TYPES_LANGUAGE_ATTRIBUTE); - - isCPlusPlus = language.equals("C++"); - + + isCPlusPlus = "C++".equals(language); + deferredWorkStack.push(NO_OP); } else if (qName.equals(STRUCT_TAG) || qName.equals(CLASS_TAG)) { String name = atts.getValue(TYPE_NAME_ATTRIBUTE); int line = getLine(atts); boolean isComplete = isComplete(atts); name = cleanName(name); - + final UserDefinedType type; if (qName.equals(STRUCT_TAG)) { type = getStruct(name, atts, line); } else { type = getClass(name, line); } - + type.setComplete(isComplete); - + typeStack.push(type); deferredWorkStack.push(POP_TYPE_STACK); } else if (qName.equals(UNION_TAG)) { String name = atts.getValue(TYPE_NAME_ATTRIBUTE); int line = getLine(atts); name = cleanName(name); - + final UserDefinedType type = getUnion(name, atts, line); - + typeStack.push(type); deferredWorkStack.push(POP_TYPE_STACK); } else if (qName.equals(BASE_CLASS_TAG)) { String name = atts.getValue(TYPE_NAME_ATTRIBUTE); - - RecordType subclass = (RecordType)typeStack.peek(); - Type superClass = getType(name,atts,0); - - if (! (superClass instanceof UserDefinedType)) { - throw new SAXException("Superclass: " + name + " of type " + superClass.getClass().getName() + " isn't a UserDefinedType"); + + RecordType subclass = (RecordType) typeStack.peek(); + Type superClass = getType(name, atts, 0); + + if (!(superClass instanceof UserDefinedType)) { + throw new SAXException("Superclass: " + name + " of type " + superClass.getClass().getName() + + " isn't a UserDefinedType"); } - + subclass.setSuperClass((UserDefinedType) superClass); deferredWorkStack.push(NO_OP); } else if (qName.equals(TYPEDEF_TAG)) { final String name = atts.getValue(TYPE_NAME_ATTRIBUTE); final int line = getLine(atts); String aliasedStr = atts.getValue(TYPEDEF_ALIASES_ATTRIBUTE); - Type aliasedType = getType(aliasedStr, atts, line); - + if (aliasedType == null) { throw new SAXException("Couldn't match aliased type: " + aliasedStr + " for typedef " + name); } - + Typedef typedef = new Typedef(name, aliasedType, converter.convert(line)); - + typedefsByName.put(name, typedef); deferredWorkStack.push(NO_OP); - } else if (qName.equals(ENUM_TAG)) { + } else if (qName.equals(ENUM_TAG)) { String name = atts.getValue(TYPE_NAME_ATTRIBUTE); int line = getLine(atts); - + name = cleanName(name); - + final EnumType type = getEnum(name, atts, line); - + if (type.isAnonymous()) { - //Anonymous enums need to have their constants exposed somewhere + // Anonymous enums need to have their constants exposed somewhere. if (typeStack.isEmpty()) { topScopeAnonymousEnums.add(type); } else { - //Enum declared inside another type + // Enum declared inside another type. UserDefinedType t = typeStack.peek(); - t.attachInnerEnum((EnumType)type); + t.attachInnerEnum((EnumType) type); } - } - + typeStack.push(type); deferredWorkStack.push(POP_TYPE_STACK); } else if (qName.equals(FIELD_TAG)) { final String name = atts.getValue(FIELD_NAME_ATTRIBUTE); String typeName = atts.getValue(FIELD_TYPE_ATTRIBUTE); final int line = getLine(atts); - - Type type = typeName != null ? new Type(typeName) : getAnonymousType(atts, line); - + + Type type = (typeName != null) ? new Type(typeName) : getAnonymousType(atts, line); + RecordType currentStruct = (RecordType) typeStack.peek(); currentStruct.addEntry(new Declaration(name, type, converter.convert(line))); - + deferredWorkStack.push(NO_OP); } else if (qName.equals(ENUM_CONSTANT_TAG)) { String value = atts.getValue(ENUM_CONSTANT_VALUE_ATTRIBUTE); - - EnumType parent = (EnumType)typeStack.peek(); - + + EnumType parent = (EnumType) typeStack.peek(); + parent.addConstant(new EnumerationConstant(parent, value)); deferredWorkStack.push(NO_OP); } else { @@ -377,12 +356,10 @@ public void startElement(String uri, String localName, String qName, Attributes } } - private UserDefinedType getAnonymousType(Attributes atts, int line) - { + private UserDefinedType getAnonymousType(Attributes atts, int line) { String type = atts.getValue(ANONYMOUS_TYPE_ATTRIBUTE); - long id = getAnonymousTypeId(atts); - + if (type.equals("struct")) { return getAnonymousStruct(id, line); } else if (type.equals("union")) { @@ -394,10 +371,9 @@ private UserDefinedType getAnonymousType(Attributes atts, int line) } } - private boolean isComplete(Attributes atts) - { + private static boolean isComplete(Attributes atts) { String completeString = atts.getValue(TYPE_COMPLETE_ATTRIBUTE); - + if (completeString == null) { return false; } else { @@ -405,156 +381,143 @@ private boolean isComplete(Attributes atts) } } - private EnumType getEnum(String name, Attributes atts, int line) - { + private EnumType getEnum(String name, Attributes atts, int line) { if (name == null) { return getAnonymousEnum(getAnonymousTypeId(atts), line); } - + EnumType type = enumsByName.get(name); - + if (type == null) { type = new EnumType(name, converter.convert(line)); enumsByName.put(name, type); } + return type; } - private long getAnonymousTypeId(Attributes atts) - { + private long getAnonymousTypeId(Attributes atts) { String working = atts.getValue(ANONYMOUS_TYPE_ID_ATTRIBUTE); - + if (working.startsWith("0x")) { working = working.substring(2); } - + return Long.parseLong(working, 16); } - private UnionType getUnion(String name, Attributes atts, int line) - { + private UnionType getUnion(String name, Attributes atts, int line) { if (name == null) { return getAnonymousUnion(getAnonymousTypeId(atts), line); } - + UnionType type = unionsByName.get(name); - + if (type == null) { type = new UnionType(name, converter.convert(line)); unionsByName.put(name, type); } - + return type; } - private StructType getClass(String name, int line) - { + private StructType getClass(String name, int line) { StructType type = structsByName.get(name); - + if (type == null) { type = new ClassType(name, converter.convert(line)); structsByName.put(name, type); } - + return type; } - private StructType getStruct(String name, Attributes atts, int line) - { + private StructType getStruct(String name, Attributes atts, int line) { if (name == null) { return getAnonymousStruct(getAnonymousTypeId(atts), line); } - + StructType type = structsByName.get(name); - + if (type == null) { type = new StructType(name, converter.convert(line)); structsByName.put(name, type); } - + return type; } - /* Strips struct, union, enum etc. from the front of a type name */ - private String cleanName(String name) - { + /* Strips struct, union, enum etc. from the front of a type name. */ + private static String cleanName(String name) { String working = name; - - if (working == null) { - return working; + + if (working != null) { + working = stripPrefix(working, "struct "); + working = stripPrefix(working, "enum "); + working = stripPrefix(working, "union "); } - - working = stripPrefix(working, "struct "); - working = stripPrefix(working, "enum "); - working = stripPrefix(working, "union "); - + return working; } - private String stripPrefix(String name, String prefix) - { + private static String stripPrefix(String name, String prefix) { String working = name.trim(); - + if (working.startsWith(prefix)) { return working.substring(prefix.length()); } else { return working; } } - - private StructType getAnonymousStruct(long id, int line) - { + + private StructType getAnonymousStruct(long id, int line) { StructType toReturn = anonymousStructsById.get(id); - - if (null == toReturn) { + + if (toReturn == null) { toReturn = new StructType(null, converter.convert(line)); anonymousStructsById.put(id, toReturn); } - + return toReturn; } - - private EnumType getAnonymousEnum(long id, int line) - { + + private EnumType getAnonymousEnum(long id, int line) { EnumType toReturn = anonymousEnumsById.get(id); - - if (null == toReturn) { + + if (toReturn == null) { toReturn = new EnumType(null, converter.convert(line)); anonymousEnumsById.put(id, toReturn); } - + return toReturn; } - - private UnionType getAnonymousUnion(long id, int line) - { + + private UnionType getAnonymousUnion(long id, int line) { UnionType toReturn = anonymousUnionsById.get(id); - - if (null == toReturn) { + + if (toReturn == null) { toReturn = new UnionType(null, converter.convert(line)); anonymousUnionsById.put(id, toReturn); } - + return toReturn; } - - private Type getType(String name, Attributes atts, int line) - { + + private Type getType(String name, Attributes atts, int line) { if (name == null) { return getAnonymousType(atts, line); } else { return isCPlusPlus ? getCPlusPlusType(name, line) : getCType(name, line); } } - - private Type getCPlusPlusType(String name, int line) - { - //One namespace for structs, enums, unions and classes + + private Type getCPlusPlusType(String name, int line) { + // One namespace for structs, enums, unions and classes. if (name.contains("*") && !name.contains(">")) { - //Pointer type of some description + // Pointer type of some description. return new Type(name); } else if (name.contains(":") && !name.contains("::")) { - //Bitfield + // Bitfield. return new Type(name); } else if (name.contains("[")) { return new Type(name); @@ -572,46 +535,41 @@ private Type getCPlusPlusType(String name, int line) return new Type(name); } } - - private Type getCType(String name, int line) - { + + private Type getCType(String name, int line) { Type toReturn = null; - + if (name.contains("*")) { - //Pointer type of some description + // Pointer type of some description. toReturn = new Type(name); } else if (name.contains(":")) { - //Bitfield + // Bitfield. toReturn = new Type(name); } else if (name.contains("[")) { toReturn = new Type(name); } else if (name.startsWith("enum ")) { name = stripPrefix(name, "enum "); - toReturn = getEnum(name, null, line); } else if (name.startsWith("struct ")) { name = stripPrefix(name, "struct "); - - toReturn = getStruct(name,null, line); + toReturn = getStruct(name, null, line); } else if (name.startsWith("union ")) { name = stripPrefix(name, "union "); - toReturn = getUnion(name, null, line); } else if (primitiveTypesByName.containsKey(name)) { - toReturn = primitiveTypesByName.get(name); + toReturn = primitiveTypesByName.get(name); } else if (typedefsByName.containsKey(name)) { - toReturn = typedefsByName.get(name); + toReturn = typedefsByName.get(name); } else if (structsByName.containsKey(name)) { - toReturn = structsByName.get(name); + toReturn = structsByName.get(name); } return toReturn; } - private int getLine(Attributes atts) - { + private static int getLine(Attributes atts) { String lineStr = atts.getValue(TYPE_LINE_ATTRIBUTE); - + if (lineStr != null) { return Integer.parseInt(lineStr); } else { @@ -620,29 +578,24 @@ private int getLine(Attributes atts) } @Override - public void endElement(String uri, String localName, String qName) throws SAXException - { + public void endElement(String uri, String localName, String qName) throws SAXException { deferredWorkStack.pop().run(); } - - + @Override - public void error(SAXParseException arg0) throws SAXException - { - throw arg0; + public void error(SAXParseException exception) throws SAXException { + throw exception; } - + @Override - public void warning(SAXParseException arg0) throws SAXException - { + public void warning(SAXParseException exception) throws SAXException { System.err.println("Warning parsing XML"); - arg0.printStackTrace(); + exception.printStackTrace(); } - + } - public boolean readCPlusPlus() - { + public boolean readCPlusPlus() { return handler.isCPlusPlus; } } diff --git a/jcl/jpp_configuration.xml b/jcl/jpp_configuration.xml index 3ca99d360b1..b13517c170d 100644 --- a/jcl/jpp_configuration.xml +++ b/jcl/jpp_configuration.xml @@ -183,6 +183,7 @@ + diff --git a/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java b/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java index 20259f34aff..f1199d5ba75 100644 --- a/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java +++ b/jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java @@ -281,11 +281,19 @@ public long getLongFromObjectVolatile(Object obj, long offset) { } public Object getObjectFromObject(Object obj, long offset) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.getReference(obj, offset); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ return unsafe.getObject(obj, offset); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public Object getObjectFromObjectVolatile(Object obj, long offset) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.getReferenceVolatile(obj, offset); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ return unsafe.getObjectVolatile(obj, offset); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public void putIntInObject(Object obj, long offset, int value) { @@ -305,35 +313,45 @@ public void putLongInObjectVolatile(Object obj, long offset, long value) { } public void putObjectInObject(Object obj, long offset, Object value) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReference(obj, offset, value); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObject(obj, offset, value); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public void putObjectInObjectVolatile(Object obj, long offset, Object value) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReferenceVolatile(obj, offset, value); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObjectVolatile(obj, offset, value); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public boolean compareAndSwapIntInObject(Object obj, long offset, int expected, int value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetInt(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapInt(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ } public boolean compareAndSwapLongInObject(Object obj, long offset, long expected, long value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetLong(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapLong(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ } public boolean compareAndSwapObjectInObject(Object obj, long offset, Object expected, Object value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.compareAndSetReference(obj, offset, expected, value); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetObject(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapObject(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public byte getByteFromArray(Object obj, long offset) { @@ -369,11 +387,19 @@ public long getLongFromArrayVolatile(Object obj, long offset) { } public Object getObjectFromArray(Object obj, long offset) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.getReference(obj, offset); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ return unsafe.getObject(obj, offset); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public Object getObjectFromArrayVolatile(Object obj, long offset) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.getReferenceVolatile(obj, offset); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ return unsafe.getObjectVolatile(obj, offset); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public void putByteInArray(Object obj, long offset, byte value) { @@ -409,35 +435,45 @@ public void putLongInArrayVolatile(Object obj, long offset, long value) { } public void putObjectInArray(Object obj, long offset, Object value) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReference(obj, offset, value); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObject(obj, offset, value); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public void putObjectInArrayVolatile(Object obj, long offset, Object value) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReferenceVolatile(obj, offset, value); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObjectVolatile(obj, offset, value); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public boolean compareAndSwapIntInArray(Object obj, long offset, int expected, int value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetInt(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapInt(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ } public boolean compareAndSwapLongInArray(Object obj, long offset, long expected, long value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetLong(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapLong(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ } public boolean compareAndSwapObjectInArray(Object obj, long offset, Object expected, Object value) { -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return unsafe.compareAndSetReference(obj, offset, expected, value); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ return unsafe.compareAndSetObject(obj, offset, expected, value); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return unsafe.compareAndSwapObject(obj, offset, expected, value); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } public char byteToCharUnsigned(byte b) { @@ -905,8 +941,13 @@ public Object optimizedClone(Object srcObj) throws CloneNotSupportedException { int countSlots = 0; for (int index = 0; numSlotsInObject != 0; index++) { if (isDescriptorPointerTagged(descriptorWord)) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + Object fieldValue = unsafe.getReference(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); + unsafe.putReference(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ Object fieldValue = unsafe.getObject(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); unsafe.putObject(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } else { int fieldValue = unsafe.getInt(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); unsafe.putInt(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); @@ -947,8 +988,13 @@ public Object optimizedClone(Object srcObj) throws CloneNotSupportedException { int countSlots = 0; for (int index = 0; numSlotsInObject != 0; index++) { if (isDescriptorPointerTagged(descriptorWord)) { + /*[IF JAVA_SPEC_VERSION >= 23]*/ + Object fieldValue = unsafe.getReference(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); + unsafe.putReference(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ Object fieldValue = unsafe.getObject(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); unsafe.putObject(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } else { long fieldValue = unsafe.getLong(srcObj, VM.OBJECT_HEADER_SIZE + (countSlots * SLOT_SIZE)); unsafe.putLong(clnObj, VM.OBJECT_HEADER_SIZE + (index * SLOT_SIZE), fieldValue); diff --git a/jcl/src/java.base/share/classes/java/lang/Access.java b/jcl/src/java.base/share/classes/java/lang/Access.java index 2f6d1e9e9f3..837a8253842 100644 --- a/jcl/src/java.base/share/classes/java/lang/Access.java +++ b/jcl/src/java.base/share/classes/java/lang/Access.java @@ -353,7 +353,7 @@ public List getDeclaredPublicMethods(Class clz, String name, Class public void addOpensToAllUnnamed(Module fromModule, Iterator packages) { fromModule.implAddOpensToAllUnnamed(packages); } - /*[ELSEIF (JAVA_SPEC_VERSION < 25) | INLINE-TYPES]*/ + /*[ELSEIF JAVA_SPEC_VERSION < 25]*/ @Override public void addOpensToAllUnnamed(Module fromModule, Set concealedPackages, Set exportedPackages) { fromModule.implAddOpensToAllUnnamed(concealedPackages, exportedPackages); @@ -370,7 +370,7 @@ public boolean isReflectivelyExported(Module fromModule, String pkg, Module toMo return fromModule.isReflectivelyExported(pkg, toModule); } - /*[IF ((10 <= JAVA_SPEC_VERSION) & (JAVA_SPEC_VERSION < 26)) | INLINE-TYPES]*/ + /*[IF (10 <= JAVA_SPEC_VERSION) & (JAVA_SPEC_VERSION < 26)]*/ @Override public String newStringUTF8NoRepl(byte[] bytes, int offset, int length) { /*[IF JAVA_SPEC_VERSION < 17]*/ @@ -381,7 +381,9 @@ public String newStringUTF8NoRepl(byte[] bytes, int offset, int length) { return String.newStringUTF8NoRepl(bytes, offset, length, true); /*[ENDIF] JAVA_SPEC_VERSION < 17 */ } + /*[ENDIF] (10 <= JAVA_SPEC_VERSION) & (JAVA_SPEC_VERSION < 26) */ + /*[IF ((10 <= JAVA_SPEC_VERSION) & (JAVA_SPEC_VERSION < 26)) | INLINE-TYPES]*/ @Override public byte[] getBytesUTF8NoRepl(String str) { /*[IF JAVA_SPEC_VERSION < 17]*/ @@ -402,7 +404,7 @@ public void blockedOn(Interruptible interruptible) { /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } - /*[IF (JAVA_SPEC_VERSION < 25) | INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION < 25]*/ @Override public byte[] getBytesNoRepl(String str, Charset charset) throws CharacterCodingException { /*[IF JAVA_SPEC_VERSION < 17]*/ @@ -420,7 +422,9 @@ public String newStringNoRepl(byte[] bytes, Charset charset) throws CharacterCod return String.newStringNoRepl(bytes, charset); /*[ENDIF] JAVA_SPEC_VERSION < 17 */ } - /*[ELSEIF JAVA_SPEC_VERSION == 25]*/ + /*[ENDIF] JAVA_SPEC_VERSION < 25 */ + + /*[IF (JAVA_SPEC_VERSION == 25) | INLINE-TYPES]*/ @Override public byte[] uncheckedGetBytesNoRepl(String str, Charset charset) throws CharacterCodingException { return String.getBytesNoRepl(str, charset); @@ -430,7 +434,7 @@ public byte[] uncheckedGetBytesNoRepl(String str, Charset charset) throws Charac public String uncheckedNewStringNoRepl(byte[] bytes, Charset charset) throws CharacterCodingException { return String.newStringNoRepl(bytes, charset); } - /*[ENDIF] (JAVA_SPEC_VERSION < 25) | INLINE-TYPES] */ + /*[ENDIF] (JAVA_SPEC_VERSION == 25) | INLINE-TYPES */ /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ @@ -496,20 +500,20 @@ public void addExports(Module fromModule, String pkg) { /*[IF JAVA_SPEC_VERSION >= 17]*/ @Override - /*[IF (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION == 25]*/ public int uncheckedDecodeASCII(byte[] srcBytes, int srcPos, char[] dstChars, int dstPos, int length) { - /*[ELSE] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION == 25 */ public int decodeASCII(byte[] srcBytes, int srcPos, char[] dstChars, int dstPos, int length) { - /*[ENDIF] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION == 25 */ return String.decodeASCII(srcBytes, srcPos, dstChars, dstPos, length); } @Override - /*[IF (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION == 25]*/ public void uncheckedInflateBytesToChars(byte[] srcBytes, int srcOffset, char[] dstChars, int dstOffset, int length) { - /*[ELSE] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION == 25 */ public void inflateBytesToChars(byte[] srcBytes, int srcOffset, char[] dstChars, int dstOffset, int length) { - /*[ENDIF] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION == 25 */ StringLatin1.inflate(srcBytes, srcOffset, dstChars, dstOffset, length); } @@ -583,11 +587,11 @@ public int getCharsUTF16(long i, int index, byte[] buf) { /*[ENDIF] JAVA_SPEC_VERSION < 25 */ @Override - /*[IF (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION >= 25]*/ public void uncheckedPutCharUTF16(byte[] val, int index, int c) { - /*[ELSE] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION >= 25 */ public void putCharUTF16(byte[] val, int index, int c) { - /*[ENDIF] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 25 */ StringUTF16.putChar(val, index, c); } @@ -623,24 +627,24 @@ public long findNative(ClassLoader loader, String entryName) { } /*[ENDIF] JAVA_SPEC_VERSION < 25 */ - /*[IF (JAVA_SPEC_VERSION < 25) | INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION < 25]*/ @Override public void exit(int status) { Shutdown.exit(status); } - /*[ENDIF] (JAVA_SPEC_VERSION < 25) | INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION < 25 */ @Override - /*[IF (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION == 25]*/ public int uncheckedEncodeASCII(char[] sa, int sp, byte[] da, int dp, int len) { - /*[ELSE] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION == 25 */ public int encodeASCII(char[] sa, int sp, byte[] da, int dp, int len) { - /*[ENDIF] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ - /*[IF (JAVA_SPEC_VERSION >= 26) & !INLINE-TYPES]*/ + /*[ENDIF] JAVA_SPEC_VERSION == 25 */ + /*[IF JAVA_SPEC_VERSION >= 26]*/ return StringCoding.encodeAsciiArray(sa, sp, da, dp, len); - /*[ELSE] (JAVA_SPEC_VERSION >= 26) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION >= 26 */ return StringCoding.implEncodeAsciiArray(sa, sp, da, dp, len); - /*[ENDIF] (JAVA_SPEC_VERSION >= 26) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 26 */ } /*[ENDIF] JAVA_SPEC_VERSION >= 17 */ @@ -703,20 +707,20 @@ public InputStream initialSystemIn() { /*[IF JAVA_SPEC_VERSION >= 21]*/ @Override - /*[IF (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION >= 25]*/ public char uncheckedGetUTF16Char(byte[] val, int index) { - /*[ELSE] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION >= 25 */ public char getUTF16Char(byte[] val, int index) { - /*[ENDIF] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 25 */ return StringUTF16.getChar(val, index); } @Override - /*[IF (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION == 25]*/ public int uncheckedCountPositives(byte[] ba, int off, int len) { - /*[ELSE] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION == 25 */ public int countPositives(byte[] ba, int off, int len) { - /*[ENDIF] (JAVA_SPEC_VERSION == 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION == 25 */ return StringCoding.countPositives(ba, off, len); } @@ -829,12 +833,12 @@ private static ThreadLocal asThreadLocal(CarrierThreadLocal local) { return local; } - /*[IF (JAVA_SPEC_VERSION < 25) | INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION < 25]*/ @Override public boolean isCarrierThreadLocalPresent(CarrierThreadLocal carrierThreadlocal) { return asThreadLocal(carrierThreadlocal).isCarrierThreadLocalPresent(); } - /*[ENDIF] (JAVA_SPEC_VERSION < 25) | INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION < 25 */ @Override public T getCarrierThreadLocal(CarrierThreadLocal carrierThreadlocal) { @@ -901,11 +905,11 @@ public int classFileFormatVersion(Class c) { /*[IF JAVA_SPEC_VERSION >= 24]*/ @Override - /*[IF (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION >= 25]*/ public Object uncheckedStringConcat1(String[] constants) { - /*[ELSE] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ELSE] JAVA_SPEC_VERSION >= 25 */ public Object stringConcat1(String[] constants) { - /*[ENDIF] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 25 */ return new StringConcatHelper.Concat1(constants); } @@ -939,31 +943,32 @@ public Executor virtualThreadDefaultScheduler() { return VirtualThread.defaultScheduler(); } - /*[IF (JAVA_SPEC_VERSION < 25) | INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION < 25]*/ @Override public Stream virtualThreadDelayedTaskSchedulers() { return VirtualThread.delayedTaskSchedulers(); } - /*[ENDIF] (JAVA_SPEC_VERSION < 25) | INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION < 25 */ /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ - /*[IF (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION >= 25]*/ @Override public int classFileVersion(Class clazz) { return clazz.getClassFileVersion(); } - /*[ENDIF] (JAVA_SPEC_VERSION >= 25) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 25 */ - /*[IF (JAVA_SPEC_VERSION >= 26) & !INLINE-TYPES]*/ + /*[IF JAVA_SPEC_VERSION >= 26]*/ @Override - public byte[] getBytesUTF8OrThrow(String s) throws CharacterCodingException { - return String.getBytesUTF8OrThrow(s); + public int getClassFileAccessFlags(Class clazz) { + return clazz.getClassFileAccessFlags(); } + /*[IF !INLINE-TYPES]*/ @Override - public int getClassFileAccessFlags(Class clazz) { - return clazz.getClassFileAccessFlags(); + public byte[] getBytesUTF8OrThrow(String s) throws CharacterCodingException { + return String.getBytesUTF8OrThrow(s); } @Override @@ -975,10 +980,11 @@ public byte[] uncheckedGetBytesOrThrow(String s, Charset cs) throws CharacterCod public String uncheckedNewStringOrThrow(byte[] bytes, Charset cs) throws CharacterCodingException { return String.newStringOrThrow(bytes, cs); } + /*[ENDIF] !INLINE-TYPES */ @Override public String uncheckedNewStringWithLatin1Bytes(byte[] src) { return String.newStringWithLatin1Bytes(src); } - /*[ENDIF] (JAVA_SPEC_VERSION >= 26) & !INLINE-TYPES */ + /*[ENDIF] JAVA_SPEC_VERSION >= 26 */ } diff --git a/jcl/src/java.base/share/classes/java/lang/Class.java b/jcl/src/java.base/share/classes/java/lang/Class.java index 5831e2e2d41..546cd0a961a 100644 --- a/jcl/src/java.base/share/classes/java/lang/Class.java +++ b/jcl/src/java.base/share/classes/java/lang/Class.java @@ -508,11 +508,13 @@ public Field run() { localTypeOffset = getUnsafe().objectFieldOffset(field); AnnotationVars.annotationTypeOffset = localTypeOffset; } -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 23]*/ + return getUnsafe().compareAndSetReference(localAnnotationVars, localTypeOffset, oldType, newType); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ return getUnsafe().compareAndSetObject(localAnnotationVars, localTypeOffset, oldType, newType); -/*[ELSE] JAVA_SPEC_VERSION >= 9 */ + /*[ELSE] JAVA_SPEC_VERSION >= 9 */ return getUnsafe().compareAndSwapObject(localAnnotationVars, localTypeOffset, oldType, newType); -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } /** @@ -3584,11 +3586,13 @@ AnnotationVars getAnnotationVars() { if (annotationVars == null) { // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the annotationVars field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(this, annotationVarsOffset, tempAnnotationVars); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(this, annotationVarsOffset, tempAnnotationVars); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(this, annotationVarsOffset, tempAnnotationVars); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } else { tempAnnotationVars = annotationVars; } @@ -3618,11 +3622,13 @@ public MethodHandle run() { long implLookupOffset = getUnsafe().staticFieldOffset(implLookupField); // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the implLookup field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(Class.class, implLookupOffset, localImplLookup); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(Class.class, implLookupOffset, localImplLookup); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(Class.class, implLookupOffset, localImplLookup); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } handle = localImplLookup.findVirtual(Class.this, "value", methodType); //$NON-NLS-1$ if (AnnotationVars.valueMethodOffset == -1) { @@ -3631,11 +3637,13 @@ public MethodHandle run() { } // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the valueMethod field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(localAnnotationVars, AnnotationVars.valueMethodOffset, handle); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } catch (NoSuchMethodException e) { handle = null; } catch (IllegalAccessException | NoSuchFieldException e) { @@ -3700,11 +3708,13 @@ private String cacheCanonicalName(String canonicalName) { * field specified by the {@code fieldOffset} of the {@code target} object */ private static void writeFieldValue(Object target, long fieldOffset, Object fieldValue) { - /*[IF JAVA_SPEC_VERSION >= 11] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(target, fieldOffset, fieldValue); + /*[ELSEIF JAVA_SPEC_VERSION >= 11]*/ getUnsafe().putObjectRelease(target, fieldOffset, fieldValue); /*[ELSE] JAVA_SPEC_VERSION >= 11 */ getUnsafe().putOrderedObject(target, fieldOffset, fieldValue); - /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } private void writeFieldValue(long fieldOffset, Object fieldValue) { @@ -3834,11 +3844,13 @@ private AnnotationCache getAnnotationCache() { } // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the annotationCache field. - /*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(this, localAnnotationCacheOffset, annotationCacheResult); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(this, localAnnotationCacheOffset, annotationCacheResult); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(this, localAnnotationCacheOffset, annotationCacheResult); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } return annotationCacheResult; } @@ -3944,11 +3956,13 @@ private EnumVars getEnumVars() { tempEnumVars = new EnumVars<>(); // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the enumVars field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(this, localEnumVarsOffset, tempEnumVars); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(this, localEnumVarsOffset, tempEnumVars); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(this, localEnumVarsOffset, tempEnumVars); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } return tempEnumVars; } @@ -3993,11 +4007,13 @@ Map enumConstantDirectory() { } // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the cachedEnumConstantDirectory field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(localEnumVars, EnumVars.enumDirOffset, map); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(localEnumVars, EnumVars.enumDirOffset, map); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(localEnumVars, EnumVars.enumDirOffset, map); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } return map; } @@ -4052,11 +4068,13 @@ public Method run() throws Exception { } // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the cachedEnumConstants field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(localEnumVars, localEnumConstantsOffset, enums); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(localEnumVars, localEnumConstantsOffset, enums); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(localEnumVars, localEnumConstantsOffset, enums); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException /*[IF JAVA_SPEC_VERSION >= 24]*/ | NoSuchMethodException @@ -5066,15 +5084,21 @@ private ReflectCache acquireReflectCache() { ReflectCache newCache = new ReflectCache(this); do { // Some thread will insert this new cache making it available to all. -/*[IF JAVA_SPEC_VERSION >= 9]*/ + /*[IF JAVA_SPEC_VERSION >= 23]*/ + if (theUnsafe.compareAndSetReference(this, cacheOffset, null, newCache)) { + /*[ELSEIF JAVA_SPEC_VERSION >= 9] if (theUnsafe.compareAndSetObject(this, cacheOffset, null, newCache)) { -/*[ELSE] JAVA_SPEC_VERSION >= 9 + /*[ELSE] JAVA_SPEC_VERSION >= 9 if (theUnsafe.compareAndSwapObject(this, cacheOffset, null, newCache)) { -/*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ cache = newCache; break; } + /*[IF JAVA_SPEC_VERSION >= 23]*/ + cache = (ReflectCache) theUnsafe.getReference(this, cacheOffset); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ cache = (ReflectCache) theUnsafe.getObject(this, cacheOffset); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } while (cache == null); } return cache.acquire(); @@ -5098,11 +5122,13 @@ private static long getReflectCacheOffset() { void setReflectCache(ReflectCache cache) { // Lazy initialization of a non-volatile field. Ensure the Object is initialized // and flushed to memory before assigning to the annotationCache field. - /*[IF JAVA_SPEC_VERSION >= 9] + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(this, getReflectCacheOffset(), cache); + /*[ELSEIF JAVA_SPEC_VERSION >= 9]*/ getUnsafe().putObjectRelease(this, getReflectCacheOffset(), cache); /*[ELSE] JAVA_SPEC_VERSION >= 9 */ getUnsafe().putOrderedObject(this, getReflectCacheOffset(), cache); - /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } private ReflectCache peekReflectCache() { @@ -6040,7 +6066,11 @@ public Class[] getPermittedSubclasses() localPermittedSubclassesCacheOffset = getUnsafe().objectFieldOffset(Class.class, "cachedPermittedSubclasses"); cachedPermittedSubclassesOffset = localPermittedSubclassesCacheOffset; } + /*[IF JAVA_SPEC_VERSION >= 23]*/ + getUnsafe().putReferenceRelease(this, localPermittedSubclassesCacheOffset, localPermittedSubclasses); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ getUnsafe().putObjectRelease(this, localPermittedSubclassesCacheOffset, localPermittedSubclasses); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } /*[IF JAVA_SPEC_VERSION < 24]*/ diff --git a/jcl/src/java.base/share/classes/java/lang/ClassLoader.java b/jcl/src/java.base/share/classes/java/lang/ClassLoader.java index 1402e3ba6dd..b01287ec7d7 100644 --- a/jcl/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/jcl/src/java.base/share/classes/java/lang/ClassLoader.java @@ -102,9 +102,6 @@ public abstract class ClassLoader { private final static String DELEGATING_CL = "sun.reflect.DelegatingClassLoader"; //$NON-NLS-1$ /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ private boolean isDelegatingCL = false; - /*[IF JAVA_SPEC_VERSION > 8]*/ - private static boolean applicationClassLoaderInited; - /*[ENDIF] JAVA_SPEC_VERSION > 8 */ /* * This is the application ClassLoader @@ -158,9 +155,10 @@ private static final class ClassNameBasedLock { ClassNameBasedLock() {} } /*[IF JAVA_SPEC_VERSION >= 9]*/ private static boolean lazyClassLoaderInit = true; /*[ELSE] JAVA_SPEC_VERSION >= 9 */ - private static boolean lazyClassLoaderInit = false; + private static boolean lazyClassLoaderInit; /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ - private static boolean specialLoaderInited = false; + private static boolean applicationClassLoaderInited; + private static boolean extOrPlatformClassLoaderInited; private static InternalAnonymousClassLoader internalAnonClassLoader; /*[IF JAVA_SPEC_VERSION >= 15]*/ private NativeLibraries nativelibs = null; @@ -258,7 +256,7 @@ static final void initializeClassLoaders() { bootstrapClassLoader = sysTemp; AbstractClassLoader.setBootstrapClassLoader(bootstrapClassLoader); lazyClassLoaderInit = true; - applicationClassLoader = bootstrapClassLoader; + applicationClassLoader = sun.misc.Launcher.getLauncher().getClassLoader(); /*[ENDIF] JAVA_SPEC_VERSION >= 11 */ /* [PR 78889] The creation of this classLoader requires lazy initialization. The internal classLoader struct @@ -310,7 +308,6 @@ static final void initializeClassLoaders() { if ("allow".equals(smvalue) || "disallow".equals(smvalue)) { //$NON-NLS-1$ //$NON-NLS-2$ System.internalGetProperties().remove("java.security.manager"); //$NON-NLS-1$ } - applicationClassLoader = sun.misc.Launcher.getLauncher().getClassLoader(); /*[ENDIF] JAVA_SPEC_VERSION >= 9 */ /* Find the extension class loader */ @@ -426,46 +423,29 @@ private ClassLoader(Void staticMethodHolder, String classLoaderName, ClassLoader // VM Critical: must set parent before calling initializeInternal() parent = parentLoader; -/*[IF JAVA_SPEC_VERSION == 8]*/ - specialLoaderInited = (bootstrapClassLoader != null); -/*[ENDIF] JAVA_SPEC_VERSION == 8 */ - if (specialLoaderInited) { -/*[IF JAVA_SPEC_VERSION > 8]*/ - /* - * Assuming the 3rd classloader initialized is application class loader as the order - * to initialize builtin class loaders is defined in the static block of - * openjdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java. - */ - if (!applicationClassLoaderInited) { - assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_APP, isParallelCapable); - applicationClassLoaderInited = true; - } else -/*[ENDIF] JAVA_SPEC_VERSION > 8 */ - { - if (!lazyClassLoaderInit) { - VM.initializeClassLoader(this, VM.J9_CLASSLOADER_TYPE_OTHERS, isParallelCapable); - } - } -/*[IF JAVA_SPEC_VERSION > 8]*/ - unnamedModule = new Module(this); -/*[ENDIF] JAVA_SPEC_VERSION > 8 */ - } -/*[IF JAVA_SPEC_VERSION > 8]*/ - else { - if (bootstrapClassLoader == null) { - // BootstrapClassLoader.unnamedModule is set by JVM_SetBootLoaderUnnamedModule - unnamedModule = null; - bootstrapClassLoader = this; - assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_BOOT, false); - } else { - // Assuming the second classloader initialized is platform classloader - assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_PLATFORM, false); - specialLoaderInited = true; - unnamedModule = new Module(this); - } + if (bootstrapClassLoader == null) { + // BootstrapClassLoader is the first classloader to be initialized. + /*[IF JAVA_SPEC_VERSION > 8]*/ + bootstrapClassLoader = this; + assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_BOOT, false); + /*[ENDIF] JAVA_SPEC_VERSION > 8 */ + } else if (!extOrPlatformClassLoaderInited) { + // Java 8 extension classloader or Java 11+ platform classloader + // is the second classloader to be initialized. + assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_PLATFORM, false); + extOrPlatformClassLoaderInited = true; + } else if (!applicationClassLoaderInited) { + // ApplicationClassLoader is the third classloader to be initialized. + assignImmortalClassLoader(VM.J9_CLASSLOADER_TYPE_APP, isParallelCapable); + applicationClassLoaderInited = true; + } else if (!lazyClassLoaderInit) { + VM.initializeClassLoader(this, VM.J9_CLASSLOADER_TYPE_OTHERS, isParallelCapable); } + /*[IF JAVA_SPEC_VERSION > 8]*/ this.classLoaderName = classLoaderName; -/*[ENDIF] JAVA_SPEC_VERSION > 8 */ + // BootstrapClassLoader.unnamedModule is set by JVM_SetBootLoaderUnnamedModule. + unnamedModule = (this == bootstrapClassLoader) ? null : new Module(this); + /*[ENDIF] JAVA_SPEC_VERSION > 8 */ /*[IF JAVA_SPEC_VERSION >= 19]*/ this.nativelibs = NativeLibraries.newInstance((this == bootstrapClassLoader) ? null : this); @@ -2665,7 +2645,6 @@ static NativeLibraries nativeLibrariesFor(ClassLoader loader) { } /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ -/*[IF JAVA_SPEC_VERSION > 8]*/ /** * Assign immortal class loaders for restore run. * @@ -2682,6 +2661,5 @@ private final void assignImmortalClassLoader(int id, boolean isParallelCapable) VM.initializeClassLoader(this, id, isParallelCapable); } } -/*[ENDIF] JAVA_SPEC_VERSION > 8 */ } diff --git a/jcl/src/java.base/share/classes/java/lang/System.java b/jcl/src/java.base/share/classes/java/lang/System.java index bad1c01deac..8988e76f19e 100644 --- a/jcl/src/java.base/share/classes/java/lang/System.java +++ b/jcl/src/java.base/share/classes/java/lang/System.java @@ -370,8 +370,13 @@ static void afterClinitInitialization() { Unsafe unsafe = Unsafe.getUnsafe(); + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReference(unsafe.staticFieldBase(f1), unsafe.staticFieldOffset(f1), com.ibm.jit.JITHelpers.getHelpers()); + unsafe.putReference(unsafe.staticFieldBase(f2), unsafe.staticFieldOffset(f2), com.ibm.jit.JITHelpers.getHelpers()); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObject(unsafe.staticFieldBase(f1), unsafe.staticFieldOffset(f1), com.ibm.jit.JITHelpers.getHelpers()); unsafe.putObject(unsafe.staticFieldBase(f2), unsafe.staticFieldOffset(f2), com.ibm.jit.JITHelpers.getHelpers()); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } catch (NoSuchFieldException e) { } /*[IF JAVA_SPEC_VERSION < 17]*/ diff --git a/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index a843513e742..ffab206eebe 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/jcl/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -436,6 +436,7 @@ private static final class InlineTypesLock { InlineTypesLock() {} } */ public native void putBoolean(Object obj, long offset, boolean value); +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Gets the value of the Object in the obj parameter referenced by offset. * This is a non-volatile operation. @@ -455,6 +456,7 @@ private static final class InlineTypesLock { InlineTypesLock() {} } * @param value Object to store in obj */ public native void putObject(Object obj, long offset, Object value); +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -619,6 +621,7 @@ public native Class defineClass0(String name, byte[] b, int offset, int bLeng */ public final native long compareAndExchangeLong(Object obj, long offset, long compareValue, long exchangeVale); +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Atomically sets the parameter value at offset in obj if the compare value * matches the existing value in the object. @@ -647,6 +650,7 @@ public native Class defineClass0(String name, byte[] b, int offset, int bLeng */ public final native Object compareAndExchangeObject(Object obj, long offset, Object compareValue, Object exchangeValue); +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -823,6 +827,7 @@ public final native Object compareAndExchangeReference(Object obj, long offset, */ public native void putBooleanVolatile(Object obj, long offset, boolean value); +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Atomically gets the value of the Object in the obj parameter referenced by offset. * @@ -840,6 +845,7 @@ public final native Object compareAndExchangeReference(Object obj, long offset, * @param value Object to store in obj */ public native void putObjectVolatile(Object obj, long offset, Object value); +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -2767,6 +2773,7 @@ public final boolean weakCompareAndSetBooleanPlain(Object obj, long offset, bool return weakCompareAndSetBytePlain(obj, offset, bool2byte(compareValue), bool2byte(setValue)); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Atomically sets the parameter value at offset in obj if the compare value * matches the existing value in the object. @@ -2864,6 +2871,7 @@ public final boolean weakCompareAndSetObjectRelease(Object obj, long offset, Obj public final boolean weakCompareAndSetObject(Object obj, long offset, Object compareValue, Object setValue) { return compareAndSetObject(obj, offset, compareValue, setValue); } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -3061,6 +3069,7 @@ public final boolean getBooleanAcquire(Object obj, long offset) { return getBooleanVolatile(obj, offset); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Gets the value of the Object in the obj parameter referenced by offset using acquire semantics. * Preceding loads will not be reordered with subsequent loads/stores. @@ -3072,6 +3081,7 @@ public final boolean getBooleanAcquire(Object obj, long offset) { public final Object getObjectAcquire(Object obj, long offset) { return getObjectVolatile(obj, offset); } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -3183,6 +3193,7 @@ public final void putBooleanRelease(Object obj, long offset, boolean value) { putBooleanVolatile(obj, offset, value); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Sets the value of the Object in the obj parameter at memory offset using acquire semantics. * Preceding stores will not be reordered with subsequent loads/stores. @@ -3194,6 +3205,7 @@ public final void putBooleanRelease(Object obj, long offset, boolean value) { public final void putObjectRelease(Object obj, long offset, Object value) { putObjectVolatile(obj, offset, value); } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -3305,6 +3317,7 @@ public final boolean getBooleanOpaque(Object obj, long offset) { return getBooleanVolatile(obj, offset); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Gets the value of the Object in the obj parameter referenced by offset. * The operation is in program order, but does enforce ordering with respect to other threads. @@ -3316,6 +3329,7 @@ public final boolean getBooleanOpaque(Object obj, long offset) { public final Object getObjectOpaque(Object obj, long offset) { return getObjectVolatile(obj, offset); } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -3427,6 +3441,7 @@ public final void putBooleanOpaque(Object obj, long offset, boolean value) { putBooleanVolatile(obj, offset, value); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Sets the value of the Object in the obj parameter at memory offset. * The operation is in program order, but does enforce ordering with respect to other threads. @@ -3438,6 +3453,7 @@ public final void putBooleanOpaque(Object obj, long offset, boolean value) { public final void putObjectOpaque(Object obj, long offset, Object value) { putObjectVolatile(obj, offset, value); } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -4349,6 +4365,7 @@ public final boolean getAndSetBooleanAcquire(Object obj, long offset, boolean va return byte2bool(result); } +/*[IF JAVA_SPEC_VERSION < 23]*/ /** * Atomically sets value at offset in obj * and returns the value of the field prior to the update. @@ -4408,6 +4425,7 @@ public final Object getAndSetObjectAcquire(Object obj, long offset, Object value } } } +/*[ENDIF] JAVA_SPEC_VERSION < 23 */ /*[IF JAVA_SPEC_VERSION >= 12]*/ /** @@ -4430,6 +4448,25 @@ public final Object getAndSetReference(Object obj, long offset, Object value) { } } + /*[IF INLINE-TYPES]*/ + public final Object getAndSetReference(Object obj, long offset, Class valueType, Object value) { + throw new Error("getAndSetReference() unimplemented"); //$NON-NLS-1$ + } + + public final Object getAndSetReferenceAcquire(Object obj, long offset, Class valueType, Object value) { + return getAndSetReference(obj, offset, valueType, value); + } + + public final Object getAndSetReferenceRelease(Object obj, long offset, Class valueType, Object value) { + return getAndSetReference(obj, offset, valueType, value); + } + + public void notifyStrictStaticAccess(Class clz, long staticFieldOffset, boolean writing) { + Objects.requireNonNull(clz); + throw new Error("notifyStrictStaticAccess() unimplemented"); //$NON-NLS-1$ + } + /*[ENDIF] INLINE-TYPES */ + /** * Atomically sets value at offset in obj * and returns the value of the field prior to the update. @@ -6629,14 +6666,6 @@ private static char convEndian(boolean isBigEndian, char value) { */ public native void putValue(Object obj, long offset, Class clz, V value); - /** - * Returns the uninitialized default instance of the specified value class - * - * @param clz the specificed value class - * @return the uninitialized default instance of clz - */ - public native V uninitializedDefaultValue(Class clz); - /** * Determines the size of the header for a specified value class * diff --git a/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java b/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java index bd5facc7d8a..704d3c228f5 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java +++ b/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java @@ -67,21 +67,22 @@ public class Continuation { private static long isAccessibleOffset = unsafe.objectFieldOffset(Continuation.class, "isAccessible"); /** - * Continuation's Pinned reasons + * Continuation's Pinned reasons. */ public enum Pinned { - /** In native code */ + /** In native code. */ NATIVE(1), - /** Holding monitor(s) */ + /*[IF JAVA_SPEC_VERSION < 26]*/ + /** Holding one or more monitors. */ MONITOR(2), - /** In critical section */ -/*[IF JAVA_SPEC_VERSION >= 24]*/ + /*[ENDIF] JAVA_SPEC_VERSION < 26 */ + /** In a critical section. */ CRITICAL_SECTION(3), - /** Exception */ - EXCEPTION(4); -/*[ELSE] JAVA_SPEC_VERSION >= 24 */ - CRITICAL_SECTION(3); -/*[ENDIF] JAVA_SPEC_VERSION >= 24 */ + /*[IF JAVA_SPEC_VERSION >= 24]*/ + /** Exception. */ + EXCEPTION(4), + /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ + ; private final int errorCode; @@ -96,29 +97,36 @@ public int errorCode() { public enum PreemptStatus { /** Success */ - SUCCESS(null), + SUCCESS, /** Permanent fail */ - PERM_FAIL_UNSUPPORTED(null), + PERM_FAIL_UNSUPPORTED, /** Permanent fail due to yielding */ - PERM_FAIL_YIELDING(null), + PERM_FAIL_YIELDING, /** Permanent fail due to continuation unmounted */ - PERM_FAIL_NOT_MOUNTED(null), + PERM_FAIL_NOT_MOUNTED, /** Transient fail due to continuation pinned {@link Pinned#CRITICAL_SECTION} */ TRANSIENT_FAIL_PINNED_CRITICAL_SECTION(Pinned.CRITICAL_SECTION), /** Transient fail due to continuation pinned {@link Pinned#NATIVE} */ TRANSIENT_FAIL_PINNED_NATIVE(Pinned.NATIVE), + /*[IF JAVA_SPEC_VERSION < 26]*/ /** Transient fail due to continuation pinned {@link Pinned#MONITOR} */ - TRANSIENT_FAIL_PINNED_MONITOR(Pinned.MONITOR); + TRANSIENT_FAIL_PINNED_MONITOR(Pinned.MONITOR), + /*[ENDIF] JAVA_SPEC_VERSION < 26 */ + ; final Pinned pinned; - public Pinned pinned() { - return pinned; + private PreemptStatus() { + this(null); } private PreemptStatus(Pinned reason) { this.pinned = reason; } + + public Pinned pinned() { + return pinned; + } } /** @@ -252,27 +260,31 @@ public static boolean yield(ContinuationScope scope) { @JvmtiMountTransition private boolean yield0() { int rcPinned = isPinnedImpl(); - if (rcPinned != 0) { - Pinned reason = null; - if (rcPinned == Pinned.CRITICAL_SECTION.errorCode()) { - reason = Pinned.CRITICAL_SECTION; - } else if (rcPinned == Pinned.MONITOR.errorCode()) { - reason = Pinned.MONITOR; - } else if (rcPinned == Pinned.NATIVE.errorCode()) { - reason = Pinned.NATIVE; + if (rcPinned == 0) { + yieldImpl(false); + onContinue(); + return true; + } + + Pinned reason; + if (rcPinned == Pinned.CRITICAL_SECTION.errorCode()) { + reason = Pinned.CRITICAL_SECTION; +/*[IF JAVA_SPEC_VERSION < 26]*/ + } else if (rcPinned == Pinned.MONITOR.errorCode()) { + reason = Pinned.MONITOR; +/*[ENDIF] JAVA_SPEC_VERSION < 26 */ + } else if (rcPinned == Pinned.NATIVE.errorCode()) { + reason = Pinned.NATIVE; /*[IF JAVA_SPEC_VERSION >= 24]*/ - } else if (rcPinned == Pinned.EXCEPTION.errorCode()) { - reason = Pinned.EXCEPTION; + } else if (rcPinned == Pinned.EXCEPTION.errorCode()) { + reason = Pinned.EXCEPTION; /*[ENDIF] JAVA_SPEC_VERSION >= 24 */ - } else { - throw new AssertionError("Unknown pinned error code: " + rcPinned); - } - onPinned(reason); } else { - yieldImpl(false); - onContinue(); + throw new AssertionError("Unknown pinned error code: " + rcPinned); } - return (rcPinned == 0); + onPinned(reason); + + return false; } protected void onPinned(Pinned reason) { diff --git a/jcl/src/java.base/share/classes/openj9/internal/criu/InternalCRIUSupport.java b/jcl/src/java.base/share/classes/openj9/internal/criu/InternalCRIUSupport.java index c582469a633..402b75c8ab6 100644 --- a/jcl/src/java.base/share/classes/openj9/internal/criu/InternalCRIUSupport.java +++ b/jcl/src/java.base/share/classes/openj9/internal/criu/InternalCRIUSupport.java @@ -975,8 +975,13 @@ private void registerRestoreEnvVariables() { @SuppressWarnings("unchecked") Map newTheUnmodifiableEnvironment = (Map) newStringEnvironment.newInstance(theEnvironment); + /*[IF JAVA_SPEC_VERSION >= 23]*/ + unsafe.putReference(processEnvironmentClass, unsafe.staticFieldOffset(theUnmodifiableEnvironmentHandle), + Collections.unmodifiableMap(newTheUnmodifiableEnvironment)); + /*[ELSE] JAVA_SPEC_VERSION >= 23 */ unsafe.putObject(processEnvironmentClass, unsafe.staticFieldOffset(theUnmodifiableEnvironmentHandle), Collections.unmodifiableMap(newTheUnmodifiableEnvironment)); + /*[ENDIF] JAVA_SPEC_VERSION >= 23 */ } catch (Throwable t) { throw throwSetEnvException(t); diff --git a/runtime/bcutil/ClassFileOracle.cpp b/runtime/bcutil/ClassFileOracle.cpp index 359dea5c20a..af4327fbe99 100644 --- a/runtime/bcutil/ClassFileOracle.cpp +++ b/runtime/bcutil/ClassFileOracle.cpp @@ -90,9 +90,6 @@ ClassFileOracle::KnownAnnotation ClassFileOracle::_knownAnnotations[] = { #define NULLRESTRICTED_SIGNATURE "Ljdk/internal/vm/annotation/NullRestricted;" {NULLRESTRICTED_SIGNATURE , sizeof(NULLRESTRICTED_SIGNATURE)}, #undef NULLRESTRICTED_SIGNATURE -#define IMPLICITLYCONSTRUCTIBLE_SIGNATURE "Ljdk/internal/vm/annotation/ImplicitlyConstructible;" - {IMPLICITLYCONSTRUCTIBLE_SIGNATURE , sizeof(IMPLICITLYCONSTRUCTIBLE_SIGNATURE)}, -#undef IMPLICITLYCONSTRUCTIBLE_SIGNATURE #define LOOSELYCONSISTENTVALUE_SIGNATURE "Ljdk/internal/vm/annotation/LooselyConsistentValue;" {LOOSELYCONSISTENTVALUE_SIGNATURE , sizeof(LOOSELYCONSISTENTVALUE_SIGNATURE)}, #undef LOOSELYCONSISTENTVALUE_SIGNATURE @@ -564,7 +561,6 @@ ClassFileOracle::walkAttributes() knownAnnotations = addAnnotationBit(knownAnnotations, UNMODIFIABLE_ANNOTATION); knownAnnotations = addAnnotationBit(knownAnnotations, VALUEBASED_ANNOTATION); #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) - knownAnnotations = addAnnotationBit(knownAnnotations, IMPLICITLYCONSTRUCTIBLE_ANNOTATION); knownAnnotations = addAnnotationBit(knownAnnotations, LOOSELYCONSISTENTVALUE_ANNOTATION); #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ _annotationsAttribute = (J9CfrAttributeRuntimeVisibleAnnotations *)attrib; @@ -580,10 +576,6 @@ ClassFileOracle::walkAttributes() _isClassValueBased = true; } #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) - if (containsKnownAnnotation(foundAnnotations, IMPLICITLYCONSTRUCTIBLE_ANNOTATION)) { - _hasImplicitCreationAttribute = true; - _implicitCreationFlags |= J9AccImplicitCreateHasDefaultValue; - } if (containsKnownAnnotation(foundAnnotations, LOOSELYCONSISTENTVALUE_ANNOTATION)) { _hasImplicitCreationAttribute = true; _implicitCreationFlags |= J9AccImplicitCreateNonAtomic; diff --git a/runtime/bcutil/ClassFileOracle.hpp b/runtime/bcutil/ClassFileOracle.hpp index 46854d04c04..ff085dec593 100644 --- a/runtime/bcutil/ClassFileOracle.hpp +++ b/runtime/bcutil/ClassFileOracle.hpp @@ -1089,7 +1089,6 @@ class RecordComponentIterator #endif /* JAVA_SPEC_VERSION >= 20 */ #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) NULLRESTRICTED_ANNOTATION, - IMPLICITLYCONSTRUCTIBLE_ANNOTATION, LOOSELYCONSISTENTVALUE_ANNOTATION, #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ KNOWN_ANNOTATION_COUNT diff --git a/runtime/cfdumper/CMakeLists.txt b/runtime/cfdumper/CMakeLists.txt index 5ef0ddd641d..1a9fda5239e 100644 --- a/runtime/cfdumper/CMakeLists.txt +++ b/runtime/cfdumper/CMakeLists.txt @@ -25,7 +25,6 @@ set(OMR_ENHANCED_WARNINGS OFF) set_source_files_properties(${j9vm_BINARY_DIR}/vm/ut_j9vm.c PROPERTIES GENERATED TRUE) j9vm_add_executable(cfdump main.c - pvdump.c romdump.c stubs.c diff --git a/runtime/cfdumper/module.xml b/runtime/cfdumper/module.xml index 92c978adc18..9f8e40efeb3 100644 --- a/runtime/cfdumper/module.xml +++ b/runtime/cfdumper/module.xml @@ -46,7 +46,6 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex - diff --git a/runtime/cfdumper/pvdump.c b/runtime/cfdumper/pvdump.c deleted file mode 100644 index fee6eb9a6bf..00000000000 --- a/runtime/cfdumper/pvdump.c +++ /dev/null @@ -1,232 +0,0 @@ -/******************************************************************************* - * Copyright IBM Corp. and others 1991 - * - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which accompanies this - * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] https://openjdk.org/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 - *******************************************************************************/ - -#include "j9.h" -#include "j9protos.h" -#include "j9port.h" -#include "cfr.h" -#include "rommeth.h" - -/* #defines from bcverify.h */ -#define TAG_SPECIAL 1 /* clear bit means not a special object */ -#define TAG_BASE_TYPE 2 /* clear bit means object or array */ -#define TAG_BASE_ARRAY 4 /* set bit means base type array, clean bit means base type */ - -#define ARITY_MASK 0xFF000000 -#define ARITY_SHIFT 24 - -#define CLASS_INDEX_MASK 0x00FFFFF0 -#define CLASS_INDEX_SHIFT 4 - -#define TYPE_INT 0x02 -#define TYPE_FLOAT 0x03 -#define TYPE_LONG 0x04 -#define TYPE_DOUBLE 0x05 -#define TYPE_OBJECT 0x07 -#define TYPE_INIT_OBJECT 0x08 -#define TYPE_NEW_OBJECT 0x09 -#define TYPE_ARG_OBJECT 0x0a -#define TYPE_LONG2 0x0c -#define TYPE_DOUBLE2 0x0d - -#define BASE_TYPE_INT 0x010 -#define BASE_TYPE_FLOAT 0x020 -#define BASE_TYPE_LONG 0x040 -#define BASE_TYPE_DOUBLE 0x080 -#define BASE_TYPE_SHORT 0x100 -#define BASE_TYPE_BYTE 0x200 -#define BASE_TYPE_CHAR 0x400 - -/* #defines from bcvcfr.h */ -#ifdef J9VM_ENV_LITTLE_ENDIAN -#define J9_READ_LITTLE_ENDIAN( value) value -#define J9_READ_BIG_ENDIAN( value ) ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) | ((value & 0xFF000000) >> 24) -#define J9_READ_LITTLE_ENDIAN16( value) value -#define J9_READ_BIG_ENDIAN16( value ) ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) -#else -#define J9_READ_LITTLE_ENDIAN( value ) ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) | ((value & 0xFF000000) >> 24) -#define J9_READ_BIG_ENDIAN( value) value -#define J9_READ_LITTLE_ENDIAN16( value) ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) -#define J9_READ_BIG_ENDIAN16( value ) value -#endif -#define J9_NEUTRAL_32( value ) (endian ? J9_READ_BIG_ENDIAN(value) : J9_READ_LITTLE_ENDIAN(value)) -#define J9_NEUTRAL_16( value ) (endian ? J9_READ_BIG_ENDIAN16(value) : J9_READ_LITTLE_ENDIAN16(value)) - -/* Prototype from rcdump.c */ - -static UDATA decodeStackEntry (J9PortLibrary* portLib, U_8* stackDataPtr, UDATA endian); -static U_32 unalignedRead4 (U_8* ptr, UDATA isBigEndian ); -static U_16 unalignedRead2 (U_8* ptr, UDATA isBigEndian ); - -static UDATA decodeStackDepth (J9PortLibrary* portLib, U_8* stackDataPtr, U_8* stackDataEnd); - -static U_16 unalignedRead2(U_8* ptr, UDATA isBigEndian ) -{ - if(isBigEndian) return (ptr[0] << 8) | ptr[1]; - else return (ptr[1] << 8) | ptr[0]; -} - - -static U_32 unalignedRead4(U_8* ptr, UDATA isBigEndian ) -{ - U_32 a,b,c,d; - - if(isBigEndian) { - a = ptr[0]; - b = ptr[1]; - c = ptr[2]; - d = ptr[3]; - } else { - d = ptr[0]; - c = ptr[1]; - b = ptr[2]; - a = ptr[3]; - } - return (a << 24) | (b << 16) | (c << 8) | d; -} - - -static UDATA decodeStackEntry(J9PortLibrary* portLib, U_8* stackDataPtr, UDATA endian) -{ - UDATA entrySize = 1; - U_32 data; - UDATA i, arity, index; - - PORT_ACCESS_FROM_PORT(portLib); - - switch(*stackDataPtr++) - { - case TYPE_INT: - j9tty_printf(PORTLIB, " I"); - break; - - case TYPE_FLOAT: - j9tty_printf(PORTLIB, " F"); - break; - - case TYPE_LONG: - j9tty_printf(PORTLIB, " > ARITY_SHIFT; - index = (data & CLASS_INDEX_MASK) >> CLASS_INDEX_SHIFT; - j9tty_printf(PORTLIB, " "); - for(i = 0; i < arity; i++) j9tty_printf(PORTLIB, "["); - if(data & TAG_BASE_ARRAY) - { - switch(data & CLASS_INDEX_MASK) - { - case BASE_TYPE_INT: - j9tty_printf(PORTLIB, "I"); - break; - case BASE_TYPE_FLOAT: - j9tty_printf(PORTLIB, "F"); - break; - case BASE_TYPE_LONG: - j9tty_printf(PORTLIB, "J"); - break; - case BASE_TYPE_DOUBLE: - j9tty_printf(PORTLIB, "D"); - break; - case BASE_TYPE_SHORT: - j9tty_printf(PORTLIB, "S"); - break; - case BASE_TYPE_BYTE: - j9tty_printf(PORTLIB, "B"); - break; - case BASE_TYPE_CHAR: - j9tty_printf(PORTLIB, "C"); - break; - } - } - else - { - j9tty_printf(PORTLIB, "L(%i)", index); - } - } - else - { - index = (data & CLASS_INDEX_MASK) >> CLASS_INDEX_SHIFT; - j9tty_printf(PORTLIB, " L(%i)", index); - } - break; - - case TYPE_INIT_OBJECT: - j9tty_printf(PORTLIB, " init"); - break; - - case TYPE_NEW_OBJECT: - data = unalignedRead4(stackDataPtr, endian); - entrySize += 4; - index = (data & CLASS_INDEX_MASK) >> CLASS_INDEX_SHIFT; - j9tty_printf(PORTLIB, " new(%i)", index); - break; - - case TYPE_LONG2: - j9tty_printf(PORTLIB, " J>"); - break; - - case TYPE_DOUBLE2: - j9tty_printf(PORTLIB, " D>"); - break; - - case 0xFF: - j9tty_printf(PORTLIB, " X"); - break; - - default: - j9tty_printf(PORTLIB, " ?%02X?", *(stackDataPtr - 1)); - } - return entrySize; -} - - -static UDATA decodeStackDepth(J9PortLibrary* portLib, U_8* stackDataPtr, U_8* stackDataEnd) -{ - UDATA depth = 0; - U_8 entry; - - PORT_ACCESS_FROM_PORT(portLib); - - while(stackDataPtr < stackDataEnd) - { - depth++; - entry = *stackDataPtr++; - if((entry == TYPE_OBJECT) || (entry == TYPE_NEW_OBJECT)) stackDataPtr += 4; - } - return depth; -} diff --git a/runtime/compiler/aarch64/runtime/Recomp.cpp b/runtime/compiler/aarch64/runtime/Recomp.cpp index 354b3bf28d0..afcdb80dfa7 100644 --- a/runtime/compiler/aarch64/runtime/Recomp.cpp +++ b/runtime/compiler/aarch64/runtime/Recomp.cpp @@ -217,10 +217,8 @@ void J9::Recompilation::methodCannotBeRecompiled(void *oldStartPC, TR_FrontEnd * TR_PersistentJittedBodyInfo *bodyInfo = getJittedBodyInfoFromPC(oldStartPC); TR_PersistentMethodInfo *methodInfo = bodyInfo->getMethodInfo(); - if (bodyInfo->getUsesPreexistence() - || methodInfo->hasBeenReplaced() - || (linkageInfo->isSamplingMethodBody() && !fej9->isAsyncCompilation()) // go interpreted for failed recomps in sync mode - || methodInfo->isExcludedPostRestore()) // go interpreted if method is excluded post restore + if ((linkageInfo->isSamplingMethodBody() && !fej9->isAsyncCompilation()) // failed recomps in sync mode + || bodyInfo->getIsInvalidated()) { // Patch the first instruction regardless of counting or sampling patchAddr = (int32_t *)((uint8_t *)oldStartPC + getJitEntryOffset(linkageInfo)); diff --git a/runtime/compiler/arm/runtime/Recomp.cpp b/runtime/compiler/arm/runtime/Recomp.cpp index 8840b0c961a..c9ec20bf6fe 100644 --- a/runtime/compiler/arm/runtime/Recomp.cpp +++ b/runtime/compiler/arm/runtime/Recomp.cpp @@ -259,10 +259,8 @@ void J9::Recompilation::methodCannotBeRecompiled(void *oldStartPC, TR_FrontEnd * TR_PersistentJittedBodyInfo *bodyInfo = getJittedBodyInfoFromPC(oldStartPC); TR_PersistentMethodInfo *methodInfo = bodyInfo->getMethodInfo(); - if (bodyInfo->getUsesPreexistence() // TODO: reconsider whether this is a race cond for info - || methodInfo->hasBeenReplaced() - || (linkageInfo->isSamplingMethodBody() && ! fej9->isAsyncCompilation()) // go interpreted for failed recomps in sync mode - || methodInfo->isExcludedPostRestore()) // go interpreted if method is excluded post restore + if ((linkageInfo->isSamplingMethodBody() && !fej9->isAsyncCompilation()) // failed recomps in sync mode + || bodyInfo->getIsInvalidated()) // TODO: reconsider whether this is a race cond for info { // Patch the first instruction regardless of counting or sampling // TODO: We may need to cross-check with Invalidation to avoid racing cond diff --git a/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp b/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp index 25550fbda86..cf9a8e369d5 100644 --- a/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp +++ b/runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp @@ -541,9 +541,6 @@ LastVectorMethod = LastVectorIntrinsicMethod, java_lang_reflect_Array_getLength, - jdk_internal_value_ValueClass_newArrayInstance, - jdk_internal_value_ValueClass_newNullRestrictedArray, - jdk_internal_value_NullRestrictedCheckedType_of, java_lang_reflect_Method_invoke, java_util_Arrays_fill, java_util_Arrays_equals, @@ -1247,7 +1244,6 @@ java_lang_J9VMInternals_isClassModifierPublic, java_lang_J9VMInternals_getArrayLengthAsObject, java_lang_J9VMInternals_rawNewInstance, - java_lang_J9VMInternals_rawNewArrayInstance, java_lang_J9VMInternals_defaultClone, java_lang_J9VMInternals_getNumBitsInReferenceField, java_lang_J9VMInternals_getNumBytesInReferenceField, diff --git a/runtime/compiler/control/CompilationThread.cpp b/runtime/compiler/control/CompilationThread.cpp index 7b3ca203b59..7d202a5ca4c 100644 --- a/runtime/compiler/control/CompilationThread.cpp +++ b/runtime/compiler/control/CompilationThread.cpp @@ -2585,6 +2585,12 @@ void TR::CompilationInfo::purgeMethodQueue(TR_CompilationErrorCode errorCode) cur->_newStartPC = startPC; cur->_compErrCode = errorCode; + if (TR::Options::isAnyVerboseOptionSet(TR_VerboseCompFailure, TR_VerboseCompileRequest)) + { + J9Method *j9m = cur->getMethodDetails().getMethod(); + TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "purge queue entry %p j9method=%p", cur, j9m); + } + // notify the sleeping threads // debugPrint(vmThread, "\tnotify sleeping threads that the compilation is done\n"); @@ -6136,7 +6142,7 @@ void *TR::CompilationInfo::compileOnSeparateThread(J9VMThread * vmThread, TR::Il if (compErrCode) *compErrCode = compilationNotNeeded; if (TR::Options::getJITCmdLineOptions()->getVerboseOption(TR_VerboseCompileRequest)) - TR_VerboseLog::writeLineLocked(TR_Vlog_CR,"%p Already compiled at %p", startPC); + TR_VerboseLog::writeLineLocked(TR_Vlog_CR,"%p Already compiled at %p", vmThread, startPC); return startPC; } @@ -9256,6 +9262,31 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void * reloRuntime, &target); +#if defined(J9VM_OPT_JITSERVER) + if (that->_methodBeingCompiled->isOutOfProcessCompReq()) + { + // use the default code cache + compiler->getOptions()->setCodeCacheKind(TR::CodeCacheKind::DEFAULT_CC); + } + else +#endif + { + TR::SimpleRegex *regex = compiler->getOptions()->getTransientClassRegex(); + if (regex) + { + J9Method *method = details.getMethod(); + J9UTF8 *className = J9ROMCLASS_CLASSNAME(J9_CLASS_FROM_METHOD(method)->romClass); + // TR::SimpleRegex::match needs a NULL-terminated string + size_t classNameLength = J9UTF8_LENGTH(className); + char *name = (char*)compiler->trMemory()->allocateMemory(classNameLength+1, stackAlloc); + strncpy(name, (char*)J9UTF8_DATA(className), classNameLength); + name[classNameLength] = '\0'; + if (TR::SimpleRegex::match(regex, name)) + { + compiler->getOptions()->setCodeCacheKind(TR::CodeCacheKind::TRANSIENT_CODE_CC); + } + } + } #if defined(J9VM_OPT_JITSERVER) // JITServer TODO: put info in optPlan so that compilation constructor can do this if (that->_methodBeingCompiled->isRemoteCompReq()) @@ -9275,8 +9306,6 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void * auto compInfoPTRemote = static_cast(that); compiler->setAOTCacheStore(compInfoPTRemote->isAOTCacheStore()); - // Only use the default code cache on the server - compiler->getOptions()->setCodeCacheKind(TR::CodeCacheKind::DEFAULT_CC); } #endif /* defined(J9VM_OPT_JITSERVER) */ @@ -11151,6 +11180,10 @@ void TR::CompilationInfoPerThreadBase::logCompilationSuccess( compiler->getRecompilationInfo()->getJittedBodyInfo()->getHasEdoSnippet()) TR_VerboseLog::write(" EDO"); + if (compiler->getRecompilationInfo() && + compiler->getRecompilationInfo()->getJittedBodyInfo()->getUsesPreexistence()) + TR_VerboseLog::write(" PREX"); + #if defined(J9VM_OPT_JITSERVER) if (_methodBeingCompiled->isRemoteCompReq()) { @@ -11667,6 +11700,17 @@ TR::CompilationInfoPerThreadBase::processExceptionCommonTasks( _methodBeingCompiled->getMethodDetails().getMethod(), translationTime, compilationErrorNames[_methodBeingCompiled->_compErrCode]); + uintptr_t vmState = vmThread->omrVMThread->vmState; + TR_VerboseLog::write(" VmState=0x%08.8x", (unsigned int)vmState); + int jitPhase = (vmState >> 8) & 0xFF; + if (_methodBeingCompiled->_compErrCode == compilationHeapLimitExceeded + && (vmState & J9VMSTATE_MAJOR) == J9VMSTATE_JIT // Jit compilation + && jitPhase != 0x00 && jitPhase != 0xFF) // not ILGen or CodeGen => Optimization phase + { + OMR::Optimizations jitPhaseOMROpt = static_cast(jitPhase); + TR_VerboseLog::write(" OptIdx=%d", compiler->getOptIndex()); + TR_VerboseLog::write(" OptName=%s", OMR::Optimizer::getOptimizationName(jitPhaseOMROpt)); + } if (entry->isAotLoad()) { TR_RelocationRuntime *reloRuntime = compiler->reloRuntime(); diff --git a/runtime/compiler/env/VMJ9.cpp b/runtime/compiler/env/VMJ9.cpp index 90e986bebfb..cb09bb6be96 100644 --- a/runtime/compiler/env/VMJ9.cpp +++ b/runtime/compiler/env/VMJ9.cpp @@ -8014,19 +8014,6 @@ TR_J9VM::inlineNativeCall(TR::Compilation * comp, TR::TreeTop * callNodeTreeTop, } return callNode; } - case TR::java_lang_J9VMInternals_rawNewArrayInstance: - { - TR::Node::recreate(callNode, TR::variableNewArray); - callNode->setSymbolReference(comp->getSymRefTab()->findOrCreateANewArraySymbolRef(callNode->getSymbol()->castToResolvedMethodSymbol())); - TR::Node *newNode = TR::Node::createWithSymRef(callNode, TR::aloadi, 1, comp->getSymRefTab()->findOrCreateArrayComponentTypeSymbolRef()); - TR::Node *newNodeChild = TR::Node::createWithSymRef(callNode, TR::aloadi, 1, comp->getSymRefTab()->findOrCreateClassFromJavaLangClassAsPrimitiveSymbolRef()); - newNode->setAndIncChild(0, newNodeChild); - newNode->setNumChildren(1); - newNodeChild->setChild(0, callNode->getChild(1)); - newNodeChild->setNumChildren(1); - callNode->setAndIncChild(1,newNode); - return callNode; - } case TR::java_lang_J9VMInternals_getArrayLengthAsObject: { TR::Node::recreate(callNode, TR::iloadi); diff --git a/runtime/compiler/env/j9method.cpp b/runtime/compiler/env/j9method.cpp index f4f83ff5544..ce3929dc62a 100644 --- a/runtime/compiler/env/j9method.cpp +++ b/runtime/compiler/env/j9method.cpp @@ -3458,7 +3458,6 @@ void TR_ResolvedJ9Method::construct() {x(TR::java_lang_J9VMInternals_isClassModifierPublic, "isClassModifierPublic", "(I)Z")}, {x(TR::java_lang_J9VMInternals_getArrayLengthAsObject, "getArrayLengthAsObject", "(Ljava/lang/Object;)I")}, {x(TR::java_lang_J9VMInternals_rawNewInstance, "rawNewInstance", "(Ljava/lang/Class;)Ljava/lang/Object;")}, - {x(TR::java_lang_J9VMInternals_rawNewArrayInstance, "rawNewArrayInstance", "(ILjava/lang/Class;)Ljava/lang/Object;")}, {x(TR::java_lang_J9VMInternals_defaultClone, "defaultClone", "(Ljava/lang/Object;)Ljava/lang/Object;")}, {x(TR::java_lang_J9VMInternals_getNumBitsInReferenceField, "getNumBitsInReferenceField", "()I")}, {x(TR::java_lang_J9VMInternals_getNumBytesInReferenceField, "getNumBytesInReferenceField", "()I")}, @@ -3930,19 +3929,6 @@ void TR_ResolvedJ9Method::construct() { TR::unknownMethod} }; - static X ValueClassMethods[] = - { - {x(TR::jdk_internal_value_ValueClass_newArrayInstance, "newArrayInstance", "(Ljdk/internal/value/CheckedType;I)[Ljava/lang/Object;")}, - {x(TR::jdk_internal_value_ValueClass_newNullRestrictedArray, "newNullRestrictedArray", "(Ljava/lang/Class;I)[Ljava/lang/Object;")}, - { TR::unknownMethod} - }; - - static X NullRestrictedCheckedTypeMethods[] = - { - {x(TR::jdk_internal_value_NullRestrictedCheckedType_of, "of", "(Ljava/lang/Class;)Ljdk/internal/value/NullRestrictedCheckedType;")}, - { TR::unknownMethod} - }; - static X SpreadHandleMethods[] = { {x(TR::java_lang_invoke_SpreadHandle_numArgsToPassThrough, "numArgsToPassThrough", "()I")}, @@ -4285,7 +4271,6 @@ void TR_ResolvedJ9Method::construct() { "sun/nio/cs/ISO_8859_1$Decoder", EncodeMethods }, { "java/io/ByteArrayOutputStream", ByteArrayOutputStreamMethods }, { "java/lang/ScopedValue$Carrier", ScopedValueMethods }, - { "jdk/internal/value/ValueClass", ValueClassMethods }, { "sun/nio/cs/SingleByte$Decoder", SingleByteDecoderMethods }, { "sun/nio/cs/SingleByte$Encoder", SingleByteEncoderMethods }, { 0 } @@ -4416,7 +4401,6 @@ void TR_ResolvedJ9Method::construct() { { "java/lang/invoke/ConvertHandle$FilterHelpers", ConvertHandleFilterHelpersMethods }, { "java/lang/invoke/DirectMethodHandle$Accessor", DirectMethodHandleAccessorMethods }, - { "jdk/internal/value/NullRestrictedCheckedType", NullRestrictedCheckedTypeMethods }, { 0 } }; diff --git a/runtime/compiler/optimizer/J9EstimateCodeSize.cpp b/runtime/compiler/optimizer/J9EstimateCodeSize.cpp index 26538bf2625..fad37ae69d2 100644 --- a/runtime/compiler/optimizer/J9EstimateCodeSize.cpp +++ b/runtime/compiler/optimizer/J9EstimateCodeSize.cpp @@ -1001,21 +1001,8 @@ TR_J9EstimateCodeSize::processBytecodeAndGenerateCFG(TR_CallTarget *calltarget, resolvedMethod = calltarget->_calleeMethod->getResolvedHandleMethod(comp(), methodTypeTableEntryIndex, &isUnresolvedInCP); if (resolvedMethod && !isUnresolvedInCP) { - char topLevelMethodNameBuffer[1024]; - const char *topLevelMethodName = NULL; - topLevelMethodName = comp()->fej9()->sampleSignature( - comp()->getCurrentMethod()->getPersistentIdentifier(), topLevelMethodNameBuffer, - 1024, comp()->trMemory()); - // javax/imageio/stream/ImageInputStreamImpl.readlong()J is implemented with two back-to-back readInt() invocations, - // and deeper down those call graphs, there are VarHandle operation methods that we are able to inline if peeking - // ILGen is done for the method containing the invokehandle bytecode. However, in warm opt level, the inlining budget - // only allows one of the two readInt() methods to get inlined. This results in a functional issue that requires some - // additional work to address. This is a temporary workaround in place until the underlying problem exposed is fixed. - if (strncmp(topLevelMethodName, "javax/imageio/stream/ImageInputStreamImpl.readLong", 50)) - { - nph.setNeedsPeekingToTrue(); - heuristicTrace(tracer(), "Depth %d: Resolved invokehandle call at bc index %d has Signature %s, enabled peeking for caller to propagate prex arg info from caller.", _recursionDepth, i, tracer()->traceSignature(resolvedMethod)); - } + nph.setNeedsPeekingToTrue(); + heuristicTrace(tracer(), "Depth %d: Resolved invokehandle call at bc index %d has Signature %s, enabled peeking for caller to propagate prex arg info from caller.", _recursionDepth, i, tracer()->traceSignature(resolvedMethod)); } } flags[i].set(InterpreterEmulator::BytecodePropertyFlag::isUnsanitizeable); diff --git a/runtime/compiler/optimizer/J9ValuePropagation.cpp b/runtime/compiler/optimizer/J9ValuePropagation.cpp index 525eb4f1b91..168a2874b11 100644 --- a/runtime/compiler/optimizer/J9ValuePropagation.cpp +++ b/runtime/compiler/optimizer/J9ValuePropagation.cpp @@ -4316,44 +4316,6 @@ J9::ValuePropagation::innerConstrainAcall(TR::Node *node) addGlobalConstraint(node, TR::VPNonNullObject::create(this)); } } - else if ((method->getRecognizedMethod() == TR::jdk_internal_value_ValueClass_newArrayInstance) && - (node->getFirstChild()->getOpCodeValue() == TR::acall)) - { - /* - * n12n acall jdk/internal/value/ValueClass.newArrayInstance(Ljdk/internal/value/CheckedType;I)[Ljava/lang/Object; - * n9n acall jdk/internal/value/NullRestrictedCheckedType.of(Ljava/lang/Class;)Ljdk/internal/value/NullRestrictedCheckedType; - * n8n aloadi - * n7n loadaddr SomeValueClass - * n11n iload Test.ARRAY_SIZE - */ - bool isGlobal; - TR::Node *firstChildAcallNode = node->getFirstChild(); - constraint = getConstraint(firstChildAcallNode, isGlobal); - - if (constraint && - constraint->isFixedClass() && - firstChildAcallNode->getSymbol()->isResolvedMethod() && - (firstChildAcallNode->getSymbol()->getResolvedMethodSymbol()->getRecognizedMethod() == TR::jdk_internal_value_NullRestrictedCheckedType_of)) - { - if (trace()) - traceMsg(comp(), "%s: node n%dn its first child fixed class %p is an instance of NullRestrictedCheckedType\n", __FUNCTION__, node->getGlobalIndex(), constraint->getClass()); - - constraint = firstChildAcallNode->getFirstChild() ? getConstraint(firstChildAcallNode->getFirstChild(), isGlobal) : NULL; - TR_OpaqueClassBlock *arrayComponentClass = (constraint && constraint->isFixedClass()) ? constraint->getClass() : NULL; - TR_OpaqueClassBlock *nullRestrictedArrayClass = arrayComponentClass ? fe()->getNullRestrictedArrayClassFromComponentClass(arrayComponentClass) : NULL; - - if (trace()) - traceMsg(comp(), "%s: node n%dn arrayComponentClass %p nullRestrictedArrayClass %p\n", __FUNCTION__, node->getGlobalIndex(), arrayComponentClass, nullRestrictedArrayClass); - - if (nullRestrictedArrayClass) - { - TR::VPConstraint *newConstraint = TR::VPFixedClass::create(this, nullRestrictedArrayClass); - addBlockOrGlobalConstraint(node, newConstraint, isGlobal); - addGlobalConstraint(node, TR::VPNonNullObject::create(this)); - return node; - } - } - } } else // if (!node->getOpCode().isIndirect()) { diff --git a/runtime/compiler/p/runtime/Recomp.cpp b/runtime/compiler/p/runtime/Recomp.cpp index 737a7ddf79e..2ea4cd02df7 100644 --- a/runtime/compiler/p/runtime/Recomp.cpp +++ b/runtime/compiler/p/runtime/Recomp.cpp @@ -204,10 +204,8 @@ void J9::Recompilation::methodCannotBeRecompiled(void *oldStartPC, TR_FrontEnd * TR_PersistentJittedBodyInfo *bodyInfo = getJittedBodyInfoFromPC(oldStartPC); TR_PersistentMethodInfo *methodInfo = bodyInfo->getMethodInfo(); - if (bodyInfo->getUsesPreexistence() // TODO: reconsider whether this is a race cond for info - || methodInfo->hasBeenReplaced() - || (linkageInfo->isSamplingMethodBody() && ! fej9->isAsyncCompilation()) // go interpreted for failed recomps in sync mode - || methodInfo->isExcludedPostRestore()) // go interpreted if method is excluded post restore + if ((linkageInfo->isSamplingMethodBody() && ! fej9->isAsyncCompilation()) // failed recomps in sync mode + || bodyInfo->getIsInvalidated()) // TODO: reconsider whether this is a race cond for info { // Patch the first instruction regardless of counting or sampling // TODO: We may need to cross-check with Invalidation to avoid racing cond diff --git a/runtime/compiler/runtime/Trampoline.cpp b/runtime/compiler/runtime/Trampoline.cpp index ac409eb173f..6527f4f695d 100644 --- a/runtime/compiler/runtime/Trampoline.cpp +++ b/runtime/compiler/runtime/Trampoline.cpp @@ -379,6 +379,19 @@ bool ppcCodePatching(void *method, void *callSite, void *currentPC, void *curren patchAddr = (uint8_t *)callSite; distance = entryAddress - (uint8_t *)callSite; currentDistance = ((oldBits << 6) >> 6) & 0xfffffffc; + uint8_t *target = patchAddr + currentDistance; + TR::CodeCache *targetCC = TR::CodeCacheManager::instance()->findCodeCacheFromPC(target); + if (!targetCC || (target >= targetCC->getHelperBase() && target < targetCC->getHelperTop())) + { + // If the target is not in a code cache or the target is in the helper section of a code cache then we can + // assume the 'bl' is calling a helper. Starting with JDK11 (JEP 181, nestmates) "invokevirtual" can be used + // for private method call sites. This results in _virtualUnresolvedHelper() snippets being used indefinitely + // which exposes us to the possibility that the helper will call a method that was just recompiled and patched + // to call _samplingPatchCallSite(). Since the helper is reached using a "bl" instruction the patching logic + // will think that the call site can be patched to call the new recompiled body, but that's not the case. + return false; + } + oldBits &= 0xfc000003; if (TR::Options::getCmdLineOptions()->getOption(TR_StressTrampolines) || !TR::Compiler->target.cpu.isTargetWithinIFormBranchRange((intptr_t)entryAddress, (intptr_t)callSite)) diff --git a/runtime/compiler/x/runtime/Recomp.cpp b/runtime/compiler/x/runtime/Recomp.cpp index 9f73b30abba..0c305522f27 100644 --- a/runtime/compiler/x/runtime/Recomp.cpp +++ b/runtime/compiler/x/runtime/Recomp.cpp @@ -293,10 +293,8 @@ void J9::Recompilation::methodCannotBeRecompiled(void *oldStartPC, TR_FrontEnd * TR_PersistentJittedBodyInfo *bodyInfo = getJittedBodyInfoFromPC(oldStartPC); TR_PersistentMethodInfo *methodInfo = bodyInfo->getMethodInfo(); - if (bodyInfo->getUsesPreexistence() - || methodInfo->hasBeenReplaced() - || (usesSampling && ! fej9->isAsyncCompilation()) // go interpreted for failed recomps in sync mode - || methodInfo->isExcludedPostRestore()) // go interpreted if method is excluded post restore + if ((usesSampling && !fej9->isAsyncCompilation()) // failed recomps in sync mode + || bodyInfo->getIsInvalidated()) { // We need to switch the method to interpreted. Change the first instruction of the // method to jump back to the call to the interpreter dispatch diff --git a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp index f7c2f4df107..d127830d7e7 100644 --- a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp @@ -4776,6 +4776,18 @@ J9::Z::TreeEvaluator::newArrayEvaluator(TR::Node * node, TR::CodeGenerator * cg) return TR::TreeEvaluator::VMnewEvaluator(node, cg); } + +static TR::Instruction* +genMemoryZeroingLoop(TR::CodeGenerator* cg, TR::Node* node, TR::Instruction*& iCursor, TR::Register * addressReg, TR::Register * loopIterRegsiter, bool use64bitLoop = false) + { + TR::LabelSymbol * loopStartLabel = generateLabelSymbol(cg); + iCursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, loopStartLabel, iCursor); + iCursor = generateSS1Instruction(cg, TR::InstOpCode::XC, node, 255, generateS390MemoryReference(addressReg, 0, cg), generateS390MemoryReference(addressReg, 0, cg), iCursor); + iCursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, addressReg, generateS390MemoryReference(addressReg, 256, cg), iCursor); + iCursor = generateS390BranchInstruction(cg, use64bitLoop ? TR::InstOpCode::BRCTG : TR::InstOpCode::BRCT, node, loopIterRegsiter, loopStartLabel, iCursor); + return iCursor; + } + /////////////////////////////////////////////////////////////////////////////////////// // newArrayEvaluator: new array of objects /////////////////////////////////////////////////////////////////////////////////////// @@ -4788,341 +4800,300 @@ J9::Z::TreeEvaluator::anewArrayEvaluator(TR::Node * node, TR::CodeGenerator * cg return TR::TreeEvaluator::VMnewEvaluator(node, cg); } -/////////////////////////////////////////////////////////////////////////////////////// -// multianewArrayEvaluator: multi-dimensional new array of objects -// NB Must only be used for arrays of at least two dimensions -/////////////////////////////////////////////////////////////////////////////////////// -static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node, TR::CodeGenerator *cg) +/** + * \brief + * Inline allocation of multi dimensional new array. + * + * \details + * Allocate multi dimensional new arrays of any type with inline instructions if the size is within the range of TLH. + * This helper method is currently supported on 64bit systems with Z196 or higher CPU version and allocates + * any non negative size two dimensional array if it fits inside the TLH. + * + * \param node + * The multianewarray node. + * + * \param cg + * The CodeGenerator objec. + * + * \param componentSize + * The leaf array component size. + * + * \return + * Register that holds new object. + */ +static TR::Register * generateMultianewArrayWithInlineAllocators(TR::Node *node, TR::CodeGenerator *cg, int32_t componentSize) { #define iComment(str) if (compDebug) compDebug->addInstructionComment(cursor, (const_cast(str))); TR::Compilation *comp = cg->comp(); TR_Debug *compDebug = comp->getDebug(); - TR_ASSERT_FATAL(comp->target().is64Bit(), "multianewArrayEvaluator is only supported on 64-bit JVMs!"); TR_J9VMBase *fej9 = comp->fej9(); - TR::Register *targetReg = cg->allocateRegister(); TR::Instruction *cursor = NULL; + int32_t elementSize = TR::Compiler->om.sizeofReferenceField(); - TR::Node *firstChild = node->getFirstChild(); - TR::Node *secondChild = node->getSecondChild(); - TR::Node *thirdChild = node->getThirdChild(); - - TR::LabelSymbol *cFlowRegionStart = generateLabelSymbol(cg); - TR::LabelSymbol *nonZeroFirstDimLabel = generateLabelSymbol(cg); - TR::LabelSymbol *cFlowRegionDone = generateLabelSymbol(cg); - TR::LabelSymbol *oolFailLabel = generateLabelSymbol(cg); - - // oolJumpLabel is a common point that all branches will jump to. From this label, we branch to OOL code. - // We do this instead of jumping directly to OOL code from mainline because the RA can only handle the case where there's - // a single jump point to OOL code. - TR::LabelSymbol *oolJumpLabel = generateLabelSymbol(cg); - - cFlowRegionStart->setStartInternalControlFlow(); - cFlowRegionDone->setEndInternalControlFlow(); - - generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionStart); - - TR::Register *dimsPtrReg = cg->evaluate(firstChild); - TR::Register *dimReg = cg->evaluate(secondChild); - TR::Register *classReg = cg->evaluate(thirdChild); - - /* In the mainline, first load the first and second dimensions' lengths into registers. - * - * LGF is used instead of L so that array size register can be used to NULL dataAddr - * field for 0-size arrays. dataAddr field is 64 bits whereas size field is 32 bits so - * we need LGF to clear upper 32 bits of the register. - */ - TR::Register *firstDimLenReg = cg->allocateRegister(); - cursor = generateRXInstruction(cg, TR::InstOpCode::LGF, node, firstDimLenReg, generateS390MemoryReference(dimsPtrReg, 4, cg)); - iComment("Load 1st dim length."); - - TR::Register *secondDimLenReg = cg->allocateRegister(); - cursor = generateRXInstruction(cg, TR::InstOpCode::LGF, node, secondDimLenReg, generateS390MemoryReference(dimsPtrReg, 0, cg)); - iComment("Load 2nd dim length."); - - // Check to see if second dimension is indeed 0. If yes, then proceed to handle the case here. Otherwise jump to OOL code. - cursor = generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::CL, node, secondDimLenReg, 0, TR::InstOpCode::COND_BNE, oolJumpLabel, false); - iComment("if 2nd dim is 0, we handle it here. Else, jump to oolJumpLabel."); + TR_ASSERT_FATAL(comp->target().is64Bit(), "multianewArrayEvaluator is only supported on 64-bit JVMs!"); + int32_t numDimensions = node->getSecondChild()->get32bitIntegralValue(); - // Now check to see if first dimension is also 0. If yes, continue below to handle the case when length for both dimensions is 0. Otherwise jump to nonZeroFirstDimLabel. - cursor = generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::CL, node, firstDimLenReg, 0, TR::InstOpCode::COND_BNE, nonZeroFirstDimLabel, false); - iComment("if 1st dim is also 0, we handle it here. Else, jump to nonZeroFirstDimLabel."); + TR_ASSERT_FATAL(numDimensions == 2, "Can not allocate %d dimensional arrays!", numDimensions); - // First dimension zero, so only allocate 1 zero-length object array - TR::Register *vmThreadReg = cg->getMethodMetaDataRealRegister(); - generateRXInstruction(cg, TR::InstOpCode::LG, node, targetReg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapAlloc), cg)); + TR_ASSERT_FATAL(comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196), "Inlining of multianewarrays with 2 dimensions is only supported on z196 or newer."); - // Take into account alignment requirements for the size of the zero-length array header - int32_t zeroArraySizeAligned = OMR::align(TR::Compiler->om.discontiguousArrayHeaderSizeInBytes(), TR::Compiler->om.getObjectAlignmentInBytes()); + TR_ASSERT_FATAL((componentSize == 1 || componentSize == 2 || componentSize == 4 || componentSize == 8), + "Received componentSize= %d is not valid!", componentSize); - // Branch to OOL if there's not enough space for an array of size 0. - TR::Register *temp1Reg = cg->allocateRegister(); - if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)) - { - generateRIEInstruction(cg, TR::InstOpCode::AGHIK, node, temp1Reg, targetReg, zeroArraySizeAligned); - } - else + if (comp->getOption(TR_TraceCG)) { - generateRRInstruction(cg, TR::InstOpCode::LGR, node, temp1Reg, targetReg); - generateRILInstruction(cg, TR::InstOpCode::AGFI, node, temp1Reg, zeroArraySizeAligned); + traceMsg(comp, "Inline allocation for multianewarray with element size: %d and leaf component size: %d", elementSize, componentSize); } - generateRXInstruction(cg, TR::InstOpCode::CLG, node, temp1Reg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapTop), cg)); - cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BH, node, oolJumpLabel); - iComment("Branch to oolJumpLabel if there isn't enough space for a 0 size array."); - - // If there's enough space, then we can continue to allocate. - generateRXInstruction(cg, TR::InstOpCode::STG, node, temp1Reg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapAlloc), cg)); - - bool use64BitClasses = comp->target().is64Bit() && !TR::Compiler->om.generateCompressedObjectHeaders(); - - generateRXInstruction(cg, use64BitClasses ? TR::InstOpCode::STG : TR::InstOpCode::ST, node, classReg, generateS390MemoryReference(targetReg, TR::Compiler->om.offsetOfObjectVftField(), cg)); + /********************************************* Register setup *********************************************/ + TR::Register *dimsPtrReg = cg->evaluate(node->getFirstChild()); + TR::Register *sizeReg = cg->allocateRegister(); + TR::RegisterDependencyConditions *dependencies = generateRegisterDependencyConditions(0,7,cg); + dependencies->addPostCondition(sizeReg, TR::RealRegister::AssignAny); + dependencies->addPostCondition(dimsPtrReg, TR::RealRegister::AssignAny); -#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) - bool isOffHeapAllocationEnabled = TR::Compiler->om.isOffHeapAllocationEnabled(); -#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */ + /********************************************* Calculate size *********************************************/ + int32_t alignmentConstant = TR::Compiler->om.getObjectAlignmentInBytes(); + cursor = generateRIInstruction(cg, TR::InstOpCode::LGHI, node, sizeReg, + OMR::align(TR::Compiler->om.discontiguousArrayHeaderSizeInBytes(), alignmentConstant), cursor); + iComment("Load discontinuous array size."); - static char * disableBatchClear = feGetEnv("TR_DisableBatchClear"); - // If batch clear is disabled, set element's size and mustBeZero fields to 0 - if (disableBatchClear) - { - // Zero size arrays are considered "discontiguous" and the "mustBeZero" field of discontiguous arrays must be located where the "size" field of contiguous arrays is. - // With this design, we can check the size of an array as if it is contiguous, if the size is not zero then array is contiguous otherwise it is discontiguous. - // Check runtime/oti/j9nonbuilder.h for layout details. Simplified layout would look like: - // Discontiguous array layout: | class | mustBeZero | size | ... - // Contiguous array layout: | class | size | ... - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, firstDimLenReg, generateS390MemoryReference(targetReg, fej9->getOffsetOfContiguousArraySizeField()/* = "mustBeZero" offset!*/, cg)); - iComment("Init 1st dim mustBeZero field."); - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, firstDimLenReg, generateS390MemoryReference(targetReg, fej9->getOffsetOfDiscontiguousArraySizeField(), cg)); - iComment("Init 1st dim size field."); - if (TR::Compiler->om.compressObjectReferences()) + if (node->getSecondChild()->getReferenceCount() > 1) { - // Clear padding in Discontiguous array header layout. Since size field is 4 bytes wide, adding 4 to size field gets us to the padding. - cursor = generateSILInstruction(cg, TR::InstOpCode::MVHI, node, generateS390MemoryReference(targetReg, fej9->getOffsetOfDiscontiguousArraySizeField() + 4, cg), 0); - iComment("Clear padding."); - } - -#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) - if (isOffHeapAllocationEnabled) - { - // Since 1st dimension is 0 length, we can use firstDimLenReg to clear - // dataAddr field. secondDimLenReg is expected to be NULL at this point. - cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, firstDimLenReg, generateS390MemoryReference(targetReg, fej9->getOffsetOfDiscontiguousDataAddrField(), cg)); - iComment("Clear 1st dim dataAddr field."); - } -#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */ + TR::Register *dimReg = cg->evaluate(node->getSecondChild()); } + TR::Register *classReg = cg->gprClobberEvaluate(node->getThirdChild()); + dependencies->addPostCondition(classReg, TR::RealRegister::AssignAny); - cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, cFlowRegionDone); - iComment("Init class field and jump."); - - // We end up in this region of the ICF if the first dimension is non-zero and the second dimension is zero. - cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, nonZeroFirstDimLabel); - iComment("nonZeroFirstDimLabel, 2nd dim length is 0."); - - TR::Register *componentClassReg = cg->allocateRegister(); - generateRXInstruction(cg, TR::InstOpCode::LG, node, componentClassReg, generateS390MemoryReference(classReg, offsetof(J9ArrayClass, componentType), cg)); + TR::Register *dim1SizeReg = cg->allocateRegister(); + dependencies->addPostCondition(dim1SizeReg, TR::RealRegister::AssignAny); + cursor = generateRXInstruction(cg, TR::InstOpCode::LTGF, node, dim1SizeReg, generateS390MemoryReference(dimsPtrReg, 4, cg)); + iComment("Load 1st dim length."); - // Calculate maximum allowable object size in elements and jump to OOL if firstDimLenReg is higher than it. - int32_t elementSize = TR::Compiler->om.sizeofReferenceField(); - uintptr_t maxObjectSize = cg->getMaxObjectSizeGuaranteedNotToOverflow(); - uintptr_t maxObjectSizeInElements = maxObjectSize / elementSize; - cursor = generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::CL, node, firstDimLenReg, static_cast(maxObjectSizeInElements), TR::InstOpCode::COND_BHR, oolJumpLabel, false); - iComment("Jump to oolJumpLabel if 1st dim len > the num of elements a block can fit."); - - // Now check to see if we have enough space to do the allocation. If not then jump to OOL code. - int32_t elementSizeAligned = OMR::align(elementSize, TR::Compiler->om.getObjectAlignmentInBytes()); - int32_t alignmentCompensation = (elementSize == elementSizeAligned) ? 0 : elementSizeAligned - 1; - static const uint8_t multiplierToStrideMap[] = {0, 0, 1, 0, 2, 0, 0, 0, 3}; - TR_ASSERT_FATAL(elementSize <= 8, "multianewArrayEvaluator - elementSize cannot be greater than 8!"); - generateRSInstruction(cg, TR::InstOpCode::SLLG, node, temp1Reg, firstDimLenReg, multiplierToStrideMap[elementSize]); - generateRILInstruction(cg, TR::InstOpCode::AGFI, node, temp1Reg, static_cast(TR::Compiler->om.contiguousArrayHeaderSizeInBytes()) + alignmentCompensation); - - if (alignmentCompensation != 0) - { - generateRILInstruction(cg, TR::InstOpCode::NILF, node, temp1Reg, -elementSizeAligned); - } - - TR::Register *temp2Reg = cg->allocateRegister(); - generateRRInstruction(cg, TR::InstOpCode::LGR, node, temp2Reg, firstDimLenReg); - generateRILInstruction(cg, TR::InstOpCode::MSGFI, node, temp2Reg, zeroArraySizeAligned); - - cursor = generateRRInstruction(cg, TR::InstOpCode::AGR, node, temp2Reg, temp1Reg); - iComment("Calculates (firstDimLen * zeroArraySizeAligned) + (arrayStrideInBytes + arrayHeaderSize)"); - - generateRXInstruction(cg, TR::InstOpCode::LG, node, targetReg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapAlloc), cg)); - generateRRInstruction(cg, TR::InstOpCode::AGR, node, temp2Reg, targetReg); - generateRXInstruction(cg, TR::InstOpCode::CLG, node, temp2Reg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapTop), cg)); - - cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BH, node, oolJumpLabel); - iComment("Branch to oolJumpLabel if we don't have enough space for both 1st and 2nd dim."); - - // We have enough space, so proceed with the allocation. - generateRXInstruction(cg, TR::InstOpCode::STG, node, temp2Reg, generateS390MemoryReference(vmThreadReg, offsetof(J9VMThread, heapAlloc), cg)); - - // Init 1st dim array class and size fields. - cursor = generateRXInstruction(cg, use64BitClasses ? TR::InstOpCode::STG : TR::InstOpCode::ST, node, classReg, generateS390MemoryReference(targetReg, TR::Compiler->om.offsetOfObjectVftField(), cg)); - iComment("Init 1st dim class field."); - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, firstDimLenReg, generateS390MemoryReference(targetReg, fej9->getOffsetOfContiguousArraySizeField(), cg)); - iComment("Init 1st dim size field."); - if (!TR::Compiler->om.compressObjectReferences()) - { - // Clear padding in contiguous array header layout. Since size field is 4 bytes wide, adding 4 to size field gets us to the padding. - cursor = generateSILInstruction(cg, TR::InstOpCode::MVHI, node, generateS390MemoryReference(targetReg, fej9->getOffsetOfContiguousArraySizeField() + 4, cg), 0); - iComment("Clear padding."); - } - - TR::Register *temp3Reg = NULL; - #if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) - if (isOffHeapAllocationEnabled) - { - temp3Reg = cg->allocateRegister(); - // Populate dataAddr slot of 1st dimension array. We don't need to worry - // about zero length array since it has already been taken care of. - generateRXInstruction(cg, - TR::InstOpCode::getLoadAddressOpCode(), - node, - temp3Reg, - generateS390MemoryReference(targetReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg)); - cursor = generateRXInstruction(cg, - TR::InstOpCode::getStoreOpCode(), - node, - temp3Reg, - generateS390MemoryReference(targetReg, fej9->getOffsetOfContiguousDataAddrField(), cg)); - iComment("populateFirstDimDataAddrSlot."); - } - #endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */ - // temp2 point to end of 1st dim array i.e. start of 2nd dim - generateRRInstruction(cg, TR::InstOpCode::LGR, node, temp2Reg, targetReg); - generateRRInstruction(cg, TR::InstOpCode::AGR, node, temp2Reg, temp1Reg); - if (cg->comp()->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196)) - { - generateRIEInstruction(cg, TR::InstOpCode::AGHIK, node, temp1Reg, targetReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes()); + // Start of the internal control flow. + TR::LabelSymbol *controlFlowStartLabel = generateLabelSymbol(cg); + controlFlowStartLabel->setStartInternalControlFlow(); + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, controlFlowStartLabel, cursor); + // If first dimension length is zero, there is only one discontiguous array for dim 1. + // Zero size arrays are considered "discontiguous" and the "mustBeZero" field of discontiguous arrays must be located where the + // "size" field of contiguous arrays is. + // To handle zero length arrays, discontiguous header size is loaded in size register so we can bypass the size calculation if + // the length is zero. Otherwise, the size is calculated and overwrite the value in size register. + // Check runtime/oti/j9nonbuilder.h for layout details. Simplified layout would look like: + // Discontiguous array layout: | class | mustBeZero | size | ... + // Contiguous array layout: | class | size | ... + TR::LabelSymbol *heapTopTestLabel = generateLabelSymbol(cg); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, heapTopTestLabel, cursor); + // Make sure first dim length is not negative. + TR::LabelSymbol *inlineAllocFailLabel = generateLabelSymbol(cg); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BL, node, inlineAllocFailLabel, cursor); + + TR::Register *dim2SizeReg = cg->allocateRegister(); + dependencies->addPostCondition(dim2SizeReg, TR::RealRegister::AssignAny); + cursor = generateRXInstruction(cg, TR::InstOpCode::LTGF, node, dim2SizeReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor); + iComment("Load 2st dim length."); + // The size of zero length array is already loaded in size register. Jump over the array size calculation instructions if length is 0. + TR::LabelSymbol *zeroSecondDimLabel = generateLabelSymbol(cg); + + if (componentSize == 1) + { + // Load int32 second dim length to a 64 bit register and set condition mask. + cursor = generateRXInstruction(cg, TR::InstOpCode::LTGF, node, dim2SizeReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor); + iComment("Load 2st dim length."); } else { - generateRRInstruction(cg, TR::InstOpCode::LGR, node, temp1Reg, targetReg); - generateRILInstruction(cg, TR::InstOpCode::AGFI, node, temp1Reg, static_cast(TR::Compiler->om.contiguousArrayHeaderSizeInBytes())); - } - - // Loop start - TR::LabelSymbol *loopLabel = generateLabelSymbol(cg); - cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, loopLabel); - iComment("loopLabel: init 2nd dim's class field."); - - // Init 2nd dim element's class - cursor = generateRXInstruction(cg, use64BitClasses ? TR::InstOpCode::STG : TR::InstOpCode::ST, node, componentClassReg, generateS390MemoryReference(temp2Reg, TR::Compiler->om.offsetOfObjectVftField(), cg)); - iComment("Init 2nd dim class field."); - - // If batch clear is disabled, set element's size and mustBeZero ('0') fields to 0 - if (disableBatchClear) - { - // Similar to the previous case when the first dimension length is zero. - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, secondDimLenReg, generateS390MemoryReference(temp2Reg, fej9->getOffsetOfContiguousArraySizeField()/* = "mustBeZero" offset!*/, cg)); - iComment("Init 2st dim mustBeZero field."); - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, secondDimLenReg, generateS390MemoryReference(temp2Reg, fej9->getOffsetOfDiscontiguousArraySizeField(), cg)); - iComment("Init 2st dim size field."); - if (TR::Compiler->om.compressObjectReferences()) - { - // Clear padding in Discontiguous array header layout. Since size field is 4 bytes wide, adding 4 to size field gets us to the padding. - cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, secondDimLenReg, generateS390MemoryReference(temp2Reg, fej9->getOffsetOfDiscontiguousArraySizeField() + 4, cg)); - iComment("Clear padding."); - } - -#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION) - if (isOffHeapAllocationEnabled) - { - // Since 2nd dimension array is 0 length, we can use secondDimLenReg - // to clear dataAddr field. secondDimLenReg is expected to be NULL - // at this point. - cursor = generateRXInstruction(cg, TR::InstOpCode::getStoreOpCode(), node, secondDimLenReg, generateS390MemoryReference(temp2Reg, fej9->getOffsetOfDiscontiguousDataAddrField(), cg)); - iComment("Clear 2nd dim dataAddr field."); - } -#endif /* J9VM_GC_SPARSE_HEAP_ALLOCATION */ - } - - if (NULL == temp3Reg) - temp3Reg = cg->allocateRegister(); - - // Store 2nd dim element into 1st dim array slot, compress temp2 if needed - if (comp->target().is64Bit() && comp->useCompressedPointers()) + // Load int32 second dim length to a 64 bit register. + cursor = generateRXInstruction(cg, TR::InstOpCode::LGF, node, dim2SizeReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor); + iComment("Load 2st dim length."); + // By using SLA, we can make sure that the size of all elements (length * component size) in the leaf array is positive and + // within INT32_MAX range. It limits the allocation size but simplifies the instruction selection and guarantee no overflow + // in the following instructions. Assuming allocation of 2D arrays with leaf size > INT32_MAX and having large enough TLH to + // allocate inline is not frequent. + cursor = generateRSInstruction(cg, TR::InstOpCode::SLA, node, dim2SizeReg, trailingZeroes(componentSize), cursor); + } + // Bypass dim2 size calculation if the size is zero. + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, zeroSecondDimLabel, cursor); + // Call helper if the length is negative or length * componentSize is larger that INT32_MAX (overflow). + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK5, node, inlineAllocFailLabel, cursor); + + int32_t headerSize= TR::Compiler->om.contiguousArrayHeaderSizeInBytes(); + // size = (size + alignmentConstant - 1) & -alignmentConstant equation round up the size to a factor of alignmentConstant. + bool alignSecondDim = !(OMR::aligned(headerSize, alignmentConstant) && OMR::aligned(componentSize, alignmentConstant)); + cursor = generateRIInstruction(cg, TR::InstOpCode::AGHI, node, dim2SizeReg, alignSecondDim ? (headerSize + alignmentConstant - 1) : headerSize, cursor); + if (alignSecondDim) + cursor = generateRIInstruction(cg, TR::InstOpCode::NILL, node, dim2SizeReg, -alignmentConstant, cursor); + cursor = generateRRInstruction(cg, TR::InstOpCode::LGR, node, sizeReg, dim2SizeReg, cursor); + + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, zeroSecondDimLabel, cursor); + // If jumping from zero second dim match, set second dim size to discontiguous. Otherwise this wont change values. + cursor = generateRRInstruction(cg, TR::InstOpCode::LGR, node, dim2SizeReg, sizeReg, cursor); + // Total size = (second dim size * number of second dim arrays) + first dim size. + // We limited the leaf array size to int32 when converted the length to size so no overflow is possible here. + cursor = generateRREInstruction(cg, TR::InstOpCode::MSGR, node, sizeReg, dim1SizeReg, cursor); + + // Size = (element size * dimension length) + header size. final size must get aligned. + cursor = generateRSInstruction(cg, TR::InstOpCode::SLLG, node, dim1SizeReg, dim1SizeReg, trailingZeroes(elementSize), cursor); + bool alignFirstDim = !(OMR::aligned(headerSize, alignmentConstant) && OMR::aligned(elementSize, alignmentConstant)); + cursor = generateRIInstruction(cg, TR::InstOpCode::AGHI, node, dim1SizeReg, alignFirstDim ? (headerSize + alignmentConstant - 1) : headerSize, cursor); + if (alignFirstDim) + cursor = generateRIInstruction(cg, TR::InstOpCode::NILL, node, dim1SizeReg, -alignmentConstant, cursor); + + // Add first dimension array size to sizeReg. Can not overflow. + cursor = generateRREInstruction(cg, TR::InstOpCode::ALGR, node, sizeReg, dim1SizeReg, cursor); + iComment("Total size in sizeReg."); + + /********************************************* heap top test *********************************************/ + bool allocateFromNonZeroHeap = !comp->getOption(TR_DisableDualTLH) && node->canSkipZeroInitialization(); + int32_t heapAllocOffset = allocateFromNonZeroHeap ? offsetof(J9VMThread, nonZeroHeapAlloc) : offsetof(J9VMThread, heapAlloc); + int32_t heapTopOffset = allocateFromNonZeroHeap ? offsetof(J9VMThread, nonZeroHeapTop) : offsetof(J9VMThread, heapTop); + TR::Register *resultReg = cg->allocateRegister(); + dependencies->addPostCondition(resultReg, TR::RealRegister::AssignAny); + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, heapTopTestLabel, cursor); + TR::Register *vmThreadReg = cg->getMethodMetaDataRealRegister(); + cursor = generateRXInstruction(cg, TR::InstOpCode::LG, node, resultReg, generateS390MemoryReference(vmThreadReg, heapAllocOffset, cg), cursor); + iComment("Set result reg."); + cursor = generateRREInstruction(cg, TR::InstOpCode::ALGR, node, sizeReg, resultReg, cursor); + // Only a positive number with no overflow is acceptable. + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_MASK11, node, inlineAllocFailLabel, cursor); + cursor = generateRXInstruction(cg, TR::InstOpCode::CLG, node, sizeReg, generateS390MemoryReference(vmThreadReg, heapTopOffset, cg), cursor); + + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BH, node, inlineAllocFailLabel, cursor); + + /********************************************* Allocate Object *********************************************/ + // Update heap alloc. + cursor = generateRXInstruction(cg, TR::InstOpCode::STG, node, sizeReg, generateS390MemoryReference(vmThreadReg, heapAllocOffset, cg), cursor); + iComment("Heap top test pass. Update heap alloc."); + TR::Register *scratchReg = cg->allocateRegister(); + dependencies->addPostCondition(scratchReg, TR::RealRegister::AssignAny); + + /********************************************* Zero initialize memory *********************************************/ + static bool disableBatchClear = feGetEnv("TR_DisableBatchClear") != NULL; + bool needInitialization = disableBatchClear && !node->canSkipZeroInitialization(); + if (needInitialization) + { + cursor = generateRREInstruction(cg, TR::InstOpCode::SLGR, node, sizeReg, resultReg, cursor); + iComment("start memory initialization."); + // Subtract 1 to make up for XC instruction length field. + cursor = generateRIInstruction(cg, TR::InstOpCode::AGHI, node, sizeReg, -1, cursor); + // Calculate the number of iterations. + cursor = generateRSInstruction(cg, TR::InstOpCode::SRAG, node, scratchReg, sizeReg, 8, cursor); + TR::LabelSymbol *initResedualBytesLabel = generateLabelSymbol(cg); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BZ, node, initResedualBytesLabel, cursor); + // Initialize 256 blocks. + cursor = genMemoryZeroingLoop(cg, node, cursor, resultReg, scratchReg, true /* use64bitLoop */); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_B, node, initResedualBytesLabel, cursor); + + TR::LabelSymbol *memoryInitializationExrlTargetLabel = generateLabelSymbol(cg); + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, memoryInitializationExrlTargetLabel, cursor); + cursor = generateSS1Instruction(cg, TR::InstOpCode::XC, node, 0, generateS390MemoryReference(resultReg, 0, cg), + generateS390MemoryReference(resultReg, 0, cg), cursor); + // Initialize the leftover bytes. + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, initResedualBytesLabel, cursor); + cursor = generateRILInstruction(cg, TR::InstOpCode::EXRL, node, sizeReg, memoryInitializationExrlTargetLabel, cursor); + // Recover resultReg. + cursor = generateRIInstruction(cg, TR::InstOpCode::NILL, node, sizeReg, 0xff00, cursor); + cursor = generateRREInstruction(cg, TR::InstOpCode::SLGR, node, resultReg, sizeReg, cursor); + } + + /********************************************* First dimesion class and length *********************************************/ + // Load first dim length in lower 32bits and second dim length in higher 32bits. + cursor = generateRXInstruction(cg, TR::InstOpCode::LG, node, scratchReg, generateS390MemoryReference(dimsPtrReg, 0, cg), cursor); + iComment("Start first dim alloc"); + // Fist dim class and length: + bool compressedObjectHeaders = TR::Compiler->om.generateCompressedObjectHeaders(); + cursor = generateRXInstruction(cg, compressedObjectHeaders ? TR::InstOpCode::ST : TR::InstOpCode::STG, node, classReg, + generateS390MemoryReference(resultReg, static_cast(TR::Compiler->om.offsetOfObjectVftField()), cg), cursor); + cursor = generateRXInstruction(cg, TR::InstOpCode::ST, node, scratchReg, generateS390MemoryReference(resultReg, + static_cast(TR::Compiler->om.offsetOfContiguousArraySizeField()), cg), cursor); + + /********************************************* Add leaf arrays (Second dimension) *********************************************/ + // If number of leaf arrays is zero, jump to the end. + TR::LabelSymbol *controlFlowEndLabel = generateLabelSymbol(cg); + controlFlowEndLabel->setEndInternalControlFlow(); + cursor = generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::CL, node, scratchReg, 0, TR::InstOpCode::COND_BE, controlFlowEndLabel, false /* needsCC */, cursor); + + cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, dim1SizeReg, generateS390MemoryReference(dim1SizeReg, resultReg, 0, cg), cursor); + iComment("Load first leaf array address."); + // Load component class to class register. + cursor = generateRXInstruction(cg, TR::InstOpCode::LG, node, classReg, generateS390MemoryReference(classReg, offsetof(J9ArrayClass, componentType), cg), cursor); + + // Load the address of the first element of the first dimension array in sizeReg. + cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, sizeReg, + generateS390MemoryReference(resultReg, TR::Compiler->om.contiguousArrayHeaderSizeInBytes(), cg), cursor); + // Start setting second dim: + TR::LabelSymbol *secondDimLabel = generateLabelSymbol(cg); + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, secondDimLabel, cursor); + // Store the class field. + cursor = generateRXInstruction(cg, (compressedObjectHeaders ? TR::InstOpCode::ST : TR::InstOpCode::STG), node, classReg, + generateS390MemoryReference(dim1SizeReg, static_cast(TR::Compiler->om.offsetOfObjectVftField()), cg), cursor); + // Store the array length. + cursor = generateRXInstruction(cg, TR::InstOpCode::STFH, node, scratchReg, generateS390MemoryReference(dim1SizeReg, + static_cast(TR::Compiler->om.offsetOfContiguousArraySizeField()), cg), cursor); + int32_t shiftAmount = TR::Compiler->om.compressedReferenceShift(); + if (shiftAmount > 0) { - int32_t shiftAmount = TR::Compiler->om.compressedReferenceShift(); - generateRRInstruction(cg, TR::InstOpCode::LGR, node, temp3Reg, temp2Reg); - if (shiftAmount != 0) - { - generateRSInstruction(cg, TR::InstOpCode::SRAG, node, temp3Reg, temp3Reg, shiftAmount); - } - generateRXInstruction(cg, TR::InstOpCode::ST, node, temp3Reg, generateS390MemoryReference(temp1Reg, 0, cg)); + // Calculate the compressed reference of leaf array in the higher 32bits of dim2SizeReg. + cursor = generateRIEInstruction(cg, TR::InstOpCode::RISBG, node, dim2SizeReg, dim1SizeReg, 0, 31, 32-shiftAmount, cursor); + // Store the compressed 32 bit leaf address in the relevant element of the first dim array. + cursor = generateRXInstruction(cg, TR::InstOpCode::STFH, node, dim2SizeReg, generateS390MemoryReference(sizeReg, 0, cg), cursor); } else { - generateRXInstruction(cg, TR::InstOpCode::STG, node, temp2Reg, generateS390MemoryReference(temp1Reg, 0, cg)); + // Store the 32 bit leaf address in the relevant element of the first dim array. + cursor = generateRXInstruction(cg, (TR::Compiler->om.compressObjectReferences() ? TR::InstOpCode::ST : TR::InstOpCode::STG), node, dim1SizeReg, + generateS390MemoryReference(sizeReg, 0, cg), cursor); } - // Advance cursors temp1 and temp2. Then branch back or fall through if done. - generateRIInstruction(cg, TR::InstOpCode::AGHI, node, temp2Reg, zeroArraySizeAligned); - generateRIInstruction(cg, TR::InstOpCode::AGHI, node, temp1Reg, elementSize); - - generateRILInstruction(cg, TR::InstOpCode::SLFI, node, firstDimLenReg, 1); - generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::CL, node, firstDimLenReg, 0, TR::InstOpCode::COND_BNE, loopLabel, false); + // Load the next leaf address in dim1SizeReg. + cursor = generateRREInstruction(cg, TR::InstOpCode::ALGFR, node, dim1SizeReg, dim2SizeReg, cursor); + // Load the next element address of the first dim array in sizeReg. + cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, sizeReg, generateS390MemoryReference(sizeReg, elementSize, cg), cursor); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRCT, node, scratchReg, secondDimLabel, cursor); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_B, node, controlFlowEndLabel, cursor); + iComment("Allocation done!"); - generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, cFlowRegionDone); - - TR::RegisterDependencyConditions *dependencies = generateRegisterDependencyConditions(0,10,cg); - dependencies->addPostCondition(dimReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(secondDimLenReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(firstDimLenReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(targetReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(dimsPtrReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(temp1Reg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(classReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(componentClassReg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(temp2Reg, TR::RealRegister::AssignAny); - dependencies->addPostCondition(temp3Reg, TR::RealRegister::AssignAny); + TR::LabelSymbol *slowPathLabel = generateLabelSymbol(cg); + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, inlineAllocFailLabel, cursor); + cursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_B, node, slowPathLabel, cursor); - generateS390LabelInstruction(cg, TR::InstOpCode::label, node, oolJumpLabel); - generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, oolFailLabel); + /********************************************* Merge inline and helper results *********************************************/ + cursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, controlFlowEndLabel, dependencies, cursor); + // Can not have a collected reference register with unset value when helper is called. That would cause wrong GC register map. + TR::Register *collectedReferenceResultReg = cg->allocateCollectedReferenceRegister(); + cursor = generateRRInstruction(cg, TR::InstOpCode::LGR, node, collectedReferenceResultReg, resultReg, cursor); + iComment("Copy tmp result to final result."); - generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionDone, dependencies); - - TR::Register *targetRegisterFinal = cg->allocateCollectedReferenceRegister(); - generateRRInstruction(cg, TR::InstOpCode::LGR, node, targetRegisterFinal, targetReg); - - // Generate the OOL code before final bookkeeping. - TR_S390OutOfLineCodeSection *outlinedSlowPath = new (cg->trHeapMemory()) TR_S390OutOfLineCodeSection(oolFailLabel, cFlowRegionDone, cg); + /********************************************* OOL helper setup *********************************************/ + TR_S390OutOfLineCodeSection *outlinedSlowPath = new (cg->trHeapMemory()) TR_S390OutOfLineCodeSection(slowPathLabel, controlFlowEndLabel, cg); cg->getS390OutOfLineCodeSectionList().push_front(outlinedSlowPath); outlinedSlowPath->swapInstructionListsWithCompilation(); - generateS390LabelInstruction(cg, TR::InstOpCode::label, node, oolFailLabel); + generateS390LabelInstruction(cg, TR::InstOpCode::label, node, slowPathLabel); TR::ILOpCodes opCode = node->getOpCodeValue(); TR::Node::recreate(node, TR::acall); - TR::Register *targetReg2 = TR::TreeEvaluator::performCall(node, false, cg); + TR::Register *slowResultReg = TR::TreeEvaluator::performCall(node, false, cg); TR::Node::recreate(node, opCode); - generateRRInstruction(cg, TR::InstOpCode::LGR, node, targetReg, targetReg2); - generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, cFlowRegionDone); + generateRRInstruction(cg, TR::InstOpCode::LGR, node, resultReg, slowResultReg); + generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, controlFlowEndLabel); outlinedSlowPath->swapInstructionListsWithCompilation(); - // Note: We don't decrement the ref count node's children here (i.e. cg->decReferenceCount(node->getFirstChild())) because it is done by the performCall in the OOL code above. - // Doing so here would end up double decrementing the children nodes' ref count. + /********************************************* Done! *********************************************/ + cg->stopUsingRegister(sizeReg); + cg->stopUsingRegister(dim1SizeReg); + cg->stopUsingRegister(dim2SizeReg); + cg->stopUsingRegister(scratchReg); + cg->stopUsingRegister(resultReg); - cg->stopUsingRegister(targetReg); - cg->stopUsingRegister(firstDimLenReg); - cg->stopUsingRegister(secondDimLenReg); - cg->stopUsingRegister(temp1Reg); - cg->stopUsingRegister(temp2Reg); - cg->stopUsingRegister(temp3Reg); - cg->stopUsingRegister(componentClassReg); - - node->setRegister(targetRegisterFinal); - return targetRegisterFinal; + node->setRegister(collectedReferenceResultReg); + return collectedReferenceResultReg; #undef iComment } - /////////////////////////////////////////////////////////////////////////////////////// // Generate code for multianewarray -// Checks the number of dimensions. For 1 dimensional arrays call the helper, for >1 call +// Generating the inlined code for 2 dimensions; otherwise, generating helper call. // generateMultianewArrayWithInlineAllocators. /////////////////////////////////////////////////////////////////////////////////////// TR::Register * @@ -5135,12 +5106,17 @@ J9::Z::TreeEvaluator::multianewArrayEvaluator(TR::Node * node, TR::CodeGenerator // The number of dimensions should always be an iconst TR_ASSERT_FATAL(secondChild->getOpCodeValue() == TR::iconst, "dims of multianewarray must be iconst"); + uint32_t nDims = static_cast(secondChild->get32bitIntegralValue()); + + int32_t componentSize = TR::Compiler->om.getTwoDimensionalArrayComponentSize(node->getThirdChild()); - // Only generate inline code if nDims > 1 - uint32_t nDims = secondChild->get32bitIntegralValue(); - if (nDims > 1) + if ((nDims == 2) && (componentSize > 0) + && comp->target().cpu.isAtLeast(OMR_PROCESSOR_S390_Z196) + && !comp->suppressAllocationInlining() + // Temporarily disable inline allocation for offHeap. + && !TR::Compiler->om.isOffHeapAllocationEnabled()) { - return generateMultianewArrayWithInlineAllocators(node, cg); + return generateMultianewArrayWithInlineAllocators(node, cg, componentSize); } else { @@ -10304,15 +10280,6 @@ roundArrayLengthToObjectAlignment(TR::CodeGenerator* cg, TR::Node* node, TR::Ins } } -static void -genMemoryZeroingLoop(TR::CodeGenerator* cg, TR::Node* node, TR::Instruction*& iCursor, TR::Register * addressReg, TR::Register * loopIterRegsiter) - { - TR::LabelSymbol * loopStartLabel = generateLabelSymbol(cg); - iCursor = generateS390LabelInstruction(cg, TR::InstOpCode::label, node, loopStartLabel); - iCursor = generateSS1Instruction(cg, TR::InstOpCode::XC, node, 255, generateS390MemoryReference(addressReg, 0, cg), generateS390MemoryReference(addressReg, 0, cg), iCursor); - iCursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, addressReg, generateS390MemoryReference(addressReg, 256, cg), iCursor); - iCursor = generateS390BranchInstruction(cg, TR::InstOpCode::BRCT, node, loopIterRegsiter, loopStartLabel); - } static void genHeapAlloc(TR::Node * node, TR::Instruction *& iCursor, bool isVariableLen, TR::Register * enumReg, TR::Register * resReg, diff --git a/runtime/compiler/z/runtime/Recomp.cpp b/runtime/compiler/z/runtime/Recomp.cpp index b8ac23c8198..7dd882b60fa 100644 --- a/runtime/compiler/z/runtime/Recomp.cpp +++ b/runtime/compiler/z/runtime/Recomp.cpp @@ -312,10 +312,8 @@ J9::Recompilation::methodCannotBeRecompiled(void * oldStartPC, TR_FrontEnd * fe) patchAddr = (int32_t *) ((uint8_t *) oldStartPC + getJitEntryOffset(linkageInfo)); - if (bodyInfo->getUsesPreexistence() - || methodInfo->hasBeenReplaced() - || (linkageInfo->isSamplingMethodBody() && ! fej9->isAsyncCompilation()) // go interpreted for failed recomps in sync mode - || methodInfo->isExcludedPostRestore()) // go interpreted if method is excluded post restore + if ((linkageInfo->isSamplingMethodBody() && !fej9->isAsyncCompilation()) // failed recomps in sync mode + || bodyInfo->getIsInvalidated()) { bool usesSampling = linkageInfo->isSamplingMethodBody(); // We need to switch the method to interpreted. Change the first instruction of the diff --git a/runtime/include/j9memcategories.h b/runtime/include/j9memcategories.h index 4b8c1de37bb..6f249a052bc 100644 --- a/runtime/include/j9memcategories.h +++ b/runtime/include/j9memcategories.h @@ -80,7 +80,7 @@ #define J9MEM_CATEGORY_CLASSLIB_GUI_MEDIALIB 34 #define J9MEM_CATEGORY_CLASSLIB_FONT 35 #define J9MEM_CATEGORY_CLASSLIB_SOUND 36 -#define J9MEM_CATEGORY_UNUSED37 37 +#define J9MEM_CATEGORY_JFR 37 #define J9MEM_CATEGORY_SUN_MISC_UNSAFE_ALLOCATEDBB 38 #define J9MEM_CATEGORY_MODULES 39 diff --git a/runtime/j9vm/exports.cmake b/runtime/j9vm/exports.cmake index 268f0a1685c..494eeeab857 100644 --- a/runtime/j9vm/exports.cmake +++ b/runtime/j9vm/exports.cmake @@ -517,13 +517,14 @@ endif() if(J9VM_OPT_VALHALLA_VALUE_TYPES) jvm_add_exports(jvm + JVM_CopyOfSpecialArray + JVM_IsAtomicArray JVM_IsFlatArray - JVM_IsImplicitlyConstructibleClass JVM_IsNullRestrictedArray JVM_IsValhallaEnabled JVM_NewNullableAtomicArray - JVM_NewNullRestrictedArray JVM_NewNullRestrictedAtomicArray + JVM_NewNullRestrictedNonAtomicArray JVM_VirtualThreadHideFrames ) endif() diff --git a/runtime/j9vm/j9memcategories.c b/runtime/j9vm/j9memcategories.c index d9ce7b73d32..b101d462402 100644 --- a/runtime/j9vm/j9memcategories.c +++ b/runtime/j9vm/j9memcategories.c @@ -41,15 +41,15 @@ OMRMEM_CATEGORY_4_CHILDREN("JRE", J9MEM_CATEGORY_JRE, OMRMEM_CATEGORY_VM, OMRMEM_CATEGORY_JIT, J9MEM_CATEGORY_CLASS_LIBRARIES, OMRMEM_CATEGORY_UNKNOWN); #if JAVA_SPEC_VERSION >= 16 #if defined(OMR_OPT_CUDA) -OMRMEM_CATEGORY_10_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_CUDA, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_VM_FFI); +OMRMEM_CATEGORY_11_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_CUDA, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_VM_FFI, J9MEM_CATEGORY_JFR); #else /* OMR_OPT_CUDA */ -OMRMEM_CATEGORY_9_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_VM_FFI); +OMRMEM_CATEGORY_10_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_VM_FFI, J9MEM_CATEGORY_JFR); #endif /* OMR_OPT_CUDA */ #else /* JAVA_SPEC_VERSION >= 16 */ #if defined(OMR_OPT_CUDA) -OMRMEM_CATEGORY_9_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_CUDA, OMRMEM_CATEGORY_PORT_LIBRARY); +OMRMEM_CATEGORY_10_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_CUDA, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_JFR); #else /* OMR_OPT_CUDA */ -OMRMEM_CATEGORY_8_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_PORT_LIBRARY); +OMRMEM_CATEGORY_9_CHILDREN("VM", OMRMEM_CATEGORY_VM, J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_MODULES, OMRMEM_CATEGORY_MM, OMRMEM_CATEGORY_THREADS, OMRMEM_CATEGORY_TRACE, J9MEM_CATEGORY_JVMTI, J9MEM_CATEGORY_JNI, OMRMEM_CATEGORY_PORT_LIBRARY, J9MEM_CATEGORY_JFR); #endif /* OMR_OPT_CUDA */ #endif /* JAVA_SPEC_VERSION >= 16 */ OMRMEM_CATEGORY_1_CHILD("Classes", J9MEM_CATEGORY_CLASSES, J9MEM_CATEGORY_CLASSES_SHC_CACHE); @@ -95,6 +95,7 @@ OMRMEM_CATEGORY_NO_CHILDREN("CUDA", OMRMEM_CATEGORY_CUDA); #if JAVA_SPEC_VERSION >= 16 OMRMEM_CATEGORY_NO_CHILDREN("Foreign Linker API", J9MEM_CATEGORY_VM_FFI); #endif /* JAVA_SPEC_VERSION >= 16 */ +OMRMEM_CATEGORY_NO_CHILDREN("Java Flight Recorder", J9MEM_CATEGORY_JFR); static OMRMemCategory * categories[] = { CATEGORY_TABLE_ENTRY(J9MEM_CATEGORY_JRE), @@ -140,6 +141,7 @@ CATEGORY_TABLE_ENTRY(OMRMEM_CATEGORY_CUDA), #if JAVA_SPEC_VERSION >= 16 CATEGORY_TABLE_ENTRY(J9MEM_CATEGORY_VM_FFI), #endif /* JAVA_SPEC_VERSION >= 16 */ +CATEGORY_TABLE_ENTRY(J9MEM_CATEGORY_JFR), /* Only NULLs allowed from now on and resetThreadCategories below must be updated if any new NULLs are added. * New static categories must be added before the NULLs. diff --git a/runtime/j9vm/valhallavmi.cpp b/runtime/j9vm/valhallavmi.cpp index 271d68b8e08..8eb2977632b 100644 --- a/runtime/j9vm/valhallavmi.cpp +++ b/runtime/j9vm/valhallavmi.cpp @@ -20,42 +20,29 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 *******************************************************************************/ +#include #include #include "j9.h" #include "VMHelpers.hpp" extern "C" { + #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) -JNIEXPORT jboolean JNICALL -JVM_IsValhallaEnabled() + +JNIEXPORT jarray JNICALL +JVM_CopyOfSpecialArray(JNIEnv *env, jarray orig, jint from, jint to) { - return JNI_TRUE; + assert(!"JVM_CopyOfSpecialArray unimplemented"); } JNIEXPORT jboolean JNICALL -JVM_IsImplicitlyConstructibleClass(JNIEnv *env, jclass cls) +JVM_IsAtomicArray(JNIEnv *env, jobject obj) { - jboolean result = JNI_FALSE; - J9VMThread *currentThread = (J9VMThread *)env; - J9InternalVMFunctions const * const vmFuncs = currentThread->javaVM->internalVMFunctions; - vmFuncs->internalEnterVMFromJNI(currentThread); - if (NULL == cls) { - vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, NULL); - } else { - J9Class *clazz = J9VM_J9CLASS_FROM_JCLASS(currentThread, cls); - J9ROMClass *romClass = clazz->romClass; - if (J9_ARE_ALL_BITS_SET(romClass->optionalFlags, J9_ROMCLASS_OPTINFO_IMPLICITCREATION_ATTRIBUTE) - && J9_ARE_ALL_BITS_SET(getImplicitCreationFlags(romClass), J9AccImplicitCreateHasDefaultValue) - ) { - result = JNI_TRUE; - } - } - vmFuncs->internalExitVMToJNI(currentThread); - return result; + assert(!"JVM_IsAtomicArray unimplemented"); } JNIEXPORT jboolean JNICALL -JVM_IsNullRestrictedArray(JNIEnv *env, jobject obj) +JVM_IsFlatArray(JNIEnv *env, jobject obj) { jboolean result = JNI_FALSE; J9VMThread *currentThread = (J9VMThread *)env; @@ -65,7 +52,7 @@ JVM_IsNullRestrictedArray(JNIEnv *env, jobject obj) vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, NULL); } else { J9Class *j9clazz = J9OBJECT_CLAZZ(currentThread, J9_JNI_UNWRAP_REFERENCE(obj)); - if (J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(j9clazz)) { + if (J9CLASS_IS_ARRAY(j9clazz) && J9_IS_J9CLASS_FLATTENED(j9clazz)) { result = JNI_TRUE; } } @@ -74,7 +61,7 @@ JVM_IsNullRestrictedArray(JNIEnv *env, jobject obj) } JNIEXPORT jboolean JNICALL -JVM_IsFlatArray(JNIEnv *env, jobject obj) +JVM_IsNullRestrictedArray(JNIEnv *env, jobject obj) { jboolean result = JNI_FALSE; J9VMThread *currentThread = (J9VMThread *)env; @@ -84,7 +71,7 @@ JVM_IsFlatArray(JNIEnv *env, jobject obj) vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGNULLPOINTEREXCEPTION, NULL); } else { J9Class *j9clazz = J9OBJECT_CLAZZ(currentThread, J9_JNI_UNWRAP_REFERENCE(obj)); - if (J9CLASS_IS_ARRAY(j9clazz) && J9_IS_J9CLASS_FLATTENED(j9clazz)) { + if (J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(j9clazz)) { result = JNI_TRUE; } } @@ -92,6 +79,12 @@ JVM_IsFlatArray(JNIEnv *env, jobject obj) return result; } +JNIEXPORT jboolean JNICALL +JVM_IsValhallaEnabled() +{ + return JNI_TRUE; +} + static jarray newArrayHelper(JNIEnv *env, jclass componentType, jint length, bool isNullRestricted) { @@ -151,21 +144,26 @@ newArrayHelper(JNIEnv *env, jclass componentType, jint length, bool isNullRestri } JNIEXPORT jarray JNICALL -JVM_NewNullRestrictedArray(JNIEnv *env, jclass componentType, jint length) +JVM_NewNullableAtomicArray(JNIEnv *env, jclass componentType, jint length) { - return newArrayHelper(env, componentType, length, TRUE); + return newArrayHelper(env, componentType, length, false); } JNIEXPORT jarray JNICALL -JVM_NewNullRestrictedAtomicArray(JNIEnv *env, jclass componentType, jint length) +JVM_NewNullRestrictedAtomicArray(JNIEnv *env, jclass componentType, jint length, jobject initialValue) { - return newArrayHelper(env, componentType, length, TRUE); + /* TODO: An additional parameter initialValue is required for newArrayHelper(). + * https://github.com/eclipse-openj9/openj9/issues/22642 + */ + return newArrayHelper(env, componentType, length, true); } JNIEXPORT jarray JNICALL -JVM_NewNullableAtomicArray(JNIEnv *env, jclass componentType, jint length) +JVM_NewNullRestrictedNonAtomicArray(JNIEnv *env, jclass elmClass, jint len, jobject initVal) { - return newArrayHelper(env, componentType, length, FALSE); + assert(!"JVM_NewNullRestrictedNonAtomicArray unimplemented"); } + #endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */ + } /* extern "C" */ diff --git a/runtime/jcl/CMakeLists.txt b/runtime/jcl/CMakeLists.txt index 0c5437fb67b..3d3dff44e82 100644 --- a/runtime/jcl/CMakeLists.txt +++ b/runtime/jcl/CMakeLists.txt @@ -144,7 +144,7 @@ target_sources(jclse ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmthypervisor.c ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtinit.c ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtmemmgr.c - ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtmemory.c + ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtmemory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtmempool.c ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtos.c ${CMAKE_CURRENT_SOURCE_DIR}/common/mgmtosext.c diff --git a/runtime/jcl/common/jcldefine.c b/runtime/jcl/common/jcldefine.c index 9df1da30bdc..4f2cf0f079e 100644 --- a/runtime/jcl/common/jcldefine.c +++ b/runtime/jcl/common/jcldefine.c @@ -156,7 +156,8 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject, omrthread_monitor_enter(vm->classTableMutex); /* Hidden class is never added into the hash table */ if ((NULL != utf8Name) && J9_ARE_NO_BITS_SET(*options, J9_FINDCLASS_FLAG_HIDDEN)) { - if (NULL != vmFuncs->hashClassTableAt(classLoader, utf8Name, utf8Length, 0)) { + J9Class *persistedClazz = vmFuncs->hashClassTableAt(classLoader, utf8Name, utf8Length, J9_FINDCLASS_FLAG_DONT_SKIP_FROZEN_JCL_DEFINE_CLASS); + if (NULL != persistedClazz) { /* Bad, we have already defined this class - fail */ omrthread_monitor_exit(vm->classTableMutex); if (J9_ARE_NO_BITS_SET(*options, J9_FINDCLASS_FLAG_NAME_IS_INVALID)) { @@ -165,8 +166,7 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject, */ #if defined(J9VM_OPT_SNAPSHOTS) if (IS_RESTORE_RUN(vm)) { - clazz = vmFuncs->hashClassTableAt(classLoader, utf8Name, utf8Length, 0); - + clazz = persistedClazz; if (!vmFuncs->loadWarmClassFromSnapshot(currentThread, classLoader, clazz)) { clazz = NULL; goto done; @@ -281,6 +281,11 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject, } } else { result = vmFuncs->j9jni_createLocalRef(env, J9VM_J9CLASS_TO_HEAPCLASS(clazz)); +#if defined(J9VM_OPT_SNAPSHOTS) + if (!IS_RESTORE_RUN(vm)) { + clazz->classFlags |= J9ClassIsJCLDefineClass; + } +#endif /* defined(J9VM_OPT_SNAPSHOTS) */ } vmFuncs->internalExitVMToJNI(currentThread); diff --git a/runtime/jcl/common/mgmtmemory.c b/runtime/jcl/common/mgmtmemory.cpp similarity index 71% rename from runtime/jcl/common/mgmtmemory.c rename to runtime/jcl/common/mgmtmemory.cpp index cbdcdd85b7f..7d4fcf4f725 100644 --- a/runtime/jcl/common/mgmtmemory.c +++ b/runtime/jcl/common/mgmtmemory.cpp @@ -25,6 +25,9 @@ #include "mgmtinit.h" #include "jvminit.h" #include "verbose_api.h" +#include "VMHelpers.hpp" + +extern "C" { static UDATA getIndexFromMemoryPoolID(J9JavaLangManagementData *mgmt, UDATA id); static UDATA getIndexFromGCID(J9JavaLangManagementData *mgmt, UDATA id); @@ -33,68 +36,15 @@ jobject JNICALL Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getHeapMemoryUsageImpl(JNIEnv *env, jobject beanInstance, jclass memoryUsage, jobject memUsageConstructor) { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - jlong used = 0; - jlong committed = 0; - jmethodID ctor = NULL; + jlong committed = javaVM->memoryManagerFunctions->j9gc_heap_total_memory(javaVM); + jlong used = committed - javaVM->memoryManagerFunctions->j9gc_heap_free_memory(javaVM); + jmethodID ctor = env->FromReflectedMethod(memUsageConstructor); - committed = javaVM->memoryManagerFunctions->j9gc_heap_total_memory(javaVM); - used = committed - javaVM->memoryManagerFunctions->j9gc_heap_free_memory(javaVM); - - ctor = (*env)->FromReflectedMethod(env, memUsageConstructor); - if(NULL == ctor) { + if (NULL == ctor) { return NULL; } - return (*env)->NewObject(env, memoryUsage, ctor, (jlong)javaVM->managementData->initialHeapSize, used, committed, (jlong)javaVM->managementData->maximumHeapSize); -} - -/** - * @brief Subtracts sizes of all free list blocks from the accumulator. - * - * Iterates through tiny, small, and large block lists in - * j9RAMClassFreeListsPtr and subtracts each block's size from used. - * - * @param j9RAMClassFreeListsPtr Pointer to RAM class free-lists (may be NULL). - * @param used Pointer to a jlong accumulator decremented by block sizes. - */ -void -subtractFreeListBlocks(J9RAMClassFreeLists* j9RAMClassFreeListsPtr, jlong *used) -{ - if (NULL != j9RAMClassFreeListsPtr) { - J9RAMClassFreeListBlock *ramClassTinyBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassTinyBlockFreeList; - J9RAMClassFreeListBlock *ramClassSmallBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassSmallBlockFreeList; - J9RAMClassFreeListBlock *ramClassLargeBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassLargeBlockFreeList; - while (NULL != ramClassTinyBlockFreeListPtr) { - *used -= ramClassTinyBlockFreeListPtr->size; - ramClassTinyBlockFreeListPtr = ramClassTinyBlockFreeListPtr->nextFreeListBlock; - } - while (NULL != ramClassSmallBlockFreeListPtr) { - *used -= ramClassSmallBlockFreeListPtr->size; - ramClassSmallBlockFreeListPtr = ramClassSmallBlockFreeListPtr->nextFreeListBlock; - } - while (NULL != ramClassLargeBlockFreeListPtr) { - *used -= ramClassLargeBlockFreeListPtr->size; - ramClassLargeBlockFreeListPtr = ramClassLargeBlockFreeListPtr->nextFreeListBlock; - } - } -} - -/** - * @brief Subtracts the size of each UDATA block in a chain from the accumulator. - * - * Walks a chain of UDATA blocks starting at ramClassUDATABlockFreeListPtr - * and subtracts sizeof(UDATA) for each from used. - * - * @param ramClassUDATABlockFreeListPtr Head of UDATA block chain (may be NULL). - * @param used Pointer to a jlong accumulator decremented by block count * sizeof(UDATA). - */ -void -subtractUDATABlockChain(UDATA *ramClassUDATABlockFreeListPtr, jlong *used) -{ - while (NULL != ramClassUDATABlockFreeListPtr) { - *used -= sizeof(UDATA); - ramClassUDATABlockFreeListPtr = *(UDATA **)ramClassUDATABlockFreeListPtr; - } + return env->NewObject(memoryUsage, ctor, (jlong)javaVM->managementData->initialHeapSize, used, committed, (jlong)javaVM->managementData->maximumHeapSize); } jobject JNICALL @@ -102,16 +52,14 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; - jlong used = 0; + I_64 used = 0; jlong committed = 0; jlong initial = 0; jmethodID ctor = NULL; - J9MemorySegmentList *segList = NULL; - J9ClassLoader *classLoader = NULL; + J9MemorySegmentList *segList = javaVM->classMemorySegments; J9ClassLoaderWalkState walkState; UDATA idx = 0; - segList = javaVM->classMemorySegments; omrthread_monitor_enter(segList->segmentMutex); MEMORY_SEGMENT_LIST_DO(segList, seg) @@ -123,7 +71,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag /* The classTableMutex is held while allocating RAM class fragments from free lists. @see createramclass.c#internalCreateRAMClassFromROMClass() */ omrthread_monitor_enter(javaVM->classTableMutex); - classLoader = javaVM->internalVMFunctions->allClassLoadersStartDo(&walkState, javaVM, 0); + J9ClassLoader *classLoader = javaVM->internalVMFunctions->allClassLoadersStartDo(&walkState, javaVM, 0); while (NULL != classLoader) { J9RAMClassFreeLists *sub4gBlockPtr = &classLoader->sub4gBlock; J9RAMClassFreeLists *frequentlyAccessedBlockPtr = &classLoader->frequentlyAccessedBlock; @@ -132,13 +80,13 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag UDATA *ramClassFreqUDATABlockFreeListPtr = frequentlyAccessedBlockPtr->ramClassUDATABlockFreeList; UDATA *ramClassInFreqUDATABlockFreeListPtr = inFrequentlyAccessedBlockPtr->ramClassUDATABlockFreeList; - subtractUDATABlockChain(ramClassSub4gUDATABlockFreeListPtr, &used); - subtractUDATABlockChain(ramClassFreqUDATABlockFreeListPtr, &used); - subtractUDATABlockChain(ramClassInFreqUDATABlockFreeListPtr, &used); + VM_VMHelpers::subtractUDATABlockChain(ramClassSub4gUDATABlockFreeListPtr, &used); + VM_VMHelpers::subtractUDATABlockChain(ramClassFreqUDATABlockFreeListPtr, &used); + VM_VMHelpers::subtractUDATABlockChain(ramClassInFreqUDATABlockFreeListPtr, &used); - subtractFreeListBlocks(sub4gBlockPtr, &used); - subtractFreeListBlocks(frequentlyAccessedBlockPtr, &used); - subtractFreeListBlocks(inFrequentlyAccessedBlockPtr, &used); + VM_VMHelpers::subtractFreeListBlocks(sub4gBlockPtr, &used); + VM_VMHelpers::subtractFreeListBlocks(frequentlyAccessedBlockPtr, &used); + VM_VMHelpers::subtractFreeListBlocks(inFrequentlyAccessedBlockPtr, &used); classLoader = javaVM->internalVMFunctions->allClassLoadersNextDo(&walkState); } @@ -155,8 +103,8 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag omrthread_monitor_exit(segList->segmentMutex); -#if defined( J9VM_INTERP_NATIVE_SUPPORT ) - if (javaVM->jitConfig) { +#if defined(J9VM_INTERP_NATIVE_SUPPORT) + if (NULL != javaVM->jitConfig) { segList = javaVM->jitConfig->codeCacheList; omrthread_monitor_enter(segList->segmentMutex); @@ -171,8 +119,8 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag * space between the warmAlloc and coldAlloc pointers. See compiler/runtime/OMRCodeCache.hpp, the contract with the JVM is * that the address of the TR::CodeCache structure is stored at the beginning of the segment. */ - UDATA *mccCodeCache = *((UDATA**)seg->heapBase); - if (mccCodeCache) { + UDATA *mccCodeCache = *((UDATA **)seg->heapBase); + if (NULL != mccCodeCache) { warmAlloc = (UDATA)javaVM->jitConfig->codeCacheWarmAlloc(mccCodeCache); coldAlloc = (UDATA)javaVM->jitConfig->codeCacheColdAlloc(mccCodeCache); } @@ -193,17 +141,17 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getNonHeapMemoryUsag omrthread_monitor_exit(segList->segmentMutex); } -#endif +#endif /* defined(J9VM_INTERP_NATIVE_SUPPORT) */ for (idx = 0; idx < mgmt->supportedNonHeapMemoryPools; ++idx) { initial += mgmt->nonHeapMemoryPools[idx].initialSize; } - ctor = (*env)->FromReflectedMethod(env, memUsageConstructor); - if(NULL == ctor) { + ctor = env->FromReflectedMethod(memUsageConstructor); + if (NULL == ctor) { return NULL; } - return (*env)->NewObject(env, memoryUsage, ctor, initial, used, committed, (jlong)-1); + return env->NewObject(memoryUsage, ctor, initial, used, committed, (jlong)-1); } jint JNICALL @@ -212,9 +160,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getObjectPendingFina #if defined(J9VM_GC_FINALIZATION) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; return (jint)javaVM->memoryManagerFunctions->j9gc_get_objects_pending_finalization_count(javaVM); -#else +#else /* defined(J9VM_GC_FINALIZATION) */ return (jint)0; -#endif +#endif /* defined(J9VM_GC_FINALIZATION) */ } jboolean JNICALL @@ -222,7 +170,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_isVerboseImpl(JNIEnv { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - return VERBOSE_GC == (VERBOSE_GC & javaVM->verboseLevel) ; + return J9_ARE_ANY_BITS_SET(javaVM->verboseLevel, VERBOSE_GC); } void JNICALL @@ -231,9 +179,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setVerboseImpl(JNIEn J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9VerboseSettings verboseOptions; - memset(&verboseOptions, 0, sizeof(J9VerboseSettings)); + memset(&verboseOptions, 0, sizeof(verboseOptions)); if (NULL != javaVM->setVerboseState) { - verboseOptions.gc = flag? VERBOSE_SETTINGS_SET: VERBOSE_SETTINGS_CLEAR; + verboseOptions.gc = flag ? VERBOSE_SETTINGS_SET : VERBOSE_SETTINGS_CLEAR; javaVM->setVerboseState(javaVM, &verboseOptions, NULL); } } @@ -250,41 +198,40 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryManagers UDATA idx = 0; /* - This method performs the following Java code: - createMemoryManagerHelper( "J9 non-heap memory manager", 0, false ); - for supportedGarbageCollectors - createMemoryManagerHelper( gcName, gcID, true); - * + * This method performs the following Java code: + * createMemoryManagerHelper( "J9 non-heap memory manager", 0, false ); + * for supportedGarbageCollectors + * createMemoryManagerHelper( gcName, gcID, true); */ - memBean = (*env)->GetObjectClass(env, beanInstance); - if(NULL == memBean) { + memBean = env->GetObjectClass(beanInstance); + if (NULL == memBean) { return; } - helperID = (*env)->GetMethodID(env, memBean, "createMemoryManagerHelper", "(Ljava/lang/String;IZ)V"); + helperID = env->GetMethodID(memBean, "createMemoryManagerHelper", "(Ljava/lang/String;IZ)V"); if (NULL == helperID) { return; } - childName = (*env)->NewStringUTF(env, "J9 non-heap manager"); - if (NULL == childName) { + childName = env->NewStringUTF("J9 non-heap manager"); + if (NULL == childName) { return; } - (*env)->CallVoidMethod(env, beanInstance, helperID, childName, J9VM_MANAGEMENT_POOL_NONHEAP, JNI_FALSE); - if ((*env)->ExceptionCheck(env)) { + env->CallVoidMethod(beanInstance, helperID, childName, J9VM_MANAGEMENT_POOL_NONHEAP, JNI_FALSE); + if (env->ExceptionCheck()) { return; } for (idx = 0; idx < mgmt->supportedCollectors; ++idx) { id = (jint)mgmt->garbageCollectors[idx].id; - childName = (*env)->NewStringUTF(env, mgmt->garbageCollectors[idx].name); + childName = env->NewStringUTF(mgmt->garbageCollectors[idx].name); if (NULL == childName) { return; } - (*env)->CallVoidMethod(env, beanInstance, helperID, childName, id, JNI_TRUE); + env->CallVoidMethod(beanInstance, helperID, childName, id, JNI_TRUE); } } @@ -299,12 +246,12 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN jint id = 0; UDATA idx = 0; - memBean = (*env)->GetObjectClass(env, beanInstance); + memBean = env->GetObjectClass(beanInstance); if (NULL == memBean) { return; } - helperID = (*env)->GetMethodID(env, memBean, "createMemoryPoolHelper", "(Ljava/lang/String;IZ)V"); + helperID = env->GetMethodID(memBean, "createMemoryPoolHelper", "(Ljava/lang/String;IZ)V"); if (NULL == helperID) { return; } @@ -312,13 +259,13 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN /* Heap Memory Pools */ for (idx = 0; idx < mgmt->supportedMemoryPools; ++idx) { id = (jint)mgmt->memoryPools[idx].id; - childName = (*env)->NewStringUTF(env, mgmt->memoryPools[idx].name); + childName = env->NewStringUTF(mgmt->memoryPools[idx].name); if (NULL == childName) { return; } - (*env)->CallVoidMethod(env, beanInstance, helperID, childName, id, JNI_TRUE); - if ((*env)->ExceptionCheck(env)) { + env->CallVoidMethod(beanInstance, helperID, childName, id, JNI_TRUE); + if (env->ExceptionCheck()) { return; } } @@ -326,13 +273,13 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_createMemoryPools(JN /* NonHeap Memory Pools */ for (idx = 0; idx < mgmt->supportedNonHeapMemoryPools; ++idx) { id = (jint)mgmt->nonHeapMemoryPools[idx].id; - childName = (*env)->NewStringUTF(env, mgmt->nonHeapMemoryPools[idx].name); + childName = env->NewStringUTF(mgmt->nonHeapMemoryPools[idx].name); if (NULL == childName) { return; } - (*env)->CallVoidMethod(env, beanInstance, helperID, childName, id, JNI_FALSE); - if ((*env)->ExceptionCheck(env)) { + env->CallVoidMethod(beanInstance, helperID, childName, id, JNI_FALSE); + if (env->ExceptionCheck()) { return; } } @@ -383,7 +330,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheS #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)value, -1, -1, -1, -1)) { ret = JNI_TRUE; } @@ -400,7 +347,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, (I_32)value, -1, -1, -1)) { ret = JNI_TRUE; } @@ -417,7 +364,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, (I_32)value, -1, -1)) { ret = JNI_TRUE; } @@ -434,7 +381,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, -1, (I_32)value, -1)) { ret = JNI_TRUE; } @@ -451,7 +398,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_setSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { if (0 != javaVM->sharedClassConfig->setMinMaxBytes(javaVM, (U_32)-1, -1, -1, -1, (I_32)value)) { ret = JNI_TRUE; } @@ -468,7 +415,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheS #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, &ret, NULL, NULL); } #endif /* defined(J9VM_OPT_SHARED_CLASSES) */ @@ -483,7 +430,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, NULL, &ret, NULL); } #endif /* defined(J9VM_OPT_SHARED_CLASSES) */ @@ -498,7 +445,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getSharedClassCacheM #if defined(J9VM_OPT_SHARED_CLASSES) J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; - if (javaVM->sharedClassConfig) { + if (NULL != javaVM->sharedClassConfig) { javaVM->sharedClassConfig->getUnstoredBytes(javaVM, NULL, NULL, &ret); } #endif /* defined(J9VM_OPT_SHARED_CLASSES) */ @@ -518,7 +465,7 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCModeImpl(JNIEnv const char *gcMode = javaVM->memoryManagerFunctions->j9gc_get_gcmodestring(javaVM); if (NULL != gcMode) { - return (*env)->NewStringUTF(env, gcMode); + return env->NewStringUTF(gcMode); } else { return NULL; } @@ -529,10 +476,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCMainThreadCpuUs { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; - jlong result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jlong)mgmt->gcMainCpuTime; + jlong result = (jlong)mgmt->gcMainCpuTime; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -543,10 +489,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getGCWorkerThreadsCp { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; - jlong result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jlong)mgmt->gcWorkerCpuTime; + jlong result = (jlong)mgmt->gcWorkerCpuTime; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -557,10 +502,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getMaximumGCThreadsI { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; - jint result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jint)mgmt->gcMaxThreads; + jint result = (jint)mgmt->gcMaxThreads; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -571,10 +515,9 @@ Java_com_ibm_java_lang_management_internal_MemoryMXBeanImpl_getCurrentGCThreadsI { J9JavaVM *javaVM = ((J9VMThread *)env)->javaVM; J9JavaLangManagementData *mgmt = javaVM->managementData; - jint result = 0; omrthread_rwmutex_enter_read(mgmt->managementDataLock); - result = (jint)mgmt->gcCurrentThreads; + jint result = (jint)mgmt->gcCurrentThreads; omrthread_rwmutex_exit_read(mgmt->managementDataLock); return result; @@ -603,36 +546,36 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati /* cache poolNames and gcNames */ for (idx = 0; idx < mgmt->supportedMemoryPools; ++idx) { - poolNames[idx] = (*env)->NewStringUTF(env, mgmt->memoryPools[idx].name); + poolNames[idx] = env->NewStringUTF(mgmt->memoryPools[idx].name); if (NULL == poolNames[idx]) { return; } } for (idx = 0; idx < mgmt->supportedCollectors; ++idx) { - gcNames[idx] = (*env)->NewStringUTF(env, mgmt->garbageCollectors[idx].name); + gcNames[idx] = env->NewStringUTF(mgmt->garbageCollectors[idx].name); if (NULL == gcNames[idx]) { return; } } /* locate the helper that constructs and dispatches the Java notification objects */ - threadClass = (*env)->FindClass(env, "com/ibm/lang/management/internal/MemoryNotificationThread"); + threadClass = env->FindClass("com/ibm/lang/management/internal/MemoryNotificationThread"); if (NULL == threadClass) { return; } - stringClass = (*env)->FindClass(env, "java/lang/String"); + stringClass = env->FindClass("java/lang/String"); if (NULL == stringClass) { return; } - helperMemID = (*env)->GetMethodID(env, threadClass, "dispatchMemoryNotificationHelper", "(Ljava/lang/String;JJJJJJZ)V"); + helperMemID = env->GetMethodID(threadClass, "dispatchMemoryNotificationHelper", "(Ljava/lang/String;JJJJJJZ)V"); if (NULL == helperMemID) { return; } - helperGCID = (*env)->GetMethodID(env, threadClass, "dispatchGCNotificationHelper", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJ[J[J[J[J[J[J[JJ)V"); + helperGCID = env->GetMethodID(threadClass, "dispatchGCNotificationHelper", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJ[J[J[J[J[J[J[JJ)V"); if (NULL == helperGCID) { return; } @@ -641,19 +584,19 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati mgmt->notificationEnabled = 1; omrthread_rwmutex_exit_write(mgmt->managementDataLock); - while(1) { - if ((*env)->PushLocalFrame(env, 16) < 0) { + while (1) { + if (env->PushLocalFrame(16) < 0) { /* out of memory */ return; } /* wait on the notification queue monitor until a notification is posted */ j9thread_monitor_enter(mgmt->notificationMonitor); - while(0 == mgmt->notificationsPending) { + while (0 == mgmt->notificationsPending) { j9thread_monitor_wait(mgmt->notificationMonitor); } mgmt->notificationsPending -= 1; - notification = mgmt->notificationQueue; + notification = (J9MemoryNotification *)mgmt->notificationQueue; mgmt->notificationQueue = notification->next; j9thread_monitor_exit(mgmt->notificationMonitor); @@ -675,31 +618,31 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati jlongArray postCommittedArray = NULL; jlongArray postMaxArray = NULL; - initialArray = (*env)->NewLongArray(env, gcInfo->arraySize); + initialArray = env->NewLongArray(gcInfo->arraySize); if (NULL == initialArray) { return; } - preUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize); + preUsedArray = env->NewLongArray(gcInfo->arraySize); if (NULL == preUsedArray) { return; } - preCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize); + preCommittedArray = env->NewLongArray(gcInfo->arraySize); if (NULL == preCommittedArray) { return; } - preMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize); + preMaxArray = env->NewLongArray(gcInfo->arraySize); if (NULL == preMaxArray) { return; } - postUsedArray = (*env)->NewLongArray(env, gcInfo->arraySize); + postUsedArray = env->NewLongArray(gcInfo->arraySize); if (NULL == postUsedArray) { return; } - postCommittedArray = (*env)->NewLongArray(env, gcInfo->arraySize); + postCommittedArray = env->NewLongArray(gcInfo->arraySize); if (NULL == postCommittedArray) { return; } - postMaxArray = (*env)->NewLongArray(env, gcInfo->arraySize); + postMaxArray = env->NewLongArray(gcInfo->arraySize); if (NULL == postMaxArray) { return; } @@ -708,46 +651,45 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati if (NULL == gcName) { return; } - gcAction = (*env)->NewStringUTF(env, gcInfo->gcAction); + gcAction = env->NewStringUTF(gcInfo->gcAction); if (NULL == gcAction) { return; } - gcCause = (*env)->NewStringUTF(env, gcInfo->gcCause); + gcCause = env->NewStringUTF(gcInfo->gcCause); if (NULL == gcCause) { return; } - (*env)->SetLongArrayRegion(env, initialArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->initialSize[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(initialArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->initialSize[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, preUsedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preUsed[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(preUsedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preUsed[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, preCommittedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preCommitted[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(preCommittedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preCommitted[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, preMaxArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preMax[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(preMaxArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->preMax[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, postUsedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postUsed[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(postUsedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postUsed[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, postCommittedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postCommitted[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(postCommittedArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postCommitted[0]); + if (env->ExceptionCheck()) { return; } - (*env)->SetLongArrayRegion(env, postMaxArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postMax[0]); - if ((*env)->ExceptionCheck(env)) { + env->SetLongArrayRegion(postMaxArray, 0, gcInfo->arraySize, (jlong *)&gcInfo->postMax[0]); + if (env->ExceptionCheck()) { return; } - (*env)->CallVoidMethod( - env, + env->CallVoidMethod( threadInstance, helperGCID, gcName, @@ -764,7 +706,7 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati postCommittedArray, postMaxArray, (jlong)notification->sequenceNumber); - if ((*env)->ExceptionCheck(env)) { + if (env->ExceptionCheck()) { return; } } else { @@ -775,8 +717,7 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati poolName = poolNames[idx]; if (THRESHOLD_EXCEEDED == notification->type) { /* heap usage threshold exceeded */ - (*env)->CallVoidMethod( - env, + env->CallVoidMethod( threadInstance, helperMemID, poolName, @@ -787,13 +728,12 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati (jlong)usageThreshold->thresholdCrossingCount, (jlong)notification->sequenceNumber, JNI_FALSE); - if ((*env)->ExceptionCheck(env)) { + if (env->ExceptionCheck()) { return; } } else { /* COLLECTION_THRESHOLD_EXCEEDED == notification->type) */ /* heap collection usage threshold exceeded */ - (*env)->CallVoidMethod( - env, + env->CallVoidMethod( threadInstance, helperMemID, poolName, @@ -804,7 +744,7 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati (jlong)usageThreshold->thresholdCrossingCount, (jlong)notification->sequenceNumber, JNI_TRUE); - if ((*env)->ExceptionCheck(env)) { + if (env->ExceptionCheck()) { return; } } @@ -818,12 +758,12 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThread_processNotificati } j9mem_free_memory(notification); - if ((*env)->ExceptionCheck(env)) { + if (env->ExceptionCheck()) { /* if the dispatcher throws, just kill the thread for now */ break; } - (*env)->PopLocalFrame(env, NULL); + env->PopLocalFrame(NULL); } } @@ -839,7 +779,7 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThreadShutdown_sendShutd PORT_ACCESS_FROM_ENV(env); /* allocate a notification */ - notification = j9mem_allocate_memory(sizeof(*notification), J9MEM_CATEGORY_VM_JCL); + notification = (J9MemoryNotification *)j9mem_allocate_memory(sizeof(*notification), J9MEM_CATEGORY_VM_JCL); if (NULL != notification) { /* set up a shutdown notification */ notification->type = NOTIFIER_SHUTDOWN_REQUEST; @@ -853,11 +793,11 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThreadShutdown_sendShutd /* replace the queue with just this notification - the notifier thread does not care that the pending count might be >1, it will not process anything after the shutdown request */ j9thread_monitor_enter(mgmt->notificationMonitor); - next = mgmt->notificationQueue; + next = (J9MemoryNotification *)mgmt->notificationQueue; mgmt->notificationQueue = notification; /* free the old queue entries if any */ - while(NULL != next) { + while (NULL != next) { J9MemoryNotification *temp = next; next = next->next; if (NULL != temp->usageThreshold) { @@ -875,11 +815,11 @@ Java_com_ibm_lang_management_internal_MemoryNotificationThreadShutdown_sendShutd } } - -static UDATA getIndexFromMemoryPoolID(J9JavaLangManagementData *mgmt, UDATA id) +static UDATA +getIndexFromMemoryPoolID(J9JavaLangManagementData *mgmt, UDATA id) { UDATA idx = 0; - for(; idx < mgmt->supportedMemoryPools; ++idx) { + for (; idx < mgmt->supportedMemoryPools; ++idx) { if ((mgmt->memoryPools[idx].id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK) == (id & J9VM_MANAGEMENT_POOL_HEAP_ID_MASK)) { break; } @@ -887,14 +827,17 @@ static UDATA getIndexFromMemoryPoolID(J9JavaLangManagementData *mgmt, UDATA id) return idx; } -static UDATA getIndexFromGCID(J9JavaLangManagementData *mgmt, UDATA id) +static UDATA +getIndexFromGCID(J9JavaLangManagementData *mgmt, UDATA id) { UDATA idx = 0; - for(; idx < mgmt->supportedCollectors; ++idx) { + for (; idx < mgmt->supportedCollectors; ++idx) { if ((J9VM_MANAGEMENT_GC_HEAP_ID_MASK & mgmt->garbageCollectors[idx].id) == (J9VM_MANAGEMENT_GC_HEAP_ID_MASK & id)) { break; } } return idx; } + +} /* extern "C" */ diff --git a/runtime/jcl/common/reflecthelp.c b/runtime/jcl/common/reflecthelp.c index 476bd6d6ff2..9e531dd712c 100644 --- a/runtime/jcl/common/reflecthelp.c +++ b/runtime/jcl/common/reflecthelp.c @@ -834,11 +834,12 @@ createField(struct J9VMThread *vmThread, jfieldID fieldID) J9VMJAVALANGREFLECTFIELD_SET_CLAZZ(vmThread, fieldObject, J9VM_J9CLASS_TO_HEAPCLASS(j9FieldID->declaringClass)); J9VMJAVALANGREFLECTFIELD_SET_MODIFIERS(vmThread, fieldObject, j9FieldID->field->modifiers & CFR_FIELD_ACCESS_MASK); #if JAVA_SPEC_VERSION >= 15 - /* Trust that static final fields and final record or hidden class fields will not be modified. */ + /* Trust that static final fields, and final fields of hidden, record or value classes will not be modified. */ if (J9_ARE_ALL_BITS_SET(j9FieldID->field->modifiers, J9AccFinal)) { if (J9_ARE_ALL_BITS_SET(j9FieldID->field->modifiers, J9AccStatic) - || J9ROMCLASS_IS_RECORD(j9FieldID->declaringClass->romClass) - || J9ROMCLASS_IS_HIDDEN(j9FieldID->declaringClass->romClass) + || J9ROMCLASS_IS_HIDDEN(j9FieldID->declaringClass->romClass) + || J9ROMCLASS_IS_RECORD(j9FieldID->declaringClass->romClass) + || J9ROMCLASS_IS_VALUE(j9FieldID->declaringClass->romClass) ) { #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) fieldFlags |= TRUST_FINAL; diff --git a/runtime/nls/j9vm/j9vm.nls b/runtime/nls/j9vm/j9vm.nls index 1b5d344fe19..bc1aa397aa9 100644 --- a/runtime/nls/j9vm/j9vm.nls +++ b/runtime/nls/j9vm/j9vm.nls @@ -2500,3 +2500,10 @@ J9NLS_VM_CLASS_LOADING_ERROR_INVISIBLE_SUPERCLASS_OR_INTERFACE_JAVA11_PLUS.expla J9NLS_VM_CLASS_LOADING_ERROR_INVISIBLE_SUPERCLASS_OR_INTERFACE_JAVA11_PLUS.system_action=The JVM will throw an IllegalAccessError. J9NLS_VM_CLASS_LOADING_ERROR_INVISIBLE_SUPERCLASS_OR_INTERFACE_JAVA11_PLUS.user_response=Contact the provider of the classfile for a corrected version. # END NON-TRANSLATABLE + +J9NLS_VM_CLASS_LOADING_ERROR_STRICT_STATIC_FIELDS_UNSET=Strict static fields are unset after initialization of %2$.*1$s. +# START NON-TRANSLATABLE +J9NLS_VM_CLASS_LOADING_ERROR_STRICT_STATIC_FIELDS_UNSET.explanation=All strict static fields must be set before the class is initialized. +J9NLS_VM_CLASS_LOADING_ERROR_STRICT_STATIC_FIELDS_UNSET.system_action=The JVM will throw an IllegalStateException. +J9NLS_VM_CLASS_LOADING_ERROR_STRICT_STATIC_FIELDS_UNSET.user_response=Set all strict static fields prior to initialization. +# END NON-TRANSLATABLE diff --git a/runtime/oti/ContinuationHelpers.hpp b/runtime/oti/ContinuationHelpers.hpp index c59ccbdc6cb..94f36693eab 100644 --- a/runtime/oti/ContinuationHelpers.hpp +++ b/runtime/oti/ContinuationHelpers.hpp @@ -37,9 +37,11 @@ #endif /* JAVA_SPEC_VERSION >= 24 */ #include "VMHelpers.hpp" -/* These should match the error code values in enum Pinned within class Continuation. */ +/* These should match the error code values in enum Continuation.Pinned. */ #define J9VM_CONTINUATION_PINNED_REASON_NATIVE 1 +#if JAVA_SPEC_VERSION < 26 #define J9VM_CONTINUATION_PINNED_REASON_MONITOR 2 +#endif /* JAVA_SPEC_VERSION < 26 */ #define J9VM_CONTINUATION_PINNED_REASON_CRITICAL_SECTION 3 #if JAVA_SPEC_VERSION >= 24 #define J9VM_CONTINUATION_PINNED_REASON_EXCEPTION 4 diff --git a/runtime/oti/VMHelpers.hpp b/runtime/oti/VMHelpers.hpp index 707e77e4d8b..fefa4dbd69d 100644 --- a/runtime/oti/VMHelpers.hpp +++ b/runtime/oti/VMHelpers.hpp @@ -160,7 +160,6 @@ typedef enum { J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPLONG, J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT, #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) - J9_BCLOOP_SEND_TARGET_INL_UNSAFE_UNINITIALIZEDDEFAULTVALUE, J9_BCLOOP_SEND_TARGET_INL_UNSAFE_VALUEHEADERSIZE, J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECTSIZE, #endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */ @@ -1960,8 +1959,8 @@ class VM_VMHelpers /** * Determine if the field is a trusted final field. * - * A trusted final field must have be a static final field or - * a final field defined in either a hidden class or Record class + * A trusted final field must be a static final field or, + * a final field defined in a hidden, record or value class. * * @param field the field to be checked * @param romClass the declaring class of the field @@ -1972,7 +1971,11 @@ class VM_VMHelpers { bool result = false; if (J9_ARE_ALL_BITS_SET(field->modifiers, J9AccFinal)) { - if (J9_ARE_ALL_BITS_SET(field->modifiers, J9AccStatic) || J9ROMCLASS_IS_HIDDEN(romClass) || J9ROMCLASS_IS_RECORD(romClass)) { + if (J9_ARE_ALL_BITS_SET(field->modifiers, J9AccStatic) + || J9ROMCLASS_IS_HIDDEN(romClass) + || J9ROMCLASS_IS_RECORD(romClass) + || J9ROMCLASS_IS_VALUE(romClass) + ) { result = true; } } @@ -2339,6 +2342,54 @@ class VM_VMHelpers return true; } + /** + * @brief Subtracts sizes of all free list blocks from the accumulator. + * + * Iterates through tiny, small, and large block lists in + * j9RAMClassFreeListsPtr and subtracts each block's size from used. + * + * @param j9RAMClassFreeListsPtr Pointer to RAM class free-lists (may be NULL). + * @param used Pointer to a U_64 accumulator decremented by block sizes. + */ + static VMINLINE void + subtractFreeListBlocks(J9RAMClassFreeLists *j9RAMClassFreeListsPtr, I_64 *used) + { + if (NULL != j9RAMClassFreeListsPtr) { + J9RAMClassFreeListBlock *ramClassTinyBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassTinyBlockFreeList; + J9RAMClassFreeListBlock *ramClassSmallBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassSmallBlockFreeList; + J9RAMClassFreeListBlock *ramClassLargeBlockFreeListPtr = j9RAMClassFreeListsPtr->ramClassLargeBlockFreeList; + while (NULL != ramClassTinyBlockFreeListPtr) { + *used -= ramClassTinyBlockFreeListPtr->size; + ramClassTinyBlockFreeListPtr = ramClassTinyBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassSmallBlockFreeListPtr) { + *used -= ramClassSmallBlockFreeListPtr->size; + ramClassSmallBlockFreeListPtr = ramClassSmallBlockFreeListPtr->nextFreeListBlock; + } + while (NULL != ramClassLargeBlockFreeListPtr) { + *used -= ramClassLargeBlockFreeListPtr->size; + ramClassLargeBlockFreeListPtr = ramClassLargeBlockFreeListPtr->nextFreeListBlock; + } + } + } + + /** + * @brief Subtracts the size of each UDATA block in a chain from the accumulator. + * + * Walks a chain of UDATA blocks starting at ramClassUDATABlockFreeListPtr + * and subtracts sizeof(UDATA) for each from used. + * + * @param ramClassUDATABlockFreeListPtr Head of UDATA block chain (may be NULL). + * @param used Pointer to a U_64 accumulator decremented by block count * sizeof(UDATA). + */ + static VMINLINE void + subtractUDATABlockChain(UDATA *ramClassUDATABlockFreeListPtr, I_64 *used) + { + while (NULL != ramClassUDATABlockFreeListPtr) { + *used -= sizeof(UDATA); + ramClassUDATABlockFreeListPtr = *(UDATA **)ramClassUDATABlockFreeListPtr; + } + } }; -#endif /* VMHELPERS_HPP_ */ +#endif /* !defined(VMHELPERS_HPP_) */ diff --git a/runtime/oti/j9consts.h b/runtime/oti/j9consts.h index 0e4e1497a52..2b9996f9c76 100644 --- a/runtime/oti/j9consts.h +++ b/runtime/oti/j9consts.h @@ -459,6 +459,11 @@ extern "C" { #define J9_FINDCLASS_FLAG_LAMBDA 0x200000 #define J9_FINDCLASS_FLAG_LAMBDAFORM 0x400000 #define J9_FINDCLASS_FLAG_CLASS_OPTION_NULL_RESTRICTED_ARRAY 0x800000 +/* + * Used to permit a caller to find classes that are frozen and are originally + * loaded in defineClassesCommon(). + */ +#define J9_FINDCLASS_FLAG_DONT_SKIP_FROZEN_JCL_DEFINE_CLASS 0x1000000 #define J9_FINDKNOWNCLASS_FLAG_INITIALIZE 0x1 #define J9_FINDKNOWNCLASS_FLAG_EXISTING_ONLY 0x2 @@ -974,7 +979,7 @@ extern "C" { /* Class version minimum for value type support. */ -#define VALUE_TYPES_MAJOR_VERSION 69 +#define VALUE_TYPES_MAJOR_VERSION (44 + 26) #define PREVIEW_MINOR_VERSION 65535 #define J9_IS_CLASSFILE_OR_ROMCLASS_VALUETYPE_VERSION(classfileOrRomClass) (((classfileOrRomClass)->majorVersion >= VALUE_TYPES_MAJOR_VERSION) && (PREVIEW_MINOR_VERSION == (classfileOrRomClass)->minorVersion)) diff --git a/runtime/oti/j9javaaccessflags.h b/runtime/oti/j9javaaccessflags.h index d62cc152b35..8fa28b5105a 100644 --- a/runtime/oti/j9javaaccessflags.h +++ b/runtime/oti/j9javaaccessflags.h @@ -153,7 +153,7 @@ /* Inform DDR that the static field ref constants support proper narrowing */ #define J9PutfieldNarrowing 1 -/* static field flags (low 8 bits of flagsAndClass) - low 3 bits are the field type for primitibve types */ +/* static field flags (low 8 bits of flagsAndClass) - low 3 bits are the field type for primitive types */ #define J9StaticFieldRefFlagBits 0xFF #define J9StaticFieldRefTypeMask 0x7 #define J9StaticFieldRefTypeObject 0x0 @@ -163,14 +163,35 @@ #define J9StaticFieldRefTypeShort 0x4 #define J9StaticFieldRefTypeIntFloat 0x5 #define J9StaticFieldRefTypeLongDouble 0x6 -#define J9StaticFieldRefTypeUnused_0x7 0x7 +#if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) +#define J9StaticFieldIsNullRestricted 0x7 +#endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ #define J9StaticFieldRefVolatile 0x8 #define J9StaticFieldRefPutResolved 0x10 #define J9StaticFieldRefFinal 0x20 -#if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) -#define J9StaticFieldIsNullRestricted 0x40 -#endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ -#define J9StaticFieldRefUnused_0x80 0x80 +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) +/** + * Since only two flags are available they are + * used as follows to represent four states + * for strict static fields: + * 00XXXXXX - field is not strict + * 01XXXXXX - strict field has been read. This implies it was + * written at least once as well otherwise an exception would have + * been thrown. + * 10XXXXXX - strict field has been written at least once. + * 11XXXXXX - strict field has not been read or written. + */ +#define J9StaticFieldRefStrictInitRead 0x40 +#define J9StaticFieldRefStrictInitWritten 0x80 +#define J9StaticFieldRefStrictInitUnset 0xC0 +#define J9StaticFieldRefStrictInitMask 0xC0 +#define J9_STATIC_FIELD_STRICT_INIT_IS_UNSET(classAndFlags) \ + (J9StaticFieldRefStrictInitUnset == ((classAndFlags) & J9StaticFieldRefStrictInitMask)) +#define J9_STATIC_FIELD_STRICT_INIT_WAS_WRITTEN_AND_READ(classAndFlags) \ + (J9StaticFieldRefStrictInitRead == ((classAndFlags) & J9StaticFieldRefStrictInitMask)) +#define J9_STATIC_FIELD_STRICT_INIT_WAS_WRITTEN(classAndFlags) \ + (J9StaticFieldRefStrictInitWritten == ((classAndFlags) & J9StaticFieldRefStrictInitMask)) +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ /* ImplicitCreation attribute flags */ #define J9AccImplicitCreateHasDefaultValue 0x1 diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 96857652a13..4fc2bcdec22 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -98,7 +98,17 @@ #define J9ClassNeedToPruneMemberNames 0x1000000 #define J9ClassArrayIsNullRestricted 0x2000000 #define J9ClassIsLoadedFromSnapshot 0x4000000 +/* + * The frozen flag is set when a J9Class is returned from persisted state and has not yet + * been fully loaded for the restore run. Note, this flag can only be set in a restore run. + * As soon as the class is fully loaded, the frozen flag is removed. + */ #define J9ClassIsFrozen 0x8000000 +/* + * Indicates that when the class was initially loaded in the snapshot run, + * it was loaded from defineClassCommon() in jcldefine.c. + */ +#define J9ClassIsJCLDefineClass 0x10000000 /* @ddr_namespace: map_to_type=J9FieldFlags */ @@ -3553,6 +3563,9 @@ typedef struct J9Class { #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) struct J9Class *nullRestrictedArrayClass; #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + U_16 strictStaticFieldCounter; +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ } J9Class; /* Interface classes can never be instantiated, so the following fields in J9Class will not be used: @@ -3656,6 +3669,9 @@ typedef struct J9ArrayClass { */ struct J9Class *companionArray; #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + U_16 strictStaticFieldCounter; +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ } J9ArrayClass; #if defined(LINUX) && defined(J9VM_ARCH_X86) && !defined(OSX) diff --git a/runtime/oti/jclprots.h b/runtime/oti/jclprots.h index 08f3b22eeb1..c16f389f6fd 100644 --- a/runtime/oti/jclprots.h +++ b/runtime/oti/jclprots.h @@ -697,9 +697,6 @@ void JNICALL Java_jdk_internal_misc_Unsafe_freeDBBMemory(JNIEnv *env, jobject re jlong JNICALL Java_jdk_internal_misc_Unsafe_reallocateDBBMemory(JNIEnv *env, jobject receiver, jlong address, jlong size); void JNICALL Java_jdk_internal_misc_Unsafe_copySwapMemory0(JNIEnv *env, jobject receiver, jobject obj1, jlong size1, jobject obj2, jlong size2, jlong size3, jlong size4); -jint JNICALL Java_jdk_internal_misc_Unsafe_compareAndExchangeInt(JNIEnv *env, jobject receiver, jobject obj1, jlong size1, jint size2, jint size3); -jlong JNICALL Java_jdk_internal_misc_Unsafe_compareAndExchangeLong(JNIEnv *env, jobject receiver, jobject obj1, jlong size1, jlong size2, jlong size3); -jobject JNICALL Java_jdk_internal_misc_Unsafe_compareAndExchangeObject(JNIEnv *env, jobject receiver, jobject obj1, jlong size, jobject obj2, jobject obj3); /* vector natives */ jint JNICALL diff --git a/runtime/oti/vmconstantpool.xml b/runtime/oti/vmconstantpool.xml index 58c25ef54be..39eb41f18c3 100644 --- a/runtime/oti/vmconstantpool.xml +++ b/runtime/oti/vmconstantpool.xml @@ -25,6 +25,7 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex + diff --git a/runtime/redirector/forwarders.m4 b/runtime/redirector/forwarders.m4 index 86e79f5e35a..f54811d0c01 100644 --- a/runtime/redirector/forwarders.m4 +++ b/runtime/redirector/forwarders.m4 @@ -464,19 +464,21 @@ _IF([JAVA_SPEC_VERSION >= 21], _IF([JAVA_SPEC_VERSION >= 21], [_X(JVM_VirtualThreadUnmount, JNICALL, false, void, JNIEnv *env, jobject vthread, jboolean hide)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], - [_X(JVM_IsFlatArray, JNICALL, false, jboolean, JNIEnv *env, jclass cls)]) + [_X(JVM_CopyOfSpecialArray, JNICALL, false, jarray, JNIEnv *env, jarray orig, jint from, jint to)]) +_IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], + [_X(JVM_IsAtomicArray, JNICALL, false, jboolean, JNIEnv *env, jobject obj)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], - [_X(JVM_IsImplicitlyConstructibleClass, JNICALL, false, jboolean, JNIEnv *env, jclass cls)]) + [_X(JVM_IsFlatArray, JNICALL, false, jboolean, JNIEnv *env, jclass cls)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], [_X(JVM_IsNullRestrictedArray, JNICALL, false, jboolean, JNIEnv *env, jobject obj)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], [_X(JVM_IsValhallaEnabled, JNICALL, false, jboolean, void)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], [_X(JVM_NewNullableAtomicArray, JNICALL, false, jarray, JNIEnv *env, jclass cls, jint length)]) -_IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], - [_X(JVM_NewNullRestrictedArray, JNICALL, false, jarray, JNIEnv *env, jclass cls, jint length)]) _IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], [_X(JVM_NewNullRestrictedAtomicArray, JNICALL, false, jarray, JNIEnv *env, jclass cls, jint length)]) +_IF([defined(J9VM_OPT_VALHALLA_VALUE_TYPES)], + [_X(JVM_NewNullRestrictedNonAtomicArray, JNICALL, false, jarray, JNIEnv *env, jclass elmClass, jint len, jobject initVal)]) _IF([JAVA_SPEC_VERSION >= 22], [_X(JVM_ExpandStackFrameInfo, JNICALL, false, void, JNIEnv *env, jobject object)]) _IF([JAVA_SPEC_VERSION == 22], diff --git a/runtime/vm/BytecodeAction.hpp b/runtime/vm/BytecodeAction.hpp index 9d13a0bd061..4268dae48c6 100644 --- a/runtime/vm/BytecodeAction.hpp +++ b/runtime/vm/BytecodeAction.hpp @@ -60,6 +60,9 @@ typedef enum { #if defined(J9VM_OPT_CRIU_SUPPORT) THROW_CRIU_SINGLE_THREAD_MODE, #endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + THROW_ILLEGAL_STATE_EXCEPTION, +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ /* All values after this line are for the debug interpreter only - add general values above this line */ GOTO_EXECUTE_BREAKPOINTED_BYTECODE, HANDLE_POP_FRAMES, diff --git a/runtime/vm/BytecodeInterpreter.hpp b/runtime/vm/BytecodeInterpreter.hpp index 4b59f06b959..7b2439828bc 100644 --- a/runtime/vm/BytecodeInterpreter.hpp +++ b/runtime/vm/BytecodeInterpreter.hpp @@ -4448,26 +4448,6 @@ class INTERPRETER_CLASS } #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) - /* jdk.internal.misc.Unsafe: public native V uninitializedDefaultValue(Class clz); */ - VMINLINE VM_BytecodeAction - inlUnsafeUninitializedDefaultValue(REGISTER_ARGS_LIST) - { - j9object_t cls = *(j9object_t*)_sp; - j9object_t result = NULL; - - /* TODO (#14073): update this function to have the same behavior as OpenJDK when cls is null or not a valuetype (currently OpenJDK segfaults in both those scenarios) */ - if (NULL != cls) { - J9Class *j9clazz = J9VM_J9CLASS_FROM_HEAPCLASS(_currentThread, cls); - if (J9_IS_J9CLASS_PRIMITIVE_VALUETYPE(j9clazz)) { - /* It is defaultValue for primitive value type, NULL for value class. */ - result = j9clazz->flattenedClassCache->defaultValue; - } - } - - returnObjectFromINL(REGISTER_ARGS, result, 2); - return EXECUTE_BYTECODE; - } - /* jdk.internal.misc.Unsafe: public native long valueHeaderSize(Class clz); */ VMINLINE VM_BytecodeAction inlUnsafeValueHeaderSize(REGISTER_ARGS_LIST) @@ -7702,6 +7682,21 @@ class INTERPRETER_CLASS /* Swap flags and class subfield order. */ classAndFlags = J9CLASSANDFLAGS_FROM_FLAGSANDCLASS(flagsAndClass); valueAddress = J9STATICADDRESS(flagsAndClass, valueOffset); + +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + if (J9ClassInitNotInitialized == (ramConstantPool->ramClass->initializeStatus & J9ClassInitStatusMask)) { + if (J9_STATIC_FIELD_STRICT_INIT_IS_UNSET(classAndFlags)) { + /* If a strict field has never been set, fail. */ + rc = THROW_ILLEGAL_STATE_EXCEPTION; + goto done; + } else if (J9_STATIC_FIELD_STRICT_INIT_WAS_WRITTEN(classAndFlags)) { + classAndFlags &= ~J9StaticFieldRefStrictInitMask; + classAndFlags |= J9StaticFieldRefStrictInitRead; + ramStaticFieldRef->flagsAndClass = J9FLAGSANDCLASS_FROM_CLASSANDFLAGS(classAndFlags); + } + } +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ + #if defined(DO_HOOKS) if (J9_EVENT_IS_HOOKED(_vm->hookInterface, J9HOOK_VM_GET_STATIC_FIELD)) { J9Class *fieldClass = (J9Class*)(classAndFlags & ~(UDATA)J9StaticFieldRefFlagBits); @@ -7753,6 +7748,9 @@ class INTERPRETER_CLASS UDATA volatile classAndFlags = 0; void* volatile valueAddress = NULL; void *resolveResult = NULL; +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + J9Class *ramClass = NULL; +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ if (J9_UNEXPECTED(!( VM_VMHelpers::staticFieldRefIsResolved(flagsAndClass, valueOffset) && @@ -7781,6 +7779,26 @@ class INTERPRETER_CLASS /* Swap flags and class subfield order. */ classAndFlags = J9CLASSANDFLAGS_FROM_FLAGSANDCLASS(flagsAndClass); valueAddress = J9STATICADDRESS(flagsAndClass, valueOffset); + +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + ramClass = ramConstantPool->ramClass; + if (J9ClassInitNotInitialized == (ramClass->initializeStatus & J9ClassInitStatusMask)) { + if (J9_STATIC_FIELD_STRICT_INIT_IS_UNSET(classAndFlags)) { + Assert_VM_true(ramClass->strictStaticFieldCounter > 0); + ramClass->strictStaticFieldCounter -= 1; + classAndFlags &= ~J9StaticFieldRefStrictInitMask; + classAndFlags |= J9StaticFieldRefStrictInitWritten; + ramStaticFieldRef->flagsAndClass = J9FLAGSANDCLASS_FROM_CLASSANDFLAGS(classAndFlags); + } else if (J9_STATIC_FIELD_STRICT_INIT_WAS_WRITTEN_AND_READ(classAndFlags) + && J9_ARE_ANY_BITS_SET(classAndFlags, J9StaticFieldRefFinal) + ) { + /* If the strict final field was read, fail. */ + rc = THROW_ILLEGAL_STATE_EXCEPTION; + goto done; + } + } +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ + #if defined(DO_HOOKS) if (J9_EVENT_IS_HOOKED(_vm->hookInterface, J9HOOK_VM_PUT_STATIC_FIELD)) { J9Class *fieldClass = (J9Class*)(classAndFlags & ~(UDATA)J9StaticFieldRefFlagBits); @@ -8297,13 +8315,20 @@ class INTERPRETER_CLASS rc = GOTO_THROW_CURRENT_EXCEPTION; goto done; } - if (J9_ARE_ALL_BITS_SET(romMethod->modifiers, J9AccAbstract)) { + if (J9_ARE_ALL_BITS_SET(romMethod->modifiers, J9AccAbstract) + && !J9ROMCLASS_IS_INTERFACE(J9_CLASS_FROM_METHOD(_sendMethod)->romClass) + ) { /* If resulting method is abstract an error will be * thrown in throwUnsatisfiedLinkOrAbstractMethodError. * Return the interface class's method so the correct * exception handling is used. */ - _sendMethod = interfaceClass->ramMethods + methodIndex; + _sendMethod = (J9Method*)javaLookupMethod( + _currentThread, + interfaceClass, + &romMethod->nameAndSignature, + NULL, + J9_LOOK_INTERFACE | J9_LOOK_NO_THROW | J9_LOOK_INVOKE_INTERFACE); } profileInvokeReceiver(REGISTER_ARGS, receiverClass, _literals, _sendMethod); _pc += offset; @@ -10668,7 +10693,6 @@ class INTERPRETER_CLASS JUMP_TABLE_ENTRY(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPLONG), JUMP_TABLE_ENTRY(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT), #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) - JUMP_TABLE_ENTRY(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_UNINITIALIZEDDEFAULTVALUE), JUMP_TABLE_ENTRY(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_VALUEHEADERSIZE), JUMP_TABLE_ENTRY(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECTSIZE), #endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */ @@ -10769,6 +10793,14 @@ class INTERPRETER_CLASS #define PERFORM_ACTION_CRIU_STM_THROW #endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) +#define PERFORM_ACTION_ILLEGAL_STATE_EXCEPTION \ + case THROW_ILLEGAL_STATE_EXCEPTION: \ + goto illegalStateException; +#else /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ +#define PERFORM_ACTION_ILLEGAL_STATE_EXCEPTION +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ + #define PERFORM_ACTION(functionCall) \ do { \ DEBUG_UPDATE_VMSTRUCT(); \ @@ -10827,6 +10859,7 @@ class INTERPRETER_CLASS goto i2j; \ PERFORM_ACTION_VALUE_TYPE_IMSE \ PERFORM_ACTION_CRIU_STM_THROW \ + PERFORM_ACTION_ILLEGAL_STATE_EXCEPTION \ DEBUG_ACTIONS \ default: \ Assert_VM_unreachable(); \ @@ -11278,8 +11311,6 @@ runMethod: { JUMP_TARGET(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT): PERFORM_ACTION(inlUnsafeCompareAndSwapInt(REGISTER_ARGS)); #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) - JUMP_TARGET(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_UNINITIALIZEDDEFAULTVALUE): - PERFORM_ACTION(inlUnsafeUninitializedDefaultValue(REGISTER_ARGS)); JUMP_TARGET(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_VALUEHEADERSIZE): PERFORM_ACTION(inlUnsafeValueHeaderSize(REGISTER_ARGS)); JUMP_TARGET(J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECTSIZE): @@ -11534,6 +11565,15 @@ arrayIndex: { VMStructHasBeenUpdated(REGISTER_ARGS); goto throwCurrentException; +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) +illegalStateException: + updateVMStruct(REGISTER_ARGS); + prepareForExceptionThrow(_currentThread); + setCurrentExceptionUTF(_currentThread, J9VMCONSTANTPOOL_JAVALANGILLEGALSTATEEXCEPTION, NULL); + VMStructHasBeenUpdated(REGISTER_ARGS); + goto throwCurrentException; +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ + negativeArraySize: updateVMStruct(REGISTER_ARGS); prepareForExceptionThrow(_currentThread); diff --git a/runtime/vm/ClassInitialization.cpp b/runtime/vm/ClassInitialization.cpp index d3e2b98d372..76496835adc 100644 --- a/runtime/vm/ClassInitialization.cpp +++ b/runtime/vm/ClassInitialization.cpp @@ -796,6 +796,19 @@ classInitStateMachine(J9VMThread *currentThread, J9Class *clazz, J9ClassInitStat clazz = VM_VMHelpers::currentClass(clazz); goto done; } +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + /* All strict static fields must be set by the end of . */ + if (clazz->strictStaticFieldCounter > 0) { + J9UTF8 *className = J9ROMCLASS_CLASSNAME(clazz->romClass); + setCurrentExceptionNLSWithArgs( + currentThread, + J9NLS_VM_CLASS_LOADING_ERROR_STRICT_STATIC_FIELDS_UNSET, + J9VMCONSTANTPOOL_JAVALANGILLEGALSTATEEXCEPTION, + J9UTF8_LENGTH(className), + J9UTF8_DATA(className)); + goto initFailed; + } +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ initializationLock = setInitStatus(currentThread, clazz, J9ClassInitSucceeded, initializationLock); clazz = VM_VMHelpers::currentClass(clazz); classObject = J9VM_J9CLASS_TO_HEAPCLASS(clazz); diff --git a/runtime/vm/ContinuationHelpers.cpp b/runtime/vm/ContinuationHelpers.cpp index 4af5486864b..3cf8dc8e4a4 100644 --- a/runtime/vm/ContinuationHelpers.cpp +++ b/runtime/vm/ContinuationHelpers.cpp @@ -469,16 +469,15 @@ isPinnedContinuation(J9VMThread *currentThread) if (currentThread->continuationPinCount > 0) { result = J9VM_CONTINUATION_PINNED_REASON_CRITICAL_SECTION; } else if (currentThread->callOutCount > 0) { - /* TODO: This check should be changed from > 1 to > 0 once the call-ins are no - * longer used and the new design for single cInterpreter is implemented. - */ result = J9VM_CONTINUATION_PINNED_REASON_NATIVE; +#if JAVA_SPEC_VERSION < 26 } else if ((currentThread->ownedMonitorCount > 0) #if JAVA_SPEC_VERSION >= 24 && J9_ARE_NO_BITS_SET(currentThread->javaVM->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION) #endif /* JAVA_SPEC_VERSION >= 24 */ ) { result = J9VM_CONTINUATION_PINNED_REASON_MONITOR; +#endif /* JAVA_SPEC_VERSION < 26 */ } else { /* Do nothing. */ } diff --git a/runtime/vm/JFRChunkWriter.cpp b/runtime/vm/JFRChunkWriter.cpp index dbdce52e556..9096ca63596 100644 --- a/runtime/vm/JFRChunkWriter.cpp +++ b/runtime/vm/JFRChunkWriter.cpp @@ -940,7 +940,7 @@ VM_JFRChunkWriter::writeInitialEnvironmentVariableEvents() if (result >= 0) { int32_t bufferSize = result; - void *buffer = j9mem_allocate_memory(bufferSize, OMRMEM_CATEGORY_VM); + void *buffer = j9mem_allocate_memory(bufferSize, J9MEM_CATEGORY_JFR); if (NULL != buffer) { J9SysinfoEnvElement envElement = {NULL}; @@ -1003,6 +1003,56 @@ VM_JFRChunkWriter::writeClassLoadingStatisticsEvent(void *anElement, void *userD writeEventSize(_bufferWriter, dataStart); } +void +VM_JFRChunkWriter::writeClassLoaderStatisticsEvent(void *anElement, void *userData) +{ + ClassLoaderStatisticsEntry *entry = (ClassLoaderStatisticsEntry *)anElement; + VM_BufferWriter *_bufferWriter = (VM_BufferWriter *)userData; + + /* reserve size field */ + U_8 *dataStart = reserveEventSize(_bufferWriter); + + /* write event type */ + _bufferWriter->writeLEB128(ClassLoaderStatisticsID); + + /* write start time */ + _bufferWriter->writeLEB128(entry->ticks); + + /* write classLoader */ + _bufferWriter->writeLEB128(entry->classLoaderIndex); + + /* write parent classLoader */ + _bufferWriter->writeLEB128(entry->parentClassLoaderIndex); + + /* write pointer to J9ClassLoader */ + _bufferWriter->writeLEB128(entry->classLoaderData); + + /* write loaded class count */ + _bufferWriter->writeLEB128(entry->classCount); + + /* write size of all memory segments */ + _bufferWriter->writeLEB128(entry->chunkSize); + + /* write used size of all memory segments */ + if (entry->blockSize >= 0) { + _bufferWriter->writeLEB128((U_64)entry->blockSize); + } else { + _bufferWriter->writeLEB128(0); + } + + /* write hidden/anon class count */ + _bufferWriter->writeLEB128(entry->hiddenClassCount); + + /* write size of all hidden/anon memory segments */ + _bufferWriter->writeLEB128(entry->hiddenChunkSize); + + /* write used size of all hidden/anon memory segments */ + _bufferWriter->writeLEB128(entry->hiddenBlockSize); + + /* write size */ + writeEventSize(_bufferWriter, dataStart); +} + void VM_JFRChunkWriter::writeThreadContextSwitchRateEvent(void *anElement, void *userData) { @@ -1300,7 +1350,7 @@ VM_JFRChunkWriter::writeThreadDumpEvent() _bufferWriter->writeLEB128(j9time_nano_time()); const U_64 bufferSize = THREAD_DUMP_EVENT_SIZE_PER_THREAD * _vm->peakThreadCount; - U_8 *resultBuffer = (U_8 *)j9mem_allocate_memory(sizeof(U_8) * bufferSize, OMRMEM_CATEGORY_VM); + U_8 *resultBuffer = (U_8 *)j9mem_allocate_memory(sizeof(U_8) * bufferSize, J9MEM_CATEGORY_JFR); if (NULL != resultBuffer) { VM_BufferWriter resultWriter(privatePortLibrary, resultBuffer, bufferSize); diff --git a/runtime/vm/JFRChunkWriter.hpp b/runtime/vm/JFRChunkWriter.hpp index 59e10b02f74..d5252d7b1ed 100644 --- a/runtime/vm/JFRChunkWriter.hpp +++ b/runtime/vm/JFRChunkWriter.hpp @@ -85,6 +85,7 @@ enum MetadataTypeID { ThreadContextSwitchRateID = 97, ThreadStatisticsID = 99, ClassLoadingStatisticsID = 100, + ClassLoaderStatisticsID = 101, PhysicalMemoryID = 108, ExecutionSampleID = 109, ThreadDumpID = 111, @@ -188,6 +189,7 @@ class VM_JFRChunkWriter { static constexpr int THREAD_CPU_LOAD_EVENT_SIZE = (2 * sizeof(float)) + (4 * sizeof(I_64)); static constexpr int INITIAL_ENVIRONMENT_VARIABLE_EVENT_SIZE = 6000; static constexpr int CLASS_LOADING_STATISTICS_EVENT_SIZE = 5 * sizeof(I_64); + static constexpr int CLASS_LOADER_STATISTICS_EVENT_SIZE = (3 * LEB128_32_SIZE) + (9 * LEB128_64_SIZE); static constexpr int THREAD_CONTEXT_SWITCH_RATE_SIZE = sizeof(float) + (3 * sizeof(I_64)); static constexpr int THREAD_STATISTICS_EVENT_SIZE = (6 * sizeof(U_64)) + sizeof(U_32); static constexpr int THREAD_DUMP_EVENT_SIZE_PER_THREAD = 1000; @@ -344,7 +346,7 @@ class VM_JFRChunkWriter { goto done; } - buffer = (U_8 *)j9mem_allocate_memory(requiredBufferSize, J9MEM_CATEGORY_CLASSES); + buffer = (U_8 *)j9mem_allocate_memory(requiredBufferSize, J9MEM_CATEGORY_JFR); if (NULL == buffer) { _buildResult = OutOfMemory; } else { @@ -404,6 +406,8 @@ class VM_JFRChunkWriter { pool_do(_constantPoolTypes.getClassLoadingStatisticsTable(), &writeClassLoadingStatisticsEvent, _bufferWriter); + pool_do(_constantPoolTypes.getClassLoaderStatisticsTable(), &writeClassLoaderStatisticsEvent, _bufferWriter); + pool_do(_constantPoolTypes.getThreadContextSwitchRateTable(), &writeThreadContextSwitchRateEvent, _bufferWriter); pool_do(_constantPoolTypes.getThreadStatisticsTable(), &writeThreadStatisticsEvent, _bufferWriter); @@ -846,6 +850,8 @@ class VM_JFRChunkWriter { static void writeClassLoadingStatisticsEvent(void *anElement, void *userData); + static void writeClassLoaderStatisticsEvent(void *anElement, void *userData); + static void writeThreadContextSwitchRateEvent(void *anElement, void *userData); static void writeThreadStatisticsEvent(void *anElement, void *userData); @@ -926,6 +932,8 @@ class VM_JFRChunkWriter { requiredBufferSize += _constantPoolTypes.getClassLoadingStatisticsCount() * CLASS_LOADING_STATISTICS_EVENT_SIZE; + requiredBufferSize += _constantPoolTypes.getClassLoaderStatisticsCount() * CLASS_LOADER_STATISTICS_EVENT_SIZE; + requiredBufferSize += _constantPoolTypes.getThreadContextSwitchRateCount() * THREAD_CONTEXT_SWITCH_RATE_SIZE; requiredBufferSize += _constantPoolTypes.getThreadStatisticsCount() * THREAD_STATISTICS_EVENT_SIZE; diff --git a/runtime/vm/JFRConstantPoolTypes.cpp b/runtime/vm/JFRConstantPoolTypes.cpp index 78e5a3bc65e..c0d1dfa8830 100644 --- a/runtime/vm/JFRConstantPoolTypes.cpp +++ b/runtime/vm/JFRConstantPoolTypes.cpp @@ -555,7 +555,7 @@ VM_JFRConstantPoolTypes::addPackageEntry(J9Module *fromModule, J9Package *packag /* Account for the length field. */ if (pkgNameLen > (NAME_BUFFER_SIZE - sizeof(J9UTF8))) { UDATA allocationSize = sizeof(J9ROMClass) + sizeof(J9UTF8) + pkgNameLen; - queryROMClass = (J9ROMClass *)j9mem_allocate_memory(allocationSize, J9MEM_CATEGORY_VM); + queryROMClass = (J9ROMClass *)j9mem_allocate_memory(allocationSize, J9MEM_CATEGORY_JFR); if (NULL == queryROMClass) { _buildResult = OutOfMemory; goto done; diff --git a/runtime/vm/JFRConstantPoolTypes.hpp b/runtime/vm/JFRConstantPoolTypes.hpp index d84285cd6fc..e8ee11098a1 100644 --- a/runtime/vm/JFRConstantPoolTypes.hpp +++ b/runtime/vm/JFRConstantPoolTypes.hpp @@ -261,6 +261,19 @@ struct ClassLoadingStatisticsEntry { I_64 unloadedClassCount; }; +struct ClassLoaderStatisticsEntry { + I_64 ticks; + U_32 classLoaderIndex; + U_32 parentClassLoaderIndex; + U_64 classLoaderData; + I_64 classCount; + U_64 chunkSize; + I_64 blockSize; + I_64 hiddenClassCount; + U_64 hiddenChunkSize; + U_64 hiddenBlockSize; +}; + struct ThreadContextSwitchRateEntry { I_64 ticks; float switchRate; @@ -410,6 +423,8 @@ class VM_JFRConstantPoolTypes { UDATA _threadCPULoadCount; J9Pool *_classLoadingStatisticsTable; UDATA _classLoadingStatisticsCount; + J9Pool *_classLoaderStatisticsTable; + UDATA _classLoaderStatisticsCount; J9Pool *_threadContextSwitchRateTable; UDATA _threadContextSwitchRateCount; J9Pool *_threadStatisticsTable; @@ -624,7 +639,7 @@ class VM_JFRConstantPoolTypes { void mergeStringTables() { _buildResult = OK; - _globalStringTable = (void **)j9mem_allocate_memory(sizeof(void *) * (_stringUTF8Count + _packageCount), J9MEM_CATEGORY_CLASSES); + _globalStringTable = (void **)j9mem_allocate_memory(sizeof(void *) * (_stringUTF8Count + _packageCount), J9MEM_CATEGORY_JFR); if (NULL == _globalStringTable) { _buildResult = OutOfMemory; goto done; @@ -757,6 +772,11 @@ class VM_JFRConstantPoolTypes { return _classLoadingStatisticsTable; } + J9Pool *getClassLoaderStatisticsTable() + { + return _classLoaderStatisticsTable; + } + J9Pool *getThreadContextSwitchRateTable() { return _threadContextSwitchRateTable; @@ -847,6 +867,11 @@ class VM_JFRConstantPoolTypes { return _classLoadingStatisticsCount; } + UDATA getClassLoaderStatisticsCount() + { + return _classLoaderStatisticsCount; + } + UDATA getThreadContextSwitchRateCount() { return _threadContextSwitchRateCount; @@ -1071,6 +1096,7 @@ class VM_JFRConstantPoolTypes { loadSystemProcesses(_currentThread); loadNativeLibraries(_currentThread); loadModuleRequireAndModuleExportEvents(); + loadClassLoaderStatisticsEvents(_currentThread); } shallowEntries = pool_new(sizeof(ClassEntry **), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary)); @@ -1101,7 +1127,7 @@ class VM_JFRConstantPoolTypes { expandedStackTraceCount = iterateStackTraceImpl(_currentThread, (j9object_t *)walkStateCache, NULL, NULL, FALSE, FALSE, numberOfFrames, FALSE); - _currentStackFrameBuffer = (StackFrame *)j9mem_allocate_memory(sizeof(StackFrame) * expandedStackTraceCount, J9MEM_CATEGORY_CLASSES); + _currentStackFrameBuffer = (StackFrame *)j9mem_allocate_memory(sizeof(StackFrame) * expandedStackTraceCount, J9MEM_CATEGORY_JFR); _currentFrameCount = 0; if (NULL == _currentStackFrameBuffer) { _buildResult = OutOfMemory; @@ -1176,7 +1202,7 @@ class VM_JFRConstantPoolTypes { vmArgsLen += strlen(vmArgs->options[i].optionString); } - jvmInformation->jvmArguments = (char *)j9mem_allocate_memory(vmArgsLen, OMRMEM_CATEGORY_VM); + jvmInformation->jvmArguments = (char *)j9mem_allocate_memory(vmArgsLen, J9MEM_CATEGORY_JFR); char *cursor = jvmInformation->jvmArguments; if (NULL != cursor) { @@ -1237,7 +1263,7 @@ class VM_JFRConstantPoolTypes { char buffer[1024]; omrsysinfo_get_processor_feature_string(&desc, buffer, sizeof(buffer)); UDATA len = strlen(buffer) + 1; - cpuInformation->description = (char *)j9mem_allocate_memory(len, OMRMEM_CATEGORY_VM); + cpuInformation->description = (char *)j9mem_allocate_memory(len, J9MEM_CATEGORY_JFR); if (NULL != cpuInformation->description) { memcpy(cpuInformation->description, buffer, len); } else { @@ -1314,7 +1340,7 @@ class VM_JFRConstantPoolTypes { UDATA len = 3 + strlen(osName) + strlen(osVersion) + strlen(osArch); - getJFRConstantEvents(vm)->OSInfoEntry.osVersion = (char *)j9mem_allocate_memory(len, OMRMEM_CATEGORY_VM); + getJFRConstantEvents(vm)->OSInfoEntry.osVersion = (char *)j9mem_allocate_memory(len, J9MEM_CATEGORY_JFR); char *buffer = getJFRConstantEvents(vm)->OSInfoEntry.osVersion; if (NULL == buffer) { *result = OutOfMemory; @@ -1396,7 +1422,7 @@ class VM_JFRConstantPoolTypes { PORT_ACCESS_FROM_JAVAVM(constantPoolTypes->_vm); J9Pool *systemProcessTable = constantPoolTypes->getSystemProcessTable(); UDATA cmdLength = strlen(commandLine); - char *commandLineCopy = reinterpret_cast(j9mem_allocate_memory(cmdLength + 1, OMRMEM_CATEGORY_VM)); + char *commandLineCopy = reinterpret_cast(j9mem_allocate_memory(cmdLength + 1, J9MEM_CATEGORY_JFR)); if (NULL == commandLineCopy) { constantPoolTypes->_buildResult = OutOfMemory; return ~(uintptr_t)0; @@ -1442,7 +1468,7 @@ class VM_JFRConstantPoolTypes { } } size_t libraryNameLength = strlen(libraryName); - char *libraryNameCopy = (char *)j9mem_allocate_memory(libraryNameLength + 1, OMRMEM_CATEGORY_VM); + char *libraryNameCopy = (char *)j9mem_allocate_memory(libraryNameLength + 1, J9MEM_CATEGORY_JFR); if (NULL == libraryNameCopy) { /* Allocation for library name failed. */ constantPoolTypes->_buildResult = OutOfMemory; @@ -1484,9 +1510,9 @@ class VM_JFRConstantPoolTypes { J9ClassLoaderWalkState walkState; J9ClassLoader *classLoader = vmFuncs->allClassLoadersStartDo(&walkState, _vm, 0); int64_t time = j9time_nano_time(); -#ifdef J9VM_THR_PREEMPTIVE +#if defined(J9VM_THR_PREEMPTIVE) omrthread_monitor_enter(_vm->classLoaderModuleAndLocationMutex); -#endif +#endif /* defined(J9VM_THR_PREEMPTIVE) */ while (NULL != classLoader) { J9HashTableState moduleWalkState; @@ -1554,9 +1580,89 @@ class VM_JFRConstantPoolTypes { classLoader = vmFuncs->allClassLoadersNextDo(&walkState); } done: -#ifdef J9VM_THR_PREEMPTIVE +#if defined(J9VM_THR_PREEMPTIVE) omrthread_monitor_exit(_vm->classLoaderModuleAndLocationMutex); -#endif +#endif /* defined(J9VM_THR_PREEMPTIVE) */ + vmFuncs->allClassLoadersEndDo(&walkState); + } + + /** + * @brief Generate and add ClassLoaderStatistics events to _classLoaderStatisticsTable. + * + * @param currentThread[in] The pointer to the current J9VMThread + */ + void loadClassLoaderStatisticsEvents(J9VMThread *currentThread) + { + J9InternalVMFunctions *vmFuncs = _vm->internalVMFunctions; + J9ClassLoaderWalkState walkState; + J9ClassLoader *classLoader = vmFuncs->allClassLoadersStartDo(&walkState, _vm, 0); + int64_t time = j9time_nano_time(); + +#if defined(J9VM_THR_PREEMPTIVE) + omrthread_monitor_enter(_vm->classTableMutex); +#endif /* defined(J9VM_THR_PREEMPTIVE) */ + + while (NULL != classLoader) { + ClassLoaderStatisticsEntry *entry = (ClassLoaderStatisticsEntry *)pool_newElement(_classLoaderStatisticsTable); + if (NULL == entry) { + _buildResult = OutOfMemory; + goto done; + } + memset(entry, 0, sizeof(*entry)); + + entry->ticks = time; + entry->classLoaderIndex = addClassLoaderEntry(classLoader); + if (isResultNotOKay()) { + goto done; + } + j9object_t parentLoaderObject = J9VMJAVALANGCLASSLOADER_PARENT(currentThread, classLoader->classLoaderObject); + if (NULL != parentLoaderObject) { + J9ClassLoader *parentClassLoader = J9VMJAVALANGCLASSLOADER_VMREF(currentThread, parentLoaderObject); + if (NULL != parentClassLoader) { + entry->parentClassLoaderIndex = addClassLoaderEntry(parentClassLoader); + if (isResultNotOKay()) { + goto done; + } + } + } + entry->classLoaderData = (U_64)classLoader; + entry->classCount = hashTableGetCount(classLoader->classHashTable); + + J9MemorySegment *segment = classLoader->classSegments; + while (NULL != segment) { + entry->chunkSize += segment->heapAlloc - segment->baseAddress; + segment = segment->nextSegment; + } + + entry->blockSize = (I_64)entry->chunkSize; + + J9RAMClassFreeLists *sub4gBlockPtr = &classLoader->sub4gBlock; + J9RAMClassFreeLists *frequentlyAccessedBlockPtr = &classLoader->frequentlyAccessedBlock; + J9RAMClassFreeLists *inFrequentlyAccessedBlockPtr = &classLoader->inFrequentlyAccessedBlock; + UDATA *ramClassSub4gUDATABlockFreeListPtr = sub4gBlockPtr->ramClassUDATABlockFreeList; + UDATA *ramClassFreqUDATABlockFreeListPtr = frequentlyAccessedBlockPtr->ramClassUDATABlockFreeList; + UDATA *ramClassInFreqUDATABlockFreeListPtr = inFrequentlyAccessedBlockPtr->ramClassUDATABlockFreeList; + + VM_VMHelpers::subtractUDATABlockChain(ramClassSub4gUDATABlockFreeListPtr, &entry->blockSize); + VM_VMHelpers::subtractUDATABlockChain(ramClassFreqUDATABlockFreeListPtr, &entry->blockSize); + VM_VMHelpers::subtractUDATABlockChain(ramClassInFreqUDATABlockFreeListPtr, &entry->blockSize); + + VM_VMHelpers::subtractFreeListBlocks(sub4gBlockPtr, &entry->blockSize); + VM_VMHelpers::subtractFreeListBlocks(frequentlyAccessedBlockPtr, &entry->blockSize); + VM_VMHelpers::subtractFreeListBlocks(inFrequentlyAccessedBlockPtr, &entry->blockSize); + + entry->hiddenClassCount = 0; + entry->hiddenChunkSize = 0; + entry->hiddenBlockSize = 0; + + classLoader = vmFuncs->allClassLoadersNextDo(&walkState); + } + +done: +#if defined(J9VM_THR_PREEMPTIVE) + omrthread_monitor_exit(_vm->classTableMutex); +#endif /* defined(J9VM_THR_PREEMPTIVE) */ + vmFuncs->allClassLoadersEndDo(&walkState); } @@ -1605,6 +1711,8 @@ class VM_JFRConstantPoolTypes { , _threadCPULoadCount(0) , _classLoadingStatisticsTable(NULL) , _classLoadingStatisticsCount(0) + , _classLoaderStatisticsTable(NULL) + , _classLoaderStatisticsCount(0) , _threadContextSwitchRateTable(NULL) , _threadContextSwitchRateCount(0) , _threadStatisticsTable(NULL) @@ -1755,6 +1863,12 @@ class VM_JFRConstantPoolTypes { goto done; } + _classLoaderStatisticsTable = pool_new(sizeof(ClassLoaderStatisticsEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary)); + if (NULL == _classLoaderStatisticsTable) { + _buildResult = OutOfMemory; + goto done; + } + _threadContextSwitchRateTable = pool_new(sizeof(ThreadContextSwitchRateEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary)); if (NULL == _threadContextSwitchRateTable) { _buildResult = OutOfMemory; @@ -1888,6 +2002,7 @@ class VM_JFRConstantPoolTypes { pool_kill(_cpuLoadTable); pool_kill(_threadCPULoadTable); pool_kill(_classLoadingStatisticsTable); + pool_kill(_classLoaderStatisticsTable); pool_kill(_threadContextSwitchRateTable); pool_kill(_threadStatisticsTable); pool_kill(_systemProcessTable); diff --git a/runtime/vm/KeyHashTable.c b/runtime/vm/KeyHashTable.c index d5027389599..f1e3a7c964b 100644 --- a/runtime/vm/KeyHashTable.c +++ b/runtime/vm/KeyHashTable.c @@ -349,6 +349,17 @@ hashClassTableAt(J9ClassLoader *classLoader, U_8 *className, UDATA classNameLeng if (J9ROMCLASS_IS_HIDDEN(clazz->romClass)) { return NULL; } + /* Frozen classes are not loaded, so they should not be returned with J9_FINDCLASS_FLAG_EXISTING_ONLY. */ + if (J9_ARE_ANY_BITS_SET(flags, J9_FINDCLASS_FLAG_EXISTING_ONLY) + && J9_ARE_ANY_BITS_SET(clazz->classFlags, J9ClassIsFrozen) + ) { + return NULL; + } + if (J9_ARE_NO_BITS_SET(flags, J9_FINDCLASS_FLAG_DONT_SKIP_FROZEN_JCL_DEFINE_CLASS) + && J9_ARE_ALL_BITS_SET(clazz->classFlags, J9ClassIsJCLDefineClass | J9ClassIsFrozen) + ) { + return NULL; + } return clazz; } else { return NULL; @@ -748,6 +759,17 @@ hashClassTableAtString(J9ClassLoader *classLoader, j9object_t stringObject, UDAT if (J9ROMCLASS_IS_HIDDEN(clazz->romClass)) { return NULL; } + /* Frozen classes are not loaded, so they should not be returned with J9_FINDCLASS_FLAG_EXISTING_ONLY. */ + if (J9_ARE_ANY_BITS_SET(flags, J9_FINDCLASS_FLAG_EXISTING_ONLY) + && J9_ARE_ANY_BITS_SET(clazz->classFlags, J9ClassIsFrozen) + ) { + return NULL; + } + if (J9_ARE_NO_BITS_SET(flags, J9_FINDCLASS_FLAG_DONT_SKIP_FROZEN_JCL_DEFINE_CLASS) + && J9_ARE_ALL_BITS_SET(clazz->classFlags, J9ClassIsJCLDefineClass | J9ClassIsFrozen) + ) { + return NULL; + } return clazz; } return NULL; diff --git a/runtime/vm/VMSnapshotImpl.cpp b/runtime/vm/VMSnapshotImpl.cpp index da819d8b9c3..4333677045a 100644 --- a/runtime/vm/VMSnapshotImpl.cpp +++ b/runtime/vm/VMSnapshotImpl.cpp @@ -890,7 +890,9 @@ VMSnapshotImpl::saveJ9JavaVMStructures() saveMemorySegments(); savePrimitiveAndArrayClasses(); saveHiddenInstanceFields(); +#if JAVA_SPEC_VERSION > 8 saveModularityData(); +#endif /* JAVA_SPEC_VERSION > 8 */ _snapshotHeader->vm = _vm; } @@ -907,7 +909,9 @@ VMSnapshotImpl::restoreJ9JavaVMStructures() restoreMemorySegments(); restorePrimitiveAndArrayClasses(); restoreHiddenInstanceFields(); +#if JAVA_SPEC_VERSION > 8 restoreModularityData(); +#endif /* JAVA_SPEC_VERSION > 8 */ if (J9THREAD_RWMUTEX_OK != omrthread_rwmutex_init(&_vm->systemClassLoader->cpEntriesMutex, 0, "classPathEntries Mutex")) { success = false; diff --git a/runtime/vm/VMSnapshotImpl.hpp b/runtime/vm/VMSnapshotImpl.hpp index bae5d1b24b4..f28afd5c17c 100644 --- a/runtime/vm/VMSnapshotImpl.hpp +++ b/runtime/vm/VMSnapshotImpl.hpp @@ -112,8 +112,10 @@ class VMSnapshotImpl void restoreClassLoaderBlocks(); void saveMemorySegments(); void restoreMemorySegments(); +#if JAVA_SPEC_VERSION > 8 void saveModularityData(); void restoreModularityData(); +#endif /* JAVA_SPEC_VERSION > 8 */ bool setupRestoreRun(); bool setupSnapshotRun(); diff --git a/runtime/vm/bindnatv.cpp b/runtime/vm/bindnatv.cpp index 0e35c187aad..e7945bc7fb8 100644 --- a/runtime/vm/bindnatv.cpp +++ b/runtime/vm/bindnatv.cpp @@ -113,6 +113,7 @@ static inlMapping mappings[] = { { "Java_java_lang_J9VMInternals_newInstanceImpl__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_INTERNALS_NEWINSTANCEIMPL }, { "Java_java_lang_J9VMInternals_primitiveClone__Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_INTERNALS_PRIMITIVE_CLONE }, { "Java_java_lang_ref_Reference_getImpl__", J9_BCLOOP_SEND_TARGET_INL_REFERENCE_GETIMPL }, +#if JAVA_SPEC_VERSION < 11 { "Java_sun_misc_Unsafe_getByte__J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETBYTE_NATIVE }, { "Java_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETBYTE }, { "Java_sun_misc_Unsafe_getByteVolatile__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETBYTE_VOLATILE }, @@ -179,6 +180,7 @@ static inlMapping mappings[] = { { "Java_sun_misc_Unsafe_compareAndSwapObject__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPOBJECT }, { "Java_sun_misc_Unsafe_compareAndSwapLong__Ljava_lang_Object_2JJJ", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPLONG }, { "Java_sun_misc_Unsafe_compareAndSwapInt__Ljava_lang_Object_2JII", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT }, +#endif /* JAVA_SPEC_VERSION < 11 */ { "Java_java_lang_J9VMInternals_prepareClassImpl__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_INTERNALS_PREPARE_CLASS_IMPL }, { "Java_java_lang_J9VMInternals_getInterfaces__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_INTERNALS_GET_INTERFACES }, { "Java_java_lang_reflect_Array_newArrayImpl__Ljava_lang_Class_2I", J9_BCLOOP_SEND_TARGET_INL_ARRAY_NEW_ARRAY_IMPL }, @@ -198,7 +200,9 @@ static inlMapping mappings[] = { { "Java_com_ibm_oti_vm_VM_initializeClassLoader__Ljava_lang_ClassLoader_2IZ", J9_BCLOOP_SEND_TARGET_INL_VM_INITIALIZE_CLASS_LOADER }, { "Java_com_ibm_oti_vm_VM_getClassPathEntryType__Ljava_lang_Object_2I", J9_BCLOOP_SEND_TARGET_INL_VM_GET_CLASS_PATH_ENTRY_TYPE }, { "Java_com_ibm_oti_vm_VM_isBootstrapClassLoader__Ljava_lang_ClassLoader_2", J9_BCLOOP_SEND_TARGET_INL_VM_IS_BOOTSTRAP_CLASS_LOADER }, +#if JAVA_SPEC_VERSION < 11 { "Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_ALLOCATE_INSTANCE }, +#endif /* JAVA_SPEC_VERSION < 11 */ { "Java_openj9_internal_tools_attach_target_Attachment_loadAgentLibraryImpl__ZLjava_lang_ClassLoader_2Ljava_lang_String_2Ljava_lang_String_2Z", J9_BCLOOP_SEND_TARGET_INL_ATTACHMENT_LOADAGENTLIBRARYIMPL }, { "Java_com_ibm_oti_vm_VM_getStackClass__I", J9_BCLOOP_SEND_TARGET_INL_VM_GETSTACKCLASS }, /* Forward duplicated getStackClass natives to the same target */ @@ -257,10 +261,12 @@ static inlMapping mappings[] = { { "Java_jdk_internal_misc_Unsafe_putDouble__JD", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTDOUBLE_NATIVE }, { "Java_jdk_internal_misc_Unsafe_putDouble__Ljava_lang_Object_2JD", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTDOUBLE }, { "Java_jdk_internal_misc_Unsafe_putDoubleVolatile__Ljava_lang_Object_2JD", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTDOUBLE_VOLATILE }, +#if JAVA_SPEC_VERSION < 23 { "Java_jdk_internal_misc_Unsafe_getObject__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECT }, { "Java_jdk_internal_misc_Unsafe_getObjectVolatile__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECT_VOLATILE }, { "Java_jdk_internal_misc_Unsafe_putObject__Ljava_lang_Object_2JLjava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTOBJECT }, { "Java_jdk_internal_misc_Unsafe_putObjectVolatile__Ljava_lang_Object_2JLjava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTOBJECT_VOLATILE }, +#endif /* JAVA_SPEC_VERSION < 23 */ { "Java_jdk_internal_misc_Unsafe_getReference__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECT }, { "Java_jdk_internal_misc_Unsafe_getReferenceVolatile__Ljava_lang_Object_2J", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECT_VOLATILE }, { "Java_jdk_internal_misc_Unsafe_putReference__Ljava_lang_Object_2JLjava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_PUTOBJECT }, @@ -279,13 +285,14 @@ static inlMapping mappings[] = { { "Java_jdk_internal_misc_Unsafe_compareAndSwapObject__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPOBJECT }, { "Java_jdk_internal_misc_Unsafe_compareAndSwapLong__Ljava_lang_Object_2JJJ", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPLONG }, { "Java_jdk_internal_misc_Unsafe_compareAndSwapInt__Ljava_lang_Object_2JII", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT }, +#if JAVA_SPEC_VERSION < 23 { "Java_jdk_internal_misc_Unsafe_compareAndSetObject__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPOBJECT }, +#endif /* JAVA_SPEC_VERSION < 23 */ { "Java_jdk_internal_misc_Unsafe_compareAndSetReference__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPOBJECT }, { "Java_jdk_internal_misc_Unsafe_compareAndSetLong__Ljava_lang_Object_2JJJ", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPLONG }, { "Java_jdk_internal_misc_Unsafe_compareAndSetInt__Ljava_lang_Object_2JII", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_COMPAREANDSWAPINT }, { "Java_jdk_internal_misc_Unsafe_allocateInstance__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_ALLOCATE_INSTANCE }, #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) - { "Java_jdk_internal_misc_Unsafe_uninitializedDefaultValue__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_UNINITIALIZEDDEFAULTVALUE }, { "Java_jdk_internal_misc_Unsafe_valueHeaderSize__Ljava_lang_Class_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_VALUEHEADERSIZE }, { "Java_jdk_internal_misc_Unsafe_getObjectSize__Ljava_lang_Object_2", J9_BCLOOP_SEND_TARGET_INL_UNSAFE_GETOBJECTSIZE }, #endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */ @@ -327,8 +334,12 @@ typedef struct J9OutOfLineINLMapping { static J9OutOfLineINLMapping outOfLineINLmappings[] = { { "Java_jdk_internal_misc_Unsafe_fullFence__", OutOfLineINL_jdk_internal_misc_Unsafe_fullFence }, +#if JAVA_SPEC_VERSION < 11 { "Java_sun_misc_Unsafe_fullFence__", OutOfLineINL_jdk_internal_misc_Unsafe_fullFence }, +#endif /* JAVA_SPEC_VERSION < 11 */ +#if JAVA_SPEC_VERSION < 23 { "Java_jdk_internal_misc_Unsafe_compareAndExchangeObject__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", OutOfLineINL_jdk_internal_misc_Unsafe_compareAndExchangeObject }, +#endif /* JAVA_SPEC_VERSION < 23 */ { "Java_jdk_internal_misc_Unsafe_compareAndExchangeReference__Ljava_lang_Object_2JLjava_lang_Object_2Ljava_lang_Object_2", OutOfLineINL_jdk_internal_misc_Unsafe_compareAndExchangeObject }, { "Java_jdk_internal_misc_Unsafe_compareAndExchangeInt__Ljava_lang_Object_2JII", OutOfLineINL_jdk_internal_misc_Unsafe_compareAndExchangeInt }, { "Java_jdk_internal_misc_Unsafe_compareAndExchangeLong__Ljava_lang_Object_2JJJ", OutOfLineINL_jdk_internal_misc_Unsafe_compareAndExchangeLong }, diff --git a/runtime/vm/classsupport.c b/runtime/vm/classsupport.c index 1164561d0b2..8c0f402d949 100644 --- a/runtime/vm/classsupport.c +++ b/runtime/vm/classsupport.c @@ -324,7 +324,7 @@ internalFindClassString(J9VMThread* currentThread, j9object_t moduleName, j9obje if (!fastMode) { omrthread_monitor_enter(vm->classTableMutex); } - result = hashClassTableAtString(classLoader, (j9object_t) className, 0); + result = hashClassTableAtString(classLoader, (j9object_t) className, options); #if defined(J9VM_OPT_SNAPSHOTS) if ((NULL != result) && IS_RESTORE_RUN(vm)) { if (!loadWarmClassFromSnapshot(currentThread, classLoader, result)) { @@ -1086,6 +1086,7 @@ loadWarmClassFromSnapshotInternal(J9VMThread *vmThread, J9ClassLoader *classLoad } } +#if JAVA_SPEC_VERSION > 8 /* TODO: Handle/trace error/NULL paths. */ classObject = clazz->classObject; if (NULL != classObject) { @@ -1100,6 +1101,7 @@ loadWarmClassFromSnapshotInternal(J9VMThread *vmThread, J9ClassLoader *classLoad J9VMJAVALANGCLASS_SET_MODULE(vmThread, classObject, J9VMJAVALANGCLASSLOADER_UNNAMEDMODULE(vmThread, clazz->classLoader->classLoaderObject)); } } +#endif /* JAVA_SPEC_VERSION > 8 */ Trc_VM_snapshot_loadWarmClassFromSnapshot_ClassInfo(vmThread, clazz, className); } @@ -1181,7 +1183,7 @@ loadNonArrayClass(J9VMThread* vmThread, J9Module *j9module, U_8* className, UDAT omrthread_monitor_enter(vm->classTableMutex); } - foundClass = hashClassTableAt(classLoader, className, classNameLength, 0); + foundClass = hashClassTableAt(classLoader, className, classNameLength, options); if (NULL != foundClass) { #if defined(J9VM_OPT_SNAPSHOTS) if (IS_RESTORE_RUN(vm)) { @@ -1212,7 +1214,7 @@ loadNonArrayClass(J9VMThread* vmThread, J9Module *j9module, U_8* className, UDAT omrthread_monitor_enter(vm->classTableMutex); /* check again if somebody else already loaded the class */ - foundClass = hashClassTableAt(classLoader, className, classNameLength, 0); + foundClass = hashClassTableAt(classLoader, className, classNameLength, options); if (NULL != foundClass) { #if defined(J9VM_OPT_SNAPSHOTS) if (IS_RESTORE_RUN(vm) diff --git a/runtime/vm/createramclass.cpp b/runtime/vm/createramclass.cpp index 5de45c2666e..8854cc35815 100644 --- a/runtime/vm/createramclass.cpp +++ b/runtime/vm/createramclass.cpp @@ -3268,6 +3268,9 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas ramClass->module = NULL; ramClass->reservedCounter = 0; ramClass->cancelCounter = 0; +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + ramClass->strictStaticFieldCounter = 0; +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ /* hostClass is exclusively defined only in Unsafe.defineAnonymousClass. * For all other cases, clazz->hostClass points to itself (clazz). @@ -3686,6 +3689,20 @@ internalCreateRAMClassFromROMClassImpl(J9VMThread *vmThread, J9ClassLoader *clas } } +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + /* TODO Update the class version check if strict fields is released before value types. */ + if (J9_IS_CLASSFILE_OR_ROMCLASS_VALUETYPE_VERSION(romClass)) { + J9ROMFieldWalkState fieldWalkState = {0}; + J9ROMFieldShape *field = romFieldsStartDo(romClass, &fieldWalkState); + while (NULL != field) { + if (J9_ARE_ALL_BITS_SET(field->modifiers, J9AccStatic | J9AccStrictInit)) { + ramClass->strictStaticFieldCounter += 1; + } + field = romFieldsNextDo(&fieldWalkState); + } + } +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ + #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) state->valueTypeFlags = *valueTypeFlags; #endif /* J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES */ diff --git a/runtime/vm/jfr.cpp b/runtime/vm/jfr.cpp index 94f41f790fc..d6cf1f3053e 100644 --- a/runtime/vm/jfr.cpp +++ b/runtime/vm/jfr.cpp @@ -406,7 +406,7 @@ jfrThreadCreated(J9HookInterface **hook, UDATA eventNum, void *eventData, void * #endif /* defined(DEBUG) */ /* TODO: allow different buffer sizes on different threads. */ - U_8 *buffer = (U_8*)j9mem_allocate_memory(J9JFR_THREAD_BUFFER_SIZE, OMRMEM_CATEGORY_VM); + U_8 *buffer = (U_8 *)j9mem_allocate_memory(J9JFR_THREAD_BUFFER_SIZE, J9MEM_CATEGORY_JFR); if (NULL == buffer) { event->continueInitialization = FALSE; } else { @@ -802,14 +802,14 @@ initializeJFR(J9JavaVM *vm, BOOLEAN lateInit) } /* Allocate constantEvents. */ - vm->jfrState.constantEvents = j9mem_allocate_memory(sizeof(JFRConstantEvents), J9MEM_CATEGORY_VM); + vm->jfrState.constantEvents = j9mem_allocate_memory(sizeof(JFRConstantEvents), J9MEM_CATEGORY_JFR); if (NULL == vm->jfrState.constantEvents) { goto fail; } memset(vm->jfrState.constantEvents, 0, sizeof(JFRConstantEvents)); /* Allocate global data. */ - buffer = (U_8*)j9mem_allocate_memory(J9JFR_GLOBAL_BUFFER_SIZE, OMRMEM_CATEGORY_VM); + buffer = (U_8 *)j9mem_allocate_memory(J9JFR_GLOBAL_BUFFER_SIZE, J9MEM_CATEGORY_JFR); if (NULL == buffer) { goto fail; } @@ -861,7 +861,7 @@ initializeJFR(J9JavaVM *vm, BOOLEAN lateInit) while (NULL != walkThread) { /* only initialize a thread once */ if (NULL == walkThread->jfrBuffer.bufferStart) { - U_8 *buffer = (U_8*)j9mem_allocate_memory(J9JFR_THREAD_BUFFER_SIZE, OMRMEM_CATEGORY_VM); + U_8 *buffer = (U_8 *)j9mem_allocate_memory(J9JFR_THREAD_BUFFER_SIZE, J9MEM_CATEGORY_JFR); if (NULL == buffer) { goto fail; } else { diff --git a/runtime/vm/lookupmethod.c b/runtime/vm/lookupmethod.c index 2bac785b58d..701a0409526 100644 --- a/runtime/vm/lookupmethod.c +++ b/runtime/vm/lookupmethod.c @@ -575,6 +575,7 @@ javaResolveInterfaceMethods(J9VMThread *currentThread, J9Class *targetClass, J9R * * J9_LOOK_VIRTUAL Search for a virtual (instance) method * J9_LOOK_STATIC Search for a static method + * J9_LOOK_INVOKE_INTERFACE Special handling for invokeinterface resolution. * J9_LOOK_INTERFACE Search for an interface method - assumes given class is interface class and searches only it and its superinterfaces (i.e. does not search Object) * J9_LOOK_JNI Use JNI behaviour (allow virtual lookup to succeed when it finds a method in an interface class, throw only NoSuchMethodError on failure, VERIFIED C strings for name and sig) * J9_LOOK_NO_CLIMB Search only the given class, no superclasses or superinterfaces diff --git a/runtime/vm/resolvesupport.cpp b/runtime/vm/resolvesupport.cpp index 56fbbb0d301..5b72408fe6e 100644 --- a/runtime/vm/resolvesupport.cpp +++ b/runtime/vm/resolvesupport.cpp @@ -865,6 +865,12 @@ resolveStaticFieldRefInto(J9VMThread *vmStruct, J9Method *method, J9ConstantPool if ((modifiers & J9AccFinal) == J9AccFinal) { localClassAndFlagsData |= J9StaticFieldRefFinal; } +#if defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) + if (J9_ARE_ANY_BITS_SET(modifiers, J9AccStrictInit)) { + localClassAndFlagsData &= ~J9StaticFieldRefStrictInitMask; + localClassAndFlagsData |= J9StaticFieldRefStrictInitUnset; + } +#endif /* defined(J9VM_OPT_VALHALLA_STRICT_FIELDS) */ if (0 != (resolveFlags & J9_RESOLVE_FLAG_FIELD_SETTER)) { localClassAndFlagsData |= J9StaticFieldRefPutResolved; } diff --git a/test/TestConfig/resources/excludes/latest_exclude_8.txt b/test/TestConfig/resources/excludes/latest_exclude_8.txt index 0839d9747cf..123b1c3b109 100644 --- a/test/TestConfig/resources/excludes/latest_exclude_8.txt +++ b/test/TestConfig/resources/excludes/latest_exclude_8.txt @@ -22,5 +22,4 @@ # Exclude tests temporarily -j9vm.test.softmx.SoftmxRemoteTest 480 generic-all org.openj9.test.vmArguments.VmArgumentTests:testCrNocr 244 generic-all diff --git a/test/functional/JLM_Tests/playlist.xml b/test/functional/JLM_Tests/playlist.xml index a3d7dc70a37..ecce22a1e9f 100644 --- a/test/functional/JLM_Tests/playlist.xml +++ b/test/functional/JLM_Tests/playlist.xml @@ -475,41 +475,6 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex ibm - - testSoftMxRemote - - - https://github.com/eclipse-openj9/openj9/issues/480 - - - - Mode110 - Mode119 - Mode601 - Mode501 - - $(ADD_JVM_LIB_DIR_TO_LIBPATH) \ - $(JAVA_COMMAND) $(JVM_OPTIONS) \ - -Dremote.server.option=$(Q)$(JVM_OPTIONS) -Xmx1024m -Xsoftmx512m -Xmn1m -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false$(Q) \ - -verbose:gc -Xverbosegclog:$(REPORTDIR)$(D)vgc.log \ - -cp $(Q)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)jlm_tests.jar$(Q) \ - org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng.xml$(Q) \ - -testnames testSoftMxRemote \ - -groups $(TEST_GROUP) \ - -excludegroups $(DEFAULT_EXCLUDE); \ - $(TEST_STATUS) - ^spec.linux_390 - - extended - - - functional - - - openj9 - ibm - - testSoftMxRemote_zlinux_64 diff --git a/test/functional/JLM_Tests/src/j9vm/test/softmx/RemoteTestServer.java b/test/functional/JLM_Tests/src/j9vm/test/softmx/RemoteTestServer.java deleted file mode 100644 index ed5e555ed1d..00000000000 --- a/test/functional/JLM_Tests/src/j9vm/test/softmx/RemoteTestServer.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright IBM Corp. and others 2001 - * - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which accompanies this - * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] https://openjdk.org/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 - */ - -package j9vm.test.softmx; - -import j9vm.test.softmx.MemoryExhauster; -import java.lang.management.ManagementFactory; - -import org.testng.Assert; -import org.testng.log4testng.Logger; - -public class RemoteTestServer { - - private static final Logger logger = Logger.getLogger(RemoteTestServer.class); - - // Limit the test execution within 5 minutes - private static final long TIMEOUT = 5 * 60 * 1000; - - com.ibm.lang.management.MemoryMXBean ibmBean; - - /* - * Start the RemoteTestServer with softmx enabled and jmx enabled, for example: - * -Xmx1024m -Xsoftmx512m -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false - * -Dcom.sun.management.jmxremote.ssl=false - */ - - public static void main(String[] args) { - - log("=========RemoteTestServer Starts!========="); - - java.lang.management.MemoryMXBean mb = ManagementFactory.getMemoryMXBean(); - - // cast downwards so that we can use the IBM-specific functions - com.ibm.lang.management.MemoryMXBean aBean = (com.ibm.lang.management.MemoryMXBean)mb; - - long preMx = aBean.getMaxHeapSize(); - long startTime = System.currentTimeMillis(); - - MemoryExhauster memoryExhauster = new MemoryExhauster(); - - //check every second to see if max heap size is reduced by 1024 bytes - log("sleep until max heap size is reset to max heap size limit."); - log("Current Max heap size: " + aBean.getMaxHeapSize()); - log("Max heap size limit: " + aBean.getMaxHeapSizeLimit()); - while ((preMx != aBean.getMaxHeapSizeLimit()) && (System.currentTimeMillis() - startTime) < TIMEOUT) { - try { - preMx = aBean.getMaxHeapSize(); - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - //exist with -1 if max heap size is not changed during TIMEOUT - if (preMx != aBean.getMaxHeapSizeLimit()) { - log("Didn't receive signal - max heap size is set to max heap limit during " + TIMEOUT - + "ms! System exit with -1."); - Assert.fail("RemoteTestServer: Didn't receive signal - max heap size is set to max heap limit during " - + TIMEOUT + "ms! System exit with -1."); - } - - //once the max heap size is reduced by 1024 bytes, start allocate object to 80% of max heap size - log("Current max heap size is " + aBean.getMaxHeapSize()); - - memoryExhauster.usePercentageOfHeap(0.8); - - log("Now we have used approximately 80% of current max heap size: " + aBean.getHeapMemoryUsage().getUsed()); - log("Current committed max heap size is " + aBean.getHeapMemoryUsage().getCommitted()); - - //decrease max heap size 1024 bytes to notify SoftRemoteTest that allocation is done - preMx = aBean.getMaxHeapSize() - 1024; - aBean.setMaxHeapSize(preMx); - - //check every second to see if max heap size is reset to 50% of original max size; - //the actual max heap size maybe not exactly equal to 50% of original size - log("sleep until max heap size is reduced to 50% of original size."); - while ((Math.abs(aBean.getMaxHeapSize() - (long)preMx * 0.5) > 1024) - && (System.currentTimeMillis() - startTime) < TIMEOUT) { - try { - log("Current max heap size is " + aBean.getMaxHeapSize()); - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - //exist with -1 if max heap size is not changed during TIMEOUT - if ((Math.abs(aBean.getMaxHeapSize() - (long)preMx * 0.5) > 1024)) { - log("Didn't receive signal - max heap size is reduced to 50% of original size during " + TIMEOUT - + "ms! System exit with -1."); - Assert.fail( - "RemoteTestServer: Didn't receive signal - max heap size is reduced to 50% of original size during " - + TIMEOUT + "ms! System exit with -1."); - } - - log("Force Aggressive GC. Waiting for heap shrink..."); - TestNatives.setAggressiveGCPolicy(); - - boolean isShrink = false; - - //waiting for maximum 5 min (300000ms) - while ((System.currentTimeMillis() - startTime) < 300000) { - if ((aBean.getHeapMemoryUsage().getCommitted() - aBean.getMaxHeapSize()) <= 1024) { - logger.debug(" Heap shrink to " + aBean.getHeapMemoryUsage().getCommitted() + " bytes" + " in " - + (System.currentTimeMillis() - startTime) + " mSeconds"); - isShrink = true; - break; - } else { - try { - Thread.sleep(2000); - log("Current committed memory: " + aBean.getHeapMemoryUsage().getCommitted() + " bytes"); - log("max heap size " + aBean.getMaxHeapSize()); - log("Force Aggressive GC. Waiting for heap shrink..."); - TestNatives.setAggressiveGCPolicy(); - } catch (InterruptedException e) { - isShrink = false; - e.printStackTrace(); - } - } - } - - //if heap size shrank to reset max heap size, continue test heap can't expand beyond current max heap size - if (isShrink) { - //Try to use 120% of reset max heap size, expect to get OutOfMemoryError - log("Starting Object allocation until OOM error or used memory reaching 120% of current max heap size."); - - boolean OOMNotReached = memoryExhauster.usePercentageOfHeap(1.2); - - if (OOMNotReached == false) { - log("PASS: Heap can't expand beyond reset max heap size. Catch OutOfMemoryError."); - } - - if (OOMNotReached) { - log("FAIL: Heap can expand beyond reset max heap size! Generate Java core dump."); - com.ibm.jvm.Dump.JavaDump(); - com.ibm.jvm.Dump.HeapDump(); - com.ibm.jvm.Dump.SystemDump(); - } else { - //increase max heap size 1024 bytes to notify SoftmxRemoteTest that expected OOM is thrown - aBean.setMaxHeapSize(aBean.getMaxHeapSize() + 1024); - } - - } else { - log(" FAIL: Heap can't shrink to the reset max heap size within 5 minutes!"); - } - - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - log("RemoteTestServer Stops!"); - } - - public RemoteTestServer(com.ibm.lang.management.MemoryMXBean aBean) { - ibmBean = aBean; - } - - private static void log(String aString) { - logger.debug("RemoteTestServer: " + aString); - } -} diff --git a/test/functional/JLM_Tests/src/j9vm/test/softmx/SoftmxRemoteTest.java b/test/functional/JLM_Tests/src/j9vm/test/softmx/SoftmxRemoteTest.java deleted file mode 100644 index 9c138c2b4f6..00000000000 --- a/test/functional/JLM_Tests/src/j9vm/test/softmx/SoftmxRemoteTest.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright IBM Corp. and others 2001 - * - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which accompanies this - * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] https://openjdk.org/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 - */ - -package j9vm.test.softmx; - - -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; -import org.testng.log4testng.Logger; -import org.testng.annotations.BeforeMethod; -import org.testng.Assert; -import org.testng.AssertJUnit; -import java.util.*; -import javax.management.*; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.management.*; -import java.net.MalformedURLException; -import java.net.ServerSocket; - -import javax.management.remote.*; -import javax.management.ObjectName; -import com.ibm.lang.management.MemoryMXBean; - -/* - * Start the RemoteTestServer with softmx enabled and jmx enabled before run the test. - */ -@Test(groups = { "level.extended" }) -public class SoftmxRemoteTest{ - - private static final Logger logger = Logger.getLogger(SoftmxRemoteTest.class); - - JMXConnector connector; - MBeanServerConnection mbeanConnection; - ObjectName beanName; - com.ibm.lang.management.MemoryMXBean ibmBean; - - private static Process remoteServer; - private static ChildWatchdog watchdog; - - - @BeforeMethod - protected void setUp() { - - if (remoteServer == null){ - startRemoteServer(); - watchdog = new ChildWatchdog(remoteServer); - waitRemoteServer(); - } - - JMXServiceURL urlForRemoteMachine; - MemoryMXBean mxbean = null; - - try { - urlForRemoteMachine = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi"); - // connect to the remote host and create a proxy than can be used to get/set the maxHeapSize attribute - // this is the attribute which adjusts the softmx value - connector = JMXConnectorFactory.connect(urlForRemoteMachine,null); - mbeanConnection = connector.getMBeanServerConnection(); - beanName = new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); - mxbean = JMX.newMXBeanProxy(mbeanConnection,beanName, MemoryMXBean.class); - // cast downwards so that we can use the IBM-specific functions - ibmBean = (com.ibm.lang.management.MemoryMXBean) mxbean; - - } catch (MalformedURLException e) { - e.printStackTrace(); - Assert.fail("Please check your JMXServiceURL!"); - } catch (MalformedObjectNameException e) { - e.printStackTrace(); - Assert.fail("Get MalformedObjectNameException!"); - } catch (IOException e) { - e.printStackTrace(); - Assert.fail("Get IOException!"); - } - AssertJUnit.assertNotNull("JMX.newMXBeanProxy() returned null : TEST FAILED IN setUp()", mxbean); - } - - @Test - public void testJMXSetHeapSize() { - - long max_size = ibmBean.getMaxHeapSize(); - long max_limit = ibmBean.getMaxHeapSizeLimit(); - - if (ibmBean.isSetMaxHeapSizeSupported()) { - logger.debug(" Current max heap size: " + max_size + " bytes"); - logger.debug(" Max heap size limit: " + max_limit + " bytes"); - if (max_size < max_limit) { - long reset_size = (max_size + max_limit) / 2; - logger.debug(" Reset heap size to: " + reset_size + " bytes"); - ibmBean.setMaxHeapSize(reset_size); - AssertJUnit.assertEquals(reset_size, ibmBean.getMaxHeapSize()); - logger.debug(" Current max heap size is reset to: " + reset_size + " bytes"); - } else { - Assert.fail("Warning: current maximum heap size reach maximum heap size limit,it can't be reset!"); - } - } else { - Assert.fail("Warning: VM doesn't support runtime reconfiguration of the maximum heap size!"); - } - } - - @Test - public void testJMXSetHeapSizeBiggerThanLimit(){ - - long max_limit = ibmBean.getMaxHeapSizeLimit(); - if (ibmBean.isSetMaxHeapSizeSupported()){ - logger.debug ( " Max heap size limit: " + max_limit + " bytes"); - logger.debug ( " Current max heap size: " + ibmBean.getMaxHeapSize() + " bytes"); - logger.debug ( " Reset max heap size to: " + (max_limit + 1024) + " bytes"); - try { - ibmBean.setMaxHeapSize(max_limit + 1024); - Assert.fail(" FAIL: Expected to get an Exception while trying to set max sixe bigger than max heap size limit!"); - } catch (java.lang.IllegalArgumentException e){ - logger.debug (" PASS: get below expected exception while trying to set max sixe bigger than max heap size limit!"); - logger.debug("Expected exception", e); - } catch (java.lang.UnsupportedOperationException e){ - logger.warn (" java.lang.UnsupportedOperationException: this operation is not supported!"); - } catch (java.lang.SecurityException e){ - logger.warn (" java.lang.SecurityException: if a SecurityManager is being used and the caller does not have the ManagementPermission value of control"); - } catch (Exception e){ - logger.error("Unexpected exception ", e); - Assert.fail("Unexpected exception " + e); - } - }else{ - Assert.fail(" Warning: VM doesn't support runtime reconfiguration of the maximum heap size!"); - } - } - - - @Test - public void testJMXSetHeapSizeSmallerThanMin(){ - - long min_size = ibmBean.getMinHeapSize(); - if (ibmBean.isSetMaxHeapSizeSupported()){ - logger.debug ( " Current min heap size: " + min_size + " bytes"); - logger.debug ( " Reset min heap size to: " + (min_size - 1024) + " bytes"); - - try { - ibmBean.setMaxHeapSize(min_size - 1024); - Assert.fail(" FAIL: Expected to get an exception while trying to set max sixe smaller than min heap size!"); - } catch (java.lang.IllegalArgumentException e){ - logger.debug (" PASS: get below expected exception while trying to set max sixe bigger than max heap size limit!"); - logger.debug("Expected exception", e); - } catch (java.lang.UnsupportedOperationException e){ - logger.warn (" java.lang.UnsupportedOperationException: this operation is not supported!"); - } catch (java.lang.SecurityException e){ - logger.warn (" java.lang.SecurityException: if a SecurityManager is being used and the caller does not have the ManagementPermission value of control"); - } catch (Exception e){ - logger.error("Unexpected exception ", e); - Assert.fail("Unexpected exception " + e); - } - }else{ - Assert.fail(" Warning: VM doesn't support runtime reconfiguration of the maximum heap size!"); - } - - } - - - /* Steps of the test: - * 1. SoftmxRemoteTest sends signal to RemoteTestServer by resetting max heap size to max heap size limit, RemoteTestServer receive the signal, - * start allocate objects to force memory used by the heap to 80% of current max heap size; - * 2. RemoteTestServer sends signal to SoftmxRemoteTest by decreasing max heap size 1024 bytes when allocation is done; - * 3. SoftmxRemoteTest then rest max heap size to 50% of original size, RemoteTestServer trigger gc to shrink heap, verify the heap shrinks to - * the reset value within 5 minutes. - * 4. If heap shrinks within 5 minutes, RemoteTestServer will try to use 120% of reset max heap size. If RemoteTestServer gets the expected OutOfMemoryError, - * it increases max heap size 1024 bytes to notify the SoftmxRemoteTest.*/ - @Test - public void testSoftmxHasEffects(){ - - Monitor inMonitor = new Monitor(remoteServer.getInputStream()); - Monitor errorMonitor = new Monitor(remoteServer.getErrorStream()); - errorMonitor.start(); - inMonitor.start(); - - logger.debug( " Current max heap size: " + ibmBean.getMaxHeapSize() + " bytes"); - logger.debug(" Reset max heap size equal to max heap size limit to notify RemoteTestServer to start allocate object."); - - ibmBean.setMaxHeapSize(ibmBean.getMaxHeapSizeLimit()); - logger.debug( " Current max heap size: " + ibmBean.getMaxHeapSize() + " bytes"); - - - /*PrintWriter out = new PrintWriter(new BufferedWriter( - new OutputStreamWriter(remoteServer.getOutputStream())), true);*/ - - logger.debug( " Current max heap size: " + ibmBean.getMaxHeapSize() + " bytes"); - logger.debug(" Start Allocating New Object to approximately 80% of current max heap size."); - - - //RemoteTestServer will decrease max heap size to indicate allocation done, waiting for maximum 2 mins - long startTime = System.currentTimeMillis(); - boolean isDone = false; - while((System.currentTimeMillis() - startTime) < 120000 ){ - if (ibmBean.getMaxHeapSizeLimit() - ibmBean.getMaxHeapSize() == 1024){ - logger.debug( " RemoteTestServer finish allocating objects!"); - isDone = true; - break; - }else{ - try { - Thread.sleep(100); - logger.debug( " Current max heap size " + ibmBean.getMaxHeapSize() + " bytes"); - } catch (InterruptedException e) { - e.printStackTrace(); - Assert.fail(" FAIL: Catch InterruptedException"); - } - } - } - - AssertJUnit.assertTrue(" RemoteTestServer can't allocate objects within 2 mins!", isDone); - - long new_max_size = (long) (ibmBean.getMaxHeapSize() * 0.5); - logger.debug(" Reset maximum heap size to 50% of original size: " + new_max_size + - " to notify RemoteTestServer to force aggressive GC. Wait to check if heap shrinks" - + " and cannot grow beyond reset max limit."); - ibmBean.setMaxHeapSize(new_max_size); - long actual_max_size = ibmBean.getMaxHeapSize(); - logger.debug(" Actual reset maximum heap size is "+ibmBean.getMaxHeapSize()); - - boolean isPassed = false; - startTime = System.currentTimeMillis(); - - /* After heap size shrinks, the RemoteTestServer will try to use 120% of reset max heap size. If it gets OOM as expected, - * it will increase max heap size 1024 bytes to notify SoftmxRemoteTest that the test is passed. */ - while((System.currentTimeMillis() - startTime) < 360000 ){ - if (ibmBean.getMaxHeapSize() - actual_max_size == 1024){ - logger.debug( " PASS: Heap shrank and cannot grow beyond reset max limit."); - isPassed = true; - break; - }else{ - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - Assert.fail(" FAIL: Catch InterruptedException"); - } - } - } - - AssertJUnit.assertTrue (" FAIL: Did not recevie notification of test passing from RemotetestServer in 6 mins.", isPassed); - - inMonitor.stop(); - errorMonitor.stop(); - - stopRemoteServer(); - } - - @AfterMethod - protected void tearDown() throws Exception { - connector.close(); - watchdog.interrupt(); - remoteServer.destroy(); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - private void startRemoteServer() { - - // check port availability before binding - AssertJUnit.assertTrue("port 9999 is not available!!!", checkPort(9999)); - - logger.debug("Start Remote Server!"); - - ArrayList argBuffer = new ArrayList(); - char fs = File.separatorChar; - - String javaExec = System.getProperty("java.home")+fs+"bin"+fs+ "java"; - argBuffer.add(javaExec); - - argBuffer.add("-classpath"); - argBuffer.add(System.getProperty("java.class.path")); - - argBuffer.add(System.getProperty("remote.server.option")); - - argBuffer.add(RemoteTestServer.class.getName()); - - String cmdLine[] = new String[argBuffer.size()]; - argBuffer.toArray(cmdLine); - - String cmds = ""; - for (int i = 0; i < cmdLine.length; i++) - cmds = cmds + cmdLine[i] + " "; - - - logger.debug(cmds); - - try { - remoteServer = Runtime.getRuntime().exec(cmds); - } catch (IOException e) { - e.printStackTrace(); - } - - AssertJUnit.assertNotNull("failed to launch child process", remoteServer); - - } - - /* - * After RemoteTestserver child process starts, wait until the server is ready. - * Check whether the specified port (i.e. 9999) is in use in order to check if the server is ready. - * If the server is not ready after 2 mins, max wait time, destroy the child process and fail the test. - */ - private void waitRemoteServer() { - int waitLimit = 120; - int waitcount = waitLimit; - while (true == checkPort(9999)) - { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (0 == --waitcount) { - watchdog.interrupt(); - remoteServer.destroy(); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - remoteServer = null; - Assert.fail("The server is not ready after " + waitLimit + " seconds!!!"); - } - } - } - - private void stopRemoteServer(){ - try { - connector.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - watchdog.interrupt(); - remoteServer.destroy(); - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - - private class ChildWatchdog extends Thread { - Process child; - - public ChildWatchdog(Process child) { - super(); - this.child = child; - } - - @Override - public void run() { - try { - sleep(300000); - child.destroy(); - Assert.fail("child hung"); - } catch (InterruptedException e) { - return; - } - } - } - - private class Monitor extends Thread { - - private BufferedReader inputReader; - Monitor(InputStream is) { - this.inputReader = new BufferedReader(new InputStreamReader(is)); - } - public void run() { - String inLine; - try { - while (null != (inLine = inputReader.readLine())) { - logger.debug(inLine); - } - } catch (IOException e) { - e.printStackTrace(); - Assert.fail("unexpected IOException"); - } - } - } - - protected static boolean checkPort(int port) { - ServerSocket ss = null; - try { - ss = new ServerSocket(port); - return true; - } catch (IOException e) { - } finally { - if (ss != null) { - try { - ss.close(); - } catch (IOException e) { - } - } - } - return false; - } -} diff --git a/test/functional/JLM_Tests/testng.xml b/test/functional/JLM_Tests/testng.xml index a2ffc1c043d..24bd2b81056 100644 --- a/test/functional/JLM_Tests/testng.xml +++ b/test/functional/JLM_Tests/testng.xml @@ -102,11 +102,6 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex - - - - - diff --git a/test/functional/JavaAgentTest/playlist.xml b/test/functional/JavaAgentTest/playlist.xml index a53093f457f..a36e1b67ac6 100644 --- a/test/functional/JavaAgentTest/playlist.xml +++ b/test/functional/JavaAgentTest/playlist.xml @@ -439,6 +439,7 @@ TestGCClassWithStaticRetransformInGencon_SE80 Mode109 + Mode500 $(JAVA_COMMAND) $(JVM_OPTIONS) -Xgc:scvTenureAge=14,scvNoAdaptiveTenure \ -XX:+EnableExtendedHCR \ diff --git a/test/functional/UnsafeTest/build.xml b/test/functional/UnsafeTest/build.xml index 8766d130ab3..dc0c2672e02 100644 --- a/test/functional/UnsafeTest/build.xml +++ b/test/functional/UnsafeTest/build.xml @@ -33,6 +33,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex + + @@ -76,8 +78,20 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex + + + + + + + + + + + + diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccess.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccess.java similarity index 100% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccess.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccess.java diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java similarity index 100% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java similarity index 99% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java index f22242ddf31..5db7a5d818d 100644 --- a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java +++ b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java @@ -28,17 +28,17 @@ @Test(groups = { "level.sanity" }) public class TestUnsafeAccessOrdered extends UnsafeTestBase { private static Logger logger = Logger.getLogger(TestUnsafeAccessOrdered.class); - + public TestUnsafeAccessOrdered(String scenario) { super(scenario); } - + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ @Override protected Logger getLogger() { return logger; } - + @Override @BeforeMethod protected void setUp() throws Exception { @@ -61,7 +61,7 @@ public void testInstancePutOrderedShort() throws Exception { public void testInstancePutOrderedInt() throws Exception { testInt(new IntData(), ORDERED); } - + public void testInstancePutOrderedLong() throws Exception { testLong(new LongData(), ORDERED); } @@ -98,7 +98,7 @@ public void testArrayPutOrderedShort() throws Exception { public void testArrayPutOrderedInt() throws Exception { testInt(new int[modelInt.length], ORDERED); } - + public void testArrayPutOrderedLong() throws Exception { ; testLong(new long[modelLong.length], ORDERED); } @@ -135,7 +135,7 @@ public void testStaticPutOrderedShort() throws Exception { public void testStaticPutOrderedInt() throws Exception { testInt(IntData.class, ORDERED); } - + public void testStaticPutOrderedLong() throws Exception { testLong(LongData.class, ORDERED); } @@ -172,7 +172,7 @@ public void testObjectNullPutOrderedShort() throws Exception { public void testObjectNullPutOrderedInt() throws Exception { testIntNative(ORDERED); } - + public void testObjectNullPutOrderedLong() throws Exception { testLongNative(ORDERED); } diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java similarity index 98% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java index 683b1a8d63b..4ab1601ad6b 100644 --- a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java +++ b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java @@ -28,17 +28,17 @@ @Test(groups = { "level.sanity" }) public class TestUnsafeAccessVolatile extends UnsafeTestBase { private static Logger logger = Logger.getLogger(TestUnsafeAccessVolatile.class); - + public TestUnsafeAccessVolatile(String scenario) { super(scenario); } - + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ @Override protected Logger getLogger() { return logger; } - + @Override @BeforeMethod protected void setUp() throws Exception { @@ -49,31 +49,31 @@ protected void setUp() throws Exception { public void testInstancePutByteVolatile() throws Exception { testByte(new ByteData(), VOLATILE); } - + public void testInstancePutCharVolatile() throws Exception { testChar(new CharData(), VOLATILE); } - + public void testInstancePutShortVolatile() throws Exception { testShort(new ShortData(), VOLATILE); } - + public void testInstancePutIntVolatile() throws Exception { testInt(new IntData(), VOLATILE); } - + public void testInstancePutLongVolatile() throws Exception { testLong(new LongData(), VOLATILE); } - + public void testInstancePutFloatVolatile() throws Exception { testFloat(new FloatData(), VOLATILE); } - + public void testInstancePutDoubleVolatile() throws Exception { testDouble(new DoubleData(), VOLATILE); } - + public void testInstancePutBooleanVolatile() throws Exception { testBoolean(new BooleanData(), VOLATILE); } @@ -86,31 +86,31 @@ public void testInstancePutObjectVolatile() throws Exception { public void testArrayPutByteVolatile() throws Exception { testByte(new byte[modelByte.length], VOLATILE); } - + public void testArrayPutCharVolatile() throws Exception { testChar(new char[modelChar.length], VOLATILE); } - + public void testArrayPutShortVolatile() throws Exception { testShort(new short[modelShort.length], VOLATILE); } - + public void testArrayPutIntVolatile() throws Exception { testInt(new int[modelInt.length], VOLATILE); } - + public void testArrayPutLongVolatile() throws Exception { testLong(new long[modelLong.length], VOLATILE); } - + public void testArrayPutFloatVolatile() throws Exception { testFloat(new float[modelFloat.length], VOLATILE); } - + public void testArrayPutDoubleVolatile() throws Exception { testDouble(new double[modelDouble.length], VOLATILE); } - + public void testArrayPutBooleanVolatile() throws Exception { testBoolean(new boolean[modelBoolean.length], VOLATILE); } @@ -123,31 +123,31 @@ public void testArrayPutObjectVolatile() throws Exception { public void testStaticPutByteVolatile() throws Exception { testByte(ByteData.class, VOLATILE); } - + public void testStaticPutCharVolatile() throws Exception { testChar(CharData.class, VOLATILE); } - + public void testStaticPutShortVolatile() throws Exception { testShort(ShortData.class, VOLATILE); } - + public void testStaticPutIntVolatile() throws Exception { testInt(IntData.class, VOLATILE); } - + public void testStaticPutLongVolatile() throws Exception { testLong(LongData.class, VOLATILE); } - + public void testStaticPutFloatVolatile() throws Exception { testFloat(FloatData.class, VOLATILE); } - + public void testStaticPutDoubleVolatile() throws Exception { testDouble(DoubleData.class, VOLATILE); } - + public void testStaticPutBooleanVolatile() throws Exception { testBoolean(BooleanData.class, VOLATILE); } @@ -160,40 +160,40 @@ public void testStaticPutObjectVolatile() throws Exception { public void testObjectNullPutByteVolatile() throws Exception { testByteNative(VOLATILE); } - + public void testObjectNullPutCharVolatile() throws Exception { testCharNative(VOLATILE); } - + public void testObjectNullPutShortVolatile() throws Exception { testShortNative(VOLATILE); } - + public void testObjectNullPutIntVolatile() throws Exception { testIntNative(VOLATILE); } - + public void testObjectNullPutLongVolatile() throws Exception { testLongNative(VOLATILE); } - + public void testObjectNullPutFloatVolatile() throws Exception { testFloatNative(VOLATILE); } - + public void testObjectNullPutDoubleVolatile() throws Exception { testDoubleNative(VOLATILE); } - + public void testObjectNullPutBooleanVolatile() throws Exception { testBooleanNative(VOLATILE); } - + // tests for testInstanceGetXXXXVolatile public void testInstanceGetByteVolatile() throws Exception { testGetByte(new ByteData(), VOLATILE); } - + public void testInstanceGetCharVolatile() throws Exception { testGetChar(new CharData(), VOLATILE); } @@ -205,19 +205,19 @@ public void testInstanceGetShortVolatile() throws Exception { public void testInstanceGetIntVolatile() throws Exception { testGetInt(new IntData(), VOLATILE); } - + public void testInstanceGetLongVolatile() throws Exception { testGetLong(new LongData(), VOLATILE); } - + public void testInstanceGetFloatVolatile() throws Exception { - testGetFloat(new FloatData(), VOLATILE); + testGetFloat(new FloatData(), VOLATILE); } - + public void testInstanceGetDoubleVolatile() throws Exception { testGetDouble(new DoubleData(), VOLATILE); } - + public void testInstanceGetBooleanVolatile() throws Exception { testGetBoolean(new BooleanData(), VOLATILE); } @@ -230,31 +230,31 @@ public void testInstanceGetObjectVolatile() throws Exception { public void testArrayGetByteVolatile() throws Exception { testGetByte(new byte[modelByte.length], VOLATILE); } - + public void testArrayGetCharVolatile() throws Exception { testGetChar(new char[modelChar.length], VOLATILE); } - + public void testArrayGetShortVolatile() throws Exception { testGetShort(new short[modelShort.length], VOLATILE); } - + public void testArrayGetIntVolatile() throws Exception { testGetInt(new int[modelInt.length], VOLATILE); } - + public void testArrayGetLongVolatile() throws Exception { testGetLong(new long[modelLong.length], VOLATILE); } - + public void testArrayGetFloatVolatile() throws Exception { testGetFloat(new float[modelFloat.length], VOLATILE); } - + public void testArrayGetDoubleVolatile() throws Exception { testGetDouble(new double[modelDouble.length], VOLATILE); } - + public void testArrayGetBooleanVolatile() throws Exception { testGetBoolean(new boolean[modelBoolean.length], VOLATILE); } @@ -267,31 +267,31 @@ public void testArrayGetObjectVolatile() throws Exception { public void testStaticGetByteVolatile() throws Exception { testGetByte(ByteData.class, VOLATILE); } - + public void testStaticGetCharVolatile() throws Exception { testGetChar(CharData.class, VOLATILE); } - + public void testStaticGetShortVolatile() throws Exception { testGetShort(ShortData.class, VOLATILE); } - + public void testStaticGetIntVolatile() throws Exception { testGetInt(IntData.class, VOLATILE); } - + public void testStaticGetLongVolatile() throws Exception { testGetLong(LongData.class, VOLATILE); } - + public void testStaticGetFloatVolatile() throws Exception { testGetFloat(FloatData.class, VOLATILE); } - + public void testStaticGetDoubleVolatile() throws Exception { testGetDouble(DoubleData.class, VOLATILE); } - + public void testStaticGetBooleanVolatile() throws Exception { testGetBoolean(BooleanData.class, VOLATILE); } diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java similarity index 100% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java similarity index 100% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeGetAndOp.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeGetAndOp.java similarity index 100% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/TestUnsafeGetAndOp.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/TestUnsafeGetAndOp.java diff --git a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/UnsafeTestBase.java b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/UnsafeTestBase.java similarity index 99% rename from test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/UnsafeTestBase.java rename to test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/UnsafeTestBase.java index f60c7867a44..fe25e11320e 100644 --- a/test/functional/UnsafeTest/src_90/org/openj9/test/unsafe/UnsafeTestBase.java +++ b/test/functional/UnsafeTest/src_11/org/openj9/test/unsafe/UnsafeTestBase.java @@ -84,27 +84,27 @@ public class UnsafeTestBase implements ITest { private static final long BYTE_MASKL = (long) BYTE_MASK; protected long mem = 0; - + /* variables required to change test name based on run scenario (compiled first or not) */ protected String scenario; protected String mTestName = ""; - + /* use scenario string to change TestNG output showing if the run is regular or with compiled classes */ public UnsafeTestBase (String runScenario) { scenario = runScenario; } - + @BeforeMethod(alwaysRun = true) public void setTestName(Method method, Object[] parameters) { mTestName = method.getName(); logger.debug("Test started: " + mTestName); } - + @Override public String getTestName() { return mTestName + " (" + scenario + ")"; } - + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ protected Logger getLogger() { return logger; @@ -562,7 +562,7 @@ protected void setUp() throws Exception { myUnsafe = getUnsafeInstance(); } - + @AfterMethod(groups = { "level.sanity" }) protected void tearDown() throws Exception { logger.debug("Test finished: " + mTestName); @@ -2077,7 +2077,7 @@ protected void testCharNative(String method) throws Exception { } else if (method.equals(UNALIGNED)) { /* do not run this test at end of array to avoid corrupting memory we don't own */ if (i == (modelChar.length - 1)) continue; - + int sizeOfChar = 2; // bytes for (long uOffset = (pointers[i] + sizeOfChar); uOffset >= pointers[i]; --uOffset) { @@ -2149,7 +2149,7 @@ protected void testShortNative(String method) throws Exception { } else if (method.equals(UNALIGNED)) { /* do not run this test at end of array to avoid corrupting memory we don't own */ if (i == (modelShort.length - 1)) continue; - + int sizeOfShort = 2; // bytes for (long uOffset = (pointers[i] + sizeOfShort); uOffset >= pointers[i]; --uOffset) { @@ -2224,7 +2224,7 @@ protected void testIntNative(String method) throws Exception { } else if (method.equals(UNALIGNED)) { /* do not run this test at end of array to avoid corrupting memory we don't own */ if (i == (modelInt.length - 1)) continue; - + int sizeOfInt = 4; // bytes for (long uOffset = (pointers[i] + sizeOfInt); uOffset >= pointers[i]; --uOffset) { @@ -2300,7 +2300,7 @@ protected void testLongNative(String method) throws Exception { } else if (method.equals(UNALIGNED)) { /* do not run this test at end of array to avoid corrupting memory we don't own */ if (i == (modelLong.length - 1)) continue; - + int sizeOfLong = 8; // bytes for (long uOffset = (pointers[i] + sizeOfLong); uOffset >= pointers[i]; --uOffset) { @@ -2867,8 +2867,8 @@ protected long memAllocate(int size) { getLogger().debug("allocateMemory: " + mem); return address; } - - protected void freeMemory() { + + protected void freeMemory() { myUnsafe.freeMemory(mem); getLogger().debug("freeMemory: " + mem); } @@ -2889,22 +2889,22 @@ protected void alignment() { getLogger().debug("Change pointer to: " + mem); } } - + /* Create a class with the specified package name. - * This method is used to verify the correctness of + * This method is used to verify the correctness of * jdk.internal.misc.Unsafe.defineAnonymousClass. */ protected static byte[] createDummyClass(String packageName) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv = null; String className = "DummyClass"; - + if (packageName != null) { className = packageName + "/" + className; } - + cw.visit(52, ACC_PUBLIC, className, null, "java/lang/Object", null); - + { mv = cw.visitMethod(ACC_PUBLIC, "bar", "()V", null, null); mv.visitCode(); @@ -2914,7 +2914,7 @@ protected static byte[] createDummyClass(String packageName) { } cw.visitEnd(); - + return cw.toByteArray(); } diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccess.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccess.java new file mode 100644 index 00000000000..9209fd674a2 --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccess.java @@ -0,0 +1,382 @@ +/* + * Copyright IBM Corp. and others 2001 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.openj9.test.access.UnsafeClasses; +import org.openj9.test.util.VersionCheck; + +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeAccess extends UnsafeTestBase { + + private static final Logger logger = Logger.getLogger(TestUnsafeAccess.class); + + public TestUnsafeAccess(String scenario) { + super(scenario); + } + + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ + @Override + protected Logger getLogger() { + return logger; + } + + /* test put instance */ + public void testInstancePutByte() throws Exception { + testByte(new ByteData(), DEFAULT); + } + + public void testInstancePutChar() throws Exception { + testChar(new CharData(), DEFAULT); + } + + public void testInstancePutShort() throws Exception { + testShort(new ShortData(), DEFAULT); + } + + public void testInstancePutInt() throws Exception { + testInt(new IntData(), DEFAULT); + } + + public void testInstancePutLong() throws Exception { + testLong(new LongData(), DEFAULT); + } + + public void testInstancePutFloat() throws Exception { + testFloat(new FloatData(), DEFAULT); + } + + public void testInstancePutDouble() throws Exception { + testDouble(new DoubleData(), DEFAULT); + } + + public void testInstancePutBoolean() throws Exception { + testBoolean(new BooleanData(), DEFAULT); + } + + public void testInstancePutReference() throws Exception { + testReference(new ObjectData(), DEFAULT); + } + + /* test put array */ + public void testArrayPutByte() throws Exception { + testByte(new byte[modelByte.length], DEFAULT); + } + + public void testArrayPutChar() throws Exception { + testChar(new char[modelChar.length], DEFAULT); + } + + public void testArrayPutShort() throws Exception { + testShort(new short[modelShort.length], DEFAULT); + } + + public void testArrayPutInt() throws Exception { + testInt(new int[modelInt.length], DEFAULT); + } + + public void testArrayPutLong() throws Exception { + testLong(new long[modelLong.length], DEFAULT); + } + + public void testArrayPutFloat() throws Exception { + testFloat(new float[modelFloat.length], DEFAULT); + } + + public void testArrayPutDouble() throws Exception { + testDouble(new double[modelDouble.length], DEFAULT); + } + + public void testArrayPutBoolean() throws Exception { + testBoolean(new boolean[modelBoolean.length], DEFAULT); + } + + public void testArrayPutReference() throws Exception { + testReference(new Object[models.length], DEFAULT); + } + + /* test put static */ + public void testStaticPutByte() throws Exception { + testByte(ByteData.class, DEFAULT); + } + + public void testStaticPutChar() throws Exception { + testChar(CharData.class, DEFAULT); + } + + public void testStaticPutShort() throws Exception { + testShort(ShortData.class, DEFAULT); + } + + public void testStaticPutInt() throws Exception { + testInt(IntData.class, DEFAULT); + } + + public void testStaticPutLong() throws Exception { + testLong(LongData.class, DEFAULT); + } + + public void testStaticPutFloat() throws Exception { + testFloat(FloatData.class, DEFAULT); + } + + public void testStaticPutDouble() throws Exception { + testDouble(DoubleData.class, DEFAULT); + } + + public void testStaticPutBoolean() throws Exception { + testBoolean(BooleanData.class, DEFAULT); + } + + public void testStaticPutReference() throws Exception { + testReference(ObjectData.class, DEFAULT); + } + + /* test put null object */ + public void testObjectNullPutByte() throws Exception { + + testByteNative(DEFAULT); + } + + public void testObjectNullPutChar() throws Exception { + testCharNative(DEFAULT); + } + + public void testObjectNullPutShort() throws Exception { + testShortNative(DEFAULT); + } + + public void testObjectNullPutInt() throws Exception { + testIntNative(DEFAULT); + } + + public void testObjectNullPutLong() throws Exception { + testLongNative(DEFAULT); + } + + public void testObjectNullPutFloat() throws Exception { + testFloatNative(DEFAULT); + } + + public void testObjectNullPutDouble() throws Exception { + testDoubleNative(DEFAULT); + } + + public void testObjectNullPutBoolean() throws Exception { + testBooleanNative(DEFAULT); + } + + /* test put methods with no object input */ + public void testPutByte() throws Exception { + String method = mTestName + "(long, value)"; + testByteNative(method); + } + + public void testPutChar() throws Exception { + String method = mTestName + "(long, value)"; + testCharNative(method); + } + + public void testPutShort() throws Exception { + String method = mTestName + "(long, value)"; + testShortNative(method); + } + + public void testPutInt() throws Exception { + String method = mTestName + "(long, value)"; + testIntNative(method); + } + + public void testPutLong() throws Exception { + String method = mTestName + "(long, value)"; + testLongNative(method); + } + + public void testPutFloat() throws Exception { + String method = mTestName + "(long, value)"; + testFloatNative(method); + } + + public void testPutDouble() throws Exception { + String method = mTestName + "(long, value)"; + testDoubleNative(method); + } + + /* get instance */ + public void testInstanceGetByte() throws Exception { + testGetByte(new ByteData(), DEFAULT); + } + + public void testInstanceGetChar() throws Exception { + testGetChar(new CharData(), DEFAULT); + } + + public void testInstanceGetShort() throws Exception { + testGetShort(new ShortData(), DEFAULT); + } + + public void testInstanceGetInt() throws Exception { + testGetInt(new IntData(), DEFAULT); + } + + public void testInstanceGetLong() throws Exception { + testGetLong(new LongData(), DEFAULT); + } + + public void testInstanceGetFloat() throws Exception { + testGetFloat(new FloatData(), DEFAULT); + } + + public void testInstanceGetDouble() throws Exception { + testGetDouble(new DoubleData(), DEFAULT); + } + + public void testInstanceGetBoolean() throws Exception { + testGetBoolean(new BooleanData(), DEFAULT); + } + + public void testInstanceGetReference() throws Exception { + testGetReference(new ObjectData(), DEFAULT); + } + + /* get array */ + public void testArrayGetByte() throws Exception { + testGetByte(new byte[modelByte.length], DEFAULT); + } + + public void testArrayGetChar() throws Exception { + testGetChar(new char[modelChar.length], DEFAULT); + } + + public void testArrayGetShort() throws Exception { + testGetShort(new short[modelShort.length], DEFAULT); + } + + public void testArrayGetInt() throws Exception { + testGetInt(new int[modelInt.length], DEFAULT); + } + + public void testArrayGetLong() throws Exception { + testGetLong(new long[modelLong.length], DEFAULT); + } + + public void testArrayGetFloat() throws Exception { + testGetFloat(new float[modelFloat.length], DEFAULT); + } + + public void testArrayGetDouble() throws Exception { + testGetDouble(new double[modelDouble.length], DEFAULT); + } + + public void testArrayGetBoolean() throws Exception { + testGetBoolean(new boolean[modelBoolean.length], DEFAULT); + } + + public void testArrayGetReference() throws Exception { + testGetReference(new Object[models.length], DEFAULT); + } + + /* get static */ + public void testStaticGetByte() throws Exception { + testGetByte(ByteData.class, DEFAULT); + } + + public void testStaticGetChar() throws Exception { + testGetChar(CharData.class, DEFAULT); + } + + public void testStaticGetShort() throws Exception { + testGetShort(ShortData.class, DEFAULT); + } + + public void testStaticGetInt() throws Exception { + testGetInt(IntData.class, DEFAULT); + } + + public void testStaticGetLong() throws Exception { + testGetLong(LongData.class, DEFAULT); + } + + public void testStaticGetFloat() throws Exception { + testGetFloat(FloatData.class, DEFAULT); + } + + public void testStaticGetDouble() throws Exception { + testGetDouble(DoubleData.class, DEFAULT); + } + + public void testStaticGetBoolean() throws Exception { + testGetBoolean(BooleanData.class, DEFAULT); + } + + public void testStaticGetReference() throws Exception { + testGetReference(ObjectData.class, DEFAULT); + } + + /* + * Test creating anonymous classes. + */ + public void testDefineAnonymousClass() throws Exception { + if (VersionCheck.major() >= 17) { + /* Unsafe.defineAnonymousClass() is only supported in versions prior to Java 17. */ + return; + } + + byte[] bytes; + Class anon; + + /* anonymous class = DummyClass; host class = java/lang/Object */ + bytes = createDummyClass(null); + /* + * No exception should be thrown since anonymous class has no + * package name. Anonymous classes with no package name are + * considered part of host class's package. + */ + anon = UnsafeClasses.defineAnonClass(Object.class, bytes); + + /* anonymous class = java/lang/Dummyclass; host class = java/lang/Object */ + bytes = createDummyClass("java/lang"); + /* + * No exception should be thrown since anonymous class and host class + * are in the same package. + */ + anon = UnsafeClasses.defineAnonClass(Object.class, bytes); + + /* anonymous class = test/DummyClass; host class = java/lang/Object */ + bytes = createDummyClass("test"); + try { + /* + * IllegalArgumentException should be thrown since anonymous class + * and host class are in different packages. + */ + anon = UnsafeClasses.defineAnonClass(Object.class, bytes); + Assert.fail("IllegalArgumentException expected since host class and anonymous class are in different packages."); + } catch (IllegalArgumentException e) { + /* correct behavior */ + } + } + +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java new file mode 100644 index 00000000000..4aef96f849a --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOpaque.java @@ -0,0 +1,297 @@ +/* + * Copyright IBM Corp. and others 2017 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeAccessOpaque extends UnsafeTestBase { + private static Logger logger = Logger.getLogger(TestUnsafeAccessOpaque.class); + + public TestUnsafeAccessOpaque(String scenario) { + super(scenario); + } + + /* + * get logger to use, for child classes to report with their class name instead + * of UnsafeTestBase + */ + @Override + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + /* put test with new instance as object */ + public void testInstancePutOpaqueByte() throws Exception { + testByte(new ByteData(), OPAQUE); + } + + public void testInstancePutOpaqueChar() throws Exception { + testChar(new CharData(), OPAQUE); + } + + public void testInstancePutOpaqueShort() throws Exception { + testShort(new ShortData(), OPAQUE); + } + + public void testInstancePutOpaqueInt() throws Exception { + testInt(new IntData(), OPAQUE); + } + + public void testInstancePutOpaqueLong() throws Exception { + testLong(new LongData(), OPAQUE); + } + + public void testInstancePutOpaqueFloat() throws Exception { + testFloat(new FloatData(), OPAQUE); + } + + public void testInstancePutOpaqueDouble() throws Exception { + testDouble(new DoubleData(), OPAQUE); + } + + public void testInstancePutOpaqueBoolean() throws Exception { + testBoolean(new BooleanData(), OPAQUE); + } + + public void testInstancePutOpaqueReference() throws Exception { + testReference(new ObjectData(), OPAQUE); + } + + /* put tests with array as object */ + public void testArrayPutOpaqueByte() throws Exception { + testByte(new byte[modelByte.length], OPAQUE); + } + + public void testArrayPutOpaqueChar() throws Exception { + testChar(new char[modelChar.length], OPAQUE); + } + + public void testArrayPutOpaqueShort() throws Exception { + testShort(new short[modelShort.length], OPAQUE); + } + + public void testArrayPutOpaqueInt() throws Exception { + testInt(new int[modelInt.length], OPAQUE); + } + + public void testArrayPutOpaqueLong() throws Exception { + testLong(new long[modelLong.length], OPAQUE); + } + + public void testArrayPutOpaqueFloat() throws Exception { + testFloat(new float[modelFloat.length], OPAQUE); + } + + public void testArrayPutOpaqueDouble() throws Exception { + testDouble(new double[modelDouble.length], OPAQUE); + } + + public void testArrayPutOpaqueBoolean() throws Exception { + testBoolean(new boolean[modelBoolean.length], OPAQUE); + } + + public void testArrayPutOpaqueReference() throws Exception { + testReference(new Object[models.length], OPAQUE); + } + + /* put tests with static object */ + public void testStaticPutOpaqueByte() throws Exception { + testByte(ByteData.class, OPAQUE); + } + + public void testStaticPutOpaqueChar() throws Exception { + testChar(CharData.class, OPAQUE); + } + + public void testStaticPutOpaqueShort() throws Exception { + testShort(ShortData.class, OPAQUE); + } + + public void testStaticPutOpaqueInt() throws Exception { + testInt(IntData.class, OPAQUE); + } + + public void testStaticPutOpaqueLong() throws Exception { + testLong(LongData.class, OPAQUE); + } + + public void testStaticPutOpaqueFloatRelease() throws Exception { + testFloat(FloatData.class, OPAQUE); + } + + public void testStaticPutOrderdDouble() throws Exception { + testDouble(DoubleData.class, OPAQUE); + } + + public void testStaticPutOpaqueBoolean() throws Exception { + testBoolean(BooleanData.class, OPAQUE); + } + + public void testStaticPutOpaqueReference() throws Exception { + testReference(ObjectData.class, OPAQUE); + } + + /* tests with null object */ + public void testObjectNullPutOpaqueByte() throws Exception { + testByteNative(OPAQUE); + } + + public void testObjectNullPutOpaqueChar() throws Exception { + testCharNative(OPAQUE); + } + + public void testObjectNullPutOpaqueShort() throws Exception { + testShortNative(OPAQUE); + } + + public void testObjectNullPutOpaqueInt() throws Exception { + testIntNative(OPAQUE); + } + + public void testObjectNullPutOpaqueLong() throws Exception { + testLongNative(OPAQUE); + } + + public void testObjectNullPutOpaqueFloat() throws Exception { + testFloatNative(OPAQUE); + } + + public void testObjectNullPutOpaqueDouble() throws Exception { + testDoubleNative(OPAQUE); + } + + public void testObjectNullPutOpaqueBoolean() throws Exception { + testBooleanNative(OPAQUE); + } + + /* get test with new instance as object */ + public void testInstanceGetOpaqueByte() throws Exception { + testGetByte(new ByteData(), OPAQUE); + } + + public void testInstanceGetOpaqueChar() throws Exception { + testGetChar(new CharData(), OPAQUE); + } + + public void testInstanceGetOpaqueShort() throws Exception { + testGetShort(new ShortData(), OPAQUE); + } + + public void testInstanceGetOpaqueInt() throws Exception { + testGetInt(new IntData(), OPAQUE); + } + + public void testInstanceGetOpaqueLong() throws Exception { + testGetLong(new LongData(), OPAQUE); + } + + public void testInstanceGetOpaqueFloat() throws Exception { + testGetFloat(new FloatData(), OPAQUE); + } + + public void testInstanceGetOpaqueDouble() throws Exception { + testGetDouble(new DoubleData(), OPAQUE); + } + + public void testInstanceGetOpaqueBoolean() throws Exception { + testGetBoolean(new BooleanData(), OPAQUE); + } + + public void testInstanceGetOpaqueReference() throws Exception { + testGetReference(new ObjectData(), OPAQUE); + } + + /* get tests with array as object */ + public void testArrayGetOpaqueByte() throws Exception { + testGetByte(new byte[modelByte.length], OPAQUE); + } + + public void testArrayGetOpaqueChar() throws Exception { + testGetChar(new char[modelChar.length], OPAQUE); + } + + public void testArrayGetOpaqueShort() throws Exception { + testGetShort(new short[modelShort.length], OPAQUE); + } + + public void testArrayGetOpaqueInt() throws Exception { + testGetInt(new int[modelInt.length], OPAQUE); + } + + public void testArrayGetOpaqueLong() throws Exception { + testGetLong(new long[modelLong.length], OPAQUE); + } + + public void testArrayGetOpaqueDouble() throws Exception { + testGetDouble(new double[modelDouble.length], OPAQUE); + } + + public void testArrayGetOpaqueBoolean() throws Exception { + testGetBoolean(new boolean[modelBoolean.length], OPAQUE); + } + + public void testArrayGetOpaqueReference() throws Exception { + testGetReference(new Object[models.length], OPAQUE); + } + + /* get tests with static object */ + public void testStaticGetOpaqueByte() throws Exception { + testGetByte(ByteData.class, OPAQUE); + } + + public void testStaticGetOpaqueChar() throws Exception { + testGetChar(CharData.class, OPAQUE); + } + + public void testStaticGetOpaqueShort() throws Exception { + testGetShort(ShortData.class, OPAQUE); + } + + public void testStaticGetOpaqueInt() throws Exception { + testGetInt(IntData.class, OPAQUE); + } + + public void testStaticGetOpaqueLong() throws Exception { + testGetLong(LongData.class, OPAQUE); + } + + public void testStaticGetOpaqueDouble() throws Exception { + testGetDouble(DoubleData.class, OPAQUE); + } + + public void testStaticGetOpaqueBoolean() throws Exception { + testGetBoolean(BooleanData.class, OPAQUE); + } + + public void testStaticGetOpaqueReference() throws Exception { + testGetReference(ObjectData.class, OPAQUE); + } +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java new file mode 100644 index 00000000000..a58ba07031b --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessOrdered.java @@ -0,0 +1,294 @@ +/* + * Copyright IBM Corp. and others 2001 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeAccessOrdered extends UnsafeTestBase { + private static Logger logger = Logger.getLogger(TestUnsafeAccessOrdered.class); + + public TestUnsafeAccessOrdered(String scenario) { + super(scenario); + } + + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ + @Override + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + /* put test with new instance as object */ + public void testInstancePutOrderedByte() throws Exception { + testByte(new ByteData(), ORDERED); + } + + public void testInstancePutOrderedChar() throws Exception { + testChar(new CharData(), ORDERED); + } + + public void testInstancePutOrderedShort() throws Exception { + testShort(new ShortData(), ORDERED); + } + + public void testInstancePutOrderedInt() throws Exception { + testInt(new IntData(), ORDERED); + } + + public void testInstancePutOrderedLong() throws Exception { + testLong(new LongData(), ORDERED); + } + + public void testInstancePutOrderedFloat() throws Exception { + testFloat(new FloatData(), ORDERED); + } + + public void testInstancePutOrderedDouble() throws Exception { + testDouble(new DoubleData(), ORDERED); + } + + public void testInstancePutOrderedBoolean() throws Exception { + testBoolean(new BooleanData(), ORDERED); + } + + public void testInstancePutOrderedReference() throws Exception { + testReference(new ObjectData(), ORDERED); + } + + /* put tests with array as object */ + public void testArrayPutOrderedByte() throws Exception { + testByte(new byte[modelByte.length], ORDERED); + } + + public void testArrayPutOrderedChar() throws Exception { + testChar(new char[modelChar.length], ORDERED); + } + + public void testArrayPutOrderedShort() throws Exception { + testShort(new short[modelShort.length], ORDERED); + } + + public void testArrayPutOrderedInt() throws Exception { + testInt(new int[modelInt.length], ORDERED); + } + + public void testArrayPutOrderedLong() throws Exception { ; + testLong(new long[modelLong.length], ORDERED); + } + + public void testArrayPutOrderedFloat() throws Exception { + testFloat(new float[modelFloat.length], ORDERED); + } + + public void testArrayPutOrderedDouble() throws Exception { + testDouble(new double[modelDouble.length], ORDERED); + } + + public void testArrayPutOrderedBoolean() throws Exception { + testBoolean(new boolean[modelBoolean.length], ORDERED); + } + + public void testArrayPutOrderedReference() throws Exception { + testReference(new Object[models.length], ORDERED); + } + + /* put tests with static object */ + public void testStaticPutOrderedByte() throws Exception { + testByte(ByteData.class, ORDERED); + } + + public void testStaticPutOrderedChar() throws Exception { + testChar(CharData.class, ORDERED); + } + + public void testStaticPutOrderedShort() throws Exception { + testShort(ShortData.class, ORDERED); + } + + public void testStaticPutOrderedInt() throws Exception { + testInt(IntData.class, ORDERED); + } + + public void testStaticPutOrderedLong() throws Exception { + testLong(LongData.class, ORDERED); + } + + public void testStaticPutOrderedFloatRelease() throws Exception { + testFloat(FloatData.class, ORDERED); + } + + public void testStaticPutOrderdDouble() throws Exception { + testDouble(DoubleData.class, ORDERED); + } + + public void testStaticPutOrderedBoolean() throws Exception { + testBoolean(BooleanData.class, ORDERED); + } + + public void testStaticPutOrderedReference() throws Exception { + testReference(ObjectData.class, ORDERED); + } + + /* tests with null object */ + public void testObjectNullPutOrderedByte() throws Exception { + testByteNative(ORDERED); + } + + public void testObjectNullPutOrderedChar() throws Exception { + testCharNative(ORDERED); + } + + public void testObjectNullPutOrderedShort() throws Exception { + testShortNative(ORDERED); + } + + public void testObjectNullPutOrderedInt() throws Exception { + testIntNative(ORDERED); + } + + public void testObjectNullPutOrderedLong() throws Exception { + testLongNative(ORDERED); + } + + public void testObjectNullPutOrderedFloat() throws Exception { + testFloatNative(ORDERED); + } + + public void testObjectNullPutOrderedDouble() throws Exception { + testDoubleNative(ORDERED); + } + + public void testObjectNullPutOrderedBoolean() throws Exception { + testBooleanNative(ORDERED); + } + + /* get test with new instance as object */ + public void testInstanceGetOrderedByte() throws Exception { + testGetByte(new ByteData(), ORDERED); + } + + public void testInstanceGetOrderedChar() throws Exception { + testGetChar(new CharData(), ORDERED); + } + + public void testInstanceGetOrderedShort() throws Exception { + testGetShort(new ShortData(), ORDERED); + } + + public void testInstanceGetOrderedInt() throws Exception { + testGetInt(new IntData(), ORDERED); + } + + public void testInstanceGetOrderedLong() throws Exception { + testGetLong(new LongData(), ORDERED); + } + + public void testInstanceGetOrderedFloat() throws Exception { + testGetFloat(new FloatData(), ORDERED); + } + + public void testInstanceGetOrderedDouble() throws Exception { + testGetDouble(new DoubleData(), ORDERED); + } + + public void testInstanceGetOrderedBoolean() throws Exception { + testGetBoolean(new BooleanData(), ORDERED); + } + + public void testInstanceGetOrderedReference() throws Exception { + testGetReference(new ObjectData(), ORDERED); + } + + /* get tests with array as object */ + public void testArrayGetOrderedByte() throws Exception { + testGetByte(new byte[modelByte.length], ORDERED); + } + + public void testArrayGetOrderedChar() throws Exception { + testGetChar(new char[modelChar.length], ORDERED); + } + + public void testArrayGetOrderedShort() throws Exception { + testGetShort(new short[modelShort.length], ORDERED); + } + + public void testArrayGetOrderedInt() throws Exception { + testGetInt(new int[modelInt.length], ORDERED); + } + + public void testArrayGetOrderedLong() throws Exception { + testGetLong(new long[modelLong.length], ORDERED); + } + + public void testArrayGetOrderedDouble() throws Exception { + testGetDouble(new double[modelDouble.length], ORDERED); + } + + public void testArrayGetOrderedBoolean() throws Exception { + testGetBoolean(new boolean[modelBoolean.length], ORDERED); + } + + public void testArrayGetOrderedReference() throws Exception { + testGetReference(new Object[models.length], ORDERED); + } + + /* get tests with static object */ + public void testStaticGetOrderedByte() throws Exception { + testGetByte(ByteData.class, ORDERED); + } + + public void testStaticGetOrderedChar() throws Exception { + testGetChar(CharData.class, ORDERED); + } + + public void testStaticGetOrderedShort() throws Exception { + testGetShort(ShortData.class, ORDERED); + } + + public void testStaticGetOrderedInt() throws Exception { + testGetInt(IntData.class, ORDERED); + } + + public void testStaticGetOrderedLong() throws Exception { + testGetLong(LongData.class, ORDERED); + } + + public void testStaticGetOrderedDouble() throws Exception { + testGetDouble(DoubleData.class, ORDERED); + } + + public void testStaticGetOrderedBoolean() throws Exception { + testGetBoolean(BooleanData.class, ORDERED); + } + + public void testStaticGetOrderedReference() throws Exception { + testGetReference(ObjectData.class, ORDERED); + } +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java new file mode 100644 index 00000000000..c5c5eabf547 --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeAccessVolatile.java @@ -0,0 +1,302 @@ +/* + * Copyright IBM Corp. and others 2001 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeAccessVolatile extends UnsafeTestBase { + private static Logger logger = Logger.getLogger(TestUnsafeAccessVolatile.class); + + public TestUnsafeAccessVolatile(String scenario) { + super(scenario); + } + + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ + @Override + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + // tests for testInstancePutXXXXVolatile + public void testInstancePutByteVolatile() throws Exception { + testByte(new ByteData(), VOLATILE); + } + + public void testInstancePutCharVolatile() throws Exception { + testChar(new CharData(), VOLATILE); + } + + public void testInstancePutShortVolatile() throws Exception { + testShort(new ShortData(), VOLATILE); + } + + public void testInstancePutIntVolatile() throws Exception { + testInt(new IntData(), VOLATILE); + } + + public void testInstancePutLongVolatile() throws Exception { + testLong(new LongData(), VOLATILE); + } + + public void testInstancePutFloatVolatile() throws Exception { + testFloat(new FloatData(), VOLATILE); + } + + public void testInstancePutDoubleVolatile() throws Exception { + testDouble(new DoubleData(), VOLATILE); + } + + public void testInstancePutBooleanVolatile() throws Exception { + testBoolean(new BooleanData(), VOLATILE); + } + + public void testInstancePutReferenceVolatile() throws Exception { + testReference(new ObjectData(), VOLATILE); + } + + // tests for testArrayPutXXXXVolatile + public void testArrayPutByteVolatile() throws Exception { + testByte(new byte[modelByte.length], VOLATILE); + } + + public void testArrayPutCharVolatile() throws Exception { + testChar(new char[modelChar.length], VOLATILE); + } + + public void testArrayPutShortVolatile() throws Exception { + testShort(new short[modelShort.length], VOLATILE); + } + + public void testArrayPutIntVolatile() throws Exception { + testInt(new int[modelInt.length], VOLATILE); + } + + public void testArrayPutLongVolatile() throws Exception { + testLong(new long[modelLong.length], VOLATILE); + } + + public void testArrayPutFloatVolatile() throws Exception { + testFloat(new float[modelFloat.length], VOLATILE); + } + + public void testArrayPutDoubleVolatile() throws Exception { + testDouble(new double[modelDouble.length], VOLATILE); + } + + public void testArrayPutBooleanVolatile() throws Exception { + testBoolean(new boolean[modelBoolean.length], VOLATILE); + } + + public void testArrayPutReferenceVolatile() throws Exception { + testReference(new Object[models.length], VOLATILE); + } + + // tests for testStaticPutXXXXVolatile + public void testStaticPutByteVolatile() throws Exception { + testByte(ByteData.class, VOLATILE); + } + + public void testStaticPutCharVolatile() throws Exception { + testChar(CharData.class, VOLATILE); + } + + public void testStaticPutShortVolatile() throws Exception { + testShort(ShortData.class, VOLATILE); + } + + public void testStaticPutIntVolatile() throws Exception { + testInt(IntData.class, VOLATILE); + } + + public void testStaticPutLongVolatile() throws Exception { + testLong(LongData.class, VOLATILE); + } + + public void testStaticPutFloatVolatile() throws Exception { + testFloat(FloatData.class, VOLATILE); + } + + public void testStaticPutDoubleVolatile() throws Exception { + testDouble(DoubleData.class, VOLATILE); + } + + public void testStaticPutBooleanVolatile() throws Exception { + testBoolean(BooleanData.class, VOLATILE); + } + + public void testStaticPutReferenceVolatile() throws Exception { + testReference(ObjectData.class, VOLATILE); + } + + // tests for testObjectNullPutXXXXVolatile + public void testObjectNullPutByteVolatile() throws Exception { + testByteNative(VOLATILE); + } + + public void testObjectNullPutCharVolatile() throws Exception { + testCharNative(VOLATILE); + } + + public void testObjectNullPutShortVolatile() throws Exception { + testShortNative(VOLATILE); + } + + public void testObjectNullPutIntVolatile() throws Exception { + testIntNative(VOLATILE); + } + + public void testObjectNullPutLongVolatile() throws Exception { + testLongNative(VOLATILE); + } + + public void testObjectNullPutFloatVolatile() throws Exception { + testFloatNative(VOLATILE); + } + + public void testObjectNullPutDoubleVolatile() throws Exception { + testDoubleNative(VOLATILE); + } + + public void testObjectNullPutBooleanVolatile() throws Exception { + testBooleanNative(VOLATILE); + } + + // tests for testInstanceGetXXXXVolatile + public void testInstanceGetByteVolatile() throws Exception { + testGetByte(new ByteData(), VOLATILE); + } + + public void testInstanceGetCharVolatile() throws Exception { + testGetChar(new CharData(), VOLATILE); + } + + public void testInstanceGetShortVolatile() throws Exception { + testGetShort(new ShortData(), VOLATILE); + } + + public void testInstanceGetIntVolatile() throws Exception { + testGetInt(new IntData(), VOLATILE); + } + + public void testInstanceGetLongVolatile() throws Exception { + testGetLong(new LongData(), VOLATILE); + } + + public void testInstanceGetFloatVolatile() throws Exception { + testGetFloat(new FloatData(), VOLATILE); + } + + public void testInstanceGetDoubleVolatile() throws Exception { + testGetDouble(new DoubleData(), VOLATILE); + } + + public void testInstanceGetBooleanVolatile() throws Exception { + testGetBoolean(new BooleanData(), VOLATILE); + } + + public void testInstanceGetReferenceVolatile() throws Exception { + testGetReference(new ObjectData(), VOLATILE); + } + + // tests for testArrayGetXXXXVolatile + public void testArrayGetByteVolatile() throws Exception { + testGetByte(new byte[modelByte.length], VOLATILE); + } + + public void testArrayGetCharVolatile() throws Exception { + testGetChar(new char[modelChar.length], VOLATILE); + } + + public void testArrayGetShortVolatile() throws Exception { + testGetShort(new short[modelShort.length], VOLATILE); + } + + public void testArrayGetIntVolatile() throws Exception { + testGetInt(new int[modelInt.length], VOLATILE); + } + + public void testArrayGetLongVolatile() throws Exception { + testGetLong(new long[modelLong.length], VOLATILE); + } + + public void testArrayGetFloatVolatile() throws Exception { + testGetFloat(new float[modelFloat.length], VOLATILE); + } + + public void testArrayGetDoubleVolatile() throws Exception { + testGetDouble(new double[modelDouble.length], VOLATILE); + } + + public void testArrayGetBooleanVolatile() throws Exception { + testGetBoolean(new boolean[modelBoolean.length], VOLATILE); + } + + public void testArrayGetReferenceVolatile() throws Exception { + testGetReference(new Object[models.length], VOLATILE); + } + + // tests for testStaticGetXXXXVolatile + public void testStaticGetByteVolatile() throws Exception { + testGetByte(ByteData.class, VOLATILE); + } + + public void testStaticGetCharVolatile() throws Exception { + testGetChar(CharData.class, VOLATILE); + } + + public void testStaticGetShortVolatile() throws Exception { + testGetShort(ShortData.class, VOLATILE); + } + + public void testStaticGetIntVolatile() throws Exception { + testGetInt(IntData.class, VOLATILE); + } + + public void testStaticGetLongVolatile() throws Exception { + testGetLong(LongData.class, VOLATILE); + } + + public void testStaticGetFloatVolatile() throws Exception { + testGetFloat(FloatData.class, VOLATILE); + } + + public void testStaticGetDoubleVolatile() throws Exception { + testGetDouble(DoubleData.class, VOLATILE); + } + + public void testStaticGetBooleanVolatile() throws Exception { + testGetBoolean(BooleanData.class, VOLATILE); + } + + public void testStaticGetReferenceVolatile() throws Exception { + testGetReference(ObjectData.class, VOLATILE); + } +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java new file mode 100644 index 00000000000..9be29859e16 --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndExchange.java @@ -0,0 +1,290 @@ +/* + * Copyright IBM Corp. and others 2017 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeCompareAndExchange extends UnsafeTestBase { + private String[] testList = { COMPAREANDEXCH, COMPAREANDEXCHA, COMPAREANDEXCHR }; + + private static Logger logger = Logger.getLogger(TestUnsafeCompareAndExchange.class); + + public TestUnsafeCompareAndExchange(String scenario) { + super(scenario); + } + + /* + * get logger to use, for child classes to report with their class name instead + * of UnsafeTestBase + */ + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + /* test with instance as object */ + public void testInstanceCompareAndExchangeByte() throws Exception { + for (String test : testList) { + testByte(new ByteData(), test); + } + } + + public void testInstanceCompareAndExchangeChar() throws Exception { + for (String test : testList) { + testChar(new CharData(), test); + } + } + + public void testInstanceCompareAndExchangeShort() throws Exception { + for (String test : testList) { + testShort(new ShortData(), test); + } + } + + public void testInstanceCompareAndExchangeInt() throws Exception { + for (String test : testList) { + testInt(new IntData(), test); + } + } + + public void testInstanceCompareAndExchangeLong() throws Exception { + for (String test : testList) { + testLong(new LongData(), test); + } + } + + public void testInstanceCompareAndExchangeFloat() throws Exception { + for (String test : testList) { + testFloat(new FloatData(), test); + } + } + + public void testInstanceCompareAndExchangeDouble() throws Exception { + for (String test : testList) { + testDouble(new DoubleData(), test); + } + } + + public void testInstanceCompareAndExchangeBoolean() throws Exception { + for (String test : testList) { + testBoolean(new BooleanData(), test); + } + } + + public void testInstanceCompareAndExchangeReference() throws Exception { + for (String test : testList) { + testReference(new ObjectData(), test); + } + } + + /* test with array as object */ + public void testArrayCompareAndExchangeByte() throws Exception { + for (String test : testList) { + testByte(new byte[modelByte.length], test); + } + } + + public void testArrayCompareAndExchangeChar() throws Exception { + for (String test : testList) { + testChar(new char[modelChar.length], test); + } + } + + public void testArrayCompareAndExchangeShort() throws Exception { + for (String test : testList) { + testShort(new short[modelShort.length], test); + } + } + + public void testArrayCompareAndExchangeInt() throws Exception { + for (String test : testList) { + testInt(new int[modelInt.length], test); + } + } + + public void testArrayCompareAndExchangeLong() throws Exception { + for (String test : testList) { + testLong(new long[modelLong.length], test); + } + } + + public void testArrayCompareAndExchangeFloat() throws Exception { + for (String test : testList) { + testFloat(new float[modelFloat.length], test); + } + } + + public void testArrayCompareAndExchangeDouble() throws Exception { + for (String test : testList) { + testDouble(new double[modelDouble.length], test); + } + } + + public void testArrayCompareAndExchangeBoolean() throws Exception { + for (String test : testList) { + testBoolean(new boolean[modelBoolean.length], test); + } + } + + public void testArrayCompareAndExchangeReference() throws Exception { + for (String test : testList) { + testReference(new Object[models.length], test); + } + } + + /* test with static object */ + public void testStaticCompareAndExchangeByte() throws Exception { + for (String test : testList) { + testByte(ByteData.class, test); + } + } + + public void testStaticCompareAndExchangeChar() throws Exception { + for (String test : testList) { + testChar(CharData.class, test); + } + } + + public void testStaticCompareAndExchangeShort() throws Exception { + for (String test : testList) { + testShort(ShortData.class, test); + } + } + + public void testStaticCompareAndExchangeInt() throws Exception { + for (String test : testList) { + testInt(IntData.class, test); + } + } + + public void testStaticCompareAndExchangeLong() throws Exception { + for (String test : testList) { + testLong(LongData.class, test); + } + } + + public void testStaticCompareAndExchangeFloat() throws Exception { + for (String test : testList) { + testFloat(FloatData.class, test); + } + } + + public void testStaticCompareAndExchangeDouble() throws Exception { + for (String test : testList) { + testDouble(DoubleData.class, test); + } + } + + public void testStaticCompareAndExchangeBoolean() throws Exception { + for (String test : testList) { + testBoolean(BooleanData.class, test); + } + } + + public void testStaticCompareAndExchangeReference() throws Exception { + for (String test : testList) { + testReference(ObjectData.class, test); + } + } + + /* test with null object */ + public void testObjectNullCompareAndExchangeByte() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testByteNative(test); + } + } + + public void testObjectNullCompareAndExchangeChar() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testCharNative(test); + } + } + + public void testObjectNullCompareAndExchangeShort() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testShortNative(test); + } + } + + public void testObjectNullCompareAndExchangeInt() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testIntNative(test); + } + } + + public void testObjectNullCompareAndExchangeLong() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testLongNative(test); + } + } + + public void testObjectNullCompareAndExchangeFloat() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testFloatNative(test); + } + } + + public void testObjectNullCompareAndExchangeDouble() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testDoubleNative(test); + } + } + + public void testObjectNullCompareAndExchangeBoolean() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testBooleanNative(test); + } + } + +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java new file mode 100644 index 00000000000..9ae6232904f --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeCompareAndSet.java @@ -0,0 +1,288 @@ +/* + * Copyright IBM Corp. and others 2017 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeCompareAndSet extends UnsafeTestBase { + private String[] testList = { COMPAREANDEXCH, COMPAREANDEXCHA, COMPAREANDEXCHR }; + + private static Logger logger = Logger.getLogger(TestUnsafeCompareAndSet.class); + + public TestUnsafeCompareAndSet(String scenario) { + super(scenario); + } + + /* + * get logger to use, for child classes to report with their class name instead + * of UnsafeTestBase + */ + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + /* test with instance as object */ + public void testInstanceCompareAndSetByte() throws Exception { + for (String test : testList) { + testByte(new ByteData(), test); + } + } + + public void testInstanceCompareAndSetChar() throws Exception { + for (String test : testList) { + testChar(new CharData(), test); + } + } + + public void testInstanceCompareAndSetShort() throws Exception { + for (String test : testList) { + testShort(new ShortData(), test); + } + } + + public void testInstanceCompareAndSetInt() throws Exception { + for (String test : testList) { + testInt(new IntData(), test); + } + } + + public void testInstanceCompareAndSetLong() throws Exception { + for (String test : testList) { + testLong(new LongData(), test); + } + } + + public void testInstanceCompareAndSetFloat() throws Exception { + for (String test : testList) { + testFloat(new FloatData(), test); + } + } + + public void testInstanceCompareAndSetDouble() throws Exception { + for (String test : testList) { + testDouble(new DoubleData(), test); + } + } + + public void testInstanceCompareAndSetBoolean() throws Exception { + for (String test : testList) { + testBoolean(new BooleanData(), test); + } + } + + public void testInstanceCompareAndSetReference() throws Exception { + for (String test : testList) { + testReference(new ObjectData(), test); + } + } + + /* test with array as object */ + public void testArrayCompareAndSetByte() throws Exception { + for (String test : testList) { + testByte(new byte[modelByte.length], test); + } + } + + public void testArrayCompareAndSetChar() throws Exception { + for (String test : testList) { + testChar(new char[modelChar.length], test); + } + } + + public void testArrayCompareAndSetShort() throws Exception { + for (String test : testList) { + testShort(new short[modelShort.length], test); + } + } + + public void testArrayCompareAndSetInt() throws Exception { + for (String test : testList) { + testInt(new int[modelInt.length], test); + } + } + + public void testArrayCompareAndSetLong() throws Exception { + for (String test : testList) { + testLong(new long[modelLong.length], test); + } + } + + public void testArrayCompareAndSetFloat() throws Exception { + for (String test : testList) { + testFloat(new float[modelFloat.length], test); + } + } + + public void testArrayCompareAndSetDouble() throws Exception { + for (String test : testList) { + testDouble(new double[modelDouble.length], test); + } + } + + public void testArrayCompareAndSetBoolean() throws Exception { + testBoolean(new boolean[modelBoolean.length], COMPAREANDSET); + } + + public void testArrayCompareAndSetReference() throws Exception { + for (String test : testList) { + testReference(new Object[models.length], test); + } + } + + /* test with static object */ + public void testStaticCompareAndSetByte() throws Exception { + for (String test : testList) { + testByte(ByteData.class, test); + } + } + + public void testStaticCompareAndSetChar() throws Exception { + for (String test : testList) { + testChar(CharData.class, test); + } + } + + public void testStaticCompareAndSetShort() throws Exception { + for (String test : testList) { + testShort(ShortData.class, test); + } + } + + public void testStaticCompareAndSetInt() throws Exception { + for (String test : testList) { + testInt(IntData.class, test); + } + } + + public void testStaticCompareAndSetLong() throws Exception { + for (String test : testList) { + testLong(LongData.class, test); + } + } + + public void testStaticCompareAndSetFloat() throws Exception { + for (String test : testList) { + testFloat(FloatData.class, test); + } + } + + public void testStaticCompareAndSetDouble() throws Exception { + for (String test : testList) { + testDouble(DoubleData.class, test); + } + } + + public void testStaticCompareAndSetBoolean() throws Exception { + for (String test : testList) { + testBoolean(BooleanData.class, test); + } + } + + public void testStaticCompareAndSetReference() throws Exception { + for (String test : testList) { + testReference(ObjectData.class, test); + } + } + + /* test with null object */ + public void testObjectNullCompareAndSetByte() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testByteNative(test); + } + } + + public void testObjectNullCompareAndSetChar() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testCharNative(test); + } + } + + public void testObjectNullCompareAndSetShort() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testShortNative(test); + } + } + + public void testObjectNullCompareAndSetInt() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testIntNative(test); + } + } + + public void testObjectNullCompareAndSetLong() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testLongNative(test); + } + } + + public void testObjectNullCompareAndSetFloat() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testFloatNative(test); + } + } + + public void testObjectNullCompareAndSetDouble() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testDoubleNative(test); + } + } + + public void testObjectNullCompareAndSetBoolean() throws Exception { + memAllocate(100); + alignment(); + + for (String test : testList) { + testBooleanNative(test); + } + } + +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeGetAndOp.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeGetAndOp.java new file mode 100644 index 00000000000..6436584b58f --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/TestUnsafeGetAndOp.java @@ -0,0 +1,224 @@ +/* + * Copyright IBM Corp. and others 2017 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups = { "level.sanity" }) +public class TestUnsafeGetAndOp extends UnsafeTestBase { + private String[] testList = { GETANDSET, GETANDSETA, GETANDSETR, GETANDADD, GETANDADDA, GETANDADDR, GETANDBITWISEOR, + GETANDBITWISEORA, GETANDBITWISEORR, GETANDBITWISEAND, GETANDBITWISEANDA, GETANDBITWISEANDR, + GETANDBITWISEXOR, GETANDBITWISEXORA, GETANDBITWISEXORR }; + private String[] decimalTestList = { GETANDSET, GETANDSETA, GETANDSETR, GETANDADD, GETANDADDA, GETANDADDR }; + private String[] boolTestList = { GETANDSET, GETANDSETA, GETANDSETR, GETANDBITWISEOR, GETANDBITWISEORA, + GETANDBITWISEORR, GETANDBITWISEAND, GETANDBITWISEANDA, GETANDBITWISEANDR, GETANDBITWISEXOR, + GETANDBITWISEXORA, GETANDBITWISEXORR }; + private String[] objTestList = { GETANDSET, GETANDSETA, GETANDSETR }; + + private static Logger logger = Logger.getLogger(TestUnsafeGetAndOp.class); + + public TestUnsafeGetAndOp(String scenario) { + super(scenario); + } + + /* + * get logger to use, for child classes to report with their class name instead + * of UnsafeTestBase + */ + protected Logger getLogger() { + return logger; + } + + @Override + @BeforeMethod + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance2(); + } + + /* test with instance as object */ + public void testInstanceGetAndOpByte() throws Exception { + for (String test : testList) { + testGetByte(new ByteData(), test); + } + } + + public void testInstanceGetAndOpChar() throws Exception { + for (String test : testList) { + testGetChar(new CharData(), test); + } + } + + public void testInstanceGetAndOpShort() throws Exception { + for (String test : testList) { + testGetShort(new ShortData(), test); + } + } + + public void testInstanceGetAndOpInt() throws Exception { + for (String test : testList) { + testGetInt(new IntData(), test); + } + } + + public void testInstanceGetAndOpLong() throws Exception { + for (String test : testList) { + testGetLong(new LongData(), test); + } + } + + public void testInstanceGetAndOpFloat() throws Exception { + for (String test : decimalTestList) { + testGetFloat(new FloatData(), test); + } + } + + public void testInstanceGetAndOpDouble() throws Exception { + for (String test : decimalTestList) { + testGetDouble(new DoubleData(), test); + } + } + + public void testInstanceGetAndOpBoolean() throws Exception { + for (String test : boolTestList) { + testGetBoolean(new BooleanData(), test); + } + } + + public void testInstanceGetAndOpReference() throws Exception { + for (String test : objTestList) { + testGetReference(new ObjectData(), test); + } + } + + /* test with array as object */ + public void testArrayGetAndOpByte() throws Exception { + for (String test : testList) { + testGetByte(new byte[modelByte.length], test); + } + } + + public void testArrayGetAndOpChar() throws Exception { + for (String test : testList) { + testGetChar(new char[modelChar.length], test); + } + } + + public void testArrayGetAndOpShort() throws Exception { + for (String test : testList) { + testGetShort(new short[modelShort.length], test); + } + } + + public void testArrayGetAndOpInt() throws Exception { + for (String test : testList) { + testGetInt(new int[modelInt.length], test); + } + } + + public void testArrayGetAndOpLong() throws Exception { + for (String test : testList) { + testGetLong(new long[modelLong.length], test); + } + } + + public void testArrayGetAndOpFloat() throws Exception { + for (String test : decimalTestList) { + testGetFloat(new float[modelFloat.length], test); + } + } + + public void testArrayGetAndOpDouble() throws Exception { + for (String test : decimalTestList) { + testGetDouble(new double[modelDouble.length], test); + } + } + + public void testArrayGetAndOpBoolean() throws Exception { + for (String test : boolTestList) { + testGetBoolean(new boolean[modelBoolean.length], test); + } + } + + public void testArrayGetAndOpReference() throws Exception { + for (String test : objTestList) { + testGetReference(new Object[models.length], test); + } + } + + /* test with static object */ + public void testStaticGetAndOpByte() throws Exception { + for (String test : testList) { + testGetByte(ByteData.class, test); + } + } + + public void testStaticGetAndOpChar() throws Exception { + for (String test : testList) { + testGetChar(CharData.class, test); + } + } + + public void testStaticGetAndOpShort() throws Exception { + for (String test : testList) { + testGetShort(ShortData.class, test); + } + } + + public void testStaticGetAndOpInt() throws Exception { + for (String test : testList) { + testGetInt(IntData.class, test); + } + } + + public void testStaticGetAndOpLong() throws Exception { + for (String test : testList) { + testGetLong(LongData.class, test); + } + } + + public void testStaticGetAndOpFloat() throws Exception { + for (String test : decimalTestList) { + testGetFloat(FloatData.class, test); + } + } + + public void testStaticGetAndOpDouble() throws Exception { + for (String test : decimalTestList) { + testGetDouble(DoubleData.class, test); + } + } + + public void testStaticGetAndOpBoolean() throws Exception { + for (String test : boolTestList) { + testGetBoolean(BooleanData.class, test); + } + } + + public void testStaticGetAndOpReference() throws Exception { + for (String test : objTestList) { + testGetReference(ObjectData.class, test); + } + } + +} diff --git a/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/UnsafeTestBase.java b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/UnsafeTestBase.java new file mode 100644 index 00000000000..d8d14aa463d --- /dev/null +++ b/test/functional/UnsafeTest/src_25/org/openj9/test/unsafe/UnsafeTestBase.java @@ -0,0 +1,2968 @@ +/* + * Copyright IBM Corp. and others 2001 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ +package org.openj9.test.unsafe; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.testng.AssertJUnit; +import org.testng.ITest; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.log4testng.Logger; + +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; + +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.RETURN; + +import jdk.internal.misc.Unsafe; + +public class UnsafeTestBase implements ITest { + private static Logger logger = Logger.getLogger(UnsafeTestBase.class); + protected static jdk.internal.misc.Unsafe myUnsafe; + + protected final String VOLATILE = "Volatile"; + protected final String OPAQUE = "Opaque"; + protected final String ORDERED = "Ordered"; + protected final String UNALIGNED = "Unaligned"; + protected final String DEFAULT = "put"; + + /* compareAndSet methods */ + protected final String COMPAREANDSET = "CompareAndSet"; + protected final String WCOMPAREANDSET = "weakCompareAndSet"; + protected final String WCOMPAREANDSETP = "weakCompareAndSetPlain"; + protected final String WCOMPAREANDSETA = "weakCompareAndSetAcquire"; + protected final String WCOMPAREANDSETR = "weakCompareAndSetRelease"; + + /* compareAndExchange methods */ + protected final String COMPAREANDEXCH = "CompareAndExchange"; + protected final String COMPAREANDEXCHA = "CompareAndExchangeAcquire"; + protected final String COMPAREANDEXCHR = "CompareAndExchangeRelease"; + + /* getAndOp methods */ + protected final String GETANDSET = "GetAndSet"; + protected final String GETANDSETA = "GetAndSetAcquire"; + protected final String GETANDSETR = "GetAndSetRelease"; + protected final String GETANDADD = "GetAndAdd"; + protected final String GETANDADDA = "GetAndAddAcquire"; + protected final String GETANDADDR = "GetAndAddRequire"; + protected final String GETANDBITWISEOR = "GetAndBitwiseOr"; + protected final String GETANDBITWISEORA = "GetAndBitwiseOrAcquire"; + protected final String GETANDBITWISEORR = "GetAndBitwiseOrRelease"; + protected final String GETANDBITWISEAND = "GetAndBitwiseAnd"; + protected final String GETANDBITWISEANDA = "GetAndBitwiseAndAcquire"; + protected final String GETANDBITWISEANDR = "GetAndBitwiseAndRelease"; + protected final String GETANDBITWISEXOR = "GetAndBitwiseXor"; + protected final String GETANDBITWISEXORA = "GetAndBitwiseXorAcquire"; + protected final String GETANDBITWISEXORR = "GetAndBitwiseXorRelease"; + + protected final static String ADDRESS = "address"; + + private static final int BYTE_MASK = 0xFF; + private static final long BYTE_MASKL = (long) BYTE_MASK; + + protected long mem = 0; + + /* variables required to change test name based on run scenario (compiled first or not) */ + protected String scenario; + protected String mTestName = ""; + + /* use scenario string to change TestNG output showing if the run is regular or with compiled classes */ + public UnsafeTestBase (String runScenario) { + scenario = runScenario; + } + + @BeforeMethod(alwaysRun = true) + public void setTestName(Method method, Object[] parameters) { + mTestName = method.getName(); + logger.debug("Test started: " + mTestName); + } + + @Override + public String getTestName() { + return mTestName + " (" + scenario + ")"; + } + + /* get logger to use, for child classes to report with their class name instead of UnsafeTestBase*/ + protected Logger getLogger() { + return logger; + } + + /* use reflection to bypass the security manager */ + protected static Unsafe getUnsafeInstance() throws IllegalAccessException { + /* the instance is likely stored in a static field of type Unsafe */ + Field[] staticFields = Unsafe.class.getDeclaredFields(); + for (Field field : staticFields) { + if (field.getType() == Unsafe.class) { + field.setAccessible(true); + return (Unsafe) field.get(Unsafe.class); + } + } + throw new Error("Unable to find an instance of Unsafe"); + } + + protected static Unsafe getUnsafeInstance2() throws IllegalAccessException, + NoSuchFieldException, SecurityException { + Field field = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + Unsafe unsafe = (jdk.internal.misc.Unsafe) field.get(null); + return unsafe; + } + + protected static final byte[] modelByte = new byte[] { -1, -1, -2, -3, -4, + 1, 2, 3, 4, Byte.MAX_VALUE, Byte.MIN_VALUE, 0 }; + protected static final char[] modelChar = new char[] { (char) -1, + (char) -1, 1, 2, Character.MAX_VALUE, Character.MAX_VALUE - 1, 0 }; + protected static final short[] modelShort = new short[] { -1, -1, -2, 1, 2, + Short.MAX_VALUE, Short.MIN_VALUE, 0 }; + protected static final int[] modelInt = new int[] { -1, -1, 1, 2, + Integer.MAX_VALUE, Integer.MIN_VALUE, 0 }; + protected static final long[] modelLong = new long[] { -1, -1, 1, + Long.MAX_VALUE, Long.MIN_VALUE, 0 }; + protected static final float[] modelFloat = new float[] { -1f, -1f, 1.0f, + 2.0f, Float.MAX_VALUE, Float.MIN_VALUE, 0.0f }; + protected static final double[] modelDouble = new double[] { -1, -1, 1.0, + Double.MAX_VALUE, Double.MIN_VALUE, 0.0 }; + protected static final boolean[] modelBoolean = new boolean[] { true, false }; + protected static final Object[] models = new Object[] { modelByte, modelChar, modelShort, modelInt, modelLong, + modelFloat, modelDouble, modelBoolean }; + + /* compare value for compareAndXXXX tests */ + private static final byte compareValueByte = -5; + private static final char compareValueChar = (char) -5; + private static final short compareValueShort = -5; + private static final int compareValueInt = -5; + private static final long compareValueLong = -5; + private static final float compareValueFloat = -5; + private static final double compareValueDouble = -5; + private static final Object compareValueObject = new Object(); + + /* bitwise check for getAndBitwiseXXX */ + private static final byte bitwiseValueByte = (byte) 0xF; + private static final char bitwiseValueChar = (char) 0xF; + private static final short bitwiseValueShort = (short) 0xF; + private static final int bitwiseValueInt = 0xF; + private static final long bitwiseValueLong = 0xFL; + + static abstract class Data { + abstract void init(); + + Object get(int i) { + throw new Error("Invalid field index " + i); + } + + Object getStatic(int i) { + throw new Error("Invalid static field index " + i); + } + } + + static class ByteData extends Data { + byte f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11; + static byte sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7, sf8, sf9, sf10, + sf11; + + void init() { + f0 = sf0 = modelByte[0]; + f1 = sf1 = modelByte[1]; + f2 = sf2 = modelByte[2]; + f3 = sf3 = modelByte[3]; + f4 = sf4 = modelByte[4]; + f5 = sf5 = modelByte[5]; + f6 = sf6 = modelByte[6]; + f7 = sf7 = modelByte[7]; + f8 = sf8 = modelByte[8]; + f9 = sf9 = modelByte[9]; + f10 = sf10 = modelByte[10]; + f11 = sf11 = modelByte[11]; + } + + Object get(int i) { + return new byte[] { f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, + f11 }[i]; + } + + Object getStatic(int i) { + return new byte[] { sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7, sf8, + sf9, sf10, f11 }[i]; + } + } + + static class CharData extends Data { + char f0, f1, f2, f3, f4, f5, f6; + static char sf0, sf1, sf2, sf3, sf4, sf5, sf6; + + void init() { + f0 = sf0 = modelChar[0]; + f1 = sf1 = modelChar[1]; + f2 = sf2 = modelChar[2]; + f3 = sf3 = modelChar[3]; + f4 = sf4 = modelChar[4]; + f5 = sf5 = modelChar[5]; + f6 = sf6 = modelChar[6]; + } + + Object get(int i) { + return new char[] { f0, f1, f2, f3, f4, f5, f6 }[i]; + } + + Object getStatic(int i) { + return new char[] { sf0, sf1, sf2, sf3, sf4, sf5, sf6 }[i]; + } + } + + static class ShortData extends Data { + short f0, f1, f2, f3, f4, f5, f6, f7; + static short sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7; + + void init() { + f0 = sf0 = modelShort[0]; + f1 = sf1 = modelShort[1]; + f2 = sf2 = modelShort[2]; + f3 = sf3 = modelShort[3]; + f4 = sf4 = modelShort[4]; + f5 = sf5 = modelShort[5]; + f6 = sf6 = modelShort[6]; + f7 = sf7 = modelShort[7]; + } + + Object get(int i) { + return new short[] { f0, f1, f2, f3, f4, f5, f6, f7 }[i]; + } + + Object getStatic(int i) { + return new short[] { sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7 }[i]; + } + } + + static class IntData extends Data { + int f0, f1, f2, f3, f4, f5, f6; + static int sf0, sf1, sf2, sf3, sf4, sf5, sf6; + + void init() { + f0 = sf0 = modelInt[0]; + f1 = sf1 = modelInt[1]; + f2 = sf2 = modelInt[2]; + f3 = sf3 = modelInt[3]; + f4 = sf4 = modelInt[4]; + f5 = sf5 = modelInt[5]; + f6 = sf6 = modelInt[6]; + } + + Object get(int i) { + return new int[] { f0, f1, f2, f3, f4, f5, f6 }[i]; + } + + Object getStatic(int i) { + return new int[] { sf0, sf1, sf2, sf3, sf4, sf5, sf6 }[i]; + } + } + + static class LongData extends Data { + long f0, f1, f2, f3, f4, f5; + static long sf0, sf1, sf2, sf3, sf4, sf5; + + void init() { + f0 = sf0 = modelLong[0]; + f1 = sf1 = modelLong[1]; + f2 = sf2 = modelLong[2]; + f3 = sf3 = modelLong[3]; + f4 = sf4 = modelLong[4]; + f5 = sf5 = modelLong[5]; + } + + Object get(int i) { + return new long[] { f0, f1, f2, f3, f4, f5 }[i]; + } + + Object getStatic(int i) { + return new long[] { sf0, sf1, sf2, sf3, sf4, sf5 }[i]; + } + } + + static class FloatData extends Data { + float f0, f1, f2, f3, f4, f5, f6; + static float sf0, sf1, sf2, sf3, sf4, sf5, sf6; + + void init() { + f0 = sf0 = modelFloat[0]; + f1 = sf1 = modelFloat[1]; + f2 = sf2 = modelFloat[2]; + f3 = sf3 = modelFloat[3]; + f4 = sf4 = modelFloat[4]; + f5 = sf5 = modelFloat[5]; + f6 = sf6 = modelFloat[6]; + } + + Object get(int i) { + return new float[] { f0, f1, f2, f3, f4, f5, f6 }[i]; + } + + Object getStatic(int i) { + return new float[] { sf0, sf1, sf2, sf3, sf4, sf5, sf6 }[i]; + } + } + + static class DoubleData extends Data { + double f0, f1, f2, f3, f4, f5; + static double sf0, sf1, sf2, sf3, sf4, sf5; + + void init() { + f0 = sf0 = modelDouble[0]; + f1 = sf1 = modelDouble[1]; + f2 = sf2 = modelDouble[2]; + f3 = sf3 = modelDouble[3]; + f4 = sf4 = modelDouble[4]; + f5 = sf5 = modelDouble[5]; + } + + Object get(int i) { + return new double[] { f0, f1, f2, f3, f4, f5 }[i]; + } + + Object getStatic(int i) { + return new double[] { sf0, sf1, sf2, sf3, sf4, sf5 }[i]; + } + } + + static class BooleanData extends Data { + boolean f0, f1; + static boolean sf0, sf1; + + void init() { + f0 = sf0 = modelBoolean[0]; + f1 = sf1 = modelBoolean[1]; + + } + + Object get(int i) { + return new boolean[] { f0, f1 }[i]; + } + + Object getStatic(int i) { + return new boolean[] { sf0, sf1 }[i]; + } + } + + static class ObjectData extends Data { + Object f0, f1, f2, f3, f4, f5, f6, f7; + static Object sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7; + + void init() { + f0 = sf0 = models[0]; + f1 = sf1 = models[1]; + f2 = sf2 = models[2]; + f3 = sf3 = models[3]; + f4 = sf4 = models[4]; + f5 = sf5 = models[5]; + f6 = sf6 = models[6]; + f7 = sf7 = models[7]; + } + + Object get(int i) { + switch(i) { + case 0: + return f0; + case 1: + return f1; + case 2: + return f2; + case 3: + return f3; + case 4: + return f4; + case 5: + return f5; + case 6: + return f6; + default: + return f7; + } + } + + Object getStatic(int i) { + switch(i) { + case 0: + return sf0; + case 1: + return sf1; + case 2: + return sf2; + case 3: + return sf3; + case 4: + return sf4; + case 5: + return sf5; + case 6: + return sf6; + default: + return sf7; + } + } + + /* return size in bytes of primitive array being accessed */ + static int getSize(int i) { + int size; + Object obj = models[i]; + + if ((obj instanceof byte[]) || (obj instanceof boolean[])) { + size = 1 * ((byte[]) obj).length; + } else if ((obj instanceof char[]) || (obj instanceof short[])) { + size = 2 * ((char[]) obj).length; + } else if ((obj instanceof int[]) || (obj instanceof float[])) { + size = 4 * ((int[]) obj).length; + } else { + size = 8 * ((long[]) obj).length; + } + + return size; + } + } + + protected long offset(Object object, int index) throws NoSuchFieldException { + if (object instanceof Class) + return myUnsafe.staticFieldOffset(((Class) object) + .getDeclaredField("sf" + index)); + if (object instanceof Data) + return myUnsafe.objectFieldOffset(object.getClass() + .getDeclaredField("f" + index)); + if (object.getClass().isArray()) + return myUnsafe.arrayBaseOffset(object.getClass()) + + (myUnsafe.arrayIndexScale(object.getClass()) * index); + throw new Error("Unable to get offset " + index + + " from unknown object type " + object.getClass()); + } + + protected Object base(Object object, int index) throws NoSuchFieldException { + if (object == null) + return null; + else if (object instanceof Class) + return myUnsafe.staticFieldBase(((Class) object) + .getDeclaredField("sf" + index)); + return object; + } + + protected static void init(Object object) throws InstantiationException, + IllegalAccessException { + if (object instanceof Class) + ((Data) ((Class) object).newInstance()).init(); + if (object instanceof Data) + ((Data) object).init(); + if (object.getClass().isArray()) { + for (Object model : models) { + if (model.getClass().equals(object.getClass())) { + System.arraycopy(model, 0, object, 0, + Array.getLength(model)); + } + } + } + } + + protected static Object slot(Object object, int index) + throws InstantiationException, IllegalAccessException { + if (object instanceof Class) + return ((Data) ((Class) object).newInstance()).getStatic(index); + if (object instanceof Data) + return ((Data) object).get(index); + if (object.getClass().isArray()) + return Array.get(object, index); + throw new Error("Can't get slot " + index + " of unknown object type"); + } + + protected void modelCheck(Object model, Object object, int limit) + throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug("Index: " + i + " Expected: " + Array.get(model, i) + + " Actual: " + slot(object, i)); + AssertJUnit.assertEquals(Array.get(model, i), slot(object, i)); + } + } + + /** + * Intermediate model check for specified unaligned offset + */ + protected void modelCheckUnalignedChar(Object model, Object object, int i, long offset) throws Exception { + char myChar = generateUnalignedChar(object, offset); + getLogger().debug("Unaligned test: Index: " + i + " Expected: " + Array.get(model, i) + " Actual: " + myChar); + AssertJUnit.assertEquals(Array.get(model, i), myChar); + } + + protected void modelCheckUnalignedShort(Object model, Object object, int i, long offset) throws Exception { + short myShort = generateUnalignedShort(object, offset); + getLogger().debug("Unaligned test: Index: " + i + " Expected: " + Array.get(model, i) + " Actual: " + myShort); + AssertJUnit.assertEquals(Array.get(model, i), myShort); + } + + protected void modelCheckUnalignedInt(Object model, Object object, int i, long offset) throws Exception { + int myInt = generateUnalignedInt(object, offset); + getLogger().debug("Unaligned test: Index: " + i + " Expected: " + Array.get(model, i) + " Actual: " + myInt); + AssertJUnit.assertEquals(Array.get(model, i), myInt); + } + + protected void modelCheckUnalignedLong(Object model, Object object, int i, long offset) throws Exception { + long myLong = generateUnalignedLong(object, offset); + getLogger().debug("Unaligned test: Index: " + i + " Expected: " + Array.get(model, i) + " Actual: " + myLong); + AssertJUnit.assertEquals(Array.get(model, i), myLong); + } + + protected void modelCheck(Object model, int limit, long[] pointers) { + for (int i = 0; i <= limit; i++) { + Byte value = myUnsafe.getByte(null, pointers[i]); + getLogger().debug("getByte - Index: " + i + ", Expected: " + + Array.get(model, i) + ", Actual: " + value); + AssertJUnit.assertEquals(Array.get(model, i), value); + value = (byte) myUnsafe.getShort(null, pointers[i]); + getLogger().debug("getShort - Index: " + i + ", Expected: " + + Array.get(model, i) + ", Actual: " + value); + AssertJUnit.assertEquals(Array.get(model, i), value); + } + } + + protected void checkSameAt(int i, Object target, Object value) + throws InstantiationException, IllegalAccessException { + getLogger().debug("Index: " + i + " Expected: " + slot(target, i) + " Actual:" + + value); + AssertJUnit.assertEquals(slot(target, i), value); + } + + protected void checkSameAt(Object target, Object value) throws InstantiationException, IllegalAccessException { + getLogger().debug("Expected: " + target + " Actual: " + value); + AssertJUnit.assertEquals(target, value); + } + + protected void checkTrueAt(boolean value) throws InstantiationException, IllegalAccessException { + getLogger().debug("true boolean check: " + value); + AssertJUnit.assertTrue(value); + } + + @BeforeMethod(groups = { "level.sanity" }) + protected void setUp() throws Exception { + myUnsafe = getUnsafeInstance(); + } + + + @AfterMethod(groups = { "level.sanity" }) + protected void tearDown() throws Exception { + logger.debug("Test finished: " + mTestName); + if (mem != 0) { + freeMemory(); + mem = 0; + } + } + + protected void testByte(Object target, String method) throws Exception { + for (int i = 0; i < modelByte.length; i++) { + long offset = offset(target, i); + getLogger().debug("testByte Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelByte[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putByteVolatile(base(target, i), offset, modelByte[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putByteOpaque(base(target, i), offset, modelByte[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putByteRelease(base(target, i), offset, modelByte[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkTrueAt(myUnsafe.compareAndSetByte(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkTrueAt(myUnsafe.weakCompareAndSetByte(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkTrueAt( + myUnsafe.weakCompareAndSetBytePlain(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkTrueAt( + myUnsafe.weakCompareAndSetByteAcquire(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkTrueAt( + myUnsafe.weakCompareAndSetByteRelease(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkSameAt(compareValueByte, + myUnsafe.compareAndExchangeByte(base(target, i), offset, compareValueByte, modelByte[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkSameAt(compareValueByte, myUnsafe.compareAndExchangeByteAcquire(base(target, i), offset, + compareValueByte, modelByte[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putByte(base(target, i), offset, compareValueByte); + checkSameAt(compareValueByte, myUnsafe.compareAndExchangeByteRelease(base(target, i), offset, + compareValueByte, modelByte[i])); + + } else { /* default */ + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + } + modelCheck(modelByte, target, i); + + } + } + + protected void testChar(Object target, String method) throws Exception { + for (int i = 0; i < modelChar.length; i++) { + long offset = offset(target, i); + getLogger().debug("testChar Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelChar[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putCharVolatile(base(target, i), offset, modelChar[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putCharOpaque(base(target, i), offset, modelChar[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putCharRelease(base(target, i), offset, modelChar[i]); + + } else if (method.equals(UNALIGNED)) { + int sizeOfChar = 2; // bytes + + for (long uOffset = (offset + sizeOfChar); uOffset >= offset; --uOffset) { + /* putUnaligned */ + myUnsafe.putCharUnaligned(base(target, i), uOffset, modelChar[i]); + modelCheckUnalignedChar(modelChar, target, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putCharUnaligned(base(target, i), uOffset, modelChar[i], myUnsafe.isBigEndian()); + modelCheckUnalignedChar(modelChar, target, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkTrueAt(myUnsafe.compareAndSetChar(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkTrueAt(myUnsafe.weakCompareAndSetChar(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkTrueAt( + myUnsafe.weakCompareAndSetCharPlain(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkTrueAt( + myUnsafe.weakCompareAndSetCharAcquire(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkTrueAt( + myUnsafe.weakCompareAndSetCharRelease(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkSameAt(compareValueChar, + myUnsafe.compareAndExchangeChar(base(target, i), offset, compareValueChar, modelChar[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkSameAt(compareValueChar, myUnsafe.compareAndExchangeCharAcquire(base(target, i), offset, + compareValueChar, modelChar[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putChar(base(target, i), offset, compareValueChar); + checkSameAt(compareValueChar, myUnsafe.compareAndExchangeCharRelease(base(target, i), offset, + compareValueChar, modelChar[i])); + + } else { /* default */ + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + } + modelCheck(modelChar, target, i); + } + } + + protected void testShort(Object target, String method) throws Exception { + for (int i = 0; i < modelShort.length; i++) { + long offset = offset(target, i); + getLogger().debug("testShort Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelShort[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putShortVolatile(base(target, i), offset, modelShort[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putShortOpaque(base(target, i), offset, modelShort[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putShortRelease(base(target, i), offset, modelShort[i]); + + } else if (method.equals(UNALIGNED)) { + int sizeOfShort = 2; // bytes + for (long uOffset = (offset + sizeOfShort); uOffset >= offset; --uOffset) { + /* putUnaligned */ + myUnsafe.putShortUnaligned(base(target, i), uOffset, modelShort[i]); + + modelCheckUnalignedShort(modelShort, target, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putShortUnaligned(base(target, i), uOffset, modelShort[i], myUnsafe.isBigEndian()); + modelCheckUnalignedShort(modelShort, target, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkTrueAt(myUnsafe.compareAndSetShort(base(target, i), offset, compareValueShort, modelShort[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShort(base(target, i), offset, compareValueShort, modelShort[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShortPlain(base(target, i), offset, compareValueShort, + modelShort[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShortAcquire(base(target, i), offset, compareValueShort, + modelShort[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShortRelease(base(target, i), offset, compareValueShort, + modelShort[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkSameAt(compareValueShort, + myUnsafe.compareAndExchangeShort(base(target, i), offset, compareValueShort, modelShort[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkSameAt(compareValueShort, myUnsafe.compareAndExchangeShortAcquire(base(target, i), offset, + compareValueShort, modelShort[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putShort(base(target, i), offset, compareValueShort); + checkSameAt(compareValueShort, myUnsafe.compareAndExchangeShortRelease(base(target, i), offset, + compareValueShort, modelShort[i])); + + } else { /* default */ + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + } + modelCheck(modelShort, target, i); + } + } + + protected void testInt(Object target, String method) throws Exception { + for (int i = 0; i < modelInt.length; i++) { + long offset = offset(target, i); + getLogger().debug("testInt Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelInt[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putIntVolatile(base(target, i), offset, modelInt[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putIntOpaque(base(target, i), offset, modelInt[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putIntRelease(base(target, i), offset, modelInt[i]); + + } else if (method.equals(UNALIGNED)) { + int sizeOfInt = 4; // bytes + for (long uOffset = (offset + sizeOfInt); uOffset >= offset; --uOffset) { + /* putUnaligned */ + myUnsafe.putIntUnaligned(base(target, i), uOffset, modelInt[i]); + modelCheckUnalignedInt(modelInt, target, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putIntUnaligned(base(target, i), uOffset, modelInt[i], myUnsafe.isBigEndian()); + modelCheckUnalignedInt(modelInt, target, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkTrueAt(myUnsafe.compareAndSetInt(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetInt(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetIntPlain(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkTrueAt( + myUnsafe.weakCompareAndSetIntAcquire(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkTrueAt( + myUnsafe.weakCompareAndSetIntRelease(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeInt(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeIntAcquire(base(target, i), offset, compareValueInt, modelInt[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putInt(base(target, i), offset, compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeIntRelease(base(target, i), offset, compareValueInt, modelInt[i])); + + } else { /* default */ + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + } + modelCheck(modelInt, target, i); + } + } + + protected void testLong(Object target, String method) throws Exception { + for (int i = 0; i < modelLong.length; i++) { + long offset = offset(target, i); + getLogger().debug("testLong Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelLong[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putLongVolatile(base(target, i), offset, modelLong[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putLongOpaque(base(target, i), offset, modelLong[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putLongRelease(base(target, i), offset, modelLong[i]); + + } else if (method.equals(UNALIGNED)) { + int sizeOfLong = 8; // bytes + for (long uOffset = (offset + sizeOfLong); uOffset >= offset; --uOffset) { + /* putUnaligned */ + myUnsafe.putLongUnaligned(base(target, i), uOffset, modelLong[i]); + modelCheckUnalignedLong(modelLong, target, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putLongUnaligned(base(target, i), uOffset, modelLong[i], myUnsafe.isBigEndian()); + modelCheckUnalignedLong(modelLong, target, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkTrueAt(myUnsafe.compareAndSetLong(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkTrueAt(myUnsafe.weakCompareAndSetLong(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkTrueAt( + myUnsafe.weakCompareAndSetLongPlain(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkTrueAt( + myUnsafe.weakCompareAndSetLongAcquire(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkTrueAt( + myUnsafe.weakCompareAndSetLongRelease(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkSameAt(compareValueLong, + myUnsafe.compareAndExchangeLong(base(target, i), offset, compareValueLong, modelLong[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkSameAt(compareValueLong, myUnsafe.compareAndExchangeLongAcquire(base(target, i), offset, + compareValueLong, modelLong[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putLong(base(target, i), offset, compareValueLong); + checkSameAt(compareValueLong, myUnsafe.compareAndExchangeLongRelease(base(target, i), offset, + compareValueLong, modelLong[i])); + + } else { /* default */ + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + } + modelCheck(modelLong, target, i); + } + } + + protected void testFloat(Object target, String method) throws Exception { + for (int i = 0; i < modelFloat.length; i++) { + long offset = offset(target, i); + getLogger().debug("testFloat Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelFloat[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putFloatVolatile(base(target, i), offset, modelFloat[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putFloatOpaque(base(target, i), offset, modelFloat[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putFloatRelease(base(target, i), offset, modelFloat[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkTrueAt(myUnsafe.compareAndSetFloat(base(target, i), offset, compareValueFloat, modelFloat[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloat(base(target, i), offset, compareValueFloat, modelFloat[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloatPlain(base(target, i), offset, compareValueFloat, + modelFloat[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloatAcquire(base(target, i), offset, compareValueFloat, + modelFloat[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloatRelease(base(target, i), offset, compareValueFloat, + modelFloat[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkSameAt(compareValueFloat, + myUnsafe.compareAndExchangeFloat(base(target, i), offset, compareValueFloat, modelFloat[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkSameAt(compareValueFloat, myUnsafe.compareAndExchangeFloatAcquire(base(target, i), offset, + compareValueFloat, modelFloat[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putFloat(base(target, i), offset, compareValueFloat); + checkSameAt(compareValueFloat, myUnsafe.compareAndExchangeFloatRelease(base(target, i), offset, + compareValueFloat, modelFloat[i])); + + } else { /* default */ + myUnsafe.putFloat(base(target, i), offset, modelFloat[i]); + } + modelCheck(modelFloat, target, i); + } + } + + protected void testDouble(Object target, String method) throws Exception { + for (int i = 0; i < modelDouble.length; i++) { + long offset = offset(target, i); + getLogger().debug("testDouble Object: " + target.getClass().getName() + ", Offset: " + + offset + ", Data: " + modelDouble[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putDoubleVolatile(base(target, i), offset, modelDouble[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putDoubleOpaque(base(target, i), offset, modelDouble[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putDoubleRelease(base(target, i), offset, modelDouble[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkTrueAt(myUnsafe.compareAndSetDouble(base(target, i), offset, compareValueDouble, modelDouble[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkTrueAt( + myUnsafe.weakCompareAndSetDouble(base(target, i), offset, compareValueDouble, modelDouble[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkTrueAt(myUnsafe.weakCompareAndSetDoublePlain(base(target, i), offset, compareValueDouble, + modelDouble[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkTrueAt(myUnsafe.weakCompareAndSetDoubleAcquire(base(target, i), offset, compareValueDouble, + modelDouble[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkTrueAt(myUnsafe.weakCompareAndSetDoubleRelease(base(target, i), offset, compareValueDouble, + modelDouble[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkSameAt(compareValueDouble, + myUnsafe.compareAndExchangeDouble(base(target, i), offset, compareValueDouble, modelDouble[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkSameAt(compareValueDouble, myUnsafe.compareAndExchangeDoubleAcquire(base(target, i), offset, + compareValueDouble, modelDouble[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putDouble(base(target, i), offset, compareValueDouble); + checkSameAt(compareValueDouble, myUnsafe.compareAndExchangeDoubleRelease(base(target, i), offset, + compareValueDouble, modelDouble[i])); + + } else { /* default */ + myUnsafe.putDouble(base(target, i), offset, modelDouble[i]); + } + modelCheck(modelDouble, target, i); + } + } + + protected void testBoolean(Object target, String method) throws Exception { + for (int i = 0; i < modelBoolean.length; i++) { + long offset = offset(target, i); + getLogger().debug("testBoolean Method: " + method + "- Object: " + + target.getClass().getName() + ", Offset: " + offset + + ", Data: " + modelBoolean[i] + ", Index: " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putBooleanVolatile(base(target, i), offset, modelBoolean[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putBooleanOpaque(base(target, i), offset, modelBoolean[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putBooleanRelease(base(target, i), offset, modelBoolean[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkTrueAt(myUnsafe.compareAndSetBoolean(base(target, i), offset, !modelBoolean[i], modelBoolean[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkTrueAt( + myUnsafe.weakCompareAndSetBoolean(base(target, i), offset, !modelBoolean[i], modelBoolean[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkTrueAt(myUnsafe.weakCompareAndSetBooleanPlain(base(target, i), offset, !modelBoolean[i], + modelBoolean[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkTrueAt(myUnsafe.weakCompareAndSetBooleanAcquire(base(target, i), offset, !modelBoolean[i], + modelBoolean[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkTrueAt(myUnsafe.weakCompareAndSetBooleanRelease(base(target, i), offset, !modelBoolean[i], + modelBoolean[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkSameAt(!modelBoolean[i], + myUnsafe.compareAndExchangeBoolean(base(target, i), offset, !modelBoolean[i], modelBoolean[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkSameAt(!modelBoolean[i], myUnsafe.compareAndExchangeBooleanAcquire(base(target, i), offset, + !modelBoolean[i], modelBoolean[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putBoolean(base(target, i), offset, !modelBoolean[i]); + checkSameAt(!modelBoolean[i], myUnsafe.compareAndExchangeBooleanRelease(base(target, i), offset, + !modelBoolean[i], modelBoolean[i])); + + } else { /* default */ + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + } + modelCheck(modelBoolean, target, i); + } + } + + protected void testReference(Object target, String method) throws Exception { + for (int i = 0; i < models.length; i++) { + long offset = offset(target, i); + getLogger().debug("testReference Method: " + method + "- Object: " + target.getClass().getName() + ", Offset: " + + offset + ", Data: " + models[i] + ", Index " + i); + if (method.equals(VOLATILE)) { + myUnsafe.putReferenceVolatile(base(target, i), offset, models[i]); + } else if (method.equals(OPAQUE)) { + myUnsafe.putReferenceOpaque(base(target, i), offset, models[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putReferenceRelease(base(target, i), offset, models[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkTrueAt(myUnsafe.compareAndSetReference(base(target, i), offset, compareValueObject, models[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReference(base(target, i), offset, compareValueObject, models[i])); + + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReferenceAcquire(base(target, i), offset, compareValueObject, + models[i])); + + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReferenceRelease(base(target, i), offset, compareValueObject, + models[i])); + + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkTrueAt( + myUnsafe.weakCompareAndSetReferencePlain(base(target, i), offset, compareValueObject, models[i])); + + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkSameAt(compareValueObject, + myUnsafe.compareAndExchangeReference(base(target, i), offset, compareValueObject, models[i])); + + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkSameAt(compareValueObject, myUnsafe.compareAndExchangeReferenceAcquire(base(target, i), offset, + compareValueObject, models[i])); + + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putReference(base(target, i), offset, compareValueObject); + checkSameAt(compareValueObject, myUnsafe.compareAndExchangeReferenceRelease(base(target, i), offset, + compareValueObject, models[i])); + + } else { + myUnsafe.putReference(base(target, i), offset, models[i]); + } + modelCheck(models, target, i); + + } + } + + protected void testGetByte(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelByte.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetByte Method: " + method + "- Object: " + target.getClass() + ", Offset: " + offset + + ", Index: " + i); + + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getByteVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getByteOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getByteAcquire(base(target, i), offset)); + } else if (method.equals(GETANDSET)) { + byte getValue = modelByte[(i + 1) % modelByte.length]; + myUnsafe.putByte(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetByte(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, modelByte[i]); + } else if (method.equals(GETANDSETA)) { + byte getValue = modelByte[(i + 1) % modelByte.length]; + myUnsafe.putByte(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetByteAcquire(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, modelByte[i]); + } else if (method.equals(GETANDSETR)) { + byte getValue = modelByte[(i + 1) % modelByte.length]; + myUnsafe.putByte(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetByteRelease(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, modelByte[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndAddByte(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, (byte) (modelByte[i] + modelByte[i])); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndAddByteAcquire(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, (byte) (modelByte[i] + modelByte[i])); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndAddByteRelease(base(target, i), offset, modelByte[i])); + checkSameAt(i, target, (byte) (modelByte[i] + modelByte[i])); + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndBitwiseOrByte(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte | modelByte[i])); + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseOrByteAcquire(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte | modelByte[i])); + + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseOrByteRelease(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte | modelByte[i])); + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndBitwiseAndByte(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte & modelByte[i])); + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseAndByteAcquire(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte & modelByte[i])); + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseAndByteRelease(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte & modelByte[i])); + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], myUnsafe.getAndBitwiseXorByte(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte ^ modelByte[i])); + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseXorByteAcquire(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte ^ modelByte[i])); + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putByte(base(target, i), offset, modelByte[i]); + + checkSameAt(modelByte[i], + myUnsafe.getAndBitwiseXorByteRelease(base(target, i), offset, bitwiseValueByte)); + checkSameAt(myUnsafe.getByte(base(target, i), offset), (byte) (bitwiseValueByte ^ modelByte[i])); + + } else { /* default */ + checkSameAt(i, target, myUnsafe.getByte(base(target, i), offset)); + } + } + } + + protected void testGetChar(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelChar.length; i++) { + long offset = offset(target, i); + + getLogger().debug("testGetChar Method: " + method + "- Object: " + target.getClass() + ", Offset: " + offset + + ", Index: " + i); + + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getCharVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getCharOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getCharAcquire(base(target, i), offset)); + } else if (method.equals(UNALIGNED)) { + int sizeOfChar = 2; // bytes + + for (long uOffset = (offset + sizeOfChar); uOffset >= offset; --uOffset) { + myUnsafe.putCharUnaligned(base(target, i), uOffset, modelChar[i]); + + char getValue = generateUnalignedChar(target, uOffset); + + checkSameAt(getValue, myUnsafe.getCharUnaligned(base(target, i), uOffset)); + + getLogger().debug("getUnaligned() endianness test"); + + checkSameAt(getValue, myUnsafe.getCharUnaligned(base(target, i), uOffset, myUnsafe.isBigEndian())); + } + + } else if (method.equals(GETANDSET)) { + char getValue = modelChar[(i + 1) % modelChar.length]; + myUnsafe.putChar(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetChar(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, modelChar[i]); + + } else if (method.equals(GETANDSETA)) { + char getValue = modelChar[(i + 1) % modelChar.length]; + myUnsafe.putChar(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetCharAcquire(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, modelChar[i]); + } else if (method.equals(GETANDSETR)) { + char getValue = modelChar[(i + 1) % modelChar.length]; + myUnsafe.putChar(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetCharRelease(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, modelChar[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndAddChar(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, (char) (modelChar[i] + modelChar[i])); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndAddCharAcquire(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, (char) (modelChar[i] + modelChar[i])); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndAddCharRelease(base(target, i), offset, modelChar[i])); + checkSameAt(i, target, (char) (modelChar[i] + modelChar[i])); + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndBitwiseOrChar(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar | modelChar[i])); + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseOrCharAcquire(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar | modelChar[i])); + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseOrCharRelease(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar | modelChar[i])); + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndBitwiseAndChar(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar & modelChar[i])); + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseAndCharAcquire(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar & modelChar[i])); + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseAndCharRelease(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar & modelChar[i])); + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], myUnsafe.getAndBitwiseXorChar(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar ^ modelChar[i])); + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseXorCharAcquire(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar ^ modelChar[i])); + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putChar(base(target, i), offset, modelChar[i]); + + checkSameAt(modelChar[i], + myUnsafe.getAndBitwiseXorCharRelease(base(target, i), offset, bitwiseValueChar)); + checkSameAt(i, target, (char) (bitwiseValueChar ^ modelChar[i])); + + } else { /* default */ + checkSameAt(i, target, myUnsafe.getChar(base(target, i), offset)); + } + } + } + + protected void testGetShort(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelShort.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetShort Method: " + method + "- Object: " + target.getClass() + ", Offset: " + + offset + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getShortVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getShortOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getShortAcquire(base(target, i), offset)); + } else if (method.equals(UNALIGNED)) { + int sizeOfShort = 2; // bytes + + for (long uOffset = (offset + sizeOfShort); uOffset >= offset; --uOffset) { + myUnsafe.putShortUnaligned(base(target, i), uOffset, modelShort[i]); + + short getValue = generateUnalignedShort(target, uOffset); + + checkSameAt(getValue, myUnsafe.getShortUnaligned(base(target, i), uOffset)); + getLogger().debug("getUnaligned() endianness test"); + checkSameAt(getValue, myUnsafe.getShortUnaligned(base(target, i), uOffset, myUnsafe.isBigEndian())); + } + + } else if (method.equals(GETANDSET)) { + short getValue = modelShort[(i + 1) % modelShort.length]; + myUnsafe.putShort(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetShort(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, modelShort[i]); + + } else if (method.equals(GETANDSETA)) { + short getValue = modelShort[(i + 1) % modelShort.length]; + myUnsafe.putShort(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetShortAcquire(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, modelShort[i]); + } else if (method.equals(GETANDSETR)) { + short getValue = modelShort[(i + 1) % modelShort.length]; + myUnsafe.putShort(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetShortRelease(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, modelShort[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndAddShort(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, (short) (modelShort[i] + modelShort[i])); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndAddShortAcquire(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, (short) (modelShort[i] + modelShort[i])); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndAddShortRelease(base(target, i), offset, modelShort[i])); + checkSameAt(i, target, (short) (modelShort[i] + modelShort[i])); + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndBitwiseOrShort(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort | modelShort[i])); + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseOrShortAcquire(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort | modelShort[i])); + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseOrShortRelease(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort | modelShort[i])); + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndBitwiseAndShort(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort & modelShort[i])); + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseAndShortAcquire(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort & modelShort[i])); + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseAndShortRelease(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort & modelShort[i])); + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], myUnsafe.getAndBitwiseXorShort(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort ^ modelShort[i])); + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseXorShortAcquire(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort ^ modelShort[i])); + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putShort(base(target, i), offset, modelShort[i]); + + checkSameAt(modelShort[i], + myUnsafe.getAndBitwiseXorShortRelease(base(target, i), offset, bitwiseValueShort)); + checkSameAt(i, target, (short) (bitwiseValueShort ^ modelShort[i])); + + } else { /* default */ + checkSameAt(i, target, myUnsafe.getShort(base(target, i), offset)); + } + } + } + + protected void testGetInt(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelInt.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetInt Method: " + method + "- Object: " + target.getClass() + ", Offset: " + offset + + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getIntVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getIntOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getIntAcquire(base(target, i), offset)); + } else if (method.equals(UNALIGNED)) { + int sizeOfInt = 4; // bytes + + for (long uOffset = (offset + sizeOfInt); uOffset >= offset; --uOffset) { + myUnsafe.putIntUnaligned(base(target, i), uOffset, modelInt[i]); + + int getValue = generateUnalignedInt(target, uOffset); + + checkSameAt(getValue, myUnsafe.getIntUnaligned(base(target, i), uOffset)); + getLogger().debug("getUnaligned() endianness test"); + checkSameAt(getValue, myUnsafe.getIntUnaligned(base(target, i), uOffset, myUnsafe.isBigEndian())); + } + + } else if (method.equals(GETANDSET)) { + int getValue = modelInt[i] + 1; + myUnsafe.putInt(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetInt(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i]); + } else if (method.equals(GETANDSETA)) { + int getValue = modelInt[i] + 2; + myUnsafe.putInt(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetIntAcquire(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i]); + } else if (method.equals(GETANDSETR)) { + int getValue = modelInt[i] + 3; + myUnsafe.putInt(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetIntRelease(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i]); + + } else if (method.equals(GETANDADD)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndAddInt(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i] + modelInt[i]); + + } else if (method.equals(GETANDADDA)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndAddIntAcquire(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i] + modelInt[i]); + + } else if (method.equals(GETANDADDR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndAddIntRelease(base(target, i), offset, modelInt[i])); + checkSameAt(i, target, modelInt[i] + modelInt[i]); + + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseOrInt(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt | modelInt[i]); + + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseOrIntAcquire(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt | modelInt[i]); + + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseOrIntRelease(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt | modelInt[i]); + + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseAndInt(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt & modelInt[i]); + + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseAndIntAcquire(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt & modelInt[i]); + + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseAndIntRelease(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt & modelInt[i]); + + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseXorInt(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt ^ modelInt[i]); + + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseXorIntAcquire(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt ^ modelInt[i]); + + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putInt(base(target, i), offset, modelInt[i]); + + checkSameAt(modelInt[i], myUnsafe.getAndBitwiseXorIntRelease(base(target, i), offset, bitwiseValueInt)); + checkSameAt(i, target, bitwiseValueInt ^ modelInt[i]); + + } else { + checkSameAt(i, target, + myUnsafe.getInt(base(target, i), offset(target, i))); + } + } + } + + protected void testGetLong(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelLong.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetLong Method: " + method + "- Object: " + target.getClass() + ", Offset: " + offset + + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getLongVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getLongOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getLongAcquire(base(target, i), offset)); + } else if (method.equals(UNALIGNED)) { + int sizeOfLong = 8; // bytes + + for (long uOffset = (offset + sizeOfLong); uOffset >= offset; --uOffset) { + myUnsafe.putLongUnaligned(base(target, i), uOffset, modelLong[i]); + + long getValue = generateUnalignedLong(target, uOffset); + + checkSameAt(getValue, myUnsafe.getLongUnaligned(base(target, i), uOffset)); + getLogger().debug("getUnaligned() endianness test"); + checkSameAt(getValue, myUnsafe.getLongUnaligned(base(target, i), uOffset, myUnsafe.isBigEndian())); + } + + } else if (method.equals(GETANDSET)) { + long getValue = modelLong[i] + 1; + myUnsafe.putLong(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetLong(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i]); + } else if (method.equals(GETANDSETA)) { + long getValue = modelLong[i] + 2; + myUnsafe.putLong(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetLongAcquire(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i]); + } else if (method.equals(GETANDSETR)) { + long getValue = modelLong[i] + 3; + myUnsafe.putLong(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetLongRelease(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndAddLong(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i] + modelLong[i]); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndAddLongAcquire(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i] + modelLong[i]); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndAddLongRelease(base(target, i), offset, modelLong[i])); + checkSameAt(i, target, modelLong[i] + modelLong[i]); + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndBitwiseOrLong(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong | modelLong[i]); + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseOrLongAcquire(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong | modelLong[i]); + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseOrLongRelease(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong | modelLong[i]); + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndBitwiseAndLong(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong & modelLong[i]); + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseAndLongAcquire(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong & modelLong[i]); + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseAndLongRelease(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong & modelLong[i]); + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], myUnsafe.getAndBitwiseXorLong(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong ^ modelLong[i]); + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseXorLongAcquire(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong ^ modelLong[i]); + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putLong(base(target, i), offset, modelLong[i]); + + checkSameAt(modelLong[i], + myUnsafe.getAndBitwiseXorLongRelease(base(target, i), offset, bitwiseValueLong)); + checkSameAt(i, target, bitwiseValueLong ^ modelLong[i]); + + } else { + checkSameAt(i, target, myUnsafe.getLong(base(target, i), offset)); + } + } + } + + protected void testGetFloat(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelFloat.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetFloat Method: " + method + "- Object: " + target.getClass() + ", Offset: " + + offset + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getFloatVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getFloatOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getFloatAcquire(base(target, i), offset)); + } else if (method.equals(GETANDSET)) { + float getValue = modelFloat[i] + 1; + myUnsafe.putFloat(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetFloat(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i]); + } else if (method.equals(GETANDSETA)) { + float getValue = modelFloat[i] + 2; + myUnsafe.putFloat(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetFloatAcquire(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i]); + } else if (method.equals(GETANDSETR)) { + float getValue = modelFloat[i] + 3; + myUnsafe.putFloat(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetFloatRelease(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putFloat(base(target, i), offset, modelFloat[i]); + + checkSameAt(modelFloat[i], myUnsafe.getAndAddFloat(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i] + modelFloat[i]); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putFloat(base(target, i), offset, modelFloat[i]); + + checkSameAt(modelFloat[i], myUnsafe.getAndAddFloatAcquire(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i] + modelFloat[i]); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putFloat(base(target, i), offset, modelFloat[i]); + + checkSameAt(modelFloat[i], myUnsafe.getAndAddFloatRelease(base(target, i), offset, modelFloat[i])); + checkSameAt(i, target, modelFloat[i] + modelFloat[i]); + + } else { + checkSameAt(i, target, + myUnsafe.getFloat(base(target, i), offset(target, i))); + } + } + } + + protected void testGetDouble(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelDouble.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetDouble Method: " + method + "- Object: " + target.getClass() + ", Offset: " + + offset + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getDoubleVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getDoubleOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getDoubleAcquire(base(target, i), offset)); + } else if (method.equals(GETANDSET)) { + double getValue = modelDouble[i] + 1; + myUnsafe.putDouble(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetDouble(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i]); + } else if (method.equals(GETANDSETA)) { + double getValue = modelDouble[i] + 2; + myUnsafe.putDouble(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetDoubleAcquire(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i]); + } else if (method.equals(GETANDSETR)) { + double getValue = modelDouble[i] + 3; + myUnsafe.putDouble(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetDoubleRelease(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i]); + } else if (method.equals(GETANDADD)) { + myUnsafe.putDouble(base(target, i), offset, modelDouble[i]); + + checkSameAt(modelDouble[i], myUnsafe.getAndAddDouble(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i] + modelDouble[i]); + } else if (method.equals(GETANDADDA)) { + myUnsafe.putDouble(base(target, i), offset, modelDouble[i]); + + checkSameAt(modelDouble[i], myUnsafe.getAndAddDoubleAcquire(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i] + modelDouble[i]); + } else if (method.equals(GETANDADDR)) { + myUnsafe.putDouble(base(target, i), offset, modelDouble[i]); + + checkSameAt(modelDouble[i], myUnsafe.getAndAddDoubleRelease(base(target, i), offset, modelDouble[i])); + checkSameAt(i, target, modelDouble[i] + modelDouble[i]); + + } else { + checkSameAt(i, target, + myUnsafe.getDouble(base(target, i), offset(target, i))); + } + } + } + + protected void testGetBoolean(Object target, String method) throws Exception { + init(target); + for (int i = 0; i < modelBoolean.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetBoolean Method: " + method + "- Object: " + target.getClass() + ", Offset: " + + offset + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getBooleanVolatile(base(target, i), offset)); + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getBooleanOpaque(base(target, i), offset)); + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getBooleanAcquire(base(target, i), offset)); + } else if (method.equals(GETANDSET)) { + boolean getValue = modelBoolean[(i + 1) % modelBoolean.length]; + myUnsafe.putBoolean(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetBoolean(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i]); + } else if (method.equals(GETANDSETA)) { + boolean getValue = modelBoolean[(i + 1) % modelBoolean.length]; + myUnsafe.putBoolean(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetBooleanAcquire(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i]); + } else if (method.equals(GETANDSETR)) { + boolean getValue = modelBoolean[(i + 1) % modelBoolean.length]; + myUnsafe.putBoolean(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetBooleanRelease(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i]); + } else if (method.equals(GETANDBITWISEOR)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], myUnsafe.getAndBitwiseOrBoolean(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] | modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEORA)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseOrBooleanAcquire(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] | modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEORR)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseOrBooleanRelease(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] | modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEAND)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseAndBoolean(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] & modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEANDA)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseAndBooleanAcquire(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] & modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEANDR)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseAndBooleanRelease(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] & modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEXOR)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseXorBoolean(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] ^ modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEXORA)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseXorBooleanAcquire(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] ^ modelBoolean[i]); + + } else if (method.equals(GETANDBITWISEXORR)) { + myUnsafe.putBoolean(base(target, i), offset, modelBoolean[i]); + + checkSameAt(modelBoolean[i], + myUnsafe.getAndBitwiseXorBooleanRelease(base(target, i), offset, modelBoolean[i])); + checkSameAt(i, target, modelBoolean[i] ^ modelBoolean[i]); + + } else { + checkSameAt(i, target, + myUnsafe.getBoolean(base(target, i), offset(target, i))); + } + } + } + + protected void testGetReference(Object target, String method) throws Exception { + Object getValue = new Object(); + init(target); + for (int i = 0; i < models.length; i++) { + long offset = offset(target, i); + getLogger().debug("testGetReference Method: " + method + "- Object: " + target.getClass() + ", Offset: " + + offset + ", Index: " + i); + if (method.equals(VOLATILE)) { + checkSameAt(i, target, myUnsafe.getReferenceVolatile(base(target, i), offset)); + + } else if (method.equals(OPAQUE)) { + checkSameAt(i, target, myUnsafe.getReferenceOpaque(base(target, i), offset)); + + } else if (method.equals(ORDERED)) { + checkSameAt(i, target, myUnsafe.getReferenceAcquire(base(target, i), offset)); + + } else if (method.equals(GETANDSET)) { + myUnsafe.putReference(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetReference(base(target, i), offset, models[i])); + checkSameAt(i, target, models[i]); + + } else if (method.equals(GETANDSETA)) { + myUnsafe.putReference(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetReferenceAcquire(base(target, i), offset, models[i])); + checkSameAt(i, target, models[i]); + + } else if (method.equals(GETANDSETR)) { + myUnsafe.putReference(base(target, i), offset, getValue); + + checkSameAt(getValue, myUnsafe.getAndSetReferenceRelease(base(target, i), offset, models[i])); + checkSameAt(i, target, models[i]); + + } else { + + checkSameAt(i, target, myUnsafe.getReference(base(target, i), offset)); + } + + } + } + + protected void testByteNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelByte.length]; + for (int i = 0; i < modelByte.length; i++) { + pointers[i] = mem + i; // byte size: 1 + getLogger().debug("testByteNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelByte[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putByteVolatile(null, pointers[i], modelByte[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putByte(null, pointers[i], modelByte[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putByteOpaque(null, pointers[i], modelByte[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putByteRelease(null, pointers[i], modelByte[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkTrueAt(myUnsafe.compareAndSetByte(null, pointers[i], compareValueByte, modelByte[i])); + + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + AssertJUnit + .assertTrue(myUnsafe.weakCompareAndSetByte(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkTrueAt(myUnsafe.weakCompareAndSetBytePlain(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkTrueAt(myUnsafe.weakCompareAndSetByteAcquire(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkTrueAt(myUnsafe.weakCompareAndSetByteRelease(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkSameAt(compareValueByte, + myUnsafe.compareAndExchangeByte(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkSameAt(compareValueByte, + myUnsafe.compareAndExchangeByteAcquire(null, pointers[i], compareValueByte, modelByte[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putByte(null, pointers[i], compareValueByte); + checkSameAt(compareValueByte, + myUnsafe.compareAndExchangeByteRelease(null, pointers[i], compareValueByte, modelByte[i])); + + } else { + myUnsafe.putByte(pointers[i], modelByte[i]); + } + byteCheck(modelByte, i, pointers, method); + } + short value = myUnsafe.getShort(null, pointers[0]); + checkSameAt((short) -1, value); + } + + protected void testCharNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelChar.length]; + for (int i = 0; i < modelChar.length; i++) { + pointers[i] = mem + (i * 2); // char size: 2 + getLogger().debug("testCharNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelChar[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putCharVolatile(null, pointers[i], modelChar[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putChar(null, pointers[i], modelChar[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putCharOpaque(null, pointers[i], modelChar[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putCharRelease(null, pointers[i], modelChar[i]); + + } else if (method.equals(UNALIGNED)) { + /* do not run this test at end of array to avoid corrupting memory we don't own */ + if (i == (modelChar.length - 1)) continue; + + int sizeOfChar = 2; // bytes + + for (long uOffset = (pointers[i] + sizeOfChar); uOffset >= pointers[i]; --uOffset) { + /* putUnaligned */ + myUnsafe.putCharUnaligned(null, uOffset, modelChar[i]); + modelCheckUnalignedChar(modelChar, null, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putCharUnaligned(null, uOffset, modelChar[i], myUnsafe.isBigEndian()); + modelCheckUnalignedChar(modelChar, null, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkTrueAt(myUnsafe.compareAndSetChar(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + AssertJUnit + .assertTrue(myUnsafe.weakCompareAndSetChar(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkTrueAt(myUnsafe.weakCompareAndSetCharPlain(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkTrueAt(myUnsafe.weakCompareAndSetCharAcquire(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkTrueAt(myUnsafe.weakCompareAndSetCharRelease(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkSameAt(compareValueChar, + myUnsafe.compareAndExchangeChar(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkSameAt(compareValueChar, + myUnsafe.compareAndExchangeCharAcquire(null, pointers[i], compareValueChar, modelChar[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putChar(null, pointers[i], compareValueChar); + checkSameAt(compareValueChar, + myUnsafe.compareAndExchangeCharRelease(null, pointers[i], compareValueChar, modelChar[i])); + + } else { + myUnsafe.putChar(pointers[i], modelChar[i]); + } + charCheck(modelChar, i, pointers, method); + } + } + + protected void testShortNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelShort.length]; + for (int i = 0; i < modelShort.length; i++) { + pointers[i] = mem + (i * 2); // char size: 2 + getLogger().debug("testShortNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelShort[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putShortVolatile(null, pointers[i], modelShort[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putShort(null, pointers[i], modelShort[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putShortOpaque(null, pointers[i], modelShort[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putShortRelease(null, pointers[i], modelShort[i]); + + } else if (method.equals(UNALIGNED)) { + /* do not run this test at end of array to avoid corrupting memory we don't own */ + if (i == (modelShort.length - 1)) continue; + + int sizeOfShort = 2; // bytes + + for (long uOffset = (pointers[i] + sizeOfShort); uOffset >= pointers[i]; --uOffset) { + /* putUnaligned */ + myUnsafe.putShortUnaligned(null, uOffset, modelShort[i]); + modelCheckUnalignedShort(modelShort, null, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putShortUnaligned(null, uOffset, modelShort[i], myUnsafe.isBigEndian()); + modelCheckUnalignedShort(modelShort, null, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + AssertJUnit + .assertTrue(myUnsafe.compareAndSetShort(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShort(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkTrueAt(myUnsafe.weakCompareAndSetShortPlain(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkTrueAt( + myUnsafe.weakCompareAndSetShortAcquire(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkTrueAt( + myUnsafe.weakCompareAndSetShortRelease(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkSameAt(compareValueShort, + myUnsafe.compareAndExchangeShort(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkSameAt(compareValueShort, + myUnsafe.compareAndExchangeShortAcquire(null, pointers[i], compareValueShort, modelShort[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putShort(null, pointers[i], compareValueShort); + checkSameAt(compareValueShort, + myUnsafe.compareAndExchangeShortRelease(null, pointers[i], compareValueShort, modelShort[i])); + + } else { + myUnsafe.putShort(pointers[i], modelShort[i]); + } + shortCheck(modelShort, i, pointers, method); + } + } + + protected void testIntNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelInt.length]; + for (int i = 0; i < modelInt.length; i++) { + pointers[i] = mem + (i * 4); // int size: 4 + getLogger() + .debug("testIntNative Method: " + method + "- Pointer: " + pointers[i] + ", Data: " + modelInt[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putIntVolatile(null, pointers[i], modelInt[i]); + + } else if (method.equals(DEFAULT)) { + myUnsafe.putInt(null, pointers[i], modelInt[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putIntOpaque(null, pointers[i], modelInt[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putIntRelease(null, pointers[i], modelInt[i]); + + } else if (method.equals(UNALIGNED)) { + /* do not run this test at end of array to avoid corrupting memory we don't own */ + if (i == (modelInt.length - 1)) continue; + + int sizeOfInt = 4; // bytes + + for (long uOffset = (pointers[i] + sizeOfInt); uOffset >= pointers[i]; --uOffset) { + /* putUnaligned */ + myUnsafe.putIntUnaligned(null, uOffset, modelInt[i]); + modelCheckUnalignedInt(modelInt, null, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putIntUnaligned(null, uOffset, modelInt[i], myUnsafe.isBigEndian()); + modelCheckUnalignedInt(modelInt, null, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkTrueAt(myUnsafe.compareAndSetInt(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetInt(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetIntPlain(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetIntAcquire(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkTrueAt(myUnsafe.weakCompareAndSetIntRelease(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeInt(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeIntAcquire(null, pointers[i], compareValueInt, modelInt[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putInt(null, pointers[i], compareValueInt); + checkSameAt(compareValueInt, + myUnsafe.compareAndExchangeIntRelease(null, pointers[i], compareValueInt, modelInt[i])); + + } else if (method.equals(ADDRESS)) { + myUnsafe.putAddress(pointers[i], modelInt[i]); + + } else { + myUnsafe.putInt(pointers[i], modelInt[i]); + } + intCheck(modelInt, i, pointers, method); + } + long value = myUnsafe.getLong(null, pointers[0]); + checkSameAt((long) -1, value); + } + + protected void testLongNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelLong.length]; + for (int i = 0; i < modelLong.length; i++) { + pointers[i] = mem + (i * 8); // long size: 8 + getLogger().debug("testLongNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelLong[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putLongVolatile(null, pointers[i], modelLong[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putLong(null, pointers[i], modelLong[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putLongOpaque(null, pointers[i], modelLong[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putLongRelease(null, pointers[i], modelLong[i]); + + } else if (method.equals(UNALIGNED)) { + /* do not run this test at end of array to avoid corrupting memory we don't own */ + if (i == (modelLong.length - 1)) continue; + + int sizeOfLong = 8; // bytes + + for (long uOffset = (pointers[i] + sizeOfLong); uOffset >= pointers[i]; --uOffset) { + + /* putUnaligned */ + myUnsafe.putLongUnaligned(null, uOffset, modelLong[i]); + modelCheckUnalignedLong(modelLong, null, i, uOffset); + + getLogger().debug("putUnaligned() endianness test"); + + /* putUnaligned - endianness */ + myUnsafe.putLongUnaligned(null, uOffset, modelLong[i], myUnsafe.isBigEndian()); + modelCheckUnalignedLong(modelLong, null, i, uOffset); + } + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkTrueAt(myUnsafe.compareAndSetLong(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + AssertJUnit + .assertTrue(myUnsafe.weakCompareAndSetLong(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkTrueAt(myUnsafe.weakCompareAndSetLongPlain(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkTrueAt(myUnsafe.weakCompareAndSetLongAcquire(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkTrueAt(myUnsafe.weakCompareAndSetLongRelease(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkSameAt(compareValueLong, + myUnsafe.compareAndExchangeLong(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkSameAt(compareValueLong, + myUnsafe.compareAndExchangeLongAcquire(null, pointers[i], compareValueLong, modelLong[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putLong(null, pointers[i], compareValueLong); + checkSameAt(compareValueLong, + myUnsafe.compareAndExchangeLongRelease(null, pointers[i], compareValueLong, modelLong[i])); + + } else if (method.equals(ADDRESS)) { + myUnsafe.putAddress(pointers[i], modelLong[i]); + } else { + myUnsafe.putLong(pointers[i], modelLong[i]); + } + longCheck(modelLong, i, pointers, method); + } + } + + protected void testFloatNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelFloat.length]; + for (int i = 0; i < modelFloat.length; i++) { + pointers[i] = mem + (i * 4); // float size: 4 + getLogger().debug("testFloatNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelFloat[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putFloatVolatile(null, pointers[i], modelFloat[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putFloat(null, pointers[i], modelFloat[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putFloatOpaque(null, pointers[i], modelFloat[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putFloatRelease(null, pointers[i], modelFloat[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + AssertJUnit + .assertTrue(myUnsafe.compareAndSetFloat(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloat(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkTrueAt(myUnsafe.weakCompareAndSetFloatPlain(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkTrueAt( + myUnsafe.weakCompareAndSetFloatAcquire(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkTrueAt( + myUnsafe.weakCompareAndSetFloatRelease(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkSameAt(compareValueFloat, + myUnsafe.compareAndExchangeFloat(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkSameAt(compareValueFloat, + myUnsafe.compareAndExchangeFloatAcquire(null, pointers[i], compareValueFloat, modelFloat[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putFloat(null, pointers[i], compareValueFloat); + checkSameAt(compareValueFloat, + myUnsafe.compareAndExchangeFloatRelease(null, pointers[i], compareValueFloat, modelFloat[i])); + + } else { + myUnsafe.putFloat(pointers[i], modelFloat[i]); + } + floatCheck(modelFloat, i, pointers, method); + } + } + + protected void testDoubleNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelDouble.length]; + for (int i = 0; i < modelDouble.length; i++) { + pointers[i] = mem + (i * 8); // double size: 8 + getLogger().debug("testDoubleNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelDouble[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putDoubleVolatile(null, pointers[i], modelDouble[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putDouble(null, pointers[i], modelDouble[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putDoubleOpaque(null, pointers[i], modelDouble[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putDoubleRelease(null, pointers[i], modelDouble[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkTrueAt(myUnsafe.compareAndSetDouble(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkTrueAt(myUnsafe.weakCompareAndSetDouble(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkTrueAt( + myUnsafe.weakCompareAndSetDoublePlain(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkTrueAt( + myUnsafe.weakCompareAndSetDoubleAcquire(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkTrueAt( + myUnsafe.weakCompareAndSetDoubleRelease(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkSameAt(compareValueDouble, + myUnsafe.compareAndExchangeDouble(null, pointers[i], compareValueDouble, modelDouble[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkSameAt(compareValueDouble, myUnsafe.compareAndExchangeDoubleAcquire(null, pointers[i], + compareValueDouble, modelDouble[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putDouble(null, pointers[i], compareValueDouble); + checkSameAt(compareValueDouble, myUnsafe.compareAndExchangeDoubleRelease(null, pointers[i], + compareValueDouble, modelDouble[i])); + + } else { + myUnsafe.putDouble(pointers[i], modelDouble[i]); + } + doubleCheck(modelDouble, i, pointers, method); + } + } + + protected void testBooleanNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[modelBoolean.length]; + for (int i = 0; i < modelBoolean.length; i++) { + pointers[i] = mem + i; // boolean size: 1 bit + getLogger().debug("testBooleanNative Method: " + method + "- Pointer: " + pointers[i] + + ", Data: " + modelBoolean[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putBooleanVolatile(null, pointers[i], modelBoolean[i]); + } else if (method.equals(DEFAULT)) { + myUnsafe.putBoolean(null, pointers[i], modelBoolean[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putBooleanOpaque(null, pointers[i], modelBoolean[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putBooleanRelease(null, pointers[i], modelBoolean[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkTrueAt(myUnsafe.compareAndSetBoolean(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkTrueAt(myUnsafe.weakCompareAndSetBoolean(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkTrueAt( + myUnsafe.weakCompareAndSetBooleanPlain(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkTrueAt( + myUnsafe.weakCompareAndSetBooleanAcquire(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkTrueAt( + myUnsafe.weakCompareAndSetBooleanRelease(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkSameAt(!modelBoolean[i], + myUnsafe.compareAndExchangeBoolean(null, pointers[i], !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkSameAt(!modelBoolean[i], myUnsafe.compareAndExchangeBooleanAcquire(null, pointers[i], + !modelBoolean[i], modelBoolean[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putBoolean(null, pointers[i], !modelBoolean[i]); + checkSameAt(!modelBoolean[i], myUnsafe.compareAndExchangeBooleanRelease(null, pointers[i], + !modelBoolean[i], modelBoolean[i])); + + } + booleanCheck(modelBoolean, i, pointers, method); + } + } + + protected void testReferenceNative(String method) throws Exception { + mem = memAllocate(100); + long pointers[] = new long[models.length]; + for (int i = 0; i < models.length; i++) { + pointers[i] = mem + (i * ObjectData.getSize(i)); + getLogger() + .debug("testReferenceNative Method: " + method + "- Pointer: " + pointers[i] + ", Data: " + models[i]); + if (method.equals(VOLATILE)) { + myUnsafe.putReferenceVolatile(null, pointers[i], models[i]); + + } else if (method.equals(OPAQUE)) { + myUnsafe.putReferenceOpaque(null, pointers[i], models[i]); + + } else if (method.equals(ORDERED)) { + myUnsafe.putReferenceRelease(null, pointers[i], models[i]); + + } else if (method.equals(COMPAREANDSET)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkTrueAt(myUnsafe.compareAndSetReference(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(WCOMPAREANDSET)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + AssertJUnit + .assertTrue(myUnsafe.weakCompareAndSetReference(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(WCOMPAREANDSETA)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReferenceAcquire(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(WCOMPAREANDSETR)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReferenceRelease(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(WCOMPAREANDSETP)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkTrueAt(myUnsafe.weakCompareAndSetReferencePlain(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(COMPAREANDEXCH)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkSameAt(compareValueObject, + myUnsafe.compareAndExchangeReference(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(COMPAREANDEXCHA)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkSameAt(compareValueObject, + myUnsafe.compareAndExchangeReferenceAcquire(null, pointers[i], compareValueObject, models[i])); + } else if (method.equals(COMPAREANDEXCHR)) { + myUnsafe.putReference(null, pointers[i], compareValueObject); + checkSameAt(compareValueObject, + myUnsafe.compareAndExchangeReferenceRelease(null, pointers[i], compareValueObject, models[i])); + + } else { + myUnsafe.putReference(null, pointers[i], models[i]); + } + referenceCheck(models, i, pointers, method); + } + } + + private void byteCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + byte expected = (Byte) Array.get(model, i); + + if (method.equals(VOLATILE)) { + byte value = myUnsafe.getByteVolatile(null, pointers[i]); + getLogger().debug("getByteVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + byte value = myUnsafe.getByteOpaque(null, pointers[i]); + getLogger().debug("getByteOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(ORDERED)) { + byte value = myUnsafe.getByteAcquire(null, pointers[i]); + getLogger().debug("getByteAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + byte value = myUnsafe.getByte(null, pointers[i]); + getLogger().debug("getByte(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getByte(pointers[i]); + getLogger().debug("getByte(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void charCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + char expected = (Character) Array.get(model, i); + + if (method.equals(VOLATILE)) { + char value = myUnsafe.getCharVolatile(null, pointers[i]); + getLogger().debug("getCharVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + char value = myUnsafe.getCharOpaque(null, pointers[i]); + getLogger().debug("getCharOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(ORDERED)) { + char value = myUnsafe.getCharAcquire(null, pointers[i]); + getLogger().debug("getCharAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + char value = myUnsafe.getChar(null, pointers[i]); + getLogger().debug("getChar(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getChar(pointers[i]); + getLogger().debug("getChar(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void shortCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + short expected = (Short) Array.get(model, i); + + if (method.equals(VOLATILE)) { + short value = myUnsafe.getShortVolatile(null, pointers[i]); + getLogger().debug("getShortVolatile(Object, long)- Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + short value = myUnsafe.getShortOpaque(null, pointers[i]); + getLogger().debug("getShortOpaque(Object, long)- Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(ORDERED)) { + short value = myUnsafe.getShortAcquire(null, pointers[i]); + getLogger().debug("getShortAcquire(Object, long)- Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + short value = myUnsafe.getShort(null, pointers[i]); + getLogger().debug("getShort(Object, long)- Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getShort(pointers[i]); + getLogger().debug("getShort(long)- Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void intCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + int expected = (Integer) Array.get(model, i); + + if (method.equals(ADDRESS)) { + int value = (int) myUnsafe.getAddress(pointers[i]); + getLogger().debug("getAddress(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(VOLATILE)) { + int value = myUnsafe.getIntVolatile(null, pointers[i]); + getLogger().debug("getIntVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + int value = myUnsafe.getIntOpaque(null, pointers[i]); + getLogger().debug("getIntOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(ORDERED)) { + int value = myUnsafe.getIntAcquire(null, pointers[i]); + getLogger().debug("getIntAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + int value = myUnsafe.getInt(null, pointers[i]); + getLogger().debug("getInt(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getInt(pointers[i]); + getLogger().debug("getInt(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void longCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + long expected = (Long) Array.get(model, i); + + if (method.equals(ADDRESS)) { + long value = myUnsafe.getAddress(pointers[i]); + getLogger().debug("getAddress(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(VOLATILE)) { + long value = myUnsafe.getLongVolatile(null, pointers[i]); + getLogger().debug("getLongVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + long value = myUnsafe.getLongOpaque(null, pointers[i]); + getLogger().debug("getLongOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(ORDERED)) { + long value = myUnsafe.getLongAcquire(null, pointers[i]); + getLogger().debug("getLongAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + long value = myUnsafe.getLong(null, pointers[i]); + getLogger().debug("getLong(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getLong(pointers[i]); + getLogger().debug("getLong(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void floatCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + float expected = (Float) Array.get(model, i); + + if (method.equals(VOLATILE)) { + float value = myUnsafe.getFloatVolatile(null, pointers[i]); + getLogger().debug("getFloatVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + float value = myUnsafe.getFloatOpaque(null, pointers[i]); + getLogger().debug("getFloatOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (model.equals(ORDERED)) { + float value = myUnsafe.getFloatAcquire(null, pointers[i]); + getLogger().debug("getFloatAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + float value = myUnsafe.getFloat(null, pointers[i]); + getLogger().debug("getFloat(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getFloat(pointers[i]); + getLogger().debug("getFloat(long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void doubleCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + double expected = (Double) Array.get(model, i); + + if (model.equals(VOLATILE)) { + double value = myUnsafe.getDoubleVolatile(null, pointers[i]); + getLogger().debug("getDoubleVolatile(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (model.equals(OPAQUE)) { + double value = myUnsafe.getDoubleOpaque(null, pointers[i]); + getLogger().debug("getDoubleOpaque(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (model.equals(ORDERED)) { + double value = myUnsafe.getDoubleAcquire(null, pointers[i]); + getLogger().debug("getDoubleAcquire(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + double value = myUnsafe.getDouble(null, pointers[i]); + getLogger().debug("getDouble(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + value = myUnsafe.getDouble(pointers[i]); + getLogger().debug("getDouble(Object, long) - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void booleanCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i +"]: " + pointers[i]); + boolean expected = (Boolean) Array.get(model, i); + + if (method.equals(VOLATILE)) { + boolean value = myUnsafe.getBooleanVolatile(null, pointers[i]); + getLogger().debug("getBooleanVolatile - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + boolean value = myUnsafe.getBooleanOpaque(null, pointers[i]); + getLogger().debug("getBooleanOpaque - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (model.equals(ORDERED)) { + boolean value = myUnsafe.getBooleanAcquire(null, pointers[i]); + getLogger().debug("getBooleanAcquire - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + boolean value = myUnsafe.getBoolean(null, pointers[i]); + getLogger().debug("getBoolean - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + private void referenceCheck(Object model, int limit, long[] pointers, String method) throws Exception { + for (int i = 0; i <= limit; i++) { + getLogger().debug(" pointers[" + i + "]: " + pointers[i]); + Object expected = (Object) Array.get(model, i); + + if (method.equals(VOLATILE)) { + Object value = myUnsafe.getReferenceVolatile(null, pointers[i]); + getLogger().debug("getReferenceVolatile - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (method.equals(OPAQUE)) { + Object value = myUnsafe.getReferenceOpaque(null, pointers[i]); + getLogger().debug("getReferenceOpaque - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else if (model.equals(ORDERED)) { + Object value = myUnsafe.getReferenceAcquire(null, pointers[i]); + getLogger().debug("getReferenceAcquire - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + + } else { + Object value = myUnsafe.getReference(null, pointers[i]); + getLogger().debug("getReference - Expected: " + expected + ", Actual: " + value); + checkSameAt(expected, value); + } + } + } + + protected long memAllocate(int size) { + long address = myUnsafe.allocateMemory(size); + getLogger().debug("allocateMemory: " + mem); + return address; + } + + protected void freeMemory() { + myUnsafe.freeMemory(mem); + getLogger().debug("freeMemory: " + mem); + } + + protected void alignment() { + int addressSize = myUnsafe.addressSize(); + getLogger().debug("addressSize: " + addressSize); + long mod = 0; + if (addressSize > 4) { + mod = mem % 8; + getLogger().debug("memory mod 8: " + mod); + } else { + mod = mem % 4; + getLogger().debug("memory mod 4: " + mod); + } + if (mod != 0) { + mem = mem + mod; + getLogger().debug("Change pointer to: " + mem); + } + } + + /* Create a class with the specified package name. + * This method is used to verify the correctness of + * jdk.internal.misc.Unsafe.defineAnonymousClass. + */ + protected static byte[] createDummyClass(String packageName) { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv = null; + String className = "DummyClass"; + + if (packageName != null) { + className = packageName + "/" + className; + } + + cw.visit(52, ACC_PUBLIC, className, null, "java/lang/Object", null); + + { + mv = cw.visitMethod(ACC_PUBLIC, "bar", "()V", null, null); + mv.visitCode(); + mv.visitInsn(RETURN); + mv.visitMaxs(2, 1); + mv.visitEnd(); + } + + cw.visitEnd(); + + return cw.toByteArray(); + } + + protected char generateUnalignedChar(Object object, long uOffset) { + return (char) generateUnalignedShort(object, uOffset); + } + + protected short generateUnalignedShort(Object object, long uOffset) { + int first = (int) myUnsafe.getByte(object, uOffset) & BYTE_MASK; + int second = (int) myUnsafe.getByte(object, 1 + uOffset) & BYTE_MASK; + + if (myUnsafe.isBigEndian()) { + return (short) (second | (first << 8)); + } else { + return (short) (first | (second << 8)); + } + } + + protected int generateUnalignedInt(Object object, long uOffset) { + int first = (int) myUnsafe.getByte(object, uOffset) & BYTE_MASK; + int second = (int) myUnsafe.getByte(object, 1 + uOffset) & BYTE_MASK; + int third = (int) myUnsafe.getByte(object, 2 + uOffset) & BYTE_MASK; + int fourth = (int) myUnsafe.getByte(object, 3 + uOffset) & BYTE_MASK; + + if (myUnsafe.isBigEndian()) { + return fourth | (third << 8) | (second << 16) | (first << 24); + } else { + return first | (second << 8) | (third << 16) | (fourth << 24); + } + } + + protected long generateUnalignedLong(Object object, long uOffset) { + + long first = (long) myUnsafe.getByte(object, uOffset) & BYTE_MASKL; + long second = (long) myUnsafe.getByte(object, 1 + uOffset) & BYTE_MASKL; + long third = (long) myUnsafe.getByte(object, 2 + uOffset) & BYTE_MASKL; + long fourth = (long) myUnsafe.getByte(object, 3 + uOffset) & BYTE_MASKL; + long fifth = (long) myUnsafe.getByte(object, 4 + uOffset) & BYTE_MASKL; + long sixth = (long) myUnsafe.getByte(object, 5 + uOffset) & BYTE_MASKL; + long seventh = (long) myUnsafe.getByte(object, 6 + uOffset) & BYTE_MASKL; + long eighth = (long) myUnsafe.getByte(object, 7 + uOffset) & BYTE_MASKL; + + if (myUnsafe.isBigEndian()) { + return eighth | (seventh << 8) | (sixth << 16) | (fifth << 24) | (fourth << 32) | (third << 40) + | (second << 48) | (first << 56); + } else { + return first | (second << 8) | (third << 16) | (fourth << 24) | (fifth << 32) | (sixth << 40) + | (seventh << 48) | (eighth << 56); + } + } +} diff --git a/test/functional/VM_Test/build.xml b/test/functional/VM_Test/build.xml index f53cec3d26e..8180199511d 100644 --- a/test/functional/VM_Test/build.xml +++ b/test/functional/VM_Test/build.xml @@ -40,6 +40,7 @@ + @@ -134,7 +135,10 @@ - + + + + @@ -148,6 +152,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/functional/VM_Test/j9vm.xml b/test/functional/VM_Test/j9vm.xml index 9b414b85d3b..e38d2700f8b 100644 --- a/test/functional/VM_Test/j9vm.xml +++ b/test/functional/VM_Test/j9vm.xml @@ -67,10 +67,6 @@ These tests run separately and are not as part of j9vm test suite - - CMVC 158969: test runs too slow after switching to the SDK launcher - - Only applies to Linux SRT diff --git a/test/functional/VM_Test/playlist.xml b/test/functional/VM_Test/playlist.xml index 7d9eade74ac..ed25fa20c08 100644 --- a/test/functional/VM_Test/playlist.xml +++ b/test/functional/VM_Test/playlist.xml @@ -229,6 +229,10 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Mode110 Mode609 Mode610 + Mode500 + Mode501 + Mode551 + Mode550 $(JAVA_COMMAND) -Dplatform=$(PLATFORM) -cp $(Q)$(TEST_RESROOT)$(D)VM_Test.jar$(Q) \ j9vm.runner.Menu -test=$(Q)j9vm.test.xlpcodecache$(Q) -exe=$(Q)$(JAVA_COMMAND) $(JVM_OPTIONS) -Xdump$(Q) \ diff --git a/test/functional/VM_Test/src/j9vm/test/thread/InterruptNotifyWaitTest.java b/test/functional/VM_Test/src/j9vm/test/thread/InterruptNotifyWaitTest.java deleted file mode 100644 index 4b37153e468..00000000000 --- a/test/functional/VM_Test/src/j9vm/test/thread/InterruptNotifyWaitTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright IBM Corp. and others 2001 - * - * This program and the accompanying materials are made available under - * the terms of the Eclipse Public License 2.0 which accompanies this - * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ - * or the Apache License, Version 2.0 which accompanies this distribution and - * is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * This Source Code may also be made available under the following - * Secondary Licenses when the conditions for such availability set - * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU - * General Public License, version 2 with the GNU Classpath - * Exception [1] and GNU General Public License, version 2 with the - * OpenJDK Assembly Exception [2]. - * - * [1] https://www.gnu.org/software/classpath/license.html - * [2] https://openjdk.org/legal/assembly-exception.html - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 - */ -package j9vm.test.thread; - -/* - * Test contention between waiting, notifying, and interrupting threads. - */ -public class InterruptNotifyWaitTest { - Counter notifyWake = new Counter(); - Counter intrWake = new Counter(); - Counter progress = new Counter(); - - int sec = 150; - int notifyThreads = 10; - - /** - * @param args - */ - public static void main(String[] args) { - new InterruptNotifyWaitTest().run(args); - } - - public void run(String[] args) { - Object sync = new Object(); - WaitThread w = new WaitThread(sync); - NotifyThread n[] = new NotifyThread[notifyThreads]; - IntrThread r = new IntrThread(w); - IntrThread r2 = new IntrThread(w); - - if (args.length > 0) { - sec = Integer.parseInt(args[0]); - } - - for (int i = 0; i < n.length; i++) { - n[i] = new NotifyThread(sync); - } - - w.start(); - for (int i = 0; i < n.length; i++) { - n[i].start(); - } - r.start(); - r2.start(); - - long nowakeups = 0; - long oldprogress = 0; - long newprogress = 0; - - try { - for (int i = 0; i < sec; i++) { -// System.out.print("."); - Thread.sleep(1000); - - /* Check for symptoms of deadlock */ - newprogress = progress.get(); - if (oldprogress == newprogress) { - nowakeups++; - } else { - nowakeups = 0; - oldprogress = newprogress; - } - } - } catch (InterruptedException e) { - } - System.out.println("intr: " + intrWake.get() + " notify: " + notifyWake.get()); - if (nowakeups > 1) { - r.stop(); - r2.stop(); - for (int i = 0; i < n.length; i++) { - n[i].stop(); - } - w.stop(); - throw new Error("potential deadlock: no progress for " + nowakeups + "s"); - } - System.exit(0); - } - - class WaitThread extends Thread { - Object sync; - - public void run() { - while (true) { - dowait(); - progress.add(); - } - } - - WaitThread(Object sync) { - this.sync = sync; - } - - void dowait() { - synchronized (sync) { - try { - sync.wait(); - notifyWake.add(); - } catch (InterruptedException e) { - intrWake.add(); - } - } - } - } - - class NotifyThread extends Thread { - Object sync; - - NotifyThread(Object sync) { - this.sync = sync; - } - - public void run() { - while (true) { - synchronized (sync) { - sync.notify(); - } - progress.add(); - } - } - } - - class IntrThread extends Thread { - Thread target; - - IntrThread(Thread target) { - this.target = target; - } - - public void run() { - while (true) { - try { - /* - * Reduce frequency of interrupts so that notifies can - * happen - */ - Thread.sleep(147); - } catch (InterruptedException e) { - e.printStackTrace(); - } - target.interrupt(); - progress.add(); - } - } - } - - static class Counter { - private long counter = 0; - synchronized void add() { - counter++; - } - synchronized long get() { - return counter; - } - } -} diff --git a/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitFor.java b/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitFor.java index 7547f47c51b..7c89eaf6b28 100644 --- a/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitFor.java +++ b/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitFor.java @@ -79,27 +79,6 @@ public void run(){ } threadToInterrupt.interrupt(); } - } - - class Stopper implements Runnable { - Thread threadToStop; - Object synchronizer; - - public Stopper(Thread threadToStop,Object synchronizer){ - this.threadToStop = threadToStop; - this.synchronizer = synchronizer; - } - - - public void run(){ - if (synchronizer != null){ - synchronized(synchronizer){ - threadToStop.stop(); - return; - } - } - threadToStop.stop(); - } } /** @@ -264,31 +243,7 @@ public void testWaitForAfterJoinWithTimeout(){ doWaitFor(); } - - public void testWaitForAfterInterruptInSleepByStop(){ - Thread interruptor = new TimerThread(new Stopper(Thread.currentThread(),null),1000); - interruptor.start(); - - try{ - Thread.sleep(5000); - /* in this case the test is invalid because of the timing just assume pass */ - System.out.println("WaitForAfterInterruptInSleep - invalid, assuming pass"); - return; - } catch (InterruptedException e){ - System.out.println("WaitForAfterInterruptInSleep - invalid received InterruptedException, assuming pass"); - } catch (ThreadDeath e){ - /* this is expected */ - } - - try { - interruptor.join(); - } catch (InterruptedException e){ - fail("Main thread interrupted during join"); - } - - doWaitFor(); - } - + // // Due to timing this test is not reliable to be in the builds but is useful to validate that // we did not break the ability to break out of waitFor. @@ -347,7 +302,7 @@ public void doWaitFor(){ public Process startSleeper() { try { - return Runtime.getRuntime().exec(System.getProperty("java.home") + File.separator + "bin/java -cp " + RegressionTests.getVMdir() + " j9vm.test.threads.regression.Sleeper"); + return Runtime.getRuntime().exec(System.getProperty("java.home") + File.separator + "bin/java -cp " + TestUtils.getVMdir() + " j9vm.test.threads.regression.Sleeper"); } catch(IOException e){ fail("Unexpected IO Exception when starting Sleeper"); } diff --git a/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitForStop.java b/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitForStop.java new file mode 100644 index 00000000000..433c3663129 --- /dev/null +++ b/test/functional/VM_Test/src/j9vm/test/threads/regression/ProcessWaitForStop.java @@ -0,0 +1,149 @@ +package j9vm.test.threads.regression; + +/* + * Copyright IBM Corp. and others 2025 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ + +import junit.framework.Test; +import junit.framework.TestSuite; +import junit.framework.TestCase; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +public class ProcessWaitForStop extends TestCase { + + volatile int count; + + class TimerThread extends Thread { + Runnable run; + long timeoutMillis; + + public TimerThread(Runnable run, long timeoutMillis){ + this.timeoutMillis = timeoutMillis; + this.run = run; + } + + public void run(){ + try { + Thread.sleep(timeoutMillis); + } catch (InterruptedException e){ + fail("Unexpected exception in sleep:" + e); + } + run.run(); + try { + Thread.sleep(timeoutMillis); + } catch (InterruptedException e){ + fail("Unexpected exception in sleep:" + e); + } + } + } + class Stopper implements Runnable { + Thread threadToStop; + Object synchronizer; + + public Stopper(Thread threadToStop,Object synchronizer){ + this.threadToStop = threadToStop; + this.synchronizer = synchronizer; + } + + public void run(){ + if (synchronizer != null){ + synchronized(synchronizer){ + threadToStop.stop(); + return; + } + } + threadToStop.stop(); + } + } + + /** + * method that can be used to run the test by itself + * + * @param args no valid arguments + */ + public static void main (String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite(){ + return new TestSuite(ProcessWaitForStop.class); + } + + public void testWaitForAfterInterruptInSleepByStop(){ + Thread interruptor = new TimerThread(new Stopper(Thread.currentThread(),null),1000); + interruptor.start(); + + try{ + Thread.sleep(5000); + /* in this case the test is invalid because of the timing just assume pass */ + System.out.println("WaitForAfterInterruptInSleep - invalid, assuming pass"); + return; + } catch (InterruptedException e){ + System.out.println("WaitForAfterInterruptInSleep - invalid received InterruptedException, assuming pass"); + } catch (ThreadDeath e){ + /* this is expected */ + } + + try { + interruptor.join(); + } catch (InterruptedException e){ + fail("Main thread interrupted during join"); + } + + doWaitFor(); + } + + + public void doWaitFor(){ + try { + Process newProcess = null; + try { + newProcess = startSleeper(); + } catch (Exception e){ + fail("Unexpected exception while doing exec:" + e); + } + + try { + newProcess.waitFor(); + } catch (InterruptedException e){ + fail("Interrupted exception in waitFor"); + } + + newProcess.destroy(); + } catch (Exception e){ + fail("Unexpected exception:" + e); + } + } + + public Process startSleeper() { + try { + return Runtime.getRuntime().exec(System.getProperty("java.home") + File.separator + "bin/java -cp " + TestUtils.getVMdir() + " j9vm.test.threads.regression.Sleeper"); + } catch(IOException e){ + fail("Unexpected IO Exception when starting Sleeper"); + } + return null; + } +} diff --git a/test/functional/VM_Test/src/j9vm/test/threads/regression/RegressionTests.java b/test/functional/VM_Test/src/j9vm/test/threads/regression/RegressionTests.java index 7f092585b11..2fc5f6acbbc 100644 --- a/test/functional/VM_Test/src/j9vm/test/threads/regression/RegressionTests.java +++ b/test/functional/VM_Test/src/j9vm/test/threads/regression/RegressionTests.java @@ -25,37 +25,23 @@ import junit.framework.Test; import junit.framework.TestSuite; import junit.framework.TestCase; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Constructor; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; public class RegressionTests extends TestCase { - public static String[] args = null; - /** * method that can be used to run the test by itself * * @param args args[0] must be the path to where VM_Test.jar is available */ public static void main (String[] args) { - RegressionTests.args = args; + TestUtils.args = args; junit.textui.TestRunner.run(suite()); } public static Test suite(){ - return new TestSuite(ProcessWaitFor.class); - } - - /** - * returns the path to the VM_Test.jar file - * - * @return path to the VM_Test.jar file - */ - public static String getVMdir(){ - return args[0] + File.separator + "VM_Test.jar"; + TestSuite suite = new TestSuite(); + suite.addTestSuite(ProcessWaitFor.class); + suite.addTestSuite(ProcessWaitForStop.class); + return suite; } } diff --git a/test/functional/VM_Test/src/j9vm/test/threads/regression/TestUtils.java b/test/functional/VM_Test/src/j9vm/test/threads/regression/TestUtils.java new file mode 100644 index 00000000000..ac8fc4cdced --- /dev/null +++ b/test/functional/VM_Test/src/j9vm/test/threads/regression/TestUtils.java @@ -0,0 +1,39 @@ +package j9vm.test.threads.regression; + +/* + * Copyright IBM Corp. and others 2025 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ + +import java.io.File; + +public class TestUtils { + + public static String[] args = null; + + /** + * Returns the path to the VM_Test.jar file + * + * @return path to the VM_Test.jar file + */ + public static String getVMdir(){ + return args[0] + File.separator + "VM_Test.jar"; + } +} \ No newline at end of file diff --git a/test/functional/VM_Test/src_26/j9vm/test/threads/regression/RegressionTests.java b/test/functional/VM_Test/src_26/j9vm/test/threads/regression/RegressionTests.java new file mode 100644 index 00000000000..b78ceaa3014 --- /dev/null +++ b/test/functional/VM_Test/src_26/j9vm/test/threads/regression/RegressionTests.java @@ -0,0 +1,46 @@ +package j9vm.test.threads.regression; + +/* + * Copyright IBM Corp. and others 2025 + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] https://openjdk.org/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 + */ + +import junit.framework.Test; +import junit.framework.TestSuite; +import junit.framework.TestCase; + +public class RegressionTests extends TestCase { + + /** + * method that can be used to run the test by itself + * + * @param args args[0] must be the path to where VM_Test.jar is available + */ + public static void main (String[] args) { + TestUtils.args = args; + junit.textui.TestRunner.run(suite()); + } + + public static Test suite(){ + TestSuite suite = new TestSuite(); + suite.addTestSuite(ProcessWaitFor.class); + return suite; + } +} diff --git a/test/functional/Valhalla/build.xml b/test/functional/Valhalla/build.xml index 150489e4bcc..e33133cd9f5 100644 --- a/test/functional/Valhalla/build.xml +++ b/test/functional/Valhalla/build.xml @@ -64,7 +64,7 @@ - + diff --git a/test/functional/Valhalla/playlist.xml b/test/functional/Valhalla/playlist.xml index 4ede869655a..423cec86720 100644 --- a/test/functional/Valhalla/playlist.xml +++ b/test/functional/Valhalla/playlist.xml @@ -99,6 +99,11 @@ ValueTypeArrayTests + + + https://github.com/eclipse-openj9/openj9/issues/22642 + + -Xgcpolicy:optthruput -Xgcpolicy:optthruput -XX:ValueTypeFlatteningThreshold=99999 -XX:-EnableArrayFlattening @@ -191,8 +196,9 @@ ValueTypeUnsafeTests - -Xcompressedrefs -XX:ValueTypeFlatteningThreshold=99999 -XX:+EnableArrayFlattening - -Xnocompressedrefs -XX:ValueTypeFlatteningThreshold=99999 -XX:+EnableArrayFlattening + + -Xcompressedrefs -XX:-EnableArrayFlattening -Xnocompressedrefs -XX:-EnableArrayFlattening @@ -342,6 +348,11 @@ ValueTypeSystemArraycopyTests + + + https://github.com/eclipse-openj9/openj9/issues/22642 + + -Xint -Xint -Xgcpolicy:optthruput -XX:ValueTypeFlatteningThreshold=99999 diff --git a/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldGenerator.java b/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldGenerator.java index 0bc30eeef46..6d7776ed7b9 100644 --- a/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldGenerator.java +++ b/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldGenerator.java @@ -80,4 +80,70 @@ private static Class generateTestPutStrictFinalField(String className, boolea byte[] bytes = cw.toByteArray(); return generator.defineClass(className, cw.toByteArray(), 0, bytes.length); } + + public static Class generateTestGetStaticInLarvalForUnsetStrictField() { + String className = "TestGetStaticInLarvalForUnsetStrictField"; + return generateTestPutGetStrictStaticField(className, false, false, true, false); + } + + public static Class generateTestPutStaticInLarvalForReadStrictFinalField() { + String className = "TestPutStaticInLarvalForReadStrictFinalField"; + return generateTestPutGetStrictStaticField(className, false, true, true, true); + } + + public static Class generateTestStrictStaticFieldNotSetInLarval() { + String className = "TestStrictStaticFieldNotSetInLarval"; + return generateTestPutGetStrictStaticField(className, false, false, false, false); + } + + public static Class generateTestStrictStaticFieldNotSetInLarvalMulti() { + String className = "TestStrictStaticFieldNotSetInLarvalMulti"; + return generateTestPutGetStrictStaticField(className, true, true, false, false); + } + + private static Class generateTestPutGetStrictStaticField(String className, boolean secondField, boolean put1, boolean get, boolean put2) { + String fieldName = "i"; + String fieldDesc = "I"; + String fieldName2 = "i2"; + + ClassWriter cw = new ClassWriter(0); + cw.visit(ValhallaUtils.VALUE_TYPE_CLASS_FILE_VERSION, + ACC_PUBLIC + ValhallaUtils.ACC_IDENTITY, + className, null, "java/lang/Object", null); + + cw.visitField(ACC_STATIC | ACC_STRICT_INIT | ACC_FINAL, fieldName, fieldDesc, null, null); + if (secondField) { + cw.visitField(ACC_STATIC | ACC_STRICT_INIT | ACC_FINAL, fieldName2, fieldDesc, null, null); + } + + MethodVisitor mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); + mv.visitCode(); + if (put1) { + mv.visitInsn(ICONST_1); + mv.visitFieldInsn(PUTSTATIC, className, fieldName, fieldDesc); + } + if (get) { + mv.visitFieldInsn(GETSTATIC, className, fieldName, fieldDesc); + } + if (put2) { + mv.visitInsn(ICONST_2); + mv.visitFieldInsn(PUTSTATIC, className, fieldName, fieldDesc); + } + mv.visitInsn(RETURN); + mv.visitMaxs(2, 0); + mv.visitEnd(); + + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + cw.visitEnd(); + byte[] bytes = cw.toByteArray(); + + return generator.defineClass(className, cw.toByteArray(), 0, bytes.length); + } } diff --git a/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldTests.java b/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldTests.java index adf3f9b909e..7488bcd4851 100644 --- a/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldTests.java +++ b/test/functional/Valhalla/src/org/openj9/test/lworld/StrictFieldTests.java @@ -46,4 +46,58 @@ static public void testPutStrictFinalFieldUnrestricted() throws Throwable { Class c = StrictFieldGenerator.generateTestPutStrictFinalFieldUnrestricted(); c.newInstance(); } + + /* If a strict static field in larval state is unset, getstatic throws an exception. */ + @Test(expectedExceptions = IllegalStateException.class) + static public void testGetStaticInLarvalForUnsetStrictField() throws Throwable { + Class c = StrictFieldGenerator.generateTestGetStaticInLarvalForUnsetStrictField(); + try { + c.newInstance(); + } catch (ExceptionInInitializerError e) { + throw e.getException(); + } + } + + /* If a strict static final field in larval state is set after it has been + * read, an exception is thrown. + */ + @Test(expectedExceptions = IllegalStateException.class) + static public void testPutStaticInLarvalForReadStrictFinalField() throws Throwable { + Class c = StrictFieldGenerator.generateTestPutStaticInLarvalForReadStrictFinalField(); + try { + c.newInstance(); + } catch (ExceptionInInitializerError e) { + throw e.getException(); + } + } + + /* If at the end of the larval state a strict static field is not set, + * class initialization fails and an exception should be thrown. + * Test with one unset field. + */ + @Test(expectedExceptions = IllegalStateException.class, + expectedExceptionsMessageRegExp = ".*Strict static fields are unset after initialization of.*") + static public void testStrictStaticFieldNotSetInLarval() throws Throwable { + Class c = StrictFieldGenerator.generateTestStrictStaticFieldNotSetInLarval(); + try { + c.newInstance(); + } catch (ExceptionInInitializerError e) { + throw e.getException(); + } + } + + /* If at the end of the larval state a strict static field is not set, + * class initialization fails and an exception should be thrown. + * Test with one set field and one unset field. + */ + @Test(expectedExceptions = IllegalStateException.class, + expectedExceptionsMessageRegExp = ".*Strict static fields are unset after initialization of.*") + static public void testStrictStaticFieldNotSetInLarvalMulti() throws Throwable { + Class c = StrictFieldGenerator.generateTestStrictStaticFieldNotSetInLarvalMulti(); + try { + c.newInstance(); + } catch (ExceptionInInitializerError e) { + throw e.getException(); + } + } } diff --git a/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaAttributeTests.java b/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaAttributeTests.java index 7d9244166ad..5873caf8e2c 100644 --- a/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaAttributeTests.java +++ b/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaAttributeTests.java @@ -21,7 +21,6 @@ */ package org.openj9.test.lworld; -import jdk.internal.vm.annotation.ImplicitlyConstructible; import org.testng.annotations.Test; import org.testng.Assert; @@ -223,31 +222,4 @@ public static void testPutStaticNullToNullRestrictedField() throws Throwable { } Assert.fail("Test expected a NullPointerException wrapped in ExceptionInInitializerError."); } - - @ImplicitlyConstructible - static value class ImplicitClass { - Object o; - ImplicitClass(Object o) { - this.o = o; - } - } - - /* Test to verify JVM_IsImplicitlyConstructibleClass. */ - @Test - public static void testValueClassIsImplicitlyConstructible() { - Assert.assertTrue(jdk.internal.value.ValueClass.isImplicitlyConstructible(ImplicitClass.class)); - } - - static value class NonImplicitClass { - Object o; - NonImplicitClass(Object o) { - this.o = o; - } - } - - /* Test to verify JVM_IsImplicitlyConstructibleClass. */ - @Test - public static void testValueClassIsImplicitlyConstructible2() { - Assert.assertFalse(jdk.internal.value.ValueClass.isImplicitlyConstructible(NonImplicitClass.class)); - } } diff --git a/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaUtils.java b/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaUtils.java index 8c8f3db0bac..47a56a6450f 100644 --- a/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaUtils.java +++ b/test/functional/Valhalla/src/org/openj9/test/lworld/ValhallaUtils.java @@ -25,12 +25,12 @@ public class ValhallaUtils { /** - * Currently value type is built on JDK25, so use java file major version 69 for now. + * Currently value type is built on JDK26, so use java file major version (44 + 26) for now. * If moved this needs to be incremented to the next class file version. * VALUE_TYPES_MAJOR_VERSION in oti/j9consts.h needs to be updated as well. * Minor version is in 16 most significant bits for asm. */ - static final int VALUE_TYPE_CLASS_FILE_VERSION = (65535 << 16) | 69; + static final int VALUE_TYPE_CLASS_FILE_VERSION = (65535 << 16) | (44 + 26); /* workaround till the new ASM is released */ static final int ACC_IDENTITY = 0x20; diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRBackfillLayoutTest.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRBackfillLayoutTest.java index ccdfee9aee4..00e75e6d237 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRBackfillLayoutTest.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRBackfillLayoutTest.java @@ -60,11 +60,10 @@ private static void createAndCheckValueType() throws Throwable { ValueTypeQuadLong quadLongInstance = new ValueTypeQuadLong(doubleLongInstance, new ValueTypeLong(ValueTypeTests.defaultLongNew2), ValueTypeTests.defaultLongNew3); ValueTypeDoubleQuadLong doubleQuadLongInstance = new ValueTypeDoubleQuadLong(quadLongInstance, doubleLongInstance, new ValueTypeLong(ValueTypeTests.defaultLongNew4), ValueTypeTests.defaultLongNew5); - Object[] flatUnAlignedSingleBackfill2Array = ValueClass.newNullRestrictedArray(ValueTypeTests.flatUnAlignedSingleBackfillClass2, 3); - flatUnAlignedSingleBackfill2Array[1] = flatUnAlignedSingleBackfill2Instance; - - Object[] quadLongArray = ValueClass.newNullRestrictedArray(ValueTypeQuadLong.class, 3); - quadLongArray[1] = quadLongInstance; + Object[] flatUnAlignedSingleBackfill2Array = ValueClass.newNullRestrictedAtomicArray(ValueTypeTests.flatUnAlignedSingleBackfillClass2, 3, flatUnAlignedSingleBackfill2Instance); + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + // Object[] quadLongArray = ValueClass.newNullRestrictedAtomicArray(ValueTypeQuadLong.class, 3, quadLongInstance); + Object[] quadLongArray = null; ValueTypeTests.checkObject(flatSingleBackfillInstance, objectBackfillInstance, diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRValueTypeTest.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRValueTypeTest.java index ebe507e2ff7..54e6a86e06e 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRValueTypeTest.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/DDRValueTypeTest.java @@ -61,8 +61,9 @@ private static void createAndCheckValueType() throws Throwable { Object assortedValueWithSingleAlignment = ValueTypeTests.createAssorted(makeAssortedValueWithSingleAlignment, ValueTypeTests.typeWithSingleAlignmentFields); Object assortedValueWithSingleAlignmentAlt = ValueTypeTests.createAssorted(makeAssortedValueWithSingleAlignment, ValueTypeTests.typeWithSingleAlignmentFields, altFields); Object valueTypeWithVolatileFields = ValueTypeTests.createValueTypeWithVolatileFields(); - - Object[] valArray = ValueClass.newNullRestrictedArray(assortedValueWithSingleAlignmentClass, 2); + + Object[] valArray = ValueClass.newNullRestrictedAtomicArray(assortedValueWithSingleAlignmentClass, 2, assortedValueWithSingleAlignment); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. valArray[0] = assortedValueWithSingleAlignment; valArray[1] = assortedValueWithSingleAlignmentAlt; diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeArrayTests.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeArrayTests.java index be340ffb3d2..1b6f96ffab4 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeArrayTests.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeArrayTests.java @@ -25,12 +25,9 @@ import static org.testng.Assert.*; import org.testng.annotations.Test; -import jdk.internal.value.CheckedType; -import jdk.internal.value.NormalCheckedType; -import jdk.internal.value.NullRestrictedCheckedType; import jdk.internal.value.ValueClass; -import jdk.internal.vm.annotation.ImplicitlyConstructible; import jdk.internal.vm.annotation.NullRestricted; +import jdk.internal.vm.annotation.Strict; /** * Test array element assignment involving arrays of type {@code Object}, @@ -62,9 +59,10 @@ static value class PointV implements SomeIface { /** * A simple primitive value type class */ - @ImplicitlyConstructible static value class PointPV implements SomeIface { + @Strict double x; + @Strict double y; PointPV(double x, double y) { @@ -331,7 +329,7 @@ static void runTest(Object[] arr, Object sourceVal, int staticArrayKind, int sta @Test(priority=1,invocationCount=2) static public void testValueTypeArrayAssignments() throws Throwable { Object[][] testArrays = new Object[][] {new Object[2], new SomeIface[2], new PointV[2], - ValueClass.newArrayInstance(NullRestrictedCheckedType.of(PointPV.class), 2)}; + ValueClass.newNullRestrictedAtomicArray(PointPV.class, 2, new PointPV(0.0, 0.0))}; int[] kinds = {OBJ_TYPE, IFACE_TYPE, VAL_TYPE, PRIM_TYPE}; Object[] vals = new Object[] {null, bogusIfaceObj, new PointV(1.0, 2.0), new PointPV(3.0, 4.0)}; @@ -366,8 +364,8 @@ static public void testValueTypeArrayAssignments() throws Throwable { } } - @ImplicitlyConstructible static value class SomePrimitiveClassWithDoubleField { + @Strict public double d; SomePrimitiveClassWithDoubleField(double x) { @@ -375,8 +373,8 @@ static value class SomePrimitiveClassWithDoubleField { } } - @ImplicitlyConstructible static value class SomePrimitiveClassWithFloatField { + @Strict public float f; SomePrimitiveClassWithFloatField(float x) { @@ -384,8 +382,8 @@ static value class SomePrimitiveClassWithFloatField { } } - @ImplicitlyConstructible static value class SomePrimitiveClassWithLongField { + @Strict public long l; SomePrimitiveClassWithLongField(long x) { @@ -421,9 +419,10 @@ interface SomeInterface1WithSingleImplementer {} interface SomeInterface2WithSingleImplementer {} - @ImplicitlyConstructible static value class SomePrimitiveClassImplIf implements SomeInterface1WithSingleImplementer { + @Strict public double d; + @Strict public long l; SomePrimitiveClassImplIf(double val1, long val2) { @@ -602,12 +601,12 @@ static void writeArrayElementWithSomeIdentityClassImplIf(SomeClassHolder holder) static public void testValueTypeAaload() throws Throwable { int ARRAY_LENGTH = 10; - SomePrimitiveClassWithDoubleField[] data1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithDoubleField.class), ARRAY_LENGTH); - SomePrimitiveClassWithFloatField[] data2 = (SomePrimitiveClassWithFloatField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithFloatField.class), ARRAY_LENGTH); - SomePrimitiveClassWithLongField[] data3 = (SomePrimitiveClassWithLongField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithLongField.class), ARRAY_LENGTH); + SomePrimitiveClassWithDoubleField[] data1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithDoubleField.class, ARRAY_LENGTH, new SomePrimitiveClassWithDoubleField(0)); + SomePrimitiveClassWithFloatField[] data2 = (SomePrimitiveClassWithFloatField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithFloatField.class, ARRAY_LENGTH, new SomePrimitiveClassWithFloatField(0)); + SomePrimitiveClassWithLongField[] data3 = (SomePrimitiveClassWithLongField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithLongField.class, ARRAY_LENGTH, new SomePrimitiveClassWithLongField(0)); SomeIdentityClassWithDoubleField[] data4 = new SomeIdentityClassWithDoubleField[ARRAY_LENGTH]; SomeIdentityClassWithFloatField[] data5 = new SomeIdentityClassWithFloatField[ARRAY_LENGTH]; @@ -640,18 +639,18 @@ static public void testValueTypeAaload() throws Throwable { @Test(priority=1,invocationCount=2) static public void testValueTypeAastore() throws Throwable { int ARRAY_LENGTH = 10; - SomePrimitiveClassWithDoubleField[] srcData1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithDoubleField.class), ARRAY_LENGTH); - SomePrimitiveClassWithDoubleField[] dstData1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithDoubleField.class), ARRAY_LENGTH); - SomePrimitiveClassWithFloatField[] srcData2 = (SomePrimitiveClassWithFloatField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithFloatField.class), ARRAY_LENGTH); - SomePrimitiveClassWithFloatField[] dstData2 = (SomePrimitiveClassWithFloatField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithFloatField.class), ARRAY_LENGTH); - SomePrimitiveClassWithLongField[] srcData3 = (SomePrimitiveClassWithLongField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithLongField.class), ARRAY_LENGTH); - SomePrimitiveClassWithLongField[] dstData3 = (SomePrimitiveClassWithLongField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithLongField.class), ARRAY_LENGTH); + SomePrimitiveClassWithDoubleField[] srcData1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithDoubleField.class, ARRAY_LENGTH, new SomePrimitiveClassWithDoubleField(0)); + SomePrimitiveClassWithDoubleField[] dstData1 = (SomePrimitiveClassWithDoubleField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithDoubleField.class, ARRAY_LENGTH, new SomePrimitiveClassWithDoubleField(0)); + SomePrimitiveClassWithFloatField[] srcData2 = (SomePrimitiveClassWithFloatField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithFloatField.class, ARRAY_LENGTH, new SomePrimitiveClassWithFloatField(0)); + SomePrimitiveClassWithFloatField[] dstData2 = (SomePrimitiveClassWithFloatField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithFloatField.class, ARRAY_LENGTH, new SomePrimitiveClassWithFloatField(0)); + SomePrimitiveClassWithLongField[] srcData3 = (SomePrimitiveClassWithLongField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithLongField.class, ARRAY_LENGTH, new SomePrimitiveClassWithLongField(0)); + SomePrimitiveClassWithLongField[] dstData3 = (SomePrimitiveClassWithLongField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithLongField.class, ARRAY_LENGTH, new SomePrimitiveClassWithLongField(0)); SomeIdentityClassWithDoubleField[] srcData4 = new SomeIdentityClassWithDoubleField[ARRAY_LENGTH]; SomeIdentityClassWithDoubleField[] dstData4 = new SomeIdentityClassWithDoubleField[ARRAY_LENGTH]; @@ -692,7 +691,6 @@ static public void testValueTypeAastore() throws Throwable { writeArrayElementWithSomeIdentityClassImplIf(holder); } - @ImplicitlyConstructible public static value class EmptyPrim { } @@ -725,10 +723,10 @@ static void compareEmptyValArrays(EmptyVal[] arr1, EmptyVal[] arr2) { @Test(priority=1,invocationCount=2) static public void testEmptyValueArrayElement() { - EmptyPrim[] primArr1 = (EmptyPrim[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(EmptyPrim.class), 4); - EmptyPrim[] primArr2 = (EmptyPrim[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(EmptyPrim.class), 4); + EmptyPrim[] primArr1 = (EmptyPrim[])ValueClass.newNullRestrictedAtomicArray( + EmptyPrim.class, 4, new EmptyPrim()); + EmptyPrim[] primArr2 = (EmptyPrim[])ValueClass.newNullRestrictedAtomicArray( + EmptyPrim.class, 4, new EmptyPrim()); copyBetweenEmptyPrimArrays(primArr1, primArr2); compareEmptyPrimArrays(primArr1, primArr2); @@ -751,8 +749,8 @@ static void arrayElementStore(Object[] arr, int index, Object obj) { @Test(priority=1,invocationCount=2) static public void testStoreNullToNullRestrictedArrayElement1() throws Throwable { int ARRAY_LENGTH = 10; - SomePrimitiveClassWithDoubleField[] dstData = (SomePrimitiveClassWithDoubleField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithDoubleField.class), ARRAY_LENGTH); + SomePrimitiveClassWithDoubleField[] dstData = (SomePrimitiveClassWithDoubleField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithDoubleField.class, ARRAY_LENGTH, new SomePrimitiveClassWithDoubleField(0)); try { arrayElementStoreNull(dstData, ARRAY_LENGTH/2); @@ -766,8 +764,8 @@ static public void testStoreNullToNullRestrictedArrayElement1() throws Throwable @Test(priority=1,invocationCount=2) static public void testStoreNullToNullRestrictedArrayElement2() throws Throwable { int ARRAY_LENGTH = 10; - SomePrimitiveClassWithDoubleField[] dstData = (SomePrimitiveClassWithDoubleField[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(SomePrimitiveClassWithDoubleField.class), ARRAY_LENGTH); + SomePrimitiveClassWithDoubleField[] dstData = (SomePrimitiveClassWithDoubleField[])ValueClass.newNullRestrictedAtomicArray( + SomePrimitiveClassWithDoubleField.class, ARRAY_LENGTH, new SomePrimitiveClassWithDoubleField(0)); Object obj = null; try { @@ -779,7 +777,6 @@ static public void testStoreNullToNullRestrictedArrayElement2() throws Throwable Assert.fail("Expect an ArrayStoreException. No exception or wrong kind of exception thrown"); } - @ImplicitlyConstructible public static value class EmptyNullRestricted { } @@ -787,14 +784,8 @@ public static value class EmptyNullRestricted { /* Test JVM_IsNullRestrictedArray which is called by ValueClass.componentCheckedType */ @Test public static void testJVMIsNullRestrictedArray() { - EmptyNullRestricted[] nrArray = (EmptyNullRestricted[])ValueClass.newArrayInstance( - NullRestrictedCheckedType.of(EmptyNullRestricted.class), 4); - CheckedType nrType = ValueClass.componentCheckedType(nrArray); - assertTrue(nrType instanceof NullRestrictedCheckedType); - - EmptyNullRestricted[] normalArray = (EmptyNullRestricted[])ValueClass.newArrayInstance( - NormalCheckedType.of(EmptyNullRestricted.class), 4); - CheckedType normalType = ValueClass.componentCheckedType(normalArray); - assertTrue(normalType instanceof NormalCheckedType); + EmptyNullRestricted[] nrArray = (EmptyNullRestricted[])ValueClass.newNullRestrictedAtomicArray( + EmptyNullRestricted.class, 4, new EmptyNullRestricted()); + assertTrue(ValueClass.isNullRestrictedArray(nrArray)); } } diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java index beafd161e1e..b4dd71f57bd 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeSystemArraycopyTests.java @@ -27,8 +27,8 @@ import org.testng.annotations.BeforeClass; import jdk.internal.value.ValueClass; -import jdk.internal.vm.annotation.ImplicitlyConstructible; import jdk.internal.vm.annotation.NullRestricted; +import jdk.internal.vm.annotation.Strict; @Test(groups = { "level.sanity" }) public class ValueTypeSystemArraycopyTests { @@ -59,12 +59,15 @@ public static class SomeIdentityClass2 implements SomeInterface { } } - @ImplicitlyConstructible public static value class SomeValueClass implements SomeInterface { + @Strict double val1; + @Strict long val2; + @Strict @NullRestricted SomeValueClass2 val3; + @Strict int val4; SomeValueClass(int i) { @@ -75,9 +78,10 @@ public static value class SomeValueClass implements SomeInterface { } } - @ImplicitlyConstructible public static value class SomeValueClass2 implements SomeInterface { + @Strict long val1; + @Strict double val2; SomeValueClass2(int i) { @@ -93,24 +97,24 @@ public static value class SomeValueClass2 implements SomeInterface { public static SomeValueClass[] vtArrayDst = new SomeValueClass[ARRAY_SIZE]; public static SomeValueClass[] vtArraySrc = new SomeValueClass[ARRAY_SIZE]; public static SomeValueClass[] nullRestrictedVtArraySrc = - (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + (SomeValueClass[])ValueClass.newNullRestrictedAtomicArray(SomeValueClass.class, ARRAY_SIZE, new SomeValueClass(0)); public static SomeValueClass[] nullRestrictedVtArrayDst = - (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + (SomeValueClass[])ValueClass.newNullRestrictedAtomicArray(SomeValueClass.class, ARRAY_SIZE, new SomeValueClass(0)); public static SomeInterface[] ifIdArrayDst = new SomeIdentityClass[ARRAY_SIZE]; public static SomeInterface[] ifIdArraySrc = new SomeIdentityClass[ARRAY_SIZE]; public static SomeInterface[] ifVtArrayDst = new SomeValueClass[ARRAY_SIZE]; public static SomeInterface[] ifVtArraySrc = new SomeValueClass[ARRAY_SIZE]; public static SomeInterface[] ifNullRestrictedVtArrayDst = - (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + (SomeValueClass[])ValueClass.newNullRestrictedAtomicArray(SomeValueClass.class, ARRAY_SIZE, new SomeValueClass(0)); public static SomeInterface[] ifNullRestrictedVtArraySrc = - (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + (SomeValueClass[])ValueClass.newNullRestrictedAtomicArray(SomeValueClass.class, ARRAY_SIZE, new SomeValueClass(0)); public static SomeInterface[] ifArray1 = new SomeInterface[ARRAY_SIZE]; public static SomeInterface[] ifArray2 = new SomeInterface[ARRAY_SIZE]; public static SomeInterface[] ifArray3 = new SomeInterface[ARRAY_SIZE]; public static SomeIdentityClass[] idArrayDstCheckForException = new SomeIdentityClass[ARRAY_SIZE]; public static SomeValueClass[] nullRestrictedVtArrayDstCheckForException = - (SomeValueClass[])ValueClass.newNullRestrictedArray(SomeValueClass.class, ARRAY_SIZE); + (SomeValueClass[])ValueClass.newNullRestrictedAtomicArray(SomeValueClass.class, ARRAY_SIZE, new SomeValueClass(0)); static private void initArrays() { for (int i=0; i < ARRAY_SIZE; i++) { diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTestClasses.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTestClasses.java index beb1bf975e4..5813c54a084 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTestClasses.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTestClasses.java @@ -21,14 +21,14 @@ */ package org.openj9.test.lworld; -import jdk.internal.vm.annotation.ImplicitlyConstructible; import jdk.internal.vm.annotation.NullRestricted; +import jdk.internal.vm.annotation.Strict; public class ValueTypeTestClasses { - @ImplicitlyConstructible static value class ValueTypeInt { ValueTypeInt(int i) { this.i = i; } + @Strict final int i; } @@ -37,8 +37,8 @@ static value class ValueClassInt { final int i; } - @ImplicitlyConstructible static value class ValueTypeLong { + @Strict final long l; ValueTypeLong(long l) {this.l = l;} public long getL() { @@ -46,8 +46,8 @@ public long getL() { } } - @ImplicitlyConstructible static value class ValueTypePoint2D { + @Strict @NullRestricted final ValueTypeInt x, y; @@ -81,8 +81,8 @@ static class Point2D { } } - @ImplicitlyConstructible static value class ValueTypeWithLongField { + @Strict @NullRestricted final ValueTypeLong l; @@ -91,8 +91,8 @@ static value class ValueTypeWithLongField { } } - @ImplicitlyConstructible static value class ValueTypeLongPoint2D { + @Strict @NullRestricted final ValueTypeLong x, y; @@ -102,13 +102,12 @@ static value class ValueTypeLongPoint2D { } } - @ImplicitlyConstructible static value class ZeroSizeValueType { ZeroSizeValueType() {} } - @ImplicitlyConstructible static value class ZeroSizeValueTypeWrapper { + @Strict @NullRestricted final ZeroSizeValueType z; @@ -117,15 +116,16 @@ static value class ZeroSizeValueTypeWrapper { } } - @ImplicitlyConstructible static value class ValueTypeInt2 { ValueTypeInt2(int i) { this.i = i; } + @Strict final int i; } - @ImplicitlyConstructible static value class ValueTypeFastSubVT { + @Strict final int x,y,z; + @Strict final Object[] arr; ValueTypeFastSubVT(int x, int y, int z, Object[] arr) { this.x = x; @@ -135,10 +135,11 @@ static value class ValueTypeFastSubVT { } } - @ImplicitlyConstructible static value class ValueTypeDoubleLong { + @Strict @NullRestricted final ValueTypeLong l; + @Strict final long l2; ValueTypeDoubleLong(ValueTypeLong l, long l2) { this.l = l; @@ -152,12 +153,14 @@ public long getL2() { } } - @ImplicitlyConstructible static value class ValueTypeQuadLong { + @Strict @NullRestricted final ValueTypeDoubleLong l; + @Strict @NullRestricted final ValueTypeLong l2; + @Strict final long l3; ValueTypeQuadLong(ValueTypeDoubleLong l, ValueTypeLong l2, long l3) { this.l = l; @@ -175,14 +178,17 @@ public long getL3() { } } - @ImplicitlyConstructible static value class ValueTypeDoubleQuadLong { + @Strict @NullRestricted final ValueTypeQuadLong l; + @Strict @NullRestricted final ValueTypeDoubleLong l2; + @Strict @NullRestricted final ValueTypeLong l3; + @Strict final long l4; ValueTypeDoubleQuadLong(ValueTypeQuadLong l, ValueTypeDoubleLong l2, ValueTypeLong l3, long l4) { this.l = l; diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTests.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTests.java index d97addda03a..d059324e5fc 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTests.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeTests.java @@ -310,12 +310,12 @@ static public void testGCFlattenedPoint2DArray() throws Throwable { int x1 = 0xFFEEFFEE; int y1 = 0xAABBAABB; Object point2D = makePoint2D.invoke(x1, y1); - Object[] array = ValueClass.newNullRestrictedArray(point2DClass, 8); + Object[] array = ValueClass.newNullRestrictedAtomicArray(point2DClass, 8, point2D); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < 8; i++) { array[i] = point2D; } - System.gc(); Object value = array[0]; @@ -323,13 +323,14 @@ static public void testGCFlattenedPoint2DArray() throws Throwable { @Test(priority=5) static public void testGCFlattenedValueArrayWithSingleAlignment() throws Throwable { - Object[] array = ValueClass.newNullRestrictedArray(assortedValueWithSingleAlignmentClass, 4); - + Object[] array = ValueClass.newNullRestrictedAtomicArray(assortedValueWithSingleAlignmentClass, 4, + createAssorted(makeAssortedValueWithSingleAlignment, typeWithSingleAlignmentFields)); + + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < 4; i++) { Object object = createAssorted(makeAssortedValueWithSingleAlignment, typeWithSingleAlignmentFields); array[i] = object; } - System.gc(); for (int i = 0; i < 4; i++) { @@ -339,13 +340,14 @@ static public void testGCFlattenedValueArrayWithSingleAlignment() throws Throwab @Test(priority=5) static public void testGCFlattenedValueArrayWithObjectAlignment() throws Throwable { - Object[] array = ValueClass.newNullRestrictedArray(assortedValueWithObjectAlignmentClass, 4); - + Object[] array = ValueClass.newNullRestrictedAtomicArray(assortedValueWithObjectAlignmentClass, 4, + createAssorted(makeAssortedValueWithObjectAlignment, typeWithObjectAlignmentFields)); + + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < 4; i++) { Object object = createAssorted(makeAssortedValueWithObjectAlignment, typeWithObjectAlignmentFields); array[i] = object; } - System.gc(); for (int i = 0; i < 4; i++) { @@ -355,13 +357,14 @@ static public void testGCFlattenedValueArrayWithObjectAlignment() throws Throwab @Test(priority=5) static public void testGCFlattenedValueArrayWithLongAlignment() throws Throwable { - Object[] array = ValueClass.newNullRestrictedArray(assortedValueWithLongAlignmentClass, genericArraySize); - + Object[] array = ValueClass.newNullRestrictedAtomicArray(assortedValueWithLongAlignmentClass, genericArraySize, + createAssorted(makeAssortedValueWithLongAlignment, typeWithLongAlignmentFields)); + + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < genericArraySize; i++) { Object object = createAssorted(makeAssortedValueWithLongAlignment, typeWithLongAlignmentFields); array[i] = object; } - System.gc(); for (int i = 0; i < genericArraySize; i++) { @@ -371,9 +374,10 @@ static public void testGCFlattenedValueArrayWithLongAlignment() throws Throwable @Test(priority=5) static public void testGCFlattenedLargeObjectArray() throws Throwable { - Object[] array = ValueClass.newNullRestrictedArray(largeObjectValueClass, 4); + Object[] array = ValueClass.newNullRestrictedAtomicArray(largeObjectValueClass, 4, createLargeObject(new Object())); Object largeObjectRef = createLargeObject(new Object()); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < 4; i++) { array[i] = largeObjectRef; } @@ -385,11 +389,12 @@ static public void testGCFlattenedLargeObjectArray() throws Throwable { @Test(priority=5) static public void testGCFlattenedMegaObjectArray() throws Throwable { - Object[] array = ValueClass.newNullRestrictedArray(megaObjectValueClass, 4); + Object[] array = ValueClass.newNullRestrictedAtomicArray(megaObjectValueClass, 4, createMegaObject(new Object())); Object megaObjectRef = createMegaObject(new Object()); System.gc(); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int i = 0; i < 4; i++) { array[i] = megaObjectRef; } @@ -536,7 +541,8 @@ static public void testCreateArrayFlattenedLine2D() throws Throwable { Object en2 = makePoint2D.invoke(x4, y4); Object line2D_2 = makeFlattenedLine2D.invoke(st2, en2); - Object[] arrayObject = ValueClass.newNullRestrictedArray(flattenedLine2DClass, 2); + Object[] arrayObject = ValueClass.newNullRestrictedAtomicArray(flattenedLine2DClass, 2, line2D_1); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. arrayObject[0] = line2D_1; arrayObject[1] = line2D_2; Object line2D_1_check = arrayObject[0]; @@ -2296,9 +2302,11 @@ static public void testCheckCastNullableTypeOnNull() throws Throwable { checkCastRefClassOnNull.invoke(); } - @Test(priority=1) + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + @Test(priority=1, enabled=false) static public void testClassIsInstanceNullableArrays() throws Throwable { - ValueTypePoint2D[] nonNullableArray = (ValueTypePoint2D[]) ValueClass.newNullRestrictedArray(ValueTypePoint2D.class, 1); + ValueTypePoint2D[] nonNullableArray = (ValueTypePoint2D[]) ValueClass.newNullRestrictedAtomicArray( + ValueTypePoint2D.class, 1, new ValueTypePoint2D(new ValueTypeInt(0), new ValueTypeInt(0))); ValueTypePoint2D[] nullableArray = new ValueTypePoint2D[1]; assertTrue(nonNullableArray.getClass().isInstance(nonNullableArray)); @@ -2315,7 +2323,9 @@ static public void testClassIsInstanceNullableArrays() throws Throwable { static public void testValueWithLongAlignmentGCScanning() throws Throwable { ArrayList longAlignmentArrayList = new ArrayList(objectGCScanningIterationCount); for (int i = 0; i < objectGCScanningIterationCount; i++) { - Object newLongAlignmentArray = ValueClass.newNullRestrictedArray(assortedValueWithLongAlignmentClass, genericArraySize); + Object newLongAlignmentArray = ValueClass.newNullRestrictedAtomicArray(assortedValueWithLongAlignmentClass, + genericArraySize, createAssorted(makeAssortedValueWithLongAlignment, typeWithLongAlignmentFields)); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int j = 0; j < genericArraySize; j++) { Object assortedValueWithLongAlignment = createAssorted(makeAssortedValueWithLongAlignment, typeWithLongAlignmentFields); Array.set(newLongAlignmentArray, j, assortedValueWithLongAlignment); @@ -2340,7 +2350,10 @@ static public void testValueWithLongAlignmentGCScanning() throws Throwable { static public void testValueWithObjectAlignmentGCScanning() throws Throwable { ArrayList objectAlignmentArrayList = new ArrayList(objectGCScanningIterationCount); for (int i = 0; i < objectGCScanningIterationCount; i++) { - Object newObjectAlignmentArray = ValueClass.newNullRestrictedArray(assortedValueWithObjectAlignmentClass, genericArraySize); + Object newObjectAlignmentArray = ValueClass.newNullRestrictedAtomicArray( + assortedValueWithObjectAlignmentClass, genericArraySize, + createAssorted(makeAssortedValueWithObjectAlignment, typeWithObjectAlignmentFields)); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int j = 0; j < genericArraySize; j++) { Object assortedValueWithObjectAlignment = createAssorted(makeAssortedValueWithObjectAlignment, typeWithObjectAlignmentFields); Array.set(newObjectAlignmentArray, j, assortedValueWithObjectAlignment); @@ -2365,7 +2378,10 @@ static public void testValueWithObjectAlignmentGCScanning() throws Throwable { static public void testValueWithSingleAlignmentGCScanning() throws Throwable { ArrayList singleAlignmentArrayList = new ArrayList(objectGCScanningIterationCount); for (int i = 0; i < objectGCScanningIterationCount; i++) { - Object newSingleAlignmentArray = ValueClass.newNullRestrictedArray(assortedValueWithSingleAlignmentClass, genericArraySize); + Object newSingleAlignmentArray = ValueClass.newNullRestrictedAtomicArray( + assortedValueWithSingleAlignmentClass, genericArraySize, + createAssorted(makeAssortedValueWithSingleAlignment, typeWithSingleAlignmentFields)); + // TODO: Remove following initialization as per https://github.com/eclipse-openj9/openj9/issues/22642. for (int j = 0; j < genericArraySize; j++) { Object assortedValueWithSingleAlignment = createAssorted(makeAssortedValueWithSingleAlignment, typeWithSingleAlignmentFields); Array.set(newSingleAlignmentArray, j, assortedValueWithSingleAlignment); diff --git a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeUnsafeTests.java b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeUnsafeTests.java index 390813f9259..04fa4a0a97e 100644 --- a/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeUnsafeTests.java +++ b/test/functional/Valhalla/src_qtypes/org/openj9/test/lworld/ValueTypeUnsafeTests.java @@ -24,7 +24,6 @@ import jdk.internal.misc.Unsafe; import jdk.internal.value.ValueClass; -import jdk.internal.vm.annotation.ImplicitlyConstructible; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; @@ -95,11 +94,14 @@ static private long arrayElementSize(T[] array) { static public void setUp() { vtPoint = new ValueTypePoint2D(new ValueTypeInt(7), new ValueTypeInt(8)); - vtPointAry = (ValueTypePoint2D[])ValueClass.newNullRestrictedArray(ValueTypePoint2D.class, 2); - vtPointAry[0] = new ValueTypePoint2D(new ValueTypeInt(5), new ValueTypeInt(10)); - vtPointAry[1] = new ValueTypePoint2D(new ValueTypeInt(10), new ValueTypeInt(20)); + vtPointAry = null; + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + // vtPointAry = (ValueTypePoint2D[]) ValueClass.newNullRestrictedAtomicArray(ValueTypePoint2D.class, 2, + // new ValueTypePoint2D(new ValueTypeInt(0), new ValueTypeInt(0))); + // vtPointAry[0] = new ValueTypePoint2D(new ValueTypeInt(5), new ValueTypeInt(10)); + // vtPointAry[1] = new ValueTypePoint2D(new ValueTypeInt(10), new ValueTypeInt(20)); - vtPointAryOffset1 = vtPointAryOffset0 + arrayElementSize(vtPointAry); + // vtPointAryOffset1 = vtPointAryOffset0 + arrayElementSize(vtPointAry); vtIntAry = new ValueTypeInt[] { new ValueTypeInt(1), new ValueTypeInt(2) }; vtIntAryOffset1 = vtIntAryOffset0 + arrayElementSize(vtIntAry); } @@ -149,7 +151,8 @@ static public void testFlattenedFieldIsFlattened() throws Throwable { assertEquals(isFlattened, isFlatteningEnabled); } - @Test + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + @Test(enabled = false) static public void testFlattenedArrayIsFlattened() throws Throwable { boolean isArrayFlattened = myUnsafe.isFlatArray(vtPointAry.getClass()); assertEquals(isArrayFlattened, isArrayFlatteningEnabled); @@ -248,50 +251,6 @@ static public void testValueHeaderSizeOfArray() throws Throwable { assertEquals(size, 0); } - @Test - static public void testUninitializedDefaultValueOfValueType() throws Throwable { - // create a new ValueTypePoint2D to ensure that the class has been initialized befoere myUnsafe.uninitializedDefaultValue is called - ValueTypePoint2D newPoint = new ValueTypePoint2D(new ValueTypeInt(1), new ValueTypeInt(1)); - ValueTypePoint2D p = myUnsafe.uninitializedDefaultValue(newPoint.getClass()); - assertEquals(p.x.i, 0); - assertEquals(p.y.i, 0); - } - - @Test - static public void testUninitializedDefaultValueOfNonValueType() throws Throwable { - Point2D p = myUnsafe.uninitializedDefaultValue(Point2D.class); - assertNull(p); - } - - @Test - static public void testUninitializedDefaultValueOfNull() throws Throwable { - Object o = myUnsafe.uninitializedDefaultValue(null); - assertNull(o); - } - - @Test - static public void testUninitializedDefaultValueOfVTArray() throws Throwable { - Object o = myUnsafe.uninitializedDefaultValue(vtIntAry.getClass()); - assertNull(o); - } - - @Test - static public void testUninitializedDefaultValueOfArray() throws Throwable { - Point2D[] ary = {}; - Object o = myUnsafe.uninitializedDefaultValue(ary.getClass()); - assertNull(o); - } - - @Test - static public void testuninitializedVTClassHasNullDefaultValue() { - @ImplicitlyConstructible - value class NeverInitialized { - final ValueTypeInt i; - NeverInitialized(ValueTypeInt i) { this.i = i; } - } - assertNull(myUnsafe.uninitializedDefaultValue(NeverInitialized.class)); - } - @Test static public void testNullObjGetValue() throws Throwable { assertThrows(NullPointerException.class, () -> { @@ -323,7 +282,8 @@ static public void testGetValuesOfArray() throws Throwable { } } - @Test + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + @Test(enabled = false) static public void testGetValueOfZeroSizeVTArrayDoesNotCauseError() throws Throwable { ZeroSizeValueType[] zsvtAry = new ZeroSizeValueType[] { new ZeroSizeValueType(), @@ -333,7 +293,8 @@ static public void testGetValueOfZeroSizeVTArrayDoesNotCauseError() throws Throw assertNotNull(myUnsafe.getValue(zsvtAry, zsvtAryOffset0, ZeroSizeValueType.class)); } - @Test + // TODO: Disabled as per https://github.com/eclipse-openj9/openj9/issues/22642. + @Test(enabled = false) static public void testGetValueOfZeroSizeVTObjectDoesNotCauseError() throws Throwable { ZeroSizeValueTypeWrapper zsvtw = new ZeroSizeValueTypeWrapper(); long zsvtwOffset0 = myUnsafe.objectFieldOffset(ZeroSizeValueTypeWrapper.class.getDeclaredField("z")); diff --git a/test/functional/cmdLineTests/classesdbgddrext/playlist.xml b/test/functional/cmdLineTests/classesdbgddrext/playlist.xml index de5ab8ff09c..0a499862b4a 100644 --- a/test/functional/cmdLineTests/classesdbgddrext/playlist.xml +++ b/test/functional/cmdLineTests/classesdbgddrext/playlist.xml @@ -51,6 +51,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Mode110 Mode610 + Mode501 + Mode551 perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)tools$(D)sysvcleanup.pl all ; \ $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) -Xmx1G \ @@ -81,6 +83,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Mode110 Mode610 + Mode501 + Mode551 perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)tools$(D)sysvcleanup.pl aix ; \ $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) -Xmx1G \ diff --git a/test/functional/cmdLineTests/jfr/jfrevents.xml b/test/functional/cmdLineTests/jfr/jfrevents.xml index cafa749e541..21a1fd8e27b 100644 --- a/test/functional/cmdLineTests/jfr/jfrevents.xml +++ b/test/functional/cmdLineTests/jfr/jfrevents.xml @@ -125,4 +125,11 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex targetModule jfr print: could not read recording + + $JFR_EXE$ print --xml --events "ClassLoaderStatistics" defaultJ9recording.jfr + http://www.w3.org/2001/XMLSchema-instance + jdk.ClassLoaderStatistics + classLoader + jfr print: could not read recording + diff --git a/test/functional/cmdLineTests/jfr/src/org/openj9/test/WorkLoad.java b/test/functional/cmdLineTests/jfr/src/org/openj9/test/WorkLoad.java index f6442a9b2c1..3fce98e1c3f 100644 --- a/test/functional/cmdLineTests/jfr/src/org/openj9/test/WorkLoad.java +++ b/test/functional/cmdLineTests/jfr/src/org/openj9/test/WorkLoad.java @@ -21,6 +21,9 @@ */ package org.openj9.test; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; @@ -35,8 +38,10 @@ public class WorkLoad { public static double average; public static double stdDev; + static ArrayList> classes = new ArrayList<>(); + private static long globalCounter = 0; - static interface GlobalLoack {}; + static interface GlobalLoack {} private static Object globalLock = new GlobalLoack(){}; public WorkLoad(int numberOfThreads, int sizeOfNumberList, int repeats) { @@ -100,6 +105,7 @@ private void workload() { throwThrowables(); contendOnLock(); burnCPU(); + generateClassLoader(); } } @@ -182,6 +188,23 @@ private void burnCPU() { stdDev += standardDeviation(numberList); } + public static class ClassLoaderTestClass {} + + private void generateClassLoader() { + try { + ClassLoader classLoader = new URLClassLoader( + new URL[] { + WorkLoad.class.getProtectionDomain().getCodeSource().getLocation() + }, + new URLClassLoader(new URL[] {})); + + classes.add( + classLoader.loadClass("org.openj9.test.WorkLoad$ClassLoaderTestClass")); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private double average(List numbers) { double sum = 0.0; diff --git a/test/functional/cmdLineTests/jvmtitests/playlist.xml b/test/functional/cmdLineTests/jvmtitests/playlist.xml index 468bc433c16..4add8755592 100644 --- a/test/functional/cmdLineTests/jvmtitests/playlist.xml +++ b/test/functional/cmdLineTests/jvmtitests/playlist.xml @@ -753,6 +753,8 @@ Mode148 Mode149 Mode610 + Mode501 + Mode551 $(ADD_JVM_LIB_DIR_TO_LIBPATH) \ $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) \ diff --git a/test/functional/cmdLineTests/jython/playlist.xml b/test/functional/cmdLineTests/jython/playlist.xml index bed48892425..2faafd6d50a 100644 --- a/test/functional/cmdLineTests/jython/playlist.xml +++ b/test/functional/cmdLineTests/jython/playlist.xml @@ -60,6 +60,10 @@ Mode608 Mode609 Mode616 + Mode500 + Mode501 + Mode551 + Mode550 $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) \ -DJARPATH=$(Q)$(LIB_DIR)$(D)jython-standalone.jar$(P)$(TEST_RESROOT)$(D)cmdLineTester_jython.jar$(Q) \ diff --git a/test/functional/cmdLineTests/lazyClassLoadingTest/playlist.xml b/test/functional/cmdLineTests/lazyClassLoadingTest/playlist.xml index 9a678a35a26..20420965a22 100644 --- a/test/functional/cmdLineTests/lazyClassLoadingTest/playlist.xml +++ b/test/functional/cmdLineTests/lazyClassLoadingTest/playlist.xml @@ -33,6 +33,8 @@ Mode110 Mode610 + Mode501 + Mode551 extended diff --git a/test/functional/cmdLineTests/modularityddrtests/playlist.xml b/test/functional/cmdLineTests/modularityddrtests/playlist.xml index e2dfb3027c3..997e6bba272 100644 --- a/test/functional/cmdLineTests/modularityddrtests/playlist.xml +++ b/test/functional/cmdLineTests/modularityddrtests/playlist.xml @@ -27,6 +27,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Mode110 Mode610 + Mode501 + Mode551 perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)tools$(D)sysvcleanup.pl all ; \ $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) -Xmx1G \ @@ -58,6 +60,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Mode110 Mode610 + Mode501 + Mode551 perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)tools$(D)sysvcleanup.pl all ; \ $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) -Xmx1G \ diff --git a/test/functional/cmdLineTests/reflectCache/src_15/test/reflectCache/Test_ReflectCache.java b/test/functional/cmdLineTests/reflectCache/src_15/test/reflectCache/Test_ReflectCache.java index 5a6963d716d..700d7fe14b6 100644 --- a/test/functional/cmdLineTests/reflectCache/src_15/test/reflectCache/Test_ReflectCache.java +++ b/test/functional/cmdLineTests/reflectCache/src_15/test/reflectCache/Test_ReflectCache.java @@ -49,10 +49,10 @@ public static void main(String[] args) { try { Field testField1 = testClass.getField("testField"); long fieldRootOffset = unsafe.objectFieldOffset(Field.class, "root"); - Object rootObject1 = unsafe.getObject(testField1, fieldRootOffset); + Object rootObject1 = unsafe.getReference(testField1, fieldRootOffset); Field testField2 = testClass.getField("testField"); - Object rootObject2 = unsafe.getObject(testField2, fieldRootOffset); + Object rootObject2 = unsafe.getReference(testField2, fieldRootOffset); if (rootObject1 != rootObject2) { System.out.println("TEST FAILED"); @@ -67,10 +67,10 @@ public static void main(String[] args) { Method testMethod1 = testClass.getMethod("testMethod", String.class); long methodRootOffset = unsafe.objectFieldOffset(Method.class, "root"); - rootObject1 = unsafe.getObject(testMethod1, methodRootOffset); + rootObject1 = unsafe.getReference(testMethod1, methodRootOffset); Method testMethod2 = testClass.getMethod("testMethod", String.class); - rootObject2 = unsafe.getObject(testMethod2, methodRootOffset); + rootObject2 = unsafe.getReference(testMethod2, methodRootOffset); if (rootObject1 != rootObject2) { System.out.println("TEST FAILED"); @@ -85,10 +85,10 @@ public static void main(String[] args) { Constructor testConstructor1 = testClass.getConstructor(); long constructorRootOffset = unsafe.objectFieldOffset(Constructor.class, "root"); - rootObject1 = unsafe.getObject(testConstructor1, constructorRootOffset); + rootObject1 = unsafe.getReference(testConstructor1, constructorRootOffset); Constructor testConstructor2 = testClass.getConstructor(); - rootObject2 = unsafe.getObject(testConstructor2, constructorRootOffset); + rootObject2 = unsafe.getReference(testConstructor2, constructorRootOffset); if (rootObject1 != rootObject2) { System.out.println("TEST FAILED"); @@ -102,9 +102,9 @@ public static void main(String[] args) { } Constructor testConstructorA = testClass.getConstructor(String.class); - rootObject1 = unsafe.getObject(testConstructorA, constructorRootOffset); + rootObject1 = unsafe.getReference(testConstructorA, constructorRootOffset); Constructor testConstructorB = testClass.getConstructor(String.class); - rootObject2 = unsafe.getObject(testConstructorB, constructorRootOffset); + rootObject2 = unsafe.getReference(testConstructorB, constructorRootOffset); if (rootObject1 != rootObject2) { System.out.println("TEST FAILED"); return; diff --git a/test/functional/cmdLineTests/shareClassTests/DataHelperTests/playlist.xml b/test/functional/cmdLineTests/shareClassTests/DataHelperTests/playlist.xml index d045fee41f4..935f04d165a 100644 --- a/test/functional/cmdLineTests/shareClassTests/DataHelperTests/playlist.xml +++ b/test/functional/cmdLineTests/shareClassTests/DataHelperTests/playlist.xml @@ -28,6 +28,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)DataHelperTests.jar$(Q) .; \ $(Q)$(TEST_JDK_HOME)$(D)bin$(D)jar$(EXECUTABLE_SUFFIX)$(Q) xf DataHelperTests.jar; \ diff --git a/test/functional/cmdLineTests/shareClassTests/ListAllCachesTests/playlist.xml b/test/functional/cmdLineTests/shareClassTests/ListAllCachesTests/playlist.xml index 67d41354d10..ac1f17615ed 100644 --- a/test/functional/cmdLineTests/shareClassTests/ListAllCachesTests/playlist.xml +++ b/test/functional/cmdLineTests/shareClassTests/ListAllCachesTests/playlist.xml @@ -27,6 +27,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)ShareClassesCMLTests.jar$(Q) .; \ $(Q)$(TEST_JDK_HOME)$(D)bin$(D)jar$(EXECUTABLE_SUFFIX)$(Q) xf ShareClassesCMLTests.jar; \ @@ -55,6 +57,8 @@ testSCCMLExpireAndListALLCaches Mode110 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)ShareClassesCMLTests.jar$(Q) $(REPORTDIR); \ $(Q)$(TEST_JDK_HOME)$(D)bin$(D)jar$(EXECUTABLE_SUFFIX)$(Q) xf ShareClassesCMLTests.jar; \ diff --git a/test/functional/cmdLineTests/shareClassTests/SCCMLTests/playlist.xml b/test/functional/cmdLineTests/shareClassTests/SCCMLTests/playlist.xml index 29775108503..37e627e57b6 100644 --- a/test/functional/cmdLineTests/shareClassTests/SCCMLTests/playlist.xml +++ b/test/functional/cmdLineTests/shareClassTests/SCCMLTests/playlist.xml @@ -27,6 +27,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -59,6 +61,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -91,6 +95,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -120,9 +126,23 @@ testSCCMLTests3 + + + https://github.com/eclipse-openj9/openj9/issues/12114 + Mode501 + .*zos.* + + + https://github.com/eclipse-openj9/openj9/issues/12114 + Mode110 + .*zos.* + + Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -170,6 +190,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -203,6 +225,8 @@ Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)URLHelperTests$(D)URLHelperTests.jar$(Q) .; \ true URLHelperTests.jar ;\ @@ -233,9 +257,26 @@ testSCCMLTests6 + + + https://github.com/eclipse-openj9/openj9/issues/12114 + Mode110 + .*zos.* + + + https://github.com/eclipse-openj9/openj9/issues/22710 + Mode501 + + + https://github.com/eclipse-openj9/openj9/issues/22710 + Mode551 + + Mode110 Mode610 + Mode501 + Mode551 $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) \ -DPATHSEP=$(Q)$(D)$(Q) -DCPDL=$(Q)$(P)$(Q) -DRUN_SCRIPT=$(RUN_SCRIPT) -DPROPS_DIR=$(PROPS_DIR) -DSCRIPT_SUFFIX=$(SCRIPT_SUFFIX) -DEXECUTABLE_SUFFIX=$(EXECUTABLE_SUFFIX) \ @@ -266,6 +307,8 @@ Mode110 Mode610 + Mode501 + Mode551 $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) \ -DPATHSEP=$(Q)$(D)$(Q) -DCPDL=$(Q)$(P)$(Q) -DRUN_SCRIPT=$(RUN_SCRIPT) -DPROPS_DIR=$(PROPS_DIR) -DSCRIPT_SUFFIX=$(SCRIPT_SUFFIX) -DEXECUTABLE_SUFFIX=$(EXECUTABLE_SUFFIX) \ @@ -292,9 +335,23 @@ testSCCMLSoftmx + + + https://github.com/eclipse-openj9/openj9/issues/12114 + Mode110 + .*zos.* + + + https://github.com/eclipse-openj9/openj9/issues/12114 + Mode501 + .*zos.* + + Mode110 Mode610 + Mode501 + Mode551 cp $(Q)$(TEST_RESROOT)$(D)..$(D)..$(D)..$(D)cmdline_options_testresources$(D)cmdlinetestresources.jar$(Q) .; \ true URLHelperTests.jar ;\ diff --git a/test/functional/cmdLineTests/valuetypeddrtests/flattened32bitRefBackfillTest.xml b/test/functional/cmdLineTests/valuetypeddrtests/flattened32bitRefBackfillTest.xml index fb2e84f99c1..9dd3f068007 100644 --- a/test/functional/cmdLineTests/valuetypeddrtests/flattened32bitRefBackfillTest.xml +++ b/test/functional/cmdLineTests/valuetypeddrtests/flattened32bitRefBackfillTest.xml @@ -80,7 +80,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex [9] = !fj9object 0x [10] = !fj9object 0x [11] = !fj9object 0x - [12] = !fj9object 0x + + Problem running command @@ -392,7 +393,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Problem running command - + + @@ -467,7 +469,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Problem running command - + + @@ -558,7 +561,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Problem running command - + + @@ -656,7 +660,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Problem running command - + + @@ -682,7 +687,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex Problem running command - + + diff --git a/test/functional/cmdLineTests/valuetypeddrtests/flattenedvaluetypeddrtests.xml b/test/functional/cmdLineTests/valuetypeddrtests/flattenedvaluetypeddrtests.xml index 1922661bd21..4a8ded1055d 100644 --- a/test/functional/cmdLineTests/valuetypeddrtests/flattenedvaluetypeddrtests.xml +++ b/test/functional/cmdLineTests/valuetypeddrtests/flattenedvaluetypeddrtests.xml @@ -150,7 +150,9 @@ I i = 0x45456767 Problem running command - + + + $EXE$ -Xmx24m $ARGS_NOCR$ $JARS$ $PROGRAM$ diff --git a/test/functional/cmdLineTests/xlpCMLTests/playlist.xml b/test/functional/cmdLineTests/xlpCMLTests/playlist.xml index 816ef41c767..39c492f94f5 100644 --- a/test/functional/cmdLineTests/xlpCMLTests/playlist.xml +++ b/test/functional/cmdLineTests/xlpCMLTests/playlist.xml @@ -26,6 +26,9 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex xlpCMLTests Mode109 + Mode500 + Mode501 + Mode551 $(JAVA_COMMAND) $(CMDLINETESTER_JVM_OPTIONS) \ -DEXE=$(SQ)$(JAVA_COMMAND) $(JVM_OPTIONS) $(SQ) \