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 }