Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
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 {

Expand All @@ -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
Expand All @@ -57,18 +58,19 @@ public interface HotSpotJVMCIBackendFactory {
static <CPUFeatureType extends Enum<CPUFeatureType>> EnumSet<CPUFeatureType> convertFeatures(
Class<CPUFeatureType> enumType,
Map<String, Long> constants,
long features,
LongFunction<Long> bitMaskSupplier,
LongFunction<Long> featuresSupplier,
Map<String, String> renaming) {
EnumSet<CPUFeatureType> outFeatures = EnumSet.noneOf(enumType);
List<String> missing = new ArrayList<>();
for (Entry<String, Long> 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) {
Expand All @@ -82,57 +84,4 @@ static <CPUFeatureType extends Enum<CPUFeatureType>> EnumSet<CPUFeatureType> con
return outFeatures;
}

/**
* Converts CPU features bit map into enum constants.
*
* @param <CPUFeatureType> 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 <CPUFeatureType extends Enum<CPUFeatureType>> EnumSet<CPUFeatureType> convertFeatures(
Class<CPUFeatureType> enumType,
Map<String, Long> constants,
long featuresBitMapAddress,
long featuresBitMapSize,
Map<String, String> renaming) {
EnumSet<CPUFeatureType> outFeatures = EnumSet.noneOf(enumType);
List<String> missing = new ArrayList<>();

for (Entry<String, Long> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
private static EnumSet<AArch64.CPUFeature> computeFeatures(AArch64HotSpotVMConfig config) {
// Configure the feature set using the HotSpot flag settings.
Map<String, Long> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

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;
Expand All @@ -50,11 +52,15 @@ private static EnumSet<CPUFeature> computeFeatures(AMD64HotSpotVMConfig config)
Map<String, Long> constants = config.getStore().getConstants();
Map<String, String> renaming = Map.of("3DNOW_PREFETCH", "AMD_3DNOW_PREFETCH");
long featuresBitMapAddress = config.vmVersionFeatures + config.vmFeaturesFeaturesOffset;
EnumSet<CPUFeature> features = HotSpotJVMCIBackendFactory.convertFeatures(CPUFeature.class,
constants,
featuresBitMapAddress,
config.vmFeaturesFeaturesSize,
renaming);
EnumSet<CPUFeature> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class RISCV64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
private static EnumSet<RISCV64.CPUFeature> computeFeatures(RISCV64HotSpotVMConfig config) {
// Configure the feature set using the HotSpot flag settings.
Map<String, Long> 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) {
Expand Down