< prev index next > src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
Print this page
#include "runtime/java.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"
+ #include "utilities/ostream.hpp"
int VM_Version::_cpu;
int VM_Version::_model;
int VM_Version::_model2;
int VM_Version::_variant;
int VM_Version::_initial_sve_vector_length;
int VM_Version::_max_supported_sve_vector_length;
bool VM_Version::_rop_protection;
uintptr_t VM_Version::_pac_mask;
+ const char* VM_Version::_features_names[MAX_CPU_FEATURES] = { nullptr };
+
SpinWait VM_Version::_spin_wait;
static SpinWait get_spin_wait_desc() {
if (strcmp(OnSpinWaitInst, "nop") == 0) {
return SpinWait(SpinWait::NOP, OnSpinWaitInstCount);
return SpinWait{};
}
void VM_Version::initialize() {
+ #define SET_CPU_FEATURE_NAME(id, name, bit) \
+ _features_names[bit] = XSTR(name);
+ CPU_FEATURE_FLAGS(SET_CPU_FEATURE_NAME)
+ #undef SET_CPU_FEATURE_NAME
+
_supports_atomic_getset4 = true;
_supports_atomic_getadd4 = true;
_supports_atomic_getset8 = true;
_supports_atomic_getadd8 = true;
}
}
// Cortex A53
if (_cpu == CPU_ARM && model_is(0xd03)) {
! _features |= CPU_A53MAC;
if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
}
}
}
}
// Cortex A53
if (_cpu == CPU_ARM && model_is(0xd03)) {
! set_feature(CPU_A53MAC);
if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
}
}
if (FLAG_IS_DEFAULT(AlwaysMergeDMB)) {
FLAG_SET_DEFAULT(AlwaysMergeDMB, false);
}
}
! if (_features & (CPU_FP | CPU_ASIMD)) {
if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
}
}
if (FLAG_IS_DEFAULT(AlwaysMergeDMB)) {
FLAG_SET_DEFAULT(AlwaysMergeDMB, false);
}
}
! if (supports_feature(CPU_FP) || supports_feature(CPU_ASIMD)) {
if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
}
}
} else if (UseGHASHIntrinsics) {
warning("GHASH intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
! if (_features & CPU_ASIMD) {
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
UseChaCha20Intrinsics = true;
}
} else if (UseChaCha20Intrinsics) {
if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
warning("ChaCha20 intrinsic requires ASIMD instructions");
}
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
}
! if (_features & CPU_ASIMD) {
if (FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
UseKyberIntrinsics = true;
}
} else if (UseKyberIntrinsics) {
if (!FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
warning("Kyber intrinsics require ASIMD instructions");
}
FLAG_SET_DEFAULT(UseKyberIntrinsics, false);
}
! if (_features & CPU_ASIMD) {
if (FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
UseDilithiumIntrinsics = true;
}
} else if (UseDilithiumIntrinsics) {
if (!FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
} else if (UseGHASHIntrinsics) {
warning("GHASH intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
! if (supports_feature(CPU_ASIMD)) {
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
UseChaCha20Intrinsics = true;
}
} else if (UseChaCha20Intrinsics) {
if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
warning("ChaCha20 intrinsic requires ASIMD instructions");
}
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
}
! if (supports_feature(CPU_ASIMD)) {
if (FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
UseKyberIntrinsics = true;
}
} else if (UseKyberIntrinsics) {
if (!FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
warning("Kyber intrinsics require ASIMD instructions");
}
FLAG_SET_DEFAULT(UseKyberIntrinsics, false);
}
! if (supports_feature(CPU_ASIMD)) {
if (FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
UseDilithiumIntrinsics = true;
}
} else if (UseDilithiumIntrinsics) {
if (!FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
check_virtualizations();
// Sync SVE related CPU features with flags
if (UseSVE < 2) {
! _features &= ~CPU_SVE2;
! _features &= ~CPU_SVEBITPERM;
}
if (UseSVE < 1) {
! _features &= ~CPU_SVE;
}
// Construct the "features" string
! char buf[512];
! int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
if (_model2) {
! os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
}
! size_t features_offset = strnlen(buf, sizeof(buf));
! #define ADD_FEATURE_IF_SUPPORTED(id, name, bit) \
! do { \
- if (VM_Version::supports_##name()) strcat(buf, ", " #name); \
- } while(0);
- CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
- #undef ADD_FEATURE_IF_SUPPORTED
-
- _cpu_info_string = os::strdup(buf);
! _features_string = extract_features_string(_cpu_info_string,
! strnlen(_cpu_info_string, sizeof(buf)),
- features_offset);
}
#if defined(LINUX)
static bool check_info_file(const char* fpath,
const char* virt1, VirtualizationType vt1,
check_virtualizations();
// Sync SVE related CPU features with flags
if (UseSVE < 2) {
! clear_feature(CPU_SVE2);
! clear_feature(CPU_SVEBITPERM);
}
if (UseSVE < 1) {
! clear_feature(CPU_SVE);
}
// Construct the "features" string
! stringStream ss(512);
! ss.print("0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
if (_model2) {
! ss.print("(0x%03x)", _model2);
}
! ss.print(", ");
! int features_offset = (int)ss.size();
! insert_features_names(_features, ss);
! _cpu_info_string = ss.as_string(true);
! _features_string = _cpu_info_string + features_offset;
}
#if defined(LINUX)
static bool check_info_file(const char* fpath,
const char* virt1, VirtualizationType vt1,
desc_len = (int)strlen(_cpu_desc);
snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _cpu_info_string);
_initialized = true;
}
+
+ void VM_Version::insert_features_names(uint64_t features, stringStream& ss) {
+ int i = 0;
+ ss.join([&]() {
+ const char* str = nullptr;
+ while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
+ if (supports_feature((VM_Version::Feature_Flag)i)) {
+ str = _features_names[i];
+ }
+ i += 1;
+ }
+ return str;
+ }, ", ");
+ }
+
+ void VM_Version::get_cpu_features_name(void* features_buffer, stringStream& ss) {
+ uint64_t features = *(uint64_t*)features_buffer;
+ insert_features_names(features, ss);
+ }
+
+ void VM_Version::get_missing_features_name(void* features_buffer, stringStream& ss) {
+ uint64_t features_to_test = *(uint64_t*)features_buffer;
+ int i = 0;
+ ss.join([&]() {
+ const char* str = nullptr;
+ while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
+ Feature_Flag flag = (Feature_Flag)i;
+ if (supports_feature(features_to_test, flag) && !supports_feature(flag)) {
+ str = _features_names[i];
+ }
+ i += 1;
+ }
+ return str;
+ }, ", ");
+ }
+
+ int VM_Version::cpu_features_size() {
+ return sizeof(_features);
+ }
+
+ void VM_Version::store_cpu_features(void* buf) {
+ *(uint64_t*)buf = _features;
+ }
+
+ bool VM_Version::supports_features(void* features_buffer) {
+ uint64_t features_to_test = *(uint64_t*)features_buffer;
+ return (_features & features_to_test) == features_to_test;
+ }
< prev index next >