Skip to content

Commit 88633d9

Browse files
committed
8308452: Extend internal Architecture enum with byte order and address size
8310982: jdk/internal/util/ArchTest.java fails after JDK-8308452 failed with Method isARM() Backport-of: d6dd0dc3e06d42f108fe80920e1102d47a5aa583
1 parent 0294541 commit 88633d9

File tree

5 files changed

+145
-70
lines changed

5 files changed

+145
-70
lines changed

make/modules/java.base/gensrc/GensrcMisc.gmk

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ $(eval $(call SetupTextFileProcessing, BUILD_VERSION_JAVA, \
5252

5353

5454
# Normalize OPENJDK_TARGET_CPU name to match jdk.internal.util.Architecture enum
55-
ifneq ($(filter $(OPENJDK_TARGET_CPU), ppc64le), )
56-
OPENJDK_TARGET_ARCH_CANONICAL = ppc64
57-
else ifneq ($(filter $(OPENJDK_TARGET_CPU), s390x), )
55+
ifneq ($(filter $(OPENJDK_TARGET_CPU), s390x), )
5856
OPENJDK_TARGET_ARCH_CANONICAL = s390
5957
else ifneq ($(filter $(OPENJDK_TARGET_CPU), x86_64 amd64), )
6058
OPENJDK_TARGET_ARCH_CANONICAL = x64

src/java.base/share/classes/jdk/internal/util/Architecture.java

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
package jdk.internal.util;
2626

2727
import jdk.internal.vm.annotation.ForceInline;
28+
29+
import java.nio.ByteOrder;
2830
import java.util.Locale;
2931

3032
/**
@@ -35,19 +37,81 @@
3537
* architecture values.
3638
*/
3739
public enum Architecture {
38-
OTHER, // An unknown architecture not specifically named
39-
X64, // Represents AMD64 and X86_64
40-
X86,
41-
AARCH64,
42-
ARM,
43-
RISCV64,
44-
LOONGARCH64,
45-
S390,
46-
PPC64,
47-
MIPSEL,
48-
MIPS64EL
40+
/*
41+
* An unknown architecture not specifically named.
42+
* The addrSize and ByteOrder values are those of the current architecture.
43+
*/
44+
OTHER(is64bit() ? 64 : 32, ByteOrder.nativeOrder()),
45+
X64(64, ByteOrder.LITTLE_ENDIAN), // Represents AMD64 and X86_64
46+
X86(32, ByteOrder.LITTLE_ENDIAN),
47+
AARCH64(64, ByteOrder.LITTLE_ENDIAN),
48+
ARM(32, ByteOrder.LITTLE_ENDIAN),
49+
RISCV64(64, ByteOrder.LITTLE_ENDIAN),
50+
LOONGARCH64(64, ByteOrder.LITTLE_ENDIAN),
51+
S390(64, ByteOrder.BIG_ENDIAN),
52+
PPC64(64, ByteOrder.BIG_ENDIAN),
53+
PPC64LE(64, ByteOrder.LITTLE_ENDIAN),
54+
MIPSEL(32, ByteOrder.LITTLE_ENDIAN),
55+
MIPS64EL(64, ByteOrder.LITTLE_ENDIAN)
4956
;
5057

58+
private final int addrSize;
59+
private final ByteOrder byteOrder;
60+
61+
/**
62+
* Construct an Architecture with number of address bits and byte order.
63+
* @param addrSize number of address bits, typically 64 or 32
64+
* @param byteOrder the byte order, big-endian or little-endian
65+
*/
66+
Architecture(int addrSize, ByteOrder byteOrder) {
67+
this.addrSize = addrSize;
68+
this.byteOrder = byteOrder;
69+
}
70+
71+
/**
72+
* {@return the number of address bits, typically 64 or 32}
73+
*/
74+
public int addressSize() {
75+
return addrSize;
76+
}
77+
78+
/**
79+
* {@return the byte order, {@link ByteOrder#BIG_ENDIAN} or {@link ByteOrder#LITTLE_ENDIAN}}
80+
*/
81+
public ByteOrder byteOrder() {
82+
return byteOrder;
83+
}
84+
85+
/**
86+
* {@return the Architecture by name or an alias for the architecture}
87+
* The names are mapped to upper case before mapping to an Architecture.
88+
* @param archName an Architecture name or alias for the architecture.
89+
* @throws IllegalArgumentException if the name is not an alias or an Architecture name
90+
*/
91+
public static Architecture lookupByName(String archName) {
92+
archName = archName.toUpperCase(Locale.ROOT); // normalize to uppercase
93+
return switch (archName) {
94+
case "X86_64", "AMD64" -> X64;
95+
case "I386" -> X86;
96+
case "S390X" -> S390;
97+
default -> Architecture.valueOf(archName);
98+
};
99+
}
100+
101+
/**
102+
* Returns the Architecture of the built architecture.
103+
* Build time names are mapped to respective uppercase enum values.
104+
* Names not recognized are mapped to Architecture.OTHER.
105+
*/
106+
private static Architecture initArch(String archName) {
107+
try {
108+
return lookupByName(archName);
109+
} catch (IllegalArgumentException ile) {
110+
return Architecture.OTHER;
111+
}
112+
}
113+
114+
// Initialize the architecture by mapping aliases and names to the enum values.
51115
private static Architecture CURRENT_ARCH = initArch(PlatformProps.CURRENT_ARCH_STRING);
52116

53117
/**
@@ -91,14 +155,21 @@ public static boolean isS390() {
91155
}
92156

93157
/**
94-
* {@return {@code true} if the current architecture is PPC64}
95-
* Use {@link #isLittleEndian()} to determine big or little endian.
158+
* {@return {@code true} if the current architecture is PPC64, big-endian}
96159
*/
97160
@ForceInline
98161
public static boolean isPPC64() {
99162
return PlatformProps.TARGET_ARCH_IS_PPC64;
100163
}
101164

165+
/**
166+
* {@return {@code true} if the current architecture is PPC64, little-endian}
167+
*/
168+
@ForceInline
169+
public static boolean isPPC64LE() {
170+
return PlatformProps.TARGET_ARCH_IS_PPC64LE;
171+
}
172+
102173
/**
103174
* {@return {@code true} if the current architecture is ARM}
104175
*/
@@ -153,18 +224,4 @@ public static boolean is64bit() {
153224
public static boolean isLittleEndian() {
154225
return PlatformProps.TARGET_ARCH_LITTLE_ENDIAN;
155226
}
156-
157-
158-
/**
159-
* Returns the Architecture of the built architecture.
160-
* Build time names are mapped to respective uppercase enum values.
161-
* Names not recognized are mapped to Architecture.OTHER.
162-
*/
163-
private static Architecture initArch(String archName) {
164-
try {
165-
return Architecture.valueOf(archName.toUpperCase(Locale.ROOT));
166-
} catch (IllegalArgumentException ile) {
167-
return Architecture.OTHER;
168-
}
169-
}
170227
}

src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class PlatformProps {
6060
static final boolean TARGET_ARCH_IS_LOONGARCH64 = "@@OPENJDK_TARGET_CPU@@" == "loongarch64";
6161
static final boolean TARGET_ARCH_IS_S390 = "@@OPENJDK_TARGET_CPU@@" == "s390";
6262
static final boolean TARGET_ARCH_IS_PPC64 = "@@OPENJDK_TARGET_CPU@@" == "ppc64";
63+
static final boolean TARGET_ARCH_IS_PPC64LE = "@@OPENJDK_TARGET_CPU@@" == "ppc64le";
6364
static final boolean TARGET_ARCH_IS_MIPSEL = "@@OPENJDK_TARGET_CPU@@" == "mipsel";
6465
static final boolean TARGET_ARCH_IS_MIPS64EL= "@@OPENJDK_TARGET_CPU@@" == "mips64el";
6566
}

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public static Platform parsePlatform(String platformString) {
5252
archName = platformString.substring(index + 1);
5353
// Alias architecture names, if needed
5454
archName = archName.replace("amd64", "X64");
55-
archName = archName.replace("ppc64le", "PPC64");
5655
archName = archName.replace("s390x", "S390");
5756
Architecture arch = Architecture.valueOf(archName.toUpperCase(Locale.ROOT));
5857

test/jdk/jdk/internal/util/ArchTest.java

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
* or visit www.oracle.com if you need additional information or have any
2121
* questions.
2222
*/
23+
import java.nio.ByteOrder;
24+
import java.util.List;
2325
import java.util.Locale;
2426
import java.util.stream.Stream;
2527

2628
import jdk.internal.util.Architecture;
2729
import jdk.internal.misc.Unsafe;
2830

29-
import static jdk.internal.util.Architecture.OTHER;
3031
import static jdk.internal.util.Architecture.AARCH64;
3132
import static jdk.internal.util.Architecture.ARM;
3233
import static jdk.internal.util.Architecture.PPC64;
34+
import static jdk.internal.util.Architecture.PPC64LE;
3335
import static jdk.internal.util.Architecture.RISCV64;
3436
import static jdk.internal.util.Architecture.LOONGARCH64;
3537
import static jdk.internal.util.Architecture.S390;
@@ -44,67 +46,85 @@
4446
import org.junit.jupiter.params.provider.MethodSource;
4547

4648
import static org.junit.jupiter.api.Assertions.assertEquals;
47-
import static org.junit.jupiter.api.Assertions.fail;
4849

4950
/**
5051
* @test
51-
* @bug 8304915
52+
* @bug 8304915 8308452 8310982
5253
* @summary Verify Architecture enum maps to system property os.arch
5354
* @modules java.base/jdk.internal.util
5455
* @modules java.base/jdk.internal.misc
5556
* @run junit ArchTest
5657
*/
5758
public class ArchTest {
58-
private static boolean IS_BIG_ENDIAN = Unsafe.getUnsafe().isBigEndian();
59+
private static final boolean IS_BIG_ENDIAN = Unsafe.getUnsafe().isBigEndian();
60+
61+
private static final boolean IS_64BIT_ADDRESS = Unsafe.getUnsafe().addressSize() == 8;
62+
63+
/**
64+
* Test data for Architecture name vs Arch enums, address bits, endian-ness and boolean isXXX() methods..
65+
* Each Argument contains:
66+
* - the common os.arch name,
67+
* - the Architecture Enum,
68+
* - address bits 32/64,
69+
* - the byte-order (little or big),
70+
* - the result of invoking the architecture specific static method
71+
* @return a stream of arguments for parameterized tests
72+
*/
73+
private static Stream<Arguments> archParams() {
74+
// In alphabetical order
75+
return Stream.of(
76+
Arguments.of("aarch64", AARCH64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isAARCH64()),
77+
Arguments.of("amd64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()),
78+
Arguments.of("arm", ARM, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isARM()),
79+
Arguments.of("i386", X86, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX86()),
80+
Arguments.of("loongarch64", LOONGARCH64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isLOONGARCH64()),
81+
Arguments.of("mips64el", MIPS64EL, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isMIPS64EL()),
82+
Arguments.of("mipsel", MIPSEL, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isMIPSEL()),
83+
Arguments.of("ppc64", PPC64, 64, ByteOrder.BIG_ENDIAN, Architecture.isPPC64()),
84+
Arguments.of("ppc64le", PPC64LE, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isPPC64LE()),
85+
Arguments.of("riscv64", RISCV64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isRISCV64()),
86+
Arguments.of("s390", S390, 64, ByteOrder.BIG_ENDIAN, Architecture.isS390()),
87+
Arguments.of("s390x", S390, 64, ByteOrder.BIG_ENDIAN, Architecture.isS390()),
88+
Arguments.of("x64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64()),
89+
Arguments.of("x86", X86, 32, ByteOrder.LITTLE_ENDIAN, Architecture.isX86()),
90+
Arguments.of("x86_64", X64, 64, ByteOrder.LITTLE_ENDIAN, Architecture.isX64())
91+
);
92+
}
5993

60-
private static boolean IS_64BIT_ADDRESS = Unsafe.getUnsafe().addressSize() == 8;
6194

6295
/**
6396
* Test consistency of System property "os.arch" with Architecture.current().
6497
*/
6598
@Test
6699
public void nameVsCurrent() {
67100
String osArch = System.getProperty("os.arch").toLowerCase(Locale.ROOT);
68-
System.out.printf("System property os.arch: \"%s\", Architecture.current(): \"%s\"%n",
101+
System.err.printf("System property os.arch: \"%s\", Architecture.current(): \"%s\"%n",
69102
osArch, Architecture.current());
70-
Architecture arch = switch (osArch) {
71-
case "x86_64", "amd64" -> X64;
72-
case "x86", "i386" -> X86;
73-
case "aarch64" -> AARCH64;
74-
case "arm" -> ARM;
75-
case "riscv64" -> RISCV64;
76-
case "loongarch64" -> LOONGARCH64;
77-
case "s390x", "s390" -> S390;
78-
case "ppc64", "ppc64le" -> PPC64;
79-
case "mipsel" -> MIPSEL;
80-
case "mips64el" -> MIPS64EL;
81-
default -> OTHER;
82-
};
83-
assertEquals(Architecture.current(), arch, "mismatch in Architecture.current vs " + osArch);
84-
}
85103

86-
/**
87-
* Test various Architecture enum values vs boolean isXXX() methods.
88-
* @return a stream of arguments for parameterized test
89-
*/
90-
private static Stream<Arguments> archParams() {
91-
return Stream.of(
92-
Arguments.of(X64, Architecture.isX64()),
93-
Arguments.of(X86, Architecture.isX86()),
94-
Arguments.of(AARCH64, Architecture.isAARCH64()),
95-
Arguments.of(ARM, Architecture.isARM()),
96-
Arguments.of(RISCV64, Architecture.isRISCV64()),
97-
Arguments.of(LOONGARCH64, Architecture.isLOONGARCH64()),
98-
Arguments.of(S390, Architecture.isS390()),
99-
Arguments.of(MIPSEL, Architecture.isMIPSEL()),
100-
Arguments.of(MIPS64EL, Architecture.isMIPS64EL()),
101-
Arguments.of(PPC64, Architecture.isPPC64())
102-
);
104+
// Map os.arch system property to expected Architecture
105+
List<Architecture> argList = archParams()
106+
.filter(p -> p.get()[0].equals(osArch))
107+
.map(a -> (Architecture)a.get()[1])
108+
.toList();
109+
assertEquals(1, argList.size(), osArch + " too few or too many matching system property os.arch cases: " + argList);
110+
assertEquals(Architecture.current(), argList.get(0), "mismatch in Architecture.current vs " + osArch);
103111
}
104112

105113
@ParameterizedTest
106114
@MethodSource("archParams")
107-
public void isArch(Architecture arch, boolean isArch) {
115+
public void checkParams(String archName, Architecture arch, int addrSize, ByteOrder byteOrder, boolean isArch) {
116+
Architecture actual = Architecture.lookupByName(archName);
117+
assertEquals(actual, arch, "Wrong Architecture from lookupByName");
118+
119+
actual = Architecture.lookupByName(archName.toUpperCase(Locale.ROOT));
120+
assertEquals(actual, arch, "Wrong Architecture from lookupByName (upper-case)");
121+
122+
actual = Architecture.lookupByName(archName.toLowerCase(Locale.ROOT));
123+
assertEquals(actual, arch, "Wrong Architecture from lookupByName (lower-case)");
124+
125+
assertEquals(addrSize, actual.addressSize(), "Wrong address size");
126+
assertEquals(byteOrder, actual.byteOrder(), "Wrong byteOrder");
127+
108128
Architecture current = Architecture.current();
109129
assertEquals(arch == current, isArch,
110130
"Method is" + arch + "(): returned " + isArch + ", should be (" + arch + " == " + current + ")");

0 commit comments

Comments
 (0)