8334717: Add JVMCI support for APX EGPRs

Reviewed-by: dnsimon
This commit is contained in:
Yudi Zheng 2025-05-21 08:54:19 +00:00
parent a0cdf36bdf
commit 735c7899d1
21 changed files with 227 additions and 517 deletions

View File

@ -24,12 +24,12 @@ package jdk.vm.ci.aarch64;
import java.nio.ByteOrder;
import java.util.EnumSet;
import java.util.List;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CPUFeatureName;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
@ -92,7 +92,7 @@ public class AArch64 extends Architecture {
public static final Register rscratch2 = r9;
// @formatter:off
public static final RegisterArray cpuRegisters = new RegisterArray(
public static final List<Register> cpuRegisters = List.of(
r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
@ -138,7 +138,7 @@ public class AArch64 extends Architecture {
public static final Register v31 = new Register(65, 31, "v31", SIMD);
// @formatter:off
public static final RegisterArray simdRegisters = new RegisterArray(
public static final List<Register> simdRegisters = List.of(
v0, v1, v2, v3, v4, v5, v6, v7,
v8, v9, v10, v11, v12, v13, v14, v15,
v16, v17, v18, v19, v20, v21, v22, v23,
@ -147,7 +147,7 @@ public class AArch64 extends Architecture {
// @formatter:on
// @formatter:off
public static final RegisterArray allRegisters = new RegisterArray(
public static final List<Register> allRegisters = List.of(
r0, r1, r2, r3, r4, r5, r6, r7,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
@ -189,23 +189,9 @@ public class AArch64 extends Architecture {
private final EnumSet<CPUFeature> features;
/**
* Set of flags to control code emission.
*/
public enum Flag {
UseCRC32,
UseSIMDForMemoryOps,
AvoidUnalignedAccesses,
UseLSE,
UseBlockZeroing
}
private final EnumSet<Flag> flags;
public AArch64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
public AArch64(EnumSet<CPUFeature> features) {
super("aarch64", AArch64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, 0, 0, 0);
this.features = features;
this.flags = flags;
}
@Override
@ -213,10 +199,6 @@ public class AArch64 extends Architecture {
return features;
}
public EnumSet<Flag> getFlags() {
return flags;
}
@Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
switch (javaKind) {

View File

@ -29,12 +29,12 @@ import static jdk.vm.ci.code.Register.SPECIAL;
import java.nio.ByteOrder;
import java.util.EnumSet;
import java.util.List;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CPUFeatureName;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
@ -86,10 +86,17 @@ public class AMD64 extends Architecture {
public static final Register r31 = new Register(31, 31, "r31", CPU);
// The set of common CPU registers available on all x64 platforms.
public static final Register[] cpuRegisters = {
public static final List<Register> cpuRegisters = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15
};
);
public static final List<Register> cpuRegistersAPX = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
r24, r25, r26, r27, r28, r29, r30, r31
);
public static final RegisterCategory XMM = new RegisterCategory("XMM");
@ -130,17 +137,17 @@ public class AMD64 extends Architecture {
public static final Register xmm30 = new Register(62, 30, "xmm30", XMM);
public static final Register xmm31 = new Register(63, 31, "xmm31", XMM);
public static final Register[] xmmRegistersSSE = {
public static final List<Register> xmmRegistersSSE = List.of(
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
);
public static final Register[] xmmRegistersAVX512 = {
public static final List<Register> xmmRegistersAVX512 = List.of(
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31
};
);
public static final RegisterCategory MASK = new RegisterCategory("MASK", false);
@ -153,14 +160,14 @@ public class AMD64 extends Architecture {
public static final Register k6 = new Register(70, 6, "k6", MASK);
public static final Register k7 = new Register(71, 7, "k7", MASK);
public static final RegisterArray valueRegistersSSE = new RegisterArray(
public static final List<Register> valueRegistersSSE = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
);
public static final RegisterArray valueRegistersAVX512 = new RegisterArray(
public static final List<Register> valueRegistersAVX512 = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
@ -170,12 +177,33 @@ public class AMD64 extends Architecture {
k0, k1, k2, k3, k4, k5, k6, k7
);
public static final List<Register> valueRegistersSSEAndAPX = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
r24, r25, r26, r27, r28, r29, r30, r31,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
);
public static final List<Register> valueRegistersAVX512AndAPX = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
r24, r25, r26, r27, r28, r29, r30, r31,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
k0, k1, k2, k3, k4, k5, k6, k7
);
/**
* Register used to construct an instruction-relative address.
*/
public static final Register rip = new Register(72, -1, "rip", SPECIAL);
public static final RegisterArray allRegisters = new RegisterArray(
public static final List<Register> allRegisters = List.of(
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
r16, r17, r18, r19, r20, r21, r22, r23,
@ -264,24 +292,13 @@ public class AMD64 extends Architecture {
private final EnumSet<CPUFeature> features;
/**
* Set of flags to control code emission.
*/
public enum Flag {
UseCountLeadingZerosInstruction,
UseCountTrailingZerosInstruction
}
private final EnumSet<Flag> flags;
private final AMD64Kind largestKind;
private final AMD64Kind largestMaskKind;
public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
public AMD64(EnumSet<CPUFeature> features) {
super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8);
this.features = features;
this.flags = flags;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
if (features.contains(CPUFeature.AVX512F)) {
@ -305,13 +322,15 @@ public class AMD64 extends Architecture {
return features;
}
public EnumSet<Flag> getFlags() {
return flags;
}
@Override
public RegisterArray getAvailableValueRegisters() {
if (features.contains(CPUFeature.AVX512F)) {
public List<Register> getAvailableValueRegisters() {
if (features.contains(CPUFeature.APX_F)) {
if (features.contains(CPUFeature.AVX512F)) {
return valueRegistersAVX512AndAPX;
} else {
return valueRegistersSSEAndAPX;
}
} else if (features.contains(CPUFeature.AVX512F)) {
return valueRegistersAVX512;
} else {
return valueRegistersSSE;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
package jdk.vm.ci.code;
import java.nio.ByteOrder;
import java.util.List;
import java.util.Set;
import jdk.vm.ci.code.Register.RegisterCategory;
@ -50,7 +51,7 @@ public abstract class Architecture {
* List of all available registers on this architecture. The index of each register in this list
* is equal to its {@linkplain Register#number number}.
*/
private final RegisterArray registers;
private final List<Register> registers;
/**
* The byte ordering can be either little or big endian.
@ -79,7 +80,7 @@ public abstract class Architecture {
*/
private final int returnAddressSize;
protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, RegisterArray registers, int implicitMemoryBarriers,
protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, List<Register> registers, int implicitMemoryBarriers,
int nativeCallDisplacementOffset,
int returnAddressSize) {
// registers is expected to mention all registers in order of their encoding.
@ -144,7 +145,7 @@ public abstract class Architecture {
* this particular architecture instance. The index of each register in this list is equal to
* its {@linkplain Register#number number}.
*/
public RegisterArray getRegisters() {
public List<Register> getRegisters() {
return registers;
}
@ -152,7 +153,7 @@ public abstract class Architecture {
* Gets a list of all registers available for storing values on this architecture. This may be a
* subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU.
*/
public RegisterArray getAvailableValueRegisters() {
public List<Register> getAvailableValueRegisters() {
return getRegisters();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,8 @@ import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Value;
import java.util.List;
/**
* A calling convention describes the locations in which the arguments for a call are placed and the
* location in which the return value is placed if the call is not void.
@ -49,7 +51,7 @@ public class CallingConvention {
/**
* The ordered locations in which the arguments are placed.
*/
private final AllocatableValue[] argumentLocations;
private final List<AllocatableValue> argumentLocations;
/**
* Creates a description of the registers and stack locations used by a call.
@ -63,7 +65,7 @@ public class CallingConvention {
public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) {
assert argumentLocations != null;
assert returnLocation != null;
this.argumentLocations = argumentLocations;
this.argumentLocations = List.of(argumentLocations);
this.stackSize = stackSize;
this.returnLocation = returnLocation;
assert verify();
@ -80,7 +82,7 @@ public class CallingConvention {
* Gets the location for the {@code index}'th argument.
*/
public AllocatableValue getArgument(int index) {
return argumentLocations[index];
return argumentLocations.get(index);
}
/**
@ -94,18 +96,14 @@ public class CallingConvention {
* Gets the number of locations required for the arguments.
*/
public int getArgumentCount() {
return argumentLocations.length;
return argumentLocations.size();
}
/**
* Gets the locations required for the arguments.
*/
@SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "FB false positive")
public AllocatableValue[] getArguments() {
if (argumentLocations.length == 0) {
return argumentLocations;
}
return argumentLocations.clone();
public List<AllocatableValue> getArguments() {
return argumentLocations;
}
@Override
@ -125,8 +123,8 @@ public class CallingConvention {
}
private boolean verify() {
for (int i = 0; i < argumentLocations.length; i++) {
Value location = argumentLocations[i];
for (int i = 0; i < argumentLocations.size(); i++) {
Value location = argumentLocations.get(i);
assert isStackSlot(location) || isAllocatableValue(location);
}
return true;

View File

@ -1,106 +0,0 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.code;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* An immutable ordered list of registers. Only required because Java lacks immutable arrays.
*/
public final class RegisterArray implements Iterable<Register> {
private final Register[] registers;
private int hash;
public RegisterArray(Register... registers) {
this.registers = registers;
}
public RegisterArray(Collection<Register> registers) {
this.registers = registers.toArray(new Register[registers.size()]);
}
/**
* Gets the number of registers.
*/
public int size() {
return registers.length;
}
/**
* Gets the register at a given index.
*
* @param index the index of the register to retrieve
*/
public Register get(int index) {
return registers[index];
}
public void addTo(Collection<Register> collection) {
collection.addAll(Arrays.asList(registers));
}
/**
* Gets an immutable view of the registers as a list.
*/
public List<Register> asList() {
return Collections.unmodifiableList(Arrays.asList(registers));
}
/**
* Gets a copy of the registers as an array.
*/
public Register[] toArray() {
return registers.clone();
}
@Override
public Iterator<Register> iterator() {
return Arrays.asList(registers).iterator();
}
@Override
public int hashCode() {
if (hash == 0 && registers.length > 0) {
hash = Arrays.hashCode(registers);
}
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof RegisterArray) {
return Arrays.equals(registers, ((RegisterArray) obj).registers);
}
return false;
}
@Override
public String toString() {
return Arrays.toString(registers);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -55,11 +55,11 @@ public class RegisterAttributes {
* @return an array whose length is the max register number in {@code registers} plus 1. An
* element at index i holds the attributes of the register whose number is i.
*/
public static RegisterAttributes[] createMap(RegisterConfig registerConfig, RegisterArray registers) {
public static List<RegisterAttributes> createMap(RegisterConfig registerConfig, List<Register> registers) {
RegisterAttributes[] map = new RegisterAttributes[registers.size()];
List<Register> callerSaveRegisters = registerConfig.getCallerSaveRegisters().asList();
List<Register> calleeSaveRegisters = registerConfig.getCalleeSaveRegisters() == null ? Collections.emptyList() : registerConfig.getCalleeSaveRegisters().asList();
List<Register> allocatableRegisters = registerConfig.getAllocatableRegisters().asList();
List<Register> callerSaveRegisters = registerConfig.getCallerSaveRegisters();
List<Register> calleeSaveRegisters = registerConfig.getCalleeSaveRegisters() == null ? Collections.emptyList() : registerConfig.getCalleeSaveRegisters();
List<Register> allocatableRegisters = registerConfig.getAllocatableRegisters();
for (Register reg : registers) {
if (reg != null) {
RegisterAttributes attr = new RegisterAttributes(callerSaveRegisters.contains(reg), calleeSaveRegisters.contains(reg), allocatableRegisters.contains(reg));
@ -74,7 +74,7 @@ public class RegisterAttributes {
map[i] = NONE;
}
}
return map;
return List.of(map);
}
/**

View File

@ -22,6 +22,7 @@
*/
package jdk.vm.ci.code;
import java.util.List;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
@ -71,28 +72,28 @@ public interface RegisterConfig {
* @return the ordered set of registers that may be used to pass parameters in a call conforming
* to {@code type}
*/
RegisterArray getCallingConventionRegisters(Type type, JavaKind kind);
List<Register> getCallingConventionRegisters(Type type, JavaKind kind);
/**
* Gets the set of all registers that might be used by the register allocator.
*/
RegisterArray getAllocatableRegisters();
List<Register> getAllocatableRegisters();
/**
* Filters a set of registers and returns only those that can be used by the register allocator
* for a value of a particular kind.
*/
RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers);
List<Register> filterAllocatableRegisters(PlatformKind kind, List<Register> registers);
/**
* Gets the registers whose values must be preserved by a method across any call it makes.
*/
RegisterArray getCallerSaveRegisters();
List<Register> getCallerSaveRegisters();
/**
* Gets the registers whose values must be preserved by the callee.
*/
RegisterArray getCalleeSaveRegisters();
List<Register> getCalleeSaveRegisters();
/**
* Returns the storage kind for a callee-save register, which determines how the register is
@ -108,10 +109,10 @@ public interface RegisterConfig {
* Gets a map from register {@linkplain Register#number numbers} to register
* {@linkplain RegisterAttributes attributes} for this register configuration.
*
* @return an array where an element at index i holds the attributes of the register whose
* @return a list where an element at index i holds the attributes of the register whose
* number is i
*/
RegisterAttributes[] getAttributesMap();
List<RegisterAttributes> getAttributesMap();
/**
* Determines if all {@link #getAllocatableRegisters() allocatable} registers are

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -52,33 +52,11 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap());
}
private static EnumSet<AArch64.Flag> computeFlags(AArch64HotSpotVMConfig config) {
EnumSet<AArch64.Flag> flags = EnumSet.noneOf(AArch64.Flag.class);
if (config.useCRC32) {
flags.add(AArch64.Flag.UseCRC32);
}
if (config.useSIMDForMemoryOps) {
flags.add(AArch64.Flag.UseSIMDForMemoryOps);
}
if (config.avoidUnalignedAccesses) {
flags.add(AArch64.Flag.AvoidUnalignedAccesses);
}
if (config.useLSE) {
flags.add(AArch64.Flag.UseLSE);
}
if (config.useBlockZeroing) {
flags.add(AArch64.Flag.UseBlockZeroing);
}
return flags;
}
private static TargetDescription createTarget(AArch64HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = true;
Architecture arch = new AArch64(computeFeatures(config), computeFlags(config));
Architecture arch = new AArch64(computeFeatures(config));
return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
@ -113,9 +91,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
}
@Override
@SuppressWarnings("try")
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) {
assert host == null;
AArch64HotSpotVMConfig config = new AArch64HotSpotVMConfig(runtime.getConfigStore());
TargetDescription target = createTarget(config);
@ -125,24 +101,24 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
ConstantReflectionProvider constantReflection;
HotSpotMetaAccessProvider metaAccess;
StackIntrospection stackIntrospection;
try (InitTimer t = timer("create providers")) {
try (InitTimer rt = timer("create MetaAccess provider")) {
try (InitTimer _ = timer("create providers")) {
try (InitTimer _ = timer("create MetaAccess provider")) {
metaAccess = createMetaAccess(runtime);
}
try (InitTimer rt = timer("create RegisterConfig")) {
try (InitTimer _ = timer("create RegisterConfig")) {
regConfig = createRegisterConfig(config, target);
}
try (InitTimer rt = timer("create CodeCache provider")) {
try (InitTimer _ = timer("create CodeCache provider")) {
codeCache = createCodeCache(runtime, target, regConfig);
}
try (InitTimer rt = timer("create ConstantReflection provider")) {
try (InitTimer _ = timer("create ConstantReflection provider")) {
constantReflection = createConstantReflection(runtime);
}
try (InitTimer rt = timer("create StackIntrospection provider")) {
try (InitTimer _ = timer("create StackIntrospection provider")) {
stackIntrospection = new HotSpotStackIntrospection(runtime);
}
}
try (InitTimer rt = timer("instantiate backend")) {
try (InitTimer _ = timer("instantiate backend")) {
return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,6 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
@ -79,24 +78,24 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
private final TargetDescription target;
private final RegisterArray allocatable;
private final List<Register> allocatable;
/**
* The caller saved registers always include all parameter registers.
*/
private final RegisterArray callerSaved;
private final List<Register> callerSaved;
private final boolean allAllocatableAreCallerSaved;
private final RegisterAttributes[] attributesMap;
private final List<RegisterAttributes> attributesMap;
@Override
public RegisterArray getAllocatableRegisters() {
public List<Register> getAllocatableRegisters() {
return allocatable;
}
@Override
public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) {
public List<Register> filterAllocatableRegisters(PlatformKind kind, List<Register> registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
@ -104,17 +103,17 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
}
return new RegisterArray(list);
return List.copyOf(list);
}
@Override
public RegisterAttributes[] getAttributesMap() {
return attributesMap.clone();
public List<RegisterAttributes> getAttributesMap() {
return attributesMap;
}
private final RegisterArray javaGeneralParameterRegisters = new RegisterArray(r1, r2, r3, r4, r5, r6, r7, r0);
private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(r0, r1, r2, r3, r4, r5, r6, r7);
private final RegisterArray simdParameterRegisters = new RegisterArray(v0, v1, v2, v3, v4, v5, v6, v7);
private final List<Register> javaGeneralParameterRegisters = List.of(r1, r2, r3, r4, r5, r6, r7, r0);
private final List<Register> nativeGeneralParameterRegisters = List.of(r0, r1, r2, r3, r4, r5, r6, r7);
private final List<Register> simdParameterRegisters = List.of(v0, v1, v2, v3, v4, v5, v6, v7);
public static final Register inlineCacheRegister = rscratch2;
@ -133,16 +132,15 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
public static final Register threadRegister = r28;
public static final Register fp = r29;
private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp);
private static final List<Register> reservedRegisters = List.of(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp);
private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase, boolean canUsePlatformRegister) {
RegisterArray allRegisters = arch.getAvailableValueRegisters();
private static List<Register> initAllocatable(Architecture arch, boolean reserveForHeapBase, boolean canUsePlatformRegister) {
List<Register> allRegisters = arch.getAvailableValueRegisters();
Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0) - (!canUsePlatformRegister ? 1 : 0)];
List<Register> reservedRegistersList = reservedRegisters.asList();
int idx = 0;
for (Register reg : allRegisters) {
if (reservedRegistersList.contains(reg)) {
if (reservedRegisters.contains(reg)) {
// skip reserved registers
continue;
}
@ -159,7 +157,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
assert idx == registers.length;
return new RegisterArray(registers);
return List.of(registers);
}
public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister) {
@ -167,28 +165,28 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
assert callerSaved.size() >= allocatable.size();
}
public AArch64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) {
public AArch64HotSpotRegisterConfig(TargetDescription target, List<Register> allocatable) {
this.target = target;
this.allocatable = allocatable;
Set<Register> callerSaveSet = new HashSet<>();
allocatable.addTo(callerSaveSet);
simdParameterRegisters.addTo(callerSaveSet);
javaGeneralParameterRegisters.addTo(callerSaveSet);
nativeGeneralParameterRegisters.addTo(callerSaveSet);
callerSaved = new RegisterArray(callerSaveSet);
callerSaveSet.addAll(allocatable);
callerSaveSet.addAll(simdParameterRegisters);
callerSaveSet.addAll(javaGeneralParameterRegisters);
callerSaveSet.addAll(nativeGeneralParameterRegisters);
callerSaved = List.copyOf(callerSaveSet);
allAllocatableAreCallerSaved = true;
attributesMap = RegisterAttributes.createMap(this, AArch64.allRegisters);
}
@Override
public RegisterArray getCallerSaveRegisters() {
public List<Register> getCallerSaveRegisters() {
return callerSaved;
}
@Override
public RegisterArray getCalleeSaveRegisters() {
public List<Register> getCalleeSaveRegisters() {
return null;
}
@ -209,7 +207,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) {
public List<Register> getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
@ -249,7 +247,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
return currentStackOffset;
}
private CallingConvention callingConvention(RegisterArray generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
private CallingConvention callingConvention(List<Register> generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,31 +37,5 @@ class AArch64HotSpotVMConfig extends HotSpotVMConfigAccess {
}
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
// CPU Capabilities
/*
* These flags are set based on the corresponding command line flags.
*/
final boolean useCRC32 = getFlag("UseCRC32", Boolean.class);
final boolean useSIMDForMemoryOps = getFlag("UseSIMDForMemoryOps", Boolean.class);
final boolean avoidUnalignedAccesses = getFlag("AvoidUnalignedAccesses", Boolean.class);
final boolean useLSE = getFlag("UseLSE", Boolean.class);
final boolean useBlockZeroing = getFlag("UseBlockZeroing", Boolean.class);
final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t");
/*
* These flags are set if the corresponding support is in the hardware.
*/
final long aarch64FP = getConstant("VM_Version::CPU_FP", Long.class);
final long aarch64ASIMD = getConstant("VM_Version::CPU_ASIMD", Long.class);
final long aarch64EVTSTRM = getConstant("VM_Version::CPU_EVTSTRM", Long.class);
final long aarch64AES = getConstant("VM_Version::CPU_AES", Long.class);
final long aarch64PMULL = getConstant("VM_Version::CPU_PMULL", Long.class);
final long aarch64SHA1 = getConstant("VM_Version::CPU_SHA1", Long.class);
final long aarch64SHA2 = getConstant("VM_Version::CPU_SHA2", Long.class);
final long aarch64CRC32 = getConstant("VM_Version::CPU_CRC32", Long.class);
final long aarch64LSE = getConstant("VM_Version::CPU_LSE", Long.class);
final long aarch64A53MAC = getConstant("VM_Version::CPU_A53MAC", Long.class);
}

View File

@ -26,7 +26,7 @@ import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
import java.util.Map;
import jdk.internal.util.OperatingSystem;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
import jdk.vm.ci.code.Architecture;
@ -49,34 +49,22 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
// Configure the feature set using the HotSpot flag settings.
Map<String, Long> constants = config.getStore().getConstants();
Map<String, String> renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH");
assert config.useSSE >= 2 : "minimum config for x64";
long featuresBitMapAddress = config.vmVersionFeatures + config.vmFeaturesFeaturesOffset;
EnumSet<CPUFeature> features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class,
constants,
featuresBitMapAddress,
config.vmFeaturesFeaturesSize,
renaming);
features.add(AMD64.CPUFeature.SSE);
features.add(AMD64.CPUFeature.SSE2);
assert features.contains(AMD64.CPUFeature.SSE) : "minimum config for x64";
assert features.contains(AMD64.CPUFeature.SSE2) : "minimum config for x64";
return features;
}
private static EnumSet<AMD64.Flag> computeFlags(AMD64HotSpotVMConfig config) {
EnumSet<AMD64.Flag> flags = EnumSet.noneOf(AMD64.Flag.class);
if (config.useCountLeadingZerosInstruction) {
flags.add(AMD64.Flag.UseCountLeadingZerosInstruction);
}
if (config.useCountTrailingZerosInstruction) {
flags.add(AMD64.Flag.UseCountTrailingZerosInstruction);
}
return flags;
}
private static TargetDescription createTarget(AMD64HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = true;
Architecture arch = new AMD64(computeFeatures(config), computeFlags(config));
Architecture arch = new AMD64(computeFeatures(config));
return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
@ -85,7 +73,7 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
private static RegisterConfig createRegisterConfig(AMD64HotSpotVMConfig config, TargetDescription target) {
return new AMD64HotSpotRegisterConfig(target, config.useCompressedOops, config.windowsOs);
return new AMD64HotSpotRegisterConfig(target, config.useCompressedOops, OperatingSystem.isWindows());
}
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) {
@ -107,7 +95,6 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
@Override
@SuppressWarnings("try")
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) {
assert host == null;
AMD64HotSpotVMConfig config = new AMD64HotSpotVMConfig(runtime.getConfigStore());
@ -118,24 +105,24 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
ConstantReflectionProvider constantReflection;
HotSpotMetaAccessProvider metaAccess;
StackIntrospection stackIntrospection;
try (InitTimer t = timer("create providers")) {
try (InitTimer rt = timer("create MetaAccess provider")) {
try (InitTimer _ = timer("create providers")) {
try (InitTimer _ = timer("create MetaAccess provider")) {
metaAccess = createMetaAccess(runtime);
}
try (InitTimer rt = timer("create RegisterConfig")) {
try (InitTimer _ = timer("create RegisterConfig")) {
regConfig = createRegisterConfig(config, target);
}
try (InitTimer rt = timer("create CodeCache provider")) {
try (InitTimer _ = timer("create CodeCache provider")) {
codeCache = createCodeCache(runtime, target, regConfig);
}
try (InitTimer rt = timer("create ConstantReflection provider")) {
try (InitTimer _ = timer("create ConstantReflection provider")) {
constantReflection = createConstantReflection(runtime);
}
try (InitTimer rt = timer("create StackIntrospection provider")) {
try (InitTimer _ = timer("create StackIntrospection provider")) {
stackIntrospection = new HotSpotStackIntrospection(runtime);
}
}
try (InitTimer rt = timer("instantiate backend")) {
try (InitTimer _ = timer("instantiate backend")) {
return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -50,7 +50,6 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
@ -69,24 +68,24 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
private final TargetDescription target;
private final RegisterArray allocatable;
private final List<Register> allocatable;
/**
* The caller saved registers always include all parameter registers.
*/
private final RegisterArray callerSaved;
private final List<Register> callerSaved;
private final boolean allAllocatableAreCallerSaved;
private final RegisterAttributes[] attributesMap;
private final List<RegisterAttributes> attributesMap;
@Override
public RegisterArray getAllocatableRegisters() {
public List<Register> getAllocatableRegisters() {
return allocatable;
}
@Override
public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) {
public List<Register> filterAllocatableRegisters(PlatformKind kind, List<Register> registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
@ -94,19 +93,19 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
}
RegisterArray ret = new RegisterArray(list);
List<Register> ret = List.copyOf(list);
return ret;
}
@Override
public RegisterAttributes[] getAttributesMap() {
return attributesMap.clone();
public List<RegisterAttributes> getAttributesMap() {
return attributesMap;
}
private final RegisterArray javaGeneralParameterRegisters;
private final RegisterArray nativeGeneralParameterRegisters;
private final RegisterArray javaXMMParameterRegisters;
private final RegisterArray nativeXMMParameterRegisters;
private final List<Register> javaGeneralParameterRegisters;
private final List<Register> nativeGeneralParameterRegisters;
private final List<Register> javaXMMParameterRegisters;
private final List<Register> nativeXMMParameterRegisters;
private final boolean windowsOS;
/*
@ -115,16 +114,15 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
*/
private final boolean needsNativeStackHomeSpace;
private static final RegisterArray reservedRegisters = new RegisterArray(rsp, r15);
private static final List<Register> reservedRegisters = List.of(rsp, r15);
private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) {
RegisterArray allRegisters = arch.getAvailableValueRegisters();
private static List<Register> initAllocatable(Architecture arch, boolean reserveForHeapBase) {
List<Register> allRegisters = arch.getAvailableValueRegisters();
Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)];
List<Register> reservedRegistersList = reservedRegisters.asList();
int idx = 0;
for (Register reg : allRegisters) {
if (reservedRegistersList.contains(reg)) {
if (reservedRegisters.contains(reg)) {
// skip reserved registers
continue;
}
@ -137,7 +135,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
assert idx == registers.length;
return new RegisterArray(registers);
return List.of(registers);
}
public AMD64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean windowsOs) {
@ -145,42 +143,42 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
assert callerSaved.size() >= allocatable.size();
}
public AMD64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable, boolean windowsOS) {
public AMD64HotSpotRegisterConfig(TargetDescription target, List<Register> allocatable, boolean windowsOS) {
this.target = target;
this.windowsOS = windowsOS;
if (windowsOS) {
javaGeneralParameterRegisters = new RegisterArray(rdx, r8, r9, rdi, rsi, rcx);
nativeGeneralParameterRegisters = new RegisterArray(rcx, rdx, r8, r9);
nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3);
javaGeneralParameterRegisters = List.of(rdx, r8, r9, rdi, rsi, rcx);
nativeGeneralParameterRegisters = List.of(rcx, rdx, r8, r9);
nativeXMMParameterRegisters = List.of(xmm0, xmm1, xmm2, xmm3);
this.needsNativeStackHomeSpace = true;
} else {
javaGeneralParameterRegisters = new RegisterArray(rsi, rdx, rcx, r8, r9, rdi);
nativeGeneralParameterRegisters = new RegisterArray(rdi, rsi, rdx, rcx, r8, r9);
nativeXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
javaGeneralParameterRegisters = List.of(rsi, rdx, rcx, r8, r9, rdi);
nativeGeneralParameterRegisters = List.of(rdi, rsi, rdx, rcx, r8, r9);
nativeXMMParameterRegisters = List.of(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
this.needsNativeStackHomeSpace = false;
}
javaXMMParameterRegisters = new RegisterArray(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
javaXMMParameterRegisters = List.of(xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7);
this.allocatable = allocatable;
Set<Register> callerSaveSet = new HashSet<>();
allocatable.addTo(callerSaveSet);
javaXMMParameterRegisters.addTo(callerSaveSet);
callerSaveSet.addAll(javaGeneralParameterRegisters.asList());
nativeGeneralParameterRegisters.addTo(callerSaveSet);
callerSaved = new RegisterArray(callerSaveSet);
callerSaveSet.addAll(allocatable);
callerSaveSet.addAll(javaXMMParameterRegisters);
callerSaveSet.addAll(javaGeneralParameterRegisters);
callerSaveSet.addAll(nativeGeneralParameterRegisters);
callerSaved = List.copyOf(callerSaveSet);
allAllocatableAreCallerSaved = true;
attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
}
@Override
public RegisterArray getCallerSaveRegisters() {
public List<Register> getCallerSaveRegisters() {
return callerSaved;
}
@Override
public RegisterArray getCalleeSaveRegisters() {
public List<Register> getCalleeSaveRegisters() {
return null;
}
@ -201,7 +199,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) {
public List<Register> getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
@ -237,7 +235,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
* @param valueKindFactory
* @return the resulting calling convention
*/
private CallingConvention callingConvention(RegisterArray generalParameterRegisters, RegisterArray xmmParameterRegisters, boolean unified, JavaType returnType, JavaType[] parameterTypes,
private CallingConvention callingConvention(List<Register> generalParameterRegisters, List<Register> xmmParameterRegisters, boolean unified, JavaType returnType, JavaType[] parameterTypes,
HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
assert !unified || generalParameterRegisters.size() == xmmParameterRegisters.size() : "must be same size in unified mode";

View File

@ -24,8 +24,6 @@ package jdk.vm.ci.hotspot.amd64;
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.services.Services;
import jdk.internal.util.OperatingSystem;
/**
* Used to access AMD64 specific native configuration details.
@ -36,60 +34,8 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess {
super(config);
}
final boolean windowsOs = OperatingSystem.isWindows();
final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class);
final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class);
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
final long vmVersionFeatures = getFieldAddress("VM_Version::_features", "VM_Version::VM_Features");
final long vmFeaturesFeaturesOffset = getFieldOffset("VM_Version::VM_Features::_features_bitmap[0]", Long.class, "uint64_t");
final long vmFeaturesFeaturesSize = getFieldValue("VM_Version::VM_Features::_features_bitmap_size", Long.class, "int");
// CPU capabilities
final int useSSE = getFlag("UseSSE", Integer.class);
final int useAVX = getFlag("UseAVX", Integer.class);
// CPU feature flags
final long amd64CX8 = getConstant("VM_Version::CPU_CX8", Long.class);
final long amd64CMOV = getConstant("VM_Version::CPU_CMOV", Long.class);
final long amd64FXSR = getConstant("VM_Version::CPU_FXSR", Long.class);
final long amd64HT = getConstant("VM_Version::CPU_HT", Long.class);
final long amd64MMX = getConstant("VM_Version::CPU_MMX", Long.class);
final long amd643DNOWPREFETCH = getConstant("VM_Version::CPU_3DNOW_PREFETCH", Long.class);
final long amd64SSE = getConstant("VM_Version::CPU_SSE", Long.class);
final long amd64SSE2 = getConstant("VM_Version::CPU_SSE2", Long.class);
final long amd64SSE3 = getConstant("VM_Version::CPU_SSE3", Long.class);
final long amd64SSSE3 = getConstant("VM_Version::CPU_SSSE3", Long.class);
final long amd64SSE4A = getConstant("VM_Version::CPU_SSE4A", Long.class);
final long amd64SSE41 = getConstant("VM_Version::CPU_SSE4_1", Long.class);
final long amd64SSE42 = getConstant("VM_Version::CPU_SSE4_2", Long.class);
final long amd64POPCNT = getConstant("VM_Version::CPU_POPCNT", Long.class);
final long amd64LZCNT = getConstant("VM_Version::CPU_LZCNT", Long.class);
final long amd64TSC = getConstant("VM_Version::CPU_TSC", Long.class);
final long amd64TSCINV = getConstant("VM_Version::CPU_TSCINV", Long.class);
final long amd64AVX = getConstant("VM_Version::CPU_AVX", Long.class);
final long amd64AVX2 = getConstant("VM_Version::CPU_AVX2", Long.class);
final long amd64AES = getConstant("VM_Version::CPU_AES", Long.class);
final long amd64ERMS = getConstant("VM_Version::CPU_ERMS", Long.class);
final long amd64CLMUL = getConstant("VM_Version::CPU_CLMUL", Long.class);
final long amd64BMI1 = getConstant("VM_Version::CPU_BMI1", Long.class);
final long amd64BMI2 = getConstant("VM_Version::CPU_BMI2", Long.class);
final long amd64RTM = getConstant("VM_Version::CPU_RTM", Long.class);
final long amd64ADX = getConstant("VM_Version::CPU_ADX", Long.class);
final long amd64AVX512F = getConstant("VM_Version::CPU_AVX512F", Long.class);
final long amd64AVX512DQ = getConstant("VM_Version::CPU_AVX512DQ", Long.class);
final long amd64AVX512PF = getConstant("VM_Version::CPU_AVX512PF", Long.class);
final long amd64AVX512ER = getConstant("VM_Version::CPU_AVX512ER", Long.class);
final long amd64AVX512CD = getConstant("VM_Version::CPU_AVX512CD", Long.class);
final long amd64AVX512BW = getConstant("VM_Version::CPU_AVX512BW", Long.class);
final long amd64AVX512VL = getConstant("VM_Version::CPU_AVX512VL", Long.class);
final long amd64SHA = getConstant("VM_Version::CPU_SHA", Long.class);
final long amd64FMA = getConstant("VM_Version::CPU_FMA", Long.class);
final long amd64PKU = getConstant("VM_Version::CPU_PKU", Long.class);
final long amd64OSPKE = getConstant("VM_Version::CPU_OSPKE", Long.class);
final long amd64CET_IBT = getConstant("VM_Version::CPU_CET_IBT", Long.class);
final long amd64CET_SS = getConstant("VM_Version::CPU_CET_SS", Long.class);
final long amd64AVX10_1 = getConstant("VM_Version::CPU_AVX10_1", Long.class);
final long amd64AVX10_2 = getConstant("VM_Version::CPU_AVX10_2", Long.class);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -52,39 +52,11 @@ public class RISCV64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap());
}
private static EnumSet<RISCV64.Flag> computeFlags(RISCV64HotSpotVMConfig config) {
EnumSet<RISCV64.Flag> flags = EnumSet.noneOf(RISCV64.Flag.class);
if (config.useConservativeFence) {
flags.add(RISCV64.Flag.UseConservativeFence);
}
if (config.avoidUnalignedAccesses) {
flags.add(RISCV64.Flag.AvoidUnalignedAccesses);
}
if (config.traceTraps) {
flags.add(RISCV64.Flag.TraceTraps);
}
if (config.useRVV) {
flags.add(RISCV64.Flag.UseRVV);
}
if (config.useRVC) {
flags.add(RISCV64.Flag.UseRVC);
}
if (config.useZba) {
flags.add(RISCV64.Flag.UseZba);
}
if (config.useZbb) {
flags.add(RISCV64.Flag.UseZbb);
}
return flags;
}
private static TargetDescription createTarget(RISCV64HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = true;
Architecture arch = new RISCV64(computeFeatures(config), computeFlags(config));
Architecture arch = new RISCV64(computeFeatures(config));
return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
@ -115,7 +87,6 @@ public class RISCV64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
}
@Override
@SuppressWarnings("try")
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntime runtime, JVMCIBackend host) {
assert host == null;
RISCV64HotSpotVMConfig config = new RISCV64HotSpotVMConfig(runtime.getConfigStore());
@ -126,24 +97,24 @@ public class RISCV64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
ConstantReflectionProvider constantReflection;
HotSpotMetaAccessProvider metaAccess;
StackIntrospection stackIntrospection;
try (InitTimer t = timer("create providers")) {
try (InitTimer rt = timer("create MetaAccess provider")) {
try (InitTimer _ = timer("create providers")) {
try (InitTimer _ = timer("create MetaAccess provider")) {
metaAccess = createMetaAccess(runtime);
}
try (InitTimer rt = timer("create RegisterConfig")) {
try (InitTimer _ = timer("create RegisterConfig")) {
regConfig = createRegisterConfig(config, target);
}
try (InitTimer rt = timer("create CodeCache provider")) {
try (InitTimer _ = timer("create CodeCache provider")) {
codeCache = createCodeCache(runtime, target, regConfig);
}
try (InitTimer rt = timer("create ConstantReflection provider")) {
try (InitTimer _ = timer("create ConstantReflection provider")) {
constantReflection = createConstantReflection(runtime);
}
try (InitTimer rt = timer("create StackIntrospection provider")) {
try (InitTimer _ = timer("create StackIntrospection provider")) {
stackIntrospection = new HotSpotStackIntrospection(runtime);
}
}
try (InitTimer rt = timer("instantiate backend")) {
try (InitTimer _ = timer("instantiate backend")) {
return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,6 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
@ -79,24 +78,24 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
private final TargetDescription target;
private final RegisterArray allocatable;
private final List<Register> allocatable;
/**
* The caller saved registers always include all parameter registers.
*/
private final RegisterArray callerSaved;
private final List<Register> callerSaved;
private final boolean allAllocatableAreCallerSaved;
private final RegisterAttributes[] attributesMap;
private final List<RegisterAttributes> attributesMap;
@Override
public RegisterArray getAllocatableRegisters() {
public List<Register> getAllocatableRegisters() {
return allocatable;
}
@Override
public RegisterArray filterAllocatableRegisters(PlatformKind kind, RegisterArray registers) {
public List<Register> filterAllocatableRegisters(PlatformKind kind, List<Register> registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
@ -104,17 +103,17 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
}
}
return new RegisterArray(list);
return List.copyOf(list);
}
@Override
public RegisterAttributes[] getAttributesMap() {
return attributesMap.clone();
public List<RegisterAttributes> getAttributesMap() {
return attributesMap;
}
private final RegisterArray javaGeneralParameterRegisters = new RegisterArray(x11, x12, x13, x14, x15, x16, x17, x10);
private final RegisterArray nativeGeneralParameterRegisters = new RegisterArray(x10, x11, x12, x13, x14, x15, x16, x17);
private final RegisterArray fpParameterRegisters = new RegisterArray(f10, f11, f12, f13, f14, f15, f16, f17);
private final List<Register> javaGeneralParameterRegisters = List.of(x11, x12, x13, x14, x15, x16, x17, x10);
private final List<Register> nativeGeneralParameterRegisters = List.of(x10, x11, x12, x13, x14, x15, x16, x17);
private final List<Register> fpParameterRegisters = List.of(f10, f11, f12, f13, f14, f15, f16, f17);
public static final Register zero = x0;
public static final Register ra = x1;
@ -128,16 +127,15 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
public static final Register threadRegister = x23;
public static final Register heapBaseRegister = x27;
private static final RegisterArray reservedRegisters = new RegisterArray(zero, ra, sp, gp, tp, t0, t1, t2, fp);
private static final List<Register> reservedRegisters =List.of(zero, ra, sp, gp, tp, t0, t1, t2, fp);
private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) {
RegisterArray allRegisters = arch.getAvailableValueRegisters();
private static List<Register> initAllocatable(Architecture arch, boolean reserveForHeapBase) {
List<Register> allRegisters = arch.getAvailableValueRegisters();
Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)];
List<Register> reservedRegistersList = reservedRegisters.asList();
int idx = 0;
for (Register reg : allRegisters) {
if (reservedRegistersList.contains(reg)) {
if (reservedRegisters.contains(reg)) {
// skip reserved registers
continue;
}
@ -152,7 +150,7 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
}
assert idx == registers.length;
return new RegisterArray(registers);
return List.of(registers);
}
public RISCV64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean linuxOs) {
@ -160,28 +158,28 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
assert callerSaved.size() >= allocatable.size();
}
public RISCV64HotSpotRegisterConfig(TargetDescription target, RegisterArray allocatable) {
public RISCV64HotSpotRegisterConfig(TargetDescription target, List<Register> allocatable) {
this.target = target;
this.allocatable = allocatable;
Set<Register> callerSaveSet = new HashSet<>();
allocatable.addTo(callerSaveSet);
fpParameterRegisters.addTo(callerSaveSet);
javaGeneralParameterRegisters.addTo(callerSaveSet);
nativeGeneralParameterRegisters.addTo(callerSaveSet);
callerSaved = new RegisterArray(callerSaveSet);
callerSaveSet.addAll(allocatable);
callerSaveSet.addAll(fpParameterRegisters);
callerSaveSet.addAll(javaGeneralParameterRegisters);
callerSaveSet.addAll(nativeGeneralParameterRegisters);
callerSaved = List.copyOf(callerSaveSet);
allAllocatableAreCallerSaved = true;
attributesMap = RegisterAttributes.createMap(this, RISCV64.allRegisters);
}
@Override
public RegisterArray getCallerSaveRegisters() {
public List<Register> getCallerSaveRegisters() {
return callerSaved;
}
@Override
public RegisterArray getCalleeSaveRegisters() {
public List<Register> getCalleeSaveRegisters() {
return null;
}
@ -200,7 +198,7 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public RegisterArray getCallingConventionRegisters(Type type, JavaKind kind) {
public List<Register> getCallingConventionRegisters(Type type, JavaKind kind) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
switch (kind) {
case Boolean:
@ -219,7 +217,7 @@ public class RISCV64HotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(RegisterArray generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
private CallingConvention callingConvention(List<Register> generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,19 +37,5 @@ class RISCV64HotSpotVMConfig extends HotSpotVMConfigAccess {
}
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);
// CPU Capabilities
/*
* These flags are set based on the corresponding command line flags.
*/
final boolean useConservativeFence = getFlag("UseConservativeFence", Boolean.class);
final boolean avoidUnalignedAccesses = getFlag("AvoidUnalignedAccesses", Boolean.class);
final boolean traceTraps = getFlag("TraceTraps", Boolean.class);
final boolean useRVV = getFlag("UseRVV", Boolean.class);
final boolean useRVC = getFlag("UseRVC", Boolean.class);
final boolean useZba = getFlag("UseZba", Boolean.class);
final boolean useZbb = getFlag("UseZbb", Boolean.class);
final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,12 +24,12 @@ package jdk.vm.ci.riscv64;
import java.nio.ByteOrder;
import java.util.EnumSet;
import java.util.List;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CPUFeatureName;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
@ -77,7 +77,7 @@ public class RISCV64 extends Architecture {
public static final Register x31 = new Register(31, 31, "x31", CPU);
// @formatter:off
public static final RegisterArray cpuRegisters = new RegisterArray(
public static final List<Register> cpuRegisters = List.of(
x0, x1, x2, x3, x4, x5, x6, x7,
x8, x9, x10, x11, x12, x13, x14, x15,
x16, x17, x18, x19, x20, x21, x22, x23,
@ -122,7 +122,7 @@ public class RISCV64 extends Architecture {
public static final Register f31 = new Register(63, 31, "f31", FP);
// @formatter:off
public static final RegisterArray fpRegisters = new RegisterArray(
public static final List<Register> fpRegisters = List.of(
f0, f1, f2, f3, f4, f5, f6, f7,
f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23,
@ -131,7 +131,7 @@ public class RISCV64 extends Architecture {
// @formatter:on
// @formatter:off
public static final RegisterArray allRegisters = new RegisterArray(
public static final List<Register> allRegisters = List.of(
x0, x1, x2, x3, x4, x5, x6, x7,
x8, x9, x10, x11, x12, x13, x14, x15,
x16, x17, x18, x19, x20, x21, x22, x23,
@ -160,25 +160,9 @@ public class RISCV64 extends Architecture {
private final EnumSet<CPUFeature> features;
/**
* Set of flags to control code emission.
*/
public enum Flag {
UseConservativeFence,
AvoidUnalignedAccesses,
TraceTraps,
UseRVV,
UseRVC,
UseZba,
UseZbb
}
private final EnumSet<Flag> flags;
public RISCV64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
public RISCV64(EnumSet<CPUFeature> features) {
super("riscv64", RISCV64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, 0, 0, 8);
this.features = features;
this.flags = flags;
}
@Override
@ -186,10 +170,6 @@ public class RISCV64 extends Architecture {
return features;
}
public EnumSet<Flag> getFlags() {
return flags;
}
@Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
switch (javaKind) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,6 @@ package compiler.jvmci.common;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterArray;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Site;
@ -118,8 +117,7 @@ public class CodeInstallerTest {
protected Register getRegister(PlatformKind kind, int index) {
int idx = index;
RegisterArray allRegs = arch.getAvailableValueRegisters();
for (Register reg : allRegs) {
for (Register reg : arch.getAvailableValueRegisters()) {
if (arch.canStoreValue(reg.getRegisterCategory(), kind)) {
if (idx-- == 0) {
return reg;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -24,6 +24,7 @@
package jdk.vm.ci.code.test.aarch64;
import java.util.List;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.code.CallingConvention;
@ -367,9 +368,9 @@ public class AArch64TestAssembler extends TestAssembler {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
for (int i = 0; i < args.length; i++) {
emitLoad(args[i], prim[i]);
List<AllocatableValue> args = cc.getArguments();
for (int i = 0; i < args.size(); i++) {
emitLoad(args.get(i), prim[i]);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@ package jdk.vm.ci.code.test.amd64;
import static jdk.vm.ci.amd64.AMD64.xmm0;
import java.util.List;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.CallingConvention;
@ -495,11 +496,11 @@ public class AMD64TestAssembler extends TestAssembler {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
List<AllocatableValue> args = cc.getArguments();
// Do the emission in reverse, this avoids register collisons of xmm0 - which is used a
// scratch register when putting arguments on the stack.
for (int i = args.length - 1; i >= 0; i--) {
emitLoad(args[i], prim[i]);
for (int i = args.size() - 1; i >= 0; i--) {
emitLoad(args.get(i), prim[i]);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
package jdk.vm.ci.code.test.riscv64;
import java.util.List;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.DebugInfo;
@ -227,9 +228,9 @@ public class RISCV64TestAssembler extends TestAssembler {
@Override
public void emitCallPrologue(CallingConvention cc, Object... prim) {
growFrame(cc.getStackSize());
AllocatableValue[] args = cc.getArguments();
for (int i = 0; i < args.length; i++) {
emitLoad(args[i], prim[i]);
List<AllocatableValue> args = cc.getArguments();
for (int i = 0; i < args.size(); i++) {
emitLoad(args.get(i), prim[i]);
}
}