diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java index 319b9b9bc44..e0fc314de5b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java @@ -27,10 +27,10 @@ import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.function.LongFunction; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.runtime.JVMCIBackend; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; public interface HotSpotJVMCIBackendFactory { @@ -48,7 +48,8 @@ public interface HotSpotJVMCIBackendFactory { * @param enumType the class of {@code CPUFeatureType} * @param constants VM constants. Each entry whose key starts with {@code "VM_Version::CPU_"} * specifies a CPU feature and its value is a mask for a bit in {@code features} - * @param features bits specifying CPU features + * @param bitMaskSupplier supplier to get the bit mask for the corresponding VM constant + * @param featuresSupplier supplier to get the bits specifying CPU features * @param renaming maps from VM feature names to enum constant names where the two differ * @throws IllegalArgumentException if any VM CPU feature constant cannot be converted to an * enum value @@ -57,18 +58,19 @@ public interface HotSpotJVMCIBackendFactory { static > EnumSet convertFeatures( Class enumType, Map constants, - long features, + LongFunction bitMaskSupplier, + LongFunction featuresSupplier, Map renaming) { EnumSet outFeatures = EnumSet.noneOf(enumType); List missing = new ArrayList<>(); for (Entry e : constants.entrySet()) { - long bitMask = e.getValue(); + long bitMask = bitMaskSupplier.apply(e.getValue()); String key = e.getKey(); if (key.startsWith("VM_Version::CPU_")) { String name = key.substring("VM_Version::CPU_".length()); try { CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name)); - if ((features & bitMask) != 0) { + if ((featuresSupplier.apply(e.getValue()) & bitMask) != 0) { outFeatures.add(feature); } } catch (IllegalArgumentException iae) { @@ -82,57 +84,4 @@ public interface HotSpotJVMCIBackendFactory { return outFeatures; } - /** - * Converts CPU features bit map into enum constants. - * - * @param CPU feature enum type - * @param enumType the class of {@code CPUFeatureType} - * @param constants VM constants. Each entry whose key starts with {@code "VM_Version::CPU_"} - * specifies a CPU feature and its value is a mask for a bit in {@code features} - * @param featuresBitMapAddress pointer to {@code VM_Features::_features_bitmap} field of {@code VM_Version::_features} - * @param featuresBitMapSize size of feature bit map in bytes - * @param renaming maps from VM feature names to enum constant names where the two differ - * @throws IllegalArgumentException if any VM CPU feature constant cannot be converted to an - * enum value - * @return the set of converted values - */ - static > EnumSet convertFeatures( - Class enumType, - Map constants, - long featuresBitMapAddress, - long featuresBitMapSize, - Map renaming) { - EnumSet outFeatures = EnumSet.noneOf(enumType); - List missing = new ArrayList<>(); - - for (Entry e : constants.entrySet()) { - String key = e.getKey(); - long bitIndex = e.getValue(); - if (key.startsWith("VM_Version::CPU_")) { - String name = key.substring("VM_Version::CPU_".length()); - try { - final long featuresElementShiftCount = 6; // log (# of bits per long) - final long featuresElementMask = (1L << featuresElementShiftCount) - 1; - - CPUFeatureType feature = Enum.valueOf(enumType, renaming.getOrDefault(name, name)); - - long featureIndex = bitIndex >>> featuresElementShiftCount; - long featureBitMask = 1L << (bitIndex & featuresElementMask); - assert featureIndex < featuresBitMapSize; - - long featuresElement = UNSAFE.getLong(featuresBitMapAddress + featureIndex * Long.BYTES); - - if ((featuresElement & featureBitMask) != 0) { - outFeatures.add(feature); - } - } catch (IllegalArgumentException iae) { - missing.add(name); - } - } - } - if (!missing.isEmpty()) { - throw new JVMCIError("Missing CPU feature constants: %s", missing); - } - return outFeatures; - } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java index 19c161d6bde..1ee016b73a8 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java @@ -49,7 +49,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac private static EnumSet computeFeatures(AArch64HotSpotVMConfig config) { // Configure the feature set using the HotSpot flag settings. Map constants = config.getStore().getConstants(); - return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap()); + return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, idx -> 1L << idx, _ -> config.vmVersionFeatures, emptyMap()); } private static TargetDescription createTarget(AArch64HotSpotVMConfig config) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java index 040f39e3b8a..cae6d18e71e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java @@ -26,6 +26,8 @@ import static jdk.vm.ci.common.InitTimer.timer; import java.util.EnumSet; import java.util.Map; + +import jdk.internal.misc.Unsafe; import jdk.internal.util.OperatingSystem; import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.amd64.AMD64.CPUFeature; @@ -50,11 +52,15 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto Map constants = config.getStore().getConstants(); Map renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH"); long featuresBitMapAddress = config.vmVersionFeatures + config.vmFeaturesFeaturesOffset; - EnumSet features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, - constants, - featuresBitMapAddress, - config.vmFeaturesFeaturesSize, - renaming); + EnumSet features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, idx -> { + final long featuresElementShiftCount = 6; // log (# of bits per long) + final long featuresElementMask = (1L << featuresElementShiftCount) - 1; + return 1L << (idx & featuresElementMask); + }, idx -> { + final long featuresElementShiftCount = 6; // log (# of bits per long) + long featureIndex = idx >>> featuresElementShiftCount; + return Unsafe.getUnsafe().getLong(featuresBitMapAddress + featureIndex * Long.BYTES); + }, renaming); assert features.contains(AMD64.CPUFeature.SSE) : "minimum config for x64"; assert features.contains(AMD64.CPUFeature.SSE2) : "minimum config for x64"; return features; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java index c0e31124500..f50fcf1dbbc 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java @@ -49,7 +49,7 @@ public class RISCV64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac private static EnumSet computeFeatures(RISCV64HotSpotVMConfig config) { // Configure the feature set using the HotSpot flag settings. Map constants = config.getStore().getConstants(); - return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, config.vmVersionFeatures, emptyMap()); + return HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class, constants, mask -> mask, _ -> config.vmVersionFeatures, emptyMap()); } private static TargetDescription createTarget(RISCV64HotSpotVMConfig config) {