Skip to content

Commit

Permalink
(Valhalla) Merge master HEAD into openj9-staging
Browse files Browse the repository at this point in the history
Conflicts:
	src/java.base/share/classes/java/lang/classfile/ClassElement.java
	test/jdk/tools/sincechecker/modules/java.base/JavaBaseCheckSince.java

Signed-off-by: Jason Feng <fengj@ca.ibm.com>
  • Loading branch information
JasonFengJ9 committed Dec 6, 2024
2 parents efd3e0e + a3a3004 commit a8056f4
Showing 12 changed files with 106 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/java.base/share/classes/java/lang/reflect/AccessFlag.java
Original file line number Diff line number Diff line change
@@ -574,6 +574,8 @@ public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
* @param cffv the class file format version
* @throws IllegalArgumentException if the mask contains bit
* positions not supported for the location in question
*
* @since Valhalla
*/
public static Set<AccessFlag> maskToAccessFlags(int mask, Location location,
ClassFileFormatVersion cffv) {
1 change: 1 addition & 0 deletions src/java.base/share/classes/java/util/Objects.java
Original file line number Diff line number Diff line change
@@ -185,6 +185,7 @@ public static String toIdentityString(Object o) {
*
* @param obj an object
* @throws NullPointerException if {@code obj} is {@code null}
* @since Valhalla
*/
@PreviewFeature(feature = PreviewFeature.Feature.VALUE_OBJECTS)
// @IntrinsicCandidate
5 changes: 5 additions & 0 deletions src/java.base/share/classes/java/util/WeakHashMap.java
Original file line number Diff line number Diff line change
@@ -250,6 +250,7 @@ public WeakHashMap(int initialCapacity, float loadFactor) {
* @throws IllegalArgumentException if the initial capacity is negative,
* or if the load factor is nonpositive.
* @throws NullPointerException if {@code valuePolicy} is null
* @since Valhalla
*/
public WeakHashMap(int initialCapacity, float loadFactor, ValuePolicy valuePolicy) {
if (initialCapacity < 0)
@@ -301,6 +302,8 @@ public WeakHashMap() {
*
* @param valuePolicy The {@link ValuePolicy} for keys that are value objects; non-null
* @throws NullPointerException if {@code valuePolicy} is null
*
* @since Valhalla
*/
public WeakHashMap(ValuePolicy valuePolicy) {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, valuePolicy);
@@ -328,6 +331,8 @@ public WeakHashMap(Map<? extends K, ? extends V> m) {

/**
* {@return the {@link ValuePolicy} for this WeakHashMap.}
*
* @since Valhalla
*/
public ValuePolicy valuePolicy() {
return valuePolicy;
Original file line number Diff line number Diff line change
@@ -403,6 +403,10 @@ public boolean isStatic() {
name != name.table.names._this;
}

public boolean isStrict() {
return (flags() & STRICT) != 0;
}

public boolean isInterface() {
return (flags_field & INTERFACE) != 0;
}
38 changes: 33 additions & 5 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
Original file line number Diff line number Diff line change
@@ -481,8 +481,18 @@ protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
}
}

// Do something with all static or non-static field initializers and initialization blocks.
// Do something with static or non-static field initializers and initialization blocks.
protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, Consumer<? super JCTree> handler) {
forEachInitializer(classDef, isStatic, false, handler);
}

/* Do something with static or non-static field initializers and initialization blocks.
* the `earlyOnly` argument will determine if we will deal or not with early variable instance
* initializers we want to process only those before a super() invocation and ignore them after
* it.
*/
protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, boolean earlyOnly,
Consumer<? super JCTree> handler) {
if (classDef == initScanClass) // avoid infinite loops
return;
JCClassDecl initScanClassPrev = initScanClass;
@@ -500,8 +510,18 @@ protected void forEachInitializer(JCClassDecl classDef, boolean isStatic, Consum
* code
*/
boolean isDefStatic = ((TreeInfo.flags(def) | (TreeInfo.symbolFor(def) == null ? 0 : TreeInfo.symbolFor(def).flags_field)) & STATIC) != 0;
if (!def.hasTag(METHODDEF) && (isDefStatic == isStatic))
handler.accept(def);
if (!def.hasTag(METHODDEF) && (isDefStatic == isStatic)) {
if (def instanceof JCVariableDecl varDecl) {
boolean isEarly = varDecl.init != null &&
varDecl.sym.owner.isValueClass() &&
!varDecl.sym.isStatic();
if (isEarly == earlyOnly) {
handler.accept(def);
}
} else if (!earlyOnly) {
handler.accept(def);
}
}
}
} finally {
initScanClass = initScanClassPrev;
@@ -2298,7 +2318,7 @@ void checkInit(DiagnosticPosition pos, VarSymbol sym, Error errkey) {
trackable(sym) &&
!inits.isMember(sym.adr) &&
(sym.flags_field & CLASH) == 0) {
log.error(pos, errkey);
log.error(pos, errkey);
inits.incl(sym.adr);
}
}
@@ -3032,14 +3052,22 @@ public void visitThrow(JCThrow tree) {
}

public void visitApply(JCMethodInvocation tree) {
Name name = TreeInfo.name(tree.meth);
// let's process early initializers
if (name == names._super) {
forEachInitializer(classDef, false, true, def -> {
scan(def);
clearPendingExits(false);
});
}
scanExpr(tree.meth);
scanExprs(tree.args);

// Handle superclass constructor invocations
if (isConstructor) {

// If super(): at this point all initialization blocks will execute
Name name = TreeInfo.name(tree.meth);

if (name == names._super) {
forEachInitializer(classDef, false, def -> {
scan(def);
12 changes: 6 additions & 6 deletions src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java
Original file line number Diff line number Diff line change
@@ -450,7 +450,7 @@ protected void writeField(FieldModel f) {

if (options.verbose)
writeList(String.format("flags: (0x%04x) ", flags.flagsMask()),
flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.toString()).toList(),
flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.name()).toList(),
"\n");

if (options.showAllAttrs) {
@@ -817,16 +817,16 @@ private Set<String> getClassModifiers(AccessFlags flags) {
return getModifiers(set);
}

private static Set<String> getClassModifiers(AccessFlags flags, int majorVersion, int minorVersion) {
private Set<String> getClassModifiers(AccessFlags flags, int majorVersion, int minorVersion) {
boolean previewClassFile = minorVersion == ClassFile.PREVIEW_MINOR_VERSION;
Set<AccessFlag> flagSet = flags.flags();
Set<AccessFlag> flagSet = flagsReportUnknown(flags);
if (flagSet.contains(AccessFlag.INTERFACE)) {
flagSet = EnumSet.copyOf(flagSet);
flagSet.remove(AccessFlag.ABSTRACT);
} else if (Source.isSupported(Source.Feature.VALUE_CLASSES, majorVersion) && previewClassFile) {
Set<String> classModifers = getModifiers(flagSet);
classModifers.add("value");
return classModifers;
Set<String> classModifers = getModifiers(flagSet);
classModifers.add("value");
return classModifers;
}
return getModifiers(flagSet);
}
1 change: 0 additions & 1 deletion test/jdk/ProblemList.txt
Original file line number Diff line number Diff line change
@@ -840,4 +840,3 @@ java/awt/dnd/WinMoveFileToShellTest.java 8341665 windows-all

# valhalla
jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java 8328777 generic-all
jdk/tools/sincechecker/modules/java_base/CheckSince_javaBase.java 8344541 generic-all
22 changes: 20 additions & 2 deletions test/jdk/tools/sincechecker/SinceChecker.java
Original file line number Diff line number Diff line change
@@ -101,8 +101,12 @@ of its enclosing class or interface, whether direct or inherited
it is somewhat inspired from the VM Method Descriptors. But we use the erased return so that methods
that were later generified remain the same.
To help projects still in development, unsure of actual `@since` tag value, one may want to use token name instead of continuely
updating the current version since tags. For example, `@since LongRunningProjectName`. The option `--ignoreSince` maybe used to
ignore these tags (`--ignoreSince LongRunningProjectName`). Maybe be specified multiple times.
usage: the checker is run from a module specific test
`@run main SinceChecker <moduleName> [--exclude package1,package2 | --exclude package1 package2]`
`@run main SinceChecker <moduleName> [--ignoreSince <string>] [--exclude package1,package2 | --exclude package1 package2]`
*/

public class SinceChecker {
@@ -111,6 +115,11 @@ public class SinceChecker {
private final JavaCompiler tool;
private int errorCount = 0;

// Ignored since tags
private static final Set<String> IGNORE_SINCE = new HashSet<>();
// Simply replace ignored since tags with the latest version
private static final Version IGNORE_VERSION = Version.parse(Integer.toString(Runtime.version().major()));

// packages to skip during the test
private static final Set<String> EXCLUDE_LIST = new HashSet<>();

@@ -127,7 +136,11 @@ public static void main(String[] args) throws Exception {
boolean excludeFlag = false;

for (int i = 1; i < args.length; i++) {
if ("--exclude".equals(args[i])) {
if ("--ignoreSince".equals(args[i])) {
i++;
IGNORE_SINCE.add("@since " + args[i]);
}
else if ("--exclude".equals(args[i])) {
excludeFlag = true;
continue;
}
@@ -452,6 +465,11 @@ private void checkElement(Element explicitOwner, Element element, Types types,
}

private Version extractSinceVersionFromText(String documentation) {
for (String ignoreSince : IGNORE_SINCE) {
if (documentation.contains(ignoreSince)) {
return IGNORE_VERSION;
}
}
Pattern pattern = Pattern.compile("@since\\s+(\\d+(?:\\.\\d+)?)");
Matcher matcher = pattern.matcher(documentation);
if (matcher.find()) {
1 change: 0 additions & 1 deletion test/langtools/ProblemList.txt
Original file line number Diff line number Diff line change
@@ -69,7 +69,6 @@ tools/javac/modules/SourceInSymlinkTest.java
# javap

tools/javap/output/RepeatingTypeAnnotations.java 8057687 generic-all emit correct byte code an attributes for type annotations
tools/javap/UndefinedAccessFlagTest.java 8342036 generic-all
###########################################################################
#
# jdeps
Original file line number Diff line number Diff line change
@@ -1003,6 +1003,15 @@ value class V {
}
"""
);
assertOK(
"""
value class V {
String s1;
{ System.out.println(s1); }
String s2 = (s1 = "abc");
}
"""
);
}

@Test
Original file line number Diff line number Diff line change
@@ -273,5 +273,30 @@ public static void main(String... args) {
true,
IncompatibleClassChangeError.class
);
/* Removing the value modifier from a non-abstract value class does not break compatibility with
* pre-existing binaries.
*/
testCompatibilityAfterChange(
base,
"""
package pkg;
public value class A {}
""",
"""
package pkg;
public class A {}
""",
"""
package pkg;
public class Client {
public static void main(String... args) {
A a = new A();
System.out.println("Hello World!");
}
}
""",
false,
null
);
}
}
2 changes: 1 addition & 1 deletion test/langtools/tools/javap/UndefinedAccessFlagTest.java
Original file line number Diff line number Diff line change
@@ -92,7 +92,7 @@ void test(TestLocation location) throws Throwable {
});
case InnerClassesAttribute attr when location == TestLocation.INNER_CLASS -> cb
.with(InnerClassesAttribute.of(attr.classes().stream()
.map(ic -> InnerClassInfo.of(ic.innerClass(), ic.outerClass(), ic.innerName(), ic.flagsMask() | 0x0020))
.map(ic -> InnerClassInfo.of(ic.innerClass(), ic.outerClass(), ic.innerName(), ic.flagsMask() | 0x0050))
.toList()));
default -> cb.with(ce);
}

0 comments on commit a8056f4

Please sign in to comment.