1 /*
2 * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2026 SAP SE. 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 "asm/assembler.inline.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "compiler/compilerDefinitions.inline.hpp"
29 #include "compiler/disassembler.hpp"
30 #include "jvm.h"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/globals_extension.hpp"
33 #include "runtime/java.hpp"
34 #include "runtime/os.hpp"
35 #include "runtime/stubCodeGenerator.hpp"
36 #include "runtime/vm_version.hpp"
37 #include "utilities/align.hpp"
38 #include "utilities/defaultStream.hpp"
39 #include "utilities/globalDefinitions.hpp"
40 #include "utilities/powerOfTwo.hpp"
41
42 #include <sys/sysinfo.h>
43 #if defined(_AIX)
44 #include "os_aix.hpp"
45 #include <libperfstat.h>
46 #endif
47
48 bool VM_Version::_is_determine_features_test_running = false;
49 uint64_t VM_Version::_dscr_val = 0;
50
51 #define MSG(flag) \
52 if (flag && !FLAG_IS_DEFAULT(flag)) \
53 jio_fprintf(defaultStream::error_stream(), \
54 "warning: -XX:+" #flag " requires -XX:+UseSIGTRAP\n" \
55 " -XX:+" #flag " will be disabled!\n");
56
57 void VM_Version::initialize() {
58
59 // Test which instructions are supported and measure cache line size.
60 determine_features();
61
62 // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features.
63 if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) {
64 if (VM_Version::has_brw()) {
65 FLAG_SET_ERGO(PowerArchitecturePPC64, 10);
66 } else if (VM_Version::has_darn()) {
67 FLAG_SET_ERGO(PowerArchitecturePPC64, 9);
68 } else {
69 FLAG_SET_ERGO(PowerArchitecturePPC64, 8);
70 }
71 }
72
73 bool PowerArchitecturePPC64_ok = false;
74 switch (PowerArchitecturePPC64) {
75 case 10: if (!VM_Version::has_brw() ) break;
76 case 9: if (!VM_Version::has_darn() ) break;
77 case 8: PowerArchitecturePPC64_ok = true; break;
78 default: break;
79 }
80 guarantee(PowerArchitecturePPC64_ok, "PowerArchitecturePPC64 cannot be set to "
81 "%zu on this machine", PowerArchitecturePPC64);
82
83 // Power 8: Configure Data Stream Control Register.
84 if (VM_Version::has_mfdscr()) {
85 config_dscr();
86 }
87
88 if (!UseSIGTRAP) {
89 MSG(TrapBasedICMissChecks);
90 MSG(TrapBasedNullChecks);
91 MSG(TrapBasedNMethodEntryBarriers);
92 FLAG_SET_ERGO(TrapBasedNullChecks, false);
93 FLAG_SET_ERGO(TrapBasedICMissChecks, false);
94 FLAG_SET_ERGO(TrapBasedNMethodEntryBarriers, false);
95 }
96
97 #ifdef COMPILER2
98 if (!UseSIGTRAP) {
99 MSG(TrapBasedRangeChecks);
100 FLAG_SET_ERGO(TrapBasedRangeChecks, false);
101 }
102
103 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
104 FLAG_SET_ERGO(UsePopCountInstruction, true);
105 }
106
107 if (PowerArchitecturePPC64 >= 9) {
108 // Performance is good since Power9.
109 if (FLAG_IS_DEFAULT(SuperwordUseVSX) && CompilerConfig::is_c2_enabled()) {
110 FLAG_SET_ERGO(SuperwordUseVSX, true);
111 }
112 } else if (SuperwordUseVSX) {
113 warning("SuperwordUseVSX specified, but needs at least Power9.");
114 FLAG_SET_DEFAULT(SuperwordUseVSX, false);
115 }
116
117 MaxVectorSize = SuperwordUseVSX ? 16 : 8;
118 if (!SuperwordUseVSX && FLAG_IS_DEFAULT(EnableVectorSupport)) {
119 // VectorSupport intrinsics currently have issues with MaxVectorSize < 16 (JDK-8370803).
120 FLAG_SET_ERGO(EnableVectorSupport, false);
121 }
122 if (FLAG_IS_DEFAULT(AlignVector)) {
123 FLAG_SET_ERGO(AlignVector, false);
124 }
125
126 if (PowerArchitecturePPC64 >= 9) {
127 if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstructionsPPC64)) {
128 FLAG_SET_ERGO(UseCountTrailingZerosInstructionsPPC64, true);
129 }
130 if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) {
131 FLAG_SET_ERGO(UseCharacterCompareIntrinsics, true);
132 }
133 if (SuperwordUseVSX) {
134 if (FLAG_IS_DEFAULT(UseVectorByteReverseInstructionsPPC64)) {
135 FLAG_SET_ERGO(UseVectorByteReverseInstructionsPPC64, true);
136 }
137 } else if (UseVectorByteReverseInstructionsPPC64) {
138 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs SuperwordUseVSX.");
139 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
140 }
141 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
142 FLAG_SET_ERGO(UseBASE64Intrinsics, true);
143 }
144 } else {
145 if (UseCountTrailingZerosInstructionsPPC64) {
146 warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9.");
147 FLAG_SET_DEFAULT(UseCountTrailingZerosInstructionsPPC64, false);
148 }
149 if (UseCharacterCompareIntrinsics) {
150 warning("UseCharacterCompareIntrinsics specified, but needs at least Power9.");
151 FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false);
152 }
153 if (UseVectorByteReverseInstructionsPPC64) {
154 warning("UseVectorByteReverseInstructionsPPC64 specified, but needs at least Power9.");
155 FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false);
156 }
157 if (UseBASE64Intrinsics) {
158 warning("UseBASE64Intrinsics specified, but needs at least Power9.");
159 FLAG_SET_DEFAULT(UseBASE64Intrinsics, false);
160 }
161 }
162
163 if (PowerArchitecturePPC64 >= 10) {
164 if (FLAG_IS_DEFAULT(UseByteReverseInstructions)) {
165 FLAG_SET_ERGO(UseByteReverseInstructions, true);
166 }
167 } else {
168 if (UseByteReverseInstructions) {
169 warning("UseByteReverseInstructions specified, but needs at least Power10.");
170 FLAG_SET_DEFAULT(UseByteReverseInstructions, false);
171 }
172 }
173
174 if (OptimizeFill) {
175 warning("OptimizeFill is not supported on this CPU.");
176 FLAG_SET_DEFAULT(OptimizeFill, false);
177 }
178
179 if (OptoScheduling) {
180 // The OptoScheduling information is not maintained in ppd.ad.
181 warning("OptoScheduling is not supported on this CPU.");
182 FLAG_SET_DEFAULT(OptoScheduling, false);
183 }
184 #endif
185
186 // Create and print feature-string.
187 char buf[(num_features+1) * 16]; // Max 16 chars per feature.
188 jio_snprintf(buf, sizeof(buf),
189 "ppc64 sha aes%s%s%s",
190 (has_mfdscr() ? " mfdscr" : ""),
191 (has_darn() ? " darn" : ""),
192 (has_brw() ? " brw" : "")
193 // Make sure number of %s matches num_features!
194 );
195 _cpu_info_string = os::strdup(buf);
196 if (Verbose) {
197 print_features();
198 }
199
200 // Used by C1.
201 _supports_atomic_getset4 = true;
202 _supports_atomic_getadd4 = true;
203 _supports_atomic_getset8 = true;
204 _supports_atomic_getadd8 = true;
205
206 intx cache_line_size = L1_data_cache_line_size();
207
208 if (PowerArchitecturePPC64 >= 9) {
209 if (os::supports_map_sync() == true) {
210 _data_cache_line_flush_size = cache_line_size;
211 }
212 }
213
214 if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) AllocatePrefetchStyle = 1;
215
216 if (cache_line_size > AllocatePrefetchStepSize) AllocatePrefetchStepSize = cache_line_size;
217 // PPC processors have an automatic prefetch engine.
218 if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) AllocatePrefetchLines = 1;
219 if (AllocatePrefetchDistance < 0) AllocatePrefetchDistance = 3 * cache_line_size;
220
221 assert(AllocatePrefetchLines > 0, "invalid value");
222 if (AllocatePrefetchLines < 1) { // Set valid value in product VM.
223 AllocatePrefetchLines = 1; // Conservative value.
224 }
225
226 if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) {
227 AllocatePrefetchStyle = 1; // Fall back if inappropriate.
228 }
229
230 assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
231
232 if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (cache_line_size > ContendedPaddingWidth)) {
233 ContendedPaddingWidth = cache_line_size;
234 }
235
236 // If running on Power8 or newer hardware, the implementation uses the available vector instructions.
237 // In all other cases, the implementation uses only generally available instructions.
238 if (!UseCRC32Intrinsics) {
239 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
240 FLAG_SET_DEFAULT(UseCRC32Intrinsics, true);
241 }
242 }
243
244 // Implementation does not use any of the vector instructions available with Power8.
245 // Their exploitation is still pending (aka "work in progress").
246 if (!UseCRC32CIntrinsics) {
247 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
248 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
249 }
250 }
251
252 // TODO: Provide implementation.
253 if (UseAdler32Intrinsics) {
254 warning("Adler32Intrinsics not available on this CPU.");
255 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false);
256 }
257
258 // The AES intrinsic stubs require AES instruction support.
259 if (FLAG_IS_DEFAULT(UseAES)) {
260 UseAES = true;
261 }
262
263 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
264 UseAESIntrinsics = true;
265 }
266
267 if (UseAESCTRIntrinsics) {
268 warning("AES/CTR intrinsics are not available on this CPU");
269 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
270 }
271
272 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
273 UseGHASHIntrinsics = true;
274 }
275
276 if (FLAG_IS_DEFAULT(UseFMA)) {
277 FLAG_SET_DEFAULT(UseFMA, true);
278 }
279
280 if (UseMD5Intrinsics) {
281 warning("MD5 intrinsics are not available on this CPU");
282 FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
283 }
284
285 if (FLAG_IS_DEFAULT(UseSHA)) {
286 UseSHA = true;
287 }
288
289 if (UseSHA1Intrinsics) {
290 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
291 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
292 }
293
294 if (UseSHA) {
295 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
296 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
297 }
298 } else if (UseSHA256Intrinsics) {
299 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
300 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
301 }
302
303 if (UseSHA) {
304 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
305 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
306 }
307 } else if (UseSHA512Intrinsics) {
308 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
309 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
310 }
311
312 if (UseSHA3Intrinsics) {
313 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
314 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
315 }
316
317 #ifdef COMPILER2
318 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
319 UseSquareToLenIntrinsic = true;
320 }
321 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
322 UseMulAddIntrinsic = true;
323 }
324 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
325 UseMultiplyToLenIntrinsic = true;
326 }
327 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
328 UseMontgomeryMultiplyIntrinsic = true;
329 }
330 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
331 UseMontgomerySquareIntrinsic = true;
332 }
333 #endif
334
335 if (UseVectorizedMismatchIntrinsic) {
336 warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
337 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
338 }
339
340 // This machine allows unaligned memory accesses
341 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
342 FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
343 }
344
345 if (InlineTypePassFieldsAsArgs) {
346 warning("InlineTypePassFieldsAsArgs is not supported on this CPU");
347 FLAG_SET_DEFAULT(InlineTypePassFieldsAsArgs, false);
348 }
349 if (InlineTypeReturnedAsFields) {
350 warning("InlineTypeReturnedAsFields is not supported on this CPU");
351 FLAG_SET_DEFAULT(InlineTypeReturnedAsFields, false);
352 }
353
354 // TODO: Valhalla optimizations
355 if (FLAG_IS_DEFAULT(UseArrayFlattening )) FLAG_SET_DEFAULT(UseArrayFlattening , false);
356 if (FLAG_IS_DEFAULT(UseFieldFlattening )) FLAG_SET_DEFAULT(UseFieldFlattening , false);
357 if (FLAG_IS_DEFAULT(UseNullFreeNonAtomicValueFlattening)) FLAG_SET_DEFAULT(UseNullFreeNonAtomicValueFlattening, false);
358 if (FLAG_IS_DEFAULT(UseNullableAtomicValueFlattening )) FLAG_SET_DEFAULT(UseNullableAtomicValueFlattening , false);
359 if (FLAG_IS_DEFAULT(UseNullFreeAtomicValueFlattening )) FLAG_SET_DEFAULT(UseNullFreeAtomicValueFlattening , false);
360 if (FLAG_IS_DEFAULT(UseNullableNonAtomicValueFlattening)) FLAG_SET_DEFAULT(UseNullableNonAtomicValueFlattening, false);
361
362 check_virtualizations();
363 }
364
365 void VM_Version::check_virtualizations() {
366 #if defined(_AIX)
367 int rc = 0;
368 perfstat_partition_total_t pinfo;
369 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
370 if (rc == 1) {
371 Abstract_VM_Version::_detected_virtualization = PowerVM;
372 }
373 #else
374 const char* info_file = "/proc/ppc64/lparcfg";
375 // system_type=...qemu indicates PowerKVM
376 // e.g. system_type=IBM pSeries (emulated by qemu)
377 char line[500];
378 FILE* fp = os::fopen(info_file, "r");
379 if (fp == nullptr) {
380 return;
381 }
382 const char* system_type="system_type="; // in case this line contains qemu, it is KVM
383 const char* num_lpars="NumLpars="; // in case of non-KVM : if this line is found it is PowerVM
384 bool num_lpars_found = false;
385
386 while (fgets(line, sizeof(line), fp) != nullptr) {
387 if (strncmp(line, system_type, strlen(system_type)) == 0) {
388 if (strstr(line, "qemu") != nullptr) {
389 Abstract_VM_Version::_detected_virtualization = PowerKVM;
390 fclose(fp);
391 return;
392 }
393 }
394 if (strncmp(line, num_lpars, strlen(num_lpars)) == 0) {
395 num_lpars_found = true;
396 }
397 }
398 if (num_lpars_found) {
399 Abstract_VM_Version::_detected_virtualization = PowerVM;
400 } else {
401 Abstract_VM_Version::_detected_virtualization = PowerFullPartitionMode;
402 }
403 fclose(fp);
404 #endif
405 }
406
407 void VM_Version::print_platform_virtualization_info(outputStream* st) {
408 #if defined(_AIX)
409 // more info about perfstat API see
410 // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.prftools/idprftools_perfstat_glob_partition.htm
411 int rc = 0;
412 perfstat_partition_total_t pinfo;
413 memset(&pinfo, 0, sizeof(perfstat_partition_total_t));
414 rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
415 if (rc != 1) {
416 return;
417 } else {
418 st->print_cr("Virtualization type : PowerVM");
419 }
420 // CPU information
421 perfstat_cpu_total_t cpuinfo;
422 memset(&cpuinfo, 0, sizeof(perfstat_cpu_total_t));
423 rc = perfstat_cpu_total(nullptr, &cpuinfo, sizeof(perfstat_cpu_total_t), 1);
424 if (rc != 1) {
425 return;
426 }
427
428 st->print_cr("Processor description : %s", cpuinfo.description);
429 st->print_cr("Processor speed : %llu Hz", cpuinfo.processorHZ);
430
431 st->print_cr("LPAR partition name : %s", pinfo.name);
432 st->print_cr("LPAR partition number : %u", pinfo.lpar_id);
433 st->print_cr("LPAR partition type : %s", pinfo.type.b.shared_enabled ? "shared" : "dedicated");
434 st->print_cr("LPAR mode : %s", pinfo.type.b.donate_enabled ? "donating" : pinfo.type.b.capped ? "capped" : "uncapped");
435 st->print_cr("LPAR partition group ID : %u", pinfo.group_id);
436 st->print_cr("LPAR shared pool ID : %u", pinfo.pool_id);
437
438 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_capable ? "capable" : "not capable");
439 st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_enabled ? "on" : "off");
440 st->print_cr("AME (active memory expansion) : %s", pinfo.type.b.ame_enabled ? "on" : "off");
441
442 if (pinfo.type.b.ame_enabled) {
443 st->print_cr("AME true memory in bytes : %llu", pinfo.true_memory);
444 st->print_cr("AME expanded memory in bytes : %llu", pinfo.expanded_memory);
445 }
446
447 st->print_cr("SMT : %s", pinfo.type.b.smt_capable ? "capable" : "not capable");
448 st->print_cr("SMT : %s", pinfo.type.b.smt_enabled ? "on" : "off");
449 int ocpus = pinfo.online_cpus > 0 ? pinfo.online_cpus : 1;
450 st->print_cr("LPAR threads : %d", cpuinfo.ncpus/ocpus);
451 st->print_cr("LPAR online virtual cpus : %d", pinfo.online_cpus);
452 st->print_cr("LPAR logical cpus : %d", cpuinfo.ncpus);
453 st->print_cr("LPAR maximum virtual cpus : %u", pinfo.max_cpus);
454 st->print_cr("LPAR minimum virtual cpus : %u", pinfo.min_cpus);
455 st->print_cr("LPAR entitled capacity : %4.2f", (double) (pinfo.entitled_proc_capacity/100.0));
456 st->print_cr("LPAR online memory : %llu MB", pinfo.online_memory);
457 st->print_cr("LPAR maximum memory : %llu MB", pinfo.max_memory);
458 st->print_cr("LPAR minimum memory : %llu MB", pinfo.min_memory);
459 #else
460 const char* info_file = "/proc/ppc64/lparcfg";
461 const char* kw[] = { "system_type=", // qemu indicates PowerKVM
462 "partition_entitled_capacity=", // entitled processor capacity percentage
463 "partition_max_entitled_capacity=",
464 "capacity_weight=", // partition CPU weight
465 "partition_active_processors=",
466 "partition_potential_processors=",
467 "entitled_proc_capacity_available=",
468 "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
469 "shared_processor_mode=", // (non)dedicated partition
470 "system_potential_processors=",
471 "pool=", // CPU-pool number
472 "pool_capacity=",
473 "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
474 nullptr };
475 if (!print_matching_lines_from_file(info_file, st, kw)) {
476 st->print_cr(" <%s Not Available>", info_file);
477 }
478 #endif
479 }
480
481 void VM_Version::print_features() {
482 tty->print_cr("Version: %s L1_data_cache_line_size=%d", cpu_info_string(), L1_data_cache_line_size());
483
484 if (Verbose) {
485 if (ContendedPaddingWidth > 0) {
486 tty->cr();
487 tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
488 }
489 }
490 }
491
492 void VM_Version::determine_features() {
493 #if defined(ABI_ELFv2)
494 const int code_size = (num_features + 1 /*blr*/) * BytesPerInstWord;
495 #else
496 const int code_size = (num_features + 1 /*blr*/ + 6 /* fd */) * BytesPerInstWord;
497 #endif
498 int features = 0;
499
500 // Allocate space for the code.
501 ResourceMark rm;
502 CodeBuffer cb("detect_cpu_features", code_size, 0);
503 MacroAssembler* a = new MacroAssembler(&cb);
504
505 // Must be set to true so we can generate the test code.
506 _features = VM_Version::all_features_m;
507
508 // Emit code.
509 void (*test)() = (void(*)())(void *)a->function_entry();
510 uint32_t *code = (uint32_t *)a->pc();
511 a->mfdscr(R0);
512 a->darn(R7);
513 a->brw(R5, R6);
514 a->blr();
515
516 uint32_t *code_end = (uint32_t *)a->pc();
517 a->flush();
518 _features = VM_Version::unknown_m;
519
520 // Print the detection code.
521 if (PrintAssembly) {
522 ttyLocker ttyl;
523 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
524 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
525 }
526
527 // Execute code. Illegal instructions will be replaced by 0 in the signal handler.
528 VM_Version::_is_determine_features_test_running = true;
529 (*test)();
530 VM_Version::_is_determine_features_test_running = false;
531
532 // determine which instructions are legal.
533 int feature_cntr = 0;
534 if (code[feature_cntr++]) features |= mfdscr_m;
535 if (code[feature_cntr++]) features |= darn_m;
536 if (code[feature_cntr++]) features |= brw_m;
537
538 // Print the detection code.
539 if (PrintAssembly) {
540 ttyLocker ttyl;
541 tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", p2i(code));
542 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
543 }
544
545 _features = features;
546
547 _L1_data_cache_line_size = VM_Version::get_dcache_line_size();
548 assert(_L1_data_cache_line_size >= DEFAULT_CACHE_LINE_SIZE,
549 "processors with smaller cache line size are no longer supported");
550 }
551
552 // Power 8: Configure Data Stream Control Register.
553 void VM_Version::config_dscr() {
554 // 7 InstWords for each call (function descriptor + blr instruction).
555 const int code_size = (2+2*7)*BytesPerInstWord;
556
557 // Allocate space for the code.
558 ResourceMark rm;
559 CodeBuffer cb("config_dscr", code_size, 0);
560 MacroAssembler* a = new MacroAssembler(&cb);
561
562 // Emit code.
563 uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry();
564 uint32_t *code = (uint32_t *)a->pc();
565 a->mfdscr(R3);
566 a->blr();
567
568 void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry();
569 a->mtdscr(R3);
570 a->blr();
571
572 uint32_t *code_end = (uint32_t *)a->pc();
573 a->flush();
574
575 // Print the detection code.
576 if (PrintAssembly) {
577 ttyLocker ttyl;
578 tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
579 Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
580 }
581
582 // Apply the configuration if needed.
583 _dscr_val = (*get_dscr)();
584 if (Verbose) {
585 tty->print_cr("dscr value was 0x%lx" , _dscr_val);
586 }
587 bool change_requested = false;
588 if (DSCR_PPC64 != (uintx)-1) {
589 _dscr_val = DSCR_PPC64;
590 change_requested = true;
591 }
592 if (DSCR_DPFD_PPC64 <= 7) {
593 uint64_t mask = 0x7;
594 if ((_dscr_val & mask) != DSCR_DPFD_PPC64) {
595 _dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64);
596 change_requested = true;
597 }
598 }
599 if (DSCR_URG_PPC64 <= 7) {
600 uint64_t mask = 0x7 << 6;
601 if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
602 _dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
603 change_requested = true;
604 }
605 }
606 if (change_requested) {
607 (*set_dscr)(_dscr_val);
608 if (Verbose) {
609 tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)());
610 }
611 }
612 }
613
614 static uint64_t saved_features = 0;
615
616 void VM_Version::allow_all() {
617 saved_features = _features;
618 _features = all_features_m;
619 }
620
621 void VM_Version::revert() {
622 _features = saved_features;
623 }
624
625 // get cpu information.
626 void VM_Version::initialize_cpu_information(void) {
627 // do nothing if cpu info has been initialized
628 if (_initialized) {
629 return;
630 }
631
632 _no_of_cores = os::processor_count();
633 _no_of_threads = _no_of_cores;
634 _no_of_sockets = _no_of_cores;
635 os::snprintf_checked(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
636 os::snprintf_checked(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", cpu_info_string());
637 _initialized = true;
638 }