1 /* 2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "precompiled.hpp" 27 #include "asm/macroAssembler.hpp" 28 #include "asm/macroAssembler.inline.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "runtime/java.hpp" 31 #include "runtime/os.hpp" 32 #include "runtime/stubCodeGenerator.hpp" 33 #include "runtime/vm_version.hpp" 34 #include "utilities/formatBuffer.hpp" 35 #include "utilities/macros.hpp" 36 37 #include OS_HEADER_INLINE(os) 38 39 #include <asm/hwcap.h> 40 #include <sys/auxv.h> 41 #include <sys/prctl.h> 42 43 #ifndef HWCAP_AES 44 #define HWCAP_AES (1<<3) 45 #endif 46 47 #ifndef HWCAP_PMULL 48 #define HWCAP_PMULL (1<<4) 49 #endif 50 51 #ifndef HWCAP_SHA1 52 #define HWCAP_SHA1 (1<<5) 53 #endif 54 55 #ifndef HWCAP_SHA2 56 #define HWCAP_SHA2 (1<<6) 57 #endif 58 59 #ifndef HWCAP_CRC32 60 #define HWCAP_CRC32 (1<<7) 61 #endif 62 63 #ifndef HWCAP_ATOMICS 64 #define HWCAP_ATOMICS (1<<8) 65 #endif 66 67 #ifndef HWCAP_SHA512 68 #define HWCAP_SHA512 (1 << 21) 69 #endif 70 71 #ifndef HWCAP_SVE 72 #define HWCAP_SVE (1 << 22) 73 #endif 74 75 #ifndef HWCAP2_SVE2 76 #define HWCAP2_SVE2 (1 << 1) 77 #endif 78 79 #ifndef PR_SVE_GET_VL 80 // For old toolchains which do not have SVE related macros defined. 81 #define PR_SVE_SET_VL 50 82 #define PR_SVE_GET_VL 51 83 #endif 84 85 int VM_Version::_cpu; 86 int VM_Version::_model; 87 int VM_Version::_model2; 88 int VM_Version::_variant; 89 int VM_Version::_revision; 90 int VM_Version::_stepping; 91 bool VM_Version::_dcpop; 92 int VM_Version::_initial_sve_vector_length; 93 VM_Version::PsrInfo VM_Version::_psr_info = { 0, }; 94 95 static BufferBlob* stub_blob; 96 static const int stub_size = 550; 97 98 extern "C" { 99 typedef void (*getPsrInfo_stub_t)(void*); 100 } 101 static getPsrInfo_stub_t getPsrInfo_stub = NULL; 102 103 104 class VM_Version_StubGenerator: public StubCodeGenerator { 105 public: 106 107 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 108 109 address generate_getPsrInfo() { 110 StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); 111 # define __ _masm-> 112 address start = __ pc(); 113 114 // void getPsrInfo(VM_Version::PsrInfo* psr_info); 115 116 address entry = __ pc(); 117 118 __ enter(); 119 120 __ get_dczid_el0(rscratch1); 121 __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset()))); 122 123 __ get_ctr_el0(rscratch1); 124 __ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::ctr_el0_offset()))); 125 126 __ leave(); 127 __ ret(lr); 128 129 # undef __ 130 131 return start; 132 } 133 }; 134 135 void VM_Version::get_processor_features() { 136 _supports_cx8 = true; 137 _supports_atomic_getset4 = true; 138 _supports_atomic_getadd4 = true; 139 _supports_atomic_getset8 = true; 140 _supports_atomic_getadd8 = true; 141 142 getPsrInfo_stub(&_psr_info); 143 144 int dcache_line = VM_Version::dcache_line_size(); 145 146 // Limit AllocatePrefetchDistance so that it does not exceed the 147 // constraint in AllocatePrefetchDistanceConstraintFunc. 148 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) 149 FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3*dcache_line)); 150 151 if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) 152 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line); 153 if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) 154 FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line); 155 if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) 156 FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line); 157 if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance)) 158 FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, 3*dcache_line); 159 160 if (PrefetchCopyIntervalInBytes != -1 && 161 ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) { 162 warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768"); 163 PrefetchCopyIntervalInBytes &= ~7; 164 if (PrefetchCopyIntervalInBytes >= 32768) 165 PrefetchCopyIntervalInBytes = 32760; 166 } 167 168 if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) { 169 warning("AllocatePrefetchDistance must be multiple of 8"); 170 AllocatePrefetchDistance &= ~7; 171 } 172 173 if (AllocatePrefetchStepSize & 7) { 174 warning("AllocatePrefetchStepSize must be multiple of 8"); 175 AllocatePrefetchStepSize &= ~7; 176 } 177 178 if (SoftwarePrefetchHintDistance != -1 && 179 (SoftwarePrefetchHintDistance & 7)) { 180 warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8"); 181 SoftwarePrefetchHintDistance &= ~7; 182 } 183 184 uint64_t auxv = getauxval(AT_HWCAP); 185 uint64_t auxv2 = getauxval(AT_HWCAP2); 186 187 char buf[512]; 188 189 _features = auxv; 190 191 int cpu_lines = 0; 192 if (FILE *f = fopen("/proc/cpuinfo", "r")) { 193 // need a large buffer as the flags line may include lots of text 194 char buf[1024], *p; 195 while (fgets(buf, sizeof (buf), f) != NULL) { 196 if ((p = strchr(buf, ':')) != NULL) { 197 long v = strtol(p+1, NULL, 0); 198 if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) { 199 _cpu = v; 200 cpu_lines++; 201 } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) { 202 _variant = v; 203 } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) { 204 if (_model != v) _model2 = _model; 205 _model = v; 206 } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) { 207 _revision = v; 208 } else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) { 209 if (strstr(p+1, "dcpop")) { 210 _dcpop = true; 211 } 212 } 213 } 214 } 215 fclose(f); 216 } 217 218 if (os::supports_map_sync()) { 219 // if dcpop is available publish data cache line flush size via 220 // generic field, otherwise let if default to zero thereby 221 // disabling writeback 222 if (_dcpop) { 223 _data_cache_line_flush_size = dcache_line; 224 } 225 } 226 227 // Enable vendor specific features 228 229 // Ampere eMAG 230 if (_cpu == CPU_AMCC && (_model == 0) && (_variant == 0x3)) { 231 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { 232 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); 233 } 234 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { 235 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); 236 } 237 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) { 238 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, !(_revision == 1 || _revision == 2)); 239 } 240 } 241 242 // ThunderX 243 if (_cpu == CPU_CAVIUM && (_model == 0xA1)) { 244 guarantee(_variant != 0, "Pre-release hardware no longer supported."); 245 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { 246 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); 247 } 248 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { 249 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, (_variant > 0)); 250 } 251 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) { 252 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false); 253 } 254 } 255 256 // ThunderX2 257 if ((_cpu == CPU_CAVIUM && (_model == 0xAF)) || 258 (_cpu == CPU_BROADCOM && (_model == 0x516))) { 259 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { 260 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); 261 } 262 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { 263 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); 264 } 265 } 266 267 // HiSilicon TSV110 268 if (_cpu == CPU_HISILICON && _model == 0xd01) { 269 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { 270 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); 271 } 272 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { 273 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); 274 } 275 } 276 277 // Cortex A53 278 if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) { 279 _features |= CPU_A53MAC; 280 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) { 281 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false); 282 } 283 } 284 285 // Cortex A73 286 if (_cpu == CPU_ARM && (_model == 0xd09 || _model2 == 0xd09)) { 287 if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance)) { 288 FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, -1); 289 } 290 // A73 is faster with short-and-easy-for-speculative-execution-loop 291 if (FLAG_IS_DEFAULT(UseSimpleArrayEquals)) { 292 FLAG_SET_DEFAULT(UseSimpleArrayEquals, true); 293 } 294 } 295 296 if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH; 297 // If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07) 298 // we assume the worst and assume we could be on a big little system and have 299 // undisclosed A53 cores which we could be swapped to at any stage 300 if (_cpu == CPU_ARM && cpu_lines == 1 && _model == 0xd07) _features |= CPU_A53MAC; 301 302 sprintf(buf, "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision); 303 if (_model2) sprintf(buf+strlen(buf), "(0x%03x)", _model2); 304 if (auxv & HWCAP_ASIMD) strcat(buf, ", simd"); 305 if (auxv & HWCAP_CRC32) strcat(buf, ", crc"); 306 if (auxv & HWCAP_AES) strcat(buf, ", aes"); 307 if (auxv & HWCAP_SHA1) strcat(buf, ", sha1"); 308 if (auxv & HWCAP_SHA2) strcat(buf, ", sha256"); 309 if (auxv & HWCAP_SHA512) strcat(buf, ", sha512"); 310 if (auxv & HWCAP_ATOMICS) strcat(buf, ", lse"); 311 if (auxv & HWCAP_SVE) strcat(buf, ", sve"); 312 if (auxv2 & HWCAP2_SVE2) strcat(buf, ", sve2"); 313 314 _features_string = os::strdup(buf); 315 316 if (FLAG_IS_DEFAULT(UseCRC32)) { 317 UseCRC32 = (auxv & HWCAP_CRC32) != 0; 318 } 319 320 if (UseCRC32 && (auxv & HWCAP_CRC32) == 0) { 321 warning("UseCRC32 specified, but not supported on this CPU"); 322 FLAG_SET_DEFAULT(UseCRC32, false); 323 } 324 325 if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) { 326 FLAG_SET_DEFAULT(UseAdler32Intrinsics, true); 327 } 328 329 if (UseVectorizedMismatchIntrinsic) { 330 warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU."); 331 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); 332 } 333 334 if (auxv & HWCAP_ATOMICS) { 335 if (FLAG_IS_DEFAULT(UseLSE)) 336 FLAG_SET_DEFAULT(UseLSE, true); 337 } else { 338 if (UseLSE) { 339 warning("UseLSE specified, but not supported on this CPU"); 340 FLAG_SET_DEFAULT(UseLSE, false); 341 } 342 } 343 344 if (auxv & HWCAP_AES) { 345 UseAES = UseAES || FLAG_IS_DEFAULT(UseAES); 346 UseAESIntrinsics = 347 UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics)); 348 if (UseAESIntrinsics && !UseAES) { 349 warning("UseAESIntrinsics enabled, but UseAES not, enabling"); 350 UseAES = true; 351 } 352 } else { 353 if (UseAES) { 354 warning("AES instructions are not available on this CPU"); 355 FLAG_SET_DEFAULT(UseAES, false); 356 } 357 if (UseAESIntrinsics) { 358 warning("AES intrinsics are not available on this CPU"); 359 FLAG_SET_DEFAULT(UseAESIntrinsics, false); 360 } 361 } 362 363 if (UseAESCTRIntrinsics) { 364 warning("AES/CTR intrinsics are not available on this CPU"); 365 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); 366 } 367 368 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { 369 UseCRC32Intrinsics = true; 370 } 371 372 if (auxv & HWCAP_CRC32) { 373 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) { 374 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true); 375 } 376 } else if (UseCRC32CIntrinsics) { 377 warning("CRC32C is not available on the CPU"); 378 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); 379 } 380 381 if (FLAG_IS_DEFAULT(UseFMA)) { 382 FLAG_SET_DEFAULT(UseFMA, true); 383 } 384 385 if (UseMD5Intrinsics) { 386 warning("MD5 intrinsics are not available on this CPU"); 387 FLAG_SET_DEFAULT(UseMD5Intrinsics, false); 388 } 389 390 if (auxv & (HWCAP_SHA1 | HWCAP_SHA2)) { 391 if (FLAG_IS_DEFAULT(UseSHA)) { 392 FLAG_SET_DEFAULT(UseSHA, true); 393 } 394 } else if (UseSHA) { 395 warning("SHA instructions are not available on this CPU"); 396 FLAG_SET_DEFAULT(UseSHA, false); 397 } 398 399 if (UseSHA && (auxv & HWCAP_SHA1)) { 400 if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) { 401 FLAG_SET_DEFAULT(UseSHA1Intrinsics, true); 402 } 403 } else if (UseSHA1Intrinsics) { 404 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); 405 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); 406 } 407 408 if (UseSHA && (auxv & HWCAP_SHA2)) { 409 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) { 410 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true); 411 } 412 } else if (UseSHA256Intrinsics) { 413 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); 414 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); 415 } 416 417 if (UseSHA && (auxv & HWCAP_SHA512)) { 418 // Do not auto-enable UseSHA512Intrinsics until it has been fully tested on hardware 419 // if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) { 420 // FLAG_SET_DEFAULT(UseSHA512Intrinsics, true); 421 // } 422 } else if (UseSHA512Intrinsics) { 423 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); 424 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); 425 } 426 427 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) { 428 FLAG_SET_DEFAULT(UseSHA, false); 429 } 430 431 if (auxv & HWCAP_PMULL) { 432 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { 433 FLAG_SET_DEFAULT(UseGHASHIntrinsics, true); 434 } 435 } else if (UseGHASHIntrinsics) { 436 warning("GHASH intrinsics are not available on this CPU"); 437 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); 438 } 439 440 if (is_zva_enabled()) { 441 if (FLAG_IS_DEFAULT(UseBlockZeroing)) { 442 FLAG_SET_DEFAULT(UseBlockZeroing, true); 443 } 444 if (FLAG_IS_DEFAULT(BlockZeroingLowLimit)) { 445 FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * VM_Version::zva_length()); 446 } 447 } else if (UseBlockZeroing) { 448 warning("DC ZVA is not available on this CPU"); 449 FLAG_SET_DEFAULT(UseBlockZeroing, false); 450 } 451 452 if (auxv & HWCAP_SVE) { 453 if (FLAG_IS_DEFAULT(UseSVE)) { 454 FLAG_SET_DEFAULT(UseSVE, (auxv2 & HWCAP2_SVE2) ? 2 : 1); 455 } 456 if (UseSVE > 0) { 457 _initial_sve_vector_length = prctl(PR_SVE_GET_VL); 458 } 459 } else if (UseSVE > 0) { 460 warning("UseSVE specified, but not supported on current CPU. Disabling SVE."); 461 FLAG_SET_DEFAULT(UseSVE, 0); 462 } 463 464 // This machine allows unaligned memory accesses 465 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) { 466 FLAG_SET_DEFAULT(UseUnalignedAccesses, true); 467 } 468 469 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { 470 FLAG_SET_DEFAULT(UsePopCountInstruction, true); 471 } 472 473 if (!UsePopCountInstruction) { 474 warning("UsePopCountInstruction is always enabled on this CPU"); 475 UsePopCountInstruction = true; 476 } 477 478 #ifdef COMPILER2 479 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) { 480 UseMultiplyToLenIntrinsic = true; 481 } 482 483 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) { 484 UseSquareToLenIntrinsic = true; 485 } 486 487 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) { 488 UseMulAddIntrinsic = true; 489 } 490 491 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) { 492 UseMontgomeryMultiplyIntrinsic = true; 493 } 494 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { 495 UseMontgomerySquareIntrinsic = true; 496 } 497 498 if (UseSVE > 0) { 499 if (FLAG_IS_DEFAULT(MaxVectorSize)) { 500 MaxVectorSize = _initial_sve_vector_length; 501 } else if (MaxVectorSize < 16) { 502 warning("SVE does not support vector length less than 16 bytes. Disabling SVE."); 503 UseSVE = 0; 504 } else if ((MaxVectorSize % 16) == 0 && is_power_of_2(MaxVectorSize)) { 505 int new_vl = prctl(PR_SVE_SET_VL, MaxVectorSize); 506 _initial_sve_vector_length = new_vl; 507 // If MaxVectorSize is larger than system largest supported SVE vector length, above prctl() 508 // call will set task vector length to the system largest supported value. So, we also update 509 // MaxVectorSize to that largest supported value. 510 if (new_vl < 0) { 511 vm_exit_during_initialization( 512 err_msg("Current system does not support SVE vector length for MaxVectorSize: %d", 513 (int)MaxVectorSize)); 514 } else if (new_vl != MaxVectorSize) { 515 warning("Current system only supports max SVE vector length %d. Set MaxVectorSize to %d", 516 new_vl, new_vl); 517 } 518 MaxVectorSize = new_vl; 519 } else { 520 vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize)); 521 } 522 } 523 524 if (UseSVE == 0) { // NEON 525 int min_vector_size = 8; 526 int max_vector_size = 16; 527 if (!FLAG_IS_DEFAULT(MaxVectorSize)) { 528 if (!is_power_of_2(MaxVectorSize)) { 529 vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize)); 530 } else if (MaxVectorSize < min_vector_size) { 531 warning("MaxVectorSize must be at least %i on this platform", min_vector_size); 532 FLAG_SET_DEFAULT(MaxVectorSize, min_vector_size); 533 } else if (MaxVectorSize > max_vector_size) { 534 warning("MaxVectorSize must be at most %i on this platform", max_vector_size); 535 FLAG_SET_DEFAULT(MaxVectorSize, max_vector_size); 536 } 537 } else { 538 FLAG_SET_DEFAULT(MaxVectorSize, 16); 539 } 540 } 541 542 if (FLAG_IS_DEFAULT(OptoScheduling)) { 543 OptoScheduling = true; 544 } 545 546 if (FLAG_IS_DEFAULT(AlignVector)) { 547 AlignVector = AvoidUnalignedAccesses; 548 } 549 #endif 550 } 551 552 void VM_Version::initialize() { 553 ResourceMark rm; 554 555 stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size); 556 if (stub_blob == NULL) { 557 vm_exit_during_initialization("Unable to allocate getPsrInfo_stub"); 558 } 559 560 CodeBuffer c(stub_blob); 561 VM_Version_StubGenerator g(&c); 562 getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t, 563 g.generate_getPsrInfo()); 564 565 get_processor_features(); 566 567 UNSUPPORTED_OPTION(CriticalJNINatives); 568 }