< prev index next >

src/hotspot/cpu/x86/vm_version_x86.cpp

Print this page

  21  * questions.
  22  *
  23  */
  24 
  25 #include "asm/macroAssembler.hpp"
  26 #include "asm/macroAssembler.inline.hpp"
  27 #include "classfile/vmIntrinsics.hpp"
  28 #include "code/codeBlob.hpp"
  29 #include "compiler/compilerDefinitions.inline.hpp"
  30 #include "jvm.h"
  31 #include "logging/log.hpp"
  32 #include "logging/logStream.hpp"
  33 #include "memory/resourceArea.hpp"
  34 #include "memory/universe.hpp"
  35 #include "runtime/globals_extension.hpp"
  36 #include "runtime/java.hpp"
  37 #include "runtime/os.inline.hpp"
  38 #include "runtime/stubCodeGenerator.hpp"
  39 #include "runtime/vm_version.hpp"
  40 #include "utilities/checkedCast.hpp"

  41 #include "utilities/powerOfTwo.hpp"
  42 #include "utilities/virtualizationSupport.hpp"
  43 
  44 int VM_Version::_cpu;
  45 int VM_Version::_model;
  46 int VM_Version::_stepping;
  47 bool VM_Version::_has_intel_jcc_erratum;
  48 VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, };
  49 
  50 #define DECLARE_CPU_FEATURE_NAME(id, name, bit) name,
  51 const char* VM_Version::_features_names[] = { CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_NAME)};
  52 #undef DECLARE_CPU_FEATURE_FLAG
  53 
  54 // Address of instruction which causes SEGV
  55 address VM_Version::_cpuinfo_segv_addr = nullptr;
  56 // Address of instruction after the one which causes SEGV
  57 address VM_Version::_cpuinfo_cont_addr = nullptr;
  58 // Address of instruction which causes APX specific SEGV
  59 address VM_Version::_cpuinfo_segv_addr_apx = nullptr;
  60 // Address of instruction after the one which causes APX specific SEGV
  61 address VM_Version::_cpuinfo_cont_addr_apx = nullptr;
  62 
  63 static BufferBlob* stub_blob;
  64 static const int stub_size = 2000;
  65 
  66 int VM_Version::VM_Features::_features_bitmap_size = sizeof(VM_Version::VM_Features::_features_bitmap) / BytesPerLong;
  67 
  68 VM_Version::VM_Features VM_Version::_features;
  69 VM_Version::VM_Features VM_Version::_cpu_features;
  70 

1083     // the cache. We could switch to CPUID/SERIALIZE ("4"/"5") going forward.
1084     if (supports_clwb()) {
1085       FLAG_SET_ERGO(X86ICacheSync, 3);
1086     } else if (supports_clflushopt()) {
1087       FLAG_SET_ERGO(X86ICacheSync, 2);
1088     } else {
1089       FLAG_SET_ERGO(X86ICacheSync, 1);
1090     }
1091   } else {
1092     if ((X86ICacheSync == 2) && !supports_clflushopt()) {
1093       vm_exit_during_initialization("CPU does not support CLFLUSHOPT, unable to use X86ICacheSync=2");
1094     }
1095     if ((X86ICacheSync == 3) && !supports_clwb()) {
1096       vm_exit_during_initialization("CPU does not support CLWB, unable to use X86ICacheSync=3");
1097     }
1098     if ((X86ICacheSync == 5) && !supports_serialize()) {
1099       vm_exit_during_initialization("CPU does not support SERIALIZE, unable to use X86ICacheSync=5");
1100     }
1101   }
1102 
1103   char buf[2048];
1104   size_t cpu_info_size = jio_snprintf(
1105               buf, sizeof(buf),
1106               "(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
1107               cores_per_cpu(), threads_per_core(),
1108               cpu_family(), _model, _stepping, os::cpu_microcode_revision());
1109   assert(cpu_info_size > 0, "not enough temporary space allocated");
1110 
1111   insert_features_names(_features, buf + cpu_info_size, sizeof(buf) - cpu_info_size);
1112 
1113   _cpu_info_string = os::strdup(buf);
1114 
1115   _features_string = extract_features_string(_cpu_info_string,
1116                                              strnlen(_cpu_info_string, sizeof(buf)),
1117                                              cpu_info_size);
1118 
1119   // Use AES instructions if available.
1120   if (supports_aes()) {
1121     if (FLAG_IS_DEFAULT(UseAES)) {
1122       FLAG_SET_DEFAULT(UseAES, true);
1123     }
1124     if (!UseAES) {
1125       if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
1126         warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
1127       }
1128       FLAG_SET_DEFAULT(UseAESIntrinsics, false);
1129     } else {
1130       if (UseSSE > 2) {
1131         if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
1132           FLAG_SET_DEFAULT(UseAESIntrinsics, true);
1133         }
1134       } else {
1135         // The AES intrinsic stubs require AES instruction support (of course)
1136         // but also require sse3 mode or higher for instructions it use.
1137         if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {

3279       return 128; // Pentium 3 (and all other old CPUs)
3280     }
3281   }
3282 }
3283 
3284 bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
3285   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
3286   switch (id) {
3287   case vmIntrinsics::_floatToFloat16:
3288   case vmIntrinsics::_float16ToFloat:
3289     if (!supports_float16()) {
3290       return false;
3291     }
3292     break;
3293   default:
3294     break;
3295   }
3296   return true;
3297 }
3298 
3299 void VM_Version::insert_features_names(VM_Version::VM_Features features, char* buf, size_t buflen) {
3300   for (int i = 0; i < MAX_CPU_FEATURES; i++) {
3301     if (features.supports_feature((VM_Version::Feature_Flag)i)) {
3302       int res = jio_snprintf(buf, buflen, ", %s", _features_names[i]);
3303       assert(res > 0, "not enough temporary space allocated");
3304       buf += res;
3305       buflen -= res;


3306     }
3307   }





































3308 }

  21  * questions.
  22  *
  23  */
  24 
  25 #include "asm/macroAssembler.hpp"
  26 #include "asm/macroAssembler.inline.hpp"
  27 #include "classfile/vmIntrinsics.hpp"
  28 #include "code/codeBlob.hpp"
  29 #include "compiler/compilerDefinitions.inline.hpp"
  30 #include "jvm.h"
  31 #include "logging/log.hpp"
  32 #include "logging/logStream.hpp"
  33 #include "memory/resourceArea.hpp"
  34 #include "memory/universe.hpp"
  35 #include "runtime/globals_extension.hpp"
  36 #include "runtime/java.hpp"
  37 #include "runtime/os.inline.hpp"
  38 #include "runtime/stubCodeGenerator.hpp"
  39 #include "runtime/vm_version.hpp"
  40 #include "utilities/checkedCast.hpp"
  41 #include "utilities/ostream.hpp"
  42 #include "utilities/powerOfTwo.hpp"
  43 #include "utilities/virtualizationSupport.hpp"
  44 
  45 int VM_Version::_cpu;
  46 int VM_Version::_model;
  47 int VM_Version::_stepping;
  48 bool VM_Version::_has_intel_jcc_erratum;
  49 VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, };
  50 
  51 #define DECLARE_CPU_FEATURE_NAME(id, name, bit) XSTR(name),
  52 const char* VM_Version::_features_names[] = { CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_NAME)};
  53 #undef DECLARE_CPU_FEATURE_FLAG
  54 
  55 // Address of instruction which causes SEGV
  56 address VM_Version::_cpuinfo_segv_addr = nullptr;
  57 // Address of instruction after the one which causes SEGV
  58 address VM_Version::_cpuinfo_cont_addr = nullptr;
  59 // Address of instruction which causes APX specific SEGV
  60 address VM_Version::_cpuinfo_segv_addr_apx = nullptr;
  61 // Address of instruction after the one which causes APX specific SEGV
  62 address VM_Version::_cpuinfo_cont_addr_apx = nullptr;
  63 
  64 static BufferBlob* stub_blob;
  65 static const int stub_size = 2000;
  66 
  67 int VM_Version::VM_Features::_features_bitmap_size = sizeof(VM_Version::VM_Features::_features_bitmap) / BytesPerLong;
  68 
  69 VM_Version::VM_Features VM_Version::_features;
  70 VM_Version::VM_Features VM_Version::_cpu_features;
  71 

1084     // the cache. We could switch to CPUID/SERIALIZE ("4"/"5") going forward.
1085     if (supports_clwb()) {
1086       FLAG_SET_ERGO(X86ICacheSync, 3);
1087     } else if (supports_clflushopt()) {
1088       FLAG_SET_ERGO(X86ICacheSync, 2);
1089     } else {
1090       FLAG_SET_ERGO(X86ICacheSync, 1);
1091     }
1092   } else {
1093     if ((X86ICacheSync == 2) && !supports_clflushopt()) {
1094       vm_exit_during_initialization("CPU does not support CLFLUSHOPT, unable to use X86ICacheSync=2");
1095     }
1096     if ((X86ICacheSync == 3) && !supports_clwb()) {
1097       vm_exit_during_initialization("CPU does not support CLWB, unable to use X86ICacheSync=3");
1098     }
1099     if ((X86ICacheSync == 5) && !supports_serialize()) {
1100       vm_exit_during_initialization("CPU does not support SERIALIZE, unable to use X86ICacheSync=5");
1101     }
1102   }
1103 
1104   stringStream ss(2048);
1105   ss.print("(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
1106            cores_per_cpu(), threads_per_core(),
1107            cpu_family(), _model, _stepping, os::cpu_microcode_revision());
1108   ss.print(", ");
1109   int features_offset = (int)ss.size();
1110   insert_features_names(_features, ss);
1111 
1112   _cpu_info_string = ss.as_string(true);
1113   _features_string = _cpu_info_string + features_offset;





1114 
1115   // Use AES instructions if available.
1116   if (supports_aes()) {
1117     if (FLAG_IS_DEFAULT(UseAES)) {
1118       FLAG_SET_DEFAULT(UseAES, true);
1119     }
1120     if (!UseAES) {
1121       if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
1122         warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
1123       }
1124       FLAG_SET_DEFAULT(UseAESIntrinsics, false);
1125     } else {
1126       if (UseSSE > 2) {
1127         if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
1128           FLAG_SET_DEFAULT(UseAESIntrinsics, true);
1129         }
1130       } else {
1131         // The AES intrinsic stubs require AES instruction support (of course)
1132         // but also require sse3 mode or higher for instructions it use.
1133         if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {

3275       return 128; // Pentium 3 (and all other old CPUs)
3276     }
3277   }
3278 }
3279 
3280 bool VM_Version::is_intrinsic_supported(vmIntrinsicID id) {
3281   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
3282   switch (id) {
3283   case vmIntrinsics::_floatToFloat16:
3284   case vmIntrinsics::_float16ToFloat:
3285     if (!supports_float16()) {
3286       return false;
3287     }
3288     break;
3289   default:
3290     break;
3291   }
3292   return true;
3293 }
3294 
3295 void VM_Version::insert_features_names(VM_Version::VM_Features features, stringStream& ss) {
3296   int i = 0;
3297   ss.join([&]() {
3298     const char* str = nullptr;
3299     while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
3300       if (features.supports_feature((VM_Version::Feature_Flag)i)) {
3301         str = _features_names[i];
3302       }
3303       i += 1;
3304     }
3305     return str;
3306   }, ", ");
3307 }
3308 
3309 void VM_Version::get_cpu_features_name(void* features_buffer, stringStream& ss) {
3310   VM_Features* features = (VM_Features*)features_buffer;
3311   insert_features_names(*features, ss);
3312 }
3313 
3314 void VM_Version::get_missing_features_name(void* features_buffer, stringStream& ss) {
3315   VM_Features* features_to_test = (VM_Features*)features_buffer;
3316   int i = 0;
3317   ss.join([&]() {
3318     const char* str = nullptr;
3319     while ((i < MAX_CPU_FEATURES) && (str == nullptr)) {
3320       Feature_Flag flag = (Feature_Flag)i;
3321       if (features_to_test->supports_feature(flag) && !_features.supports_feature(flag)) {
3322         str = _features_names[i];
3323       }
3324       i += 1;
3325     }
3326     return str;
3327   }, ", ");
3328 }
3329 
3330 int VM_Version::cpu_features_size() {
3331   return sizeof(VM_Features);
3332 }
3333 
3334 void VM_Version::store_cpu_features(void* buf) {
3335   VM_Features copy = _features;
3336   copy.clear_feature(CPU_HT); // HT does not result in incompatibility of aot code cache
3337   memcpy(buf, &copy, sizeof(VM_Features));
3338 }
3339 
3340 bool VM_Version::supports_features(void* features_buffer) {
3341   VM_Features* features_to_test = (VM_Features*)features_buffer;
3342   return _features.supports_features(features_to_test);
3343 }
< prev index next >