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 extends RecordType> values)
- {
- for (RecordType r : values) {
- for (Declaration dec : r.getEntries()) {
+ private void fixUpFields(Collection extends RecordType> 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
+
+ $JFR_EXE$ print --xml --events "ClassLoaderStatistics" defaultJ9recording.jfr
+
+
+
+
+
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
+
+
@@ -392,7 +393,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
-
+
+
@@ -467,7 +469,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
-
+
+
@@ -558,7 +561,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
-
+
+
@@ -656,7 +660,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
-
+
+
@@ -682,7 +687,8 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
-
+
+
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 @@
-
+
+
+
$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) \