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   check_virtualizations();
346 }
347 
348 void VM_Version::check_virtualizations() {
349 #if defined(_AIX)
350   int rc = 0;
351   perfstat_partition_total_t pinfo;
352   rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
353   if (rc == 1) {
354     Abstract_VM_Version::_detected_virtualization = PowerVM;
355   }
356 #else
357   const char* info_file = "/proc/ppc64/lparcfg";
358   // system_type=...qemu indicates PowerKVM
359   // e.g. system_type=IBM pSeries (emulated by qemu)
360   char line[500];
361   FILE* fp = os::fopen(info_file, "r");
362   if (fp == nullptr) {
363     return;
364   }
365   const char* system_type="system_type=";  // in case this line contains qemu, it is KVM
366   const char* num_lpars="NumLpars="; // in case of non-KVM : if this line is found it is PowerVM
367   bool num_lpars_found = false;
368 
369   while (fgets(line, sizeof(line), fp) != nullptr) {
370     if (strncmp(line, system_type, strlen(system_type)) == 0) {
371       if (strstr(line, "qemu") != nullptr) {
372         Abstract_VM_Version::_detected_virtualization = PowerKVM;
373         fclose(fp);
374         return;
375       }
376     }
377     if (strncmp(line, num_lpars, strlen(num_lpars)) == 0) {
378       num_lpars_found = true;
379     }
380   }
381   if (num_lpars_found) {
382     Abstract_VM_Version::_detected_virtualization = PowerVM;
383   } else {
384     Abstract_VM_Version::_detected_virtualization = PowerFullPartitionMode;
385   }
386   fclose(fp);
387 #endif
388 }
389 
390 void VM_Version::print_platform_virtualization_info(outputStream* st) {
391 #if defined(_AIX)
392   // more info about perfstat API see
393   // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.prftools/idprftools_perfstat_glob_partition.htm
394   int rc = 0;
395   perfstat_partition_total_t pinfo;
396   memset(&pinfo, 0, sizeof(perfstat_partition_total_t));
397   rc = perfstat_partition_total(nullptr, &pinfo, sizeof(perfstat_partition_total_t), 1);
398   if (rc != 1) {
399     return;
400   } else {
401     st->print_cr("Virtualization type   : PowerVM");
402   }
403   // CPU information
404   perfstat_cpu_total_t cpuinfo;
405   memset(&cpuinfo, 0, sizeof(perfstat_cpu_total_t));
406   rc = perfstat_cpu_total(nullptr, &cpuinfo, sizeof(perfstat_cpu_total_t), 1);
407   if (rc != 1) {
408     return;
409   }
410 
411   st->print_cr("Processor description : %s", cpuinfo.description);
412   st->print_cr("Processor speed       : %llu Hz", cpuinfo.processorHZ);
413 
414   st->print_cr("LPAR partition name           : %s", pinfo.name);
415   st->print_cr("LPAR partition number         : %u", pinfo.lpar_id);
416   st->print_cr("LPAR partition type           : %s", pinfo.type.b.shared_enabled ? "shared" : "dedicated");
417   st->print_cr("LPAR mode                     : %s", pinfo.type.b.donate_enabled ? "donating" : pinfo.type.b.capped ? "capped" : "uncapped");
418   st->print_cr("LPAR partition group ID       : %u", pinfo.group_id);
419   st->print_cr("LPAR shared pool ID           : %u", pinfo.pool_id);
420 
421   st->print_cr("AMS (active memory sharing)   : %s", pinfo.type.b.ams_capable ? "capable" : "not capable");
422   st->print_cr("AMS (active memory sharing)   : %s", pinfo.type.b.ams_enabled ? "on" : "off");
423   st->print_cr("AME (active memory expansion) : %s", pinfo.type.b.ame_enabled ? "on" : "off");
424 
425   if (pinfo.type.b.ame_enabled) {
426     st->print_cr("AME true memory in bytes      : %llu", pinfo.true_memory);
427     st->print_cr("AME expanded memory in bytes  : %llu", pinfo.expanded_memory);
428   }
429 
430   st->print_cr("SMT : %s", pinfo.type.b.smt_capable ? "capable" : "not capable");
431   st->print_cr("SMT : %s", pinfo.type.b.smt_enabled ? "on" : "off");
432   int ocpus = pinfo.online_cpus > 0 ?  pinfo.online_cpus : 1;
433   st->print_cr("LPAR threads              : %d", cpuinfo.ncpus/ocpus);
434   st->print_cr("LPAR online virtual cpus  : %d", pinfo.online_cpus);
435   st->print_cr("LPAR logical cpus         : %d", cpuinfo.ncpus);
436   st->print_cr("LPAR maximum virtual cpus : %u", pinfo.max_cpus);
437   st->print_cr("LPAR minimum virtual cpus : %u", pinfo.min_cpus);
438   st->print_cr("LPAR entitled capacity    : %4.2f", (double) (pinfo.entitled_proc_capacity/100.0));
439   st->print_cr("LPAR online memory        : %llu MB", pinfo.online_memory);
440   st->print_cr("LPAR maximum memory       : %llu MB", pinfo.max_memory);
441   st->print_cr("LPAR minimum memory       : %llu MB", pinfo.min_memory);
442 #else
443   const char* info_file = "/proc/ppc64/lparcfg";
444   const char* kw[] = { "system_type=", // qemu indicates PowerKVM
445                        "partition_entitled_capacity=", // entitled processor capacity percentage
446                        "partition_max_entitled_capacity=",
447                        "capacity_weight=", // partition CPU weight
448                        "partition_active_processors=",
449                        "partition_potential_processors=",
450                        "entitled_proc_capacity_available=",
451                        "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
452                        "shared_processor_mode=", // (non)dedicated partition
453                        "system_potential_processors=",
454                        "pool=", // CPU-pool number
455                        "pool_capacity=",
456                        "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
457                        nullptr };
458   if (!print_matching_lines_from_file(info_file, st, kw)) {
459     st->print_cr("  <%s Not Available>", info_file);
460   }
461 #endif
462 }
463 
464 void VM_Version::print_features() {
465   tty->print_cr("Version: %s L1_data_cache_line_size=%d", cpu_info_string(), L1_data_cache_line_size());
466 
467   if (Verbose) {
468     if (ContendedPaddingWidth > 0) {
469       tty->cr();
470       tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
471     }
472   }
473 }
474 
475 void VM_Version::determine_features() {
476 #if defined(ABI_ELFv2)
477   const int code_size = (num_features + 1 /*blr*/) * BytesPerInstWord;
478 #else
479   const int code_size = (num_features + 1 /*blr*/ + 6 /* fd */) * BytesPerInstWord;
480 #endif
481   int features = 0;
482 
483   // Allocate space for the code.
484   ResourceMark rm;
485   CodeBuffer cb("detect_cpu_features", code_size, 0);
486   MacroAssembler* a = new MacroAssembler(&cb);
487 
488   // Must be set to true so we can generate the test code.
489   _features = VM_Version::all_features_m;
490 
491   // Emit code.
492   void (*test)() = (void(*)())(void *)a->function_entry();
493   uint32_t *code = (uint32_t *)a->pc();
494   a->mfdscr(R0);
495   a->darn(R7);
496   a->brw(R5, R6);
497   a->blr();
498 
499   uint32_t *code_end = (uint32_t *)a->pc();
500   a->flush();
501   _features = VM_Version::unknown_m;
502 
503   // Print the detection code.
504   if (PrintAssembly) {
505     ttyLocker ttyl;
506     tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
507     Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
508   }
509 
510   // Execute code. Illegal instructions will be replaced by 0 in the signal handler.
511   VM_Version::_is_determine_features_test_running = true;
512   (*test)();
513   VM_Version::_is_determine_features_test_running = false;
514 
515   // determine which instructions are legal.
516   int feature_cntr = 0;
517   if (code[feature_cntr++]) features |= mfdscr_m;
518   if (code[feature_cntr++]) features |= darn_m;
519   if (code[feature_cntr++]) features |= brw_m;
520 
521   // Print the detection code.
522   if (PrintAssembly) {
523     ttyLocker ttyl;
524     tty->print_cr("Decoding cpu-feature detection stub at " INTPTR_FORMAT " after execution:", p2i(code));
525     Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
526   }
527 
528   _features = features;
529 
530   _L1_data_cache_line_size = VM_Version::get_dcache_line_size();
531   assert(_L1_data_cache_line_size >= DEFAULT_CACHE_LINE_SIZE,
532          "processors with smaller cache line size are no longer supported");
533 }
534 
535 // Power 8: Configure Data Stream Control Register.
536 void VM_Version::config_dscr() {
537   // 7 InstWords for each call (function descriptor + blr instruction).
538   const int code_size = (2+2*7)*BytesPerInstWord;
539 
540   // Allocate space for the code.
541   ResourceMark rm;
542   CodeBuffer cb("config_dscr", code_size, 0);
543   MacroAssembler* a = new MacroAssembler(&cb);
544 
545   // Emit code.
546   uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry();
547   uint32_t *code = (uint32_t *)a->pc();
548   a->mfdscr(R3);
549   a->blr();
550 
551   void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry();
552   a->mtdscr(R3);
553   a->blr();
554 
555   uint32_t *code_end = (uint32_t *)a->pc();
556   a->flush();
557 
558   // Print the detection code.
559   if (PrintAssembly) {
560     ttyLocker ttyl;
561     tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
562     Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
563   }
564 
565   // Apply the configuration if needed.
566   _dscr_val = (*get_dscr)();
567   if (Verbose) {
568     tty->print_cr("dscr value was 0x%lx" , _dscr_val);
569   }
570   bool change_requested = false;
571   if (DSCR_PPC64 != (uintx)-1) {
572     _dscr_val = DSCR_PPC64;
573     change_requested = true;
574   }
575   if (DSCR_DPFD_PPC64 <= 7) {
576     uint64_t mask = 0x7;
577     if ((_dscr_val & mask) != DSCR_DPFD_PPC64) {
578       _dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64);
579       change_requested = true;
580     }
581   }
582   if (DSCR_URG_PPC64 <= 7) {
583     uint64_t mask = 0x7 << 6;
584     if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
585       _dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
586       change_requested = true;
587     }
588   }
589   if (change_requested) {
590     (*set_dscr)(_dscr_val);
591     if (Verbose) {
592       tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)());
593     }
594   }
595 }
596 
597 static uint64_t saved_features = 0;
598 
599 void VM_Version::allow_all() {
600   saved_features = _features;
601   _features      = all_features_m;
602 }
603 
604 void VM_Version::revert() {
605   _features = saved_features;
606 }
607 
608 // get cpu information.
609 void VM_Version::initialize_cpu_information(void) {
610   // do nothing if cpu info has been initialized
611   if (_initialized) {
612     return;
613   }
614 
615   _no_of_cores  = os::processor_count();
616   _no_of_threads = _no_of_cores;
617   _no_of_sockets = _no_of_cores;
618   os::snprintf_checked(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
619   os::snprintf_checked(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", cpu_info_string());
620   _initialized = true;
621 }