src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/os_cpu/solaris_sparc/vm

src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp

Print this page




 247   _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
 248   if (_dl_handle == NULL) {
 249     return false;
 250   }
 251   if (!bind_library_functions()) {
 252     assert(false, "unexpected PICL API change");
 253     close_library();
 254     return false;
 255   }
 256   return true;
 257 }
 258 
 259 void PICL::close_library() {
 260   assert(_dl_handle != NULL, "library should be open");
 261   dlclose(_dl_handle);
 262   _dl_handle = NULL;
 263 }
 264 
 265 // We need to keep these here as long as we have to build on Solaris
 266 // versions before 10.

 267 #ifndef SI_ARCHITECTURE_32
 268 #define SI_ARCHITECTURE_32      516     /* basic 32-bit SI_ARCHITECTURE */
 269 #endif
 270 
 271 #ifndef SI_ARCHITECTURE_64
 272 #define SI_ARCHITECTURE_64      517     /* basic 64-bit SI_ARCHITECTURE */
 273 #endif
 274 
 275 static void do_sysinfo(int si, const char* string, int* features, int mask) {







 276   char   tmp;
 277   size_t bufsize = sysinfo(si, &tmp, 1);
 278 
 279   // All SI defines used below must be supported.
 280   guarantee(bufsize != -1, "must be supported");
 281 
 282   char* buf = (char*) os::malloc(bufsize, mtInternal);















 283 
 284   if (buf == NULL)
 285     return;

 286 
 287   if (sysinfo(si, buf, bufsize) == bufsize) {
 288     // Compare the string.
 289     if (strcmp(buf, string) == 0) {
 290       *features |= mask;
 291     }



 292   }
 293 
 294   os::free(buf);
 295 }

























 296 
 297 int VM_Version::platform_features(int features) {
 298   assert(os::Solaris::supports_getisax(), "getisax() must be available");
 299 
 300   // Check 32-bit architecture.
 301   do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);


 302 
 303   // Check 64-bit architecture.
 304   do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m);


 305 
 306   // Extract valid instruction set extensions.
 307   uint_t avs[2];
 308   uint_t avn = os::Solaris::getisax(avs, 2);
 309   assert(avn <= 2, "should return two or less av's");
 310   uint_t av = avs[0];
 311 
 312 #ifndef PRODUCT
 313   if (PrintMiscellaneous && Verbose) {
 314     tty->print("getisax(2) returned: " PTR32_FORMAT, av);
 315     if (avn > 1) {
 316       tty->print(", " PTR32_FORMAT, avs[1]);
 317     }
 318     tty->cr();
 319   }
 320 #endif
 321 
 322   if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
 323   if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
 324   if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;


 371 #define AV_SPARC_AES 0x00020000  /* aes instrs supported */
 372 #endif
 373   if (av & AV_SPARC_AES)       features |= aes_instructions_m;
 374 
 375 #ifndef AV_SPARC_SHA1
 376 #define AV_SPARC_SHA1   0x00400000  /* sha1 instruction supported */
 377 #endif
 378   if (av & AV_SPARC_SHA1)         features |= sha1_instruction_m;
 379 
 380 #ifndef AV_SPARC_SHA256
 381 #define AV_SPARC_SHA256 0x00800000  /* sha256 instruction supported */
 382 #endif
 383   if (av & AV_SPARC_SHA256)       features |= sha256_instruction_m;
 384 
 385 #ifndef AV_SPARC_SHA512
 386 #define AV_SPARC_SHA512 0x01000000  /* sha512 instruction supported */
 387 #endif
 388   if (av & AV_SPARC_SHA512)       features |= sha512_instruction_m;
 389 
 390   // Determine the machine type.
 391   do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);


 392 
 393   {
 394     // Using kstat to determine the machine type.







 395     kstat_ctl_t* kc = kstat_open();
 396     kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
 397     const char* implementation = "UNKNOWN";

 398     if (ksp != NULL) {
 399       if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
 400         kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
 401         for (int i = 0; i < ksp->ks_ndata; i++) {
 402           if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
 403             implementation = KSTAT_NAMED_STR_PTR(&knm[i]);

 404 #ifndef PRODUCT
 405             if (PrintMiscellaneous && Verbose) {
 406               tty->print_cr("cpu_info.implementation: %s", implementation);
 407             }
 408 #endif
 409             // Convert to UPPER case before compare.
 410             char* impl = os::strdup_check_oom(implementation);
 411 
 412             for (int i = 0; impl[i] != 0; i++)
 413               impl[i] = (char)toupper((uint)impl[i]);
 414 
 415             if (strstr(impl, "SPARC64") != NULL) {
 416               features |= sparc64_family_m;
 417             } else if (strstr(impl, "SPARC-M") != NULL) {
 418               // M-series SPARC is based on T-series.
 419               features |= (M_family_m | T_family_m);
 420             } else if (strstr(impl, "SPARC-T") != NULL) {
 421               features |= T_family_m;
 422               if (strstr(impl, "SPARC-T1") != NULL) {
 423                 features |= T1_model_m;
 424               }
 425             } else {
 426               if (strstr(impl, "SPARC") == NULL) {
 427 #ifndef PRODUCT
 428                 // kstat on Solaris 8 virtual machines (branded zones)
 429                 // returns "(unsupported)" implementation. Solaris 8 is not
 430                 // supported anymore, but include this check to be on the
 431                 // safe side.
 432                 warning("kstat cpu_info implementation = '%s', assume generic SPARC", impl);
 433 #endif
 434                 implementation = "SPARC";
 435               }
 436             }
 437             os::free((void*)impl);
 438             break;
 439           }
 440         } // for(
 441       }
 442     }
 443     assert(strcmp(implementation, "UNKNOWN") != 0,
 444            "unknown cpu info (changed kstat interface?)");
 445     kstat_close(kc);
 446   }
 447 
 448   // Figure out cache line sizes using PICL
 449   PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);














 450   _L1_data_cache_line_size = picl.L1_data_cache_line_size();
 451   _L2_data_cache_line_size = picl.L2_data_cache_line_size();
 452 
 453   return features;
 454 }


 247   _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
 248   if (_dl_handle == NULL) {
 249     return false;
 250   }
 251   if (!bind_library_functions()) {
 252     assert(false, "unexpected PICL API change");
 253     close_library();
 254     return false;
 255   }
 256   return true;
 257 }
 258 
 259 void PICL::close_library() {
 260   assert(_dl_handle != NULL, "library should be open");
 261   dlclose(_dl_handle);
 262   _dl_handle = NULL;
 263 }
 264 
 265 // We need to keep these here as long as we have to build on Solaris
 266 // versions before 10.
 267 
 268 #ifndef SI_ARCHITECTURE_32
 269 #define SI_ARCHITECTURE_32      516     /* basic 32-bit SI_ARCHITECTURE */
 270 #endif
 271 
 272 #ifndef SI_ARCHITECTURE_64
 273 #define SI_ARCHITECTURE_64      517     /* basic 64-bit SI_ARCHITECTURE */
 274 #endif
 275 
 276 #ifndef SI_CPUBRAND
 277 #define SI_CPUBRAND             523     /* return cpu brand string */
 278 #endif
 279 
 280 class Sysinfo {
 281   char* _string;
 282 public:
 283   Sysinfo(int si) : _string(NULL) {
 284     char   tmp;
 285     size_t bufsize = sysinfo(si, &tmp, 1);
 286 
 287     if (bufsize != -1) {


 288       char* buf = (char*) os::malloc(bufsize, mtInternal);
 289       if (buf != NULL) {
 290         if (sysinfo(si, buf, bufsize) == bufsize) {
 291           _string = buf;
 292         } else {
 293           os::free(buf);
 294         }
 295       }
 296     }
 297   }
 298 
 299   ~Sysinfo() {
 300     if (_string != NULL) {
 301       os::free(_string);
 302     }
 303   }
 304 
 305   const char* value() const {
 306     return _string;
 307   }
 308 
 309   bool valid() const {
 310     return _string != NULL;


 311   }
 312 
 313   bool match(const char* s) const {
 314     return valid() ? strcmp(_string, s) == 0 : false;
 315   }
 316 
 317   bool match_substring(const char* s) const {
 318     return valid() ? strstr(_string, s) != NULL : false;
 319   }
 320 };
 321 
 322 class Sysconf {
 323   int _value;
 324 public:
 325   Sysconf(int sc) : _value(-1) {
 326     _value = sysconf(sc);
 327   }
 328   bool valid() const {
 329     return _value != -1;
 330   }
 331   int value() const {
 332     return _value;
 333   }
 334 };
 335 
 336 
 337 #ifndef _SC_DCACHE_LINESZ
 338 #define _SC_DCACHE_LINESZ       508     /* Data cache line size */
 339 #endif
 340 
 341 #ifndef _SC_L2CACHE_LINESZ
 342 #define _SC_L2CACHE_LINESZ      527     /* Size of L2 cache line */
 343 #endif
 344 
 345 int VM_Version::platform_features(int features) {
 346   assert(os::Solaris::supports_getisax(), "getisax() must be available");
 347 
 348   // Check 32-bit architecture.
 349   if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
 350     features |= v8_instructions_m;
 351   }
 352 
 353   // Check 64-bit architecture.
 354   if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) {
 355     features |= generic_v9_m;
 356   }
 357 
 358   // Extract valid instruction set extensions.
 359   uint_t avs[2];
 360   uint_t avn = os::Solaris::getisax(avs, 2);
 361   assert(avn <= 2, "should return two or less av's");
 362   uint_t av = avs[0];
 363 
 364 #ifndef PRODUCT
 365   if (PrintMiscellaneous && Verbose) {
 366     tty->print("getisax(2) returned: " PTR32_FORMAT, av);
 367     if (avn > 1) {
 368       tty->print(", " PTR32_FORMAT, avs[1]);
 369     }
 370     tty->cr();
 371   }
 372 #endif
 373 
 374   if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
 375   if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
 376   if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;


 423 #define AV_SPARC_AES 0x00020000  /* aes instrs supported */
 424 #endif
 425   if (av & AV_SPARC_AES)       features |= aes_instructions_m;
 426 
 427 #ifndef AV_SPARC_SHA1
 428 #define AV_SPARC_SHA1   0x00400000  /* sha1 instruction supported */
 429 #endif
 430   if (av & AV_SPARC_SHA1)         features |= sha1_instruction_m;
 431 
 432 #ifndef AV_SPARC_SHA256
 433 #define AV_SPARC_SHA256 0x00800000  /* sha256 instruction supported */
 434 #endif
 435   if (av & AV_SPARC_SHA256)       features |= sha256_instruction_m;
 436 
 437 #ifndef AV_SPARC_SHA512
 438 #define AV_SPARC_SHA512 0x01000000  /* sha512 instruction supported */
 439 #endif
 440   if (av & AV_SPARC_SHA512)       features |= sha512_instruction_m;
 441 
 442   // Determine the machine type.
 443   if (Sysinfo(SI_MACHINE).match("sun4v")) {
 444     features |= sun4v_m;
 445   }
 446 
 447   bool use_solaris_12_api = false;
 448   Sysinfo impl(SI_CPUBRAND);
 449   if (impl.valid()) {
 450     // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
 451     // is available to us as well
 452     use_solaris_12_api = true;
 453     features |= parse_features(impl.value());
 454   } else {
 455     // Otherwise use kstat to determine the machine type.
 456     kstat_ctl_t* kc = kstat_open();
 457     kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
 458     const char* implementation;
 459     bool has_implementation = false;
 460     if (ksp != NULL) {
 461       if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
 462         kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
 463         for (int i = 0; i < ksp->ks_ndata; i++) {
 464           if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
 465             implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
 466             has_implementation = true;
 467 #ifndef PRODUCT
 468             if (PrintMiscellaneous && Verbose) {
 469               tty->print_cr("cpu_info.implementation: %s", implementation);
 470             }
 471 #endif
 472             features |= parse_features(implementation);




























 473             break;
 474           }
 475         } // for(
 476       }
 477     }
 478     assert(has_implementation, "unknown cpu info (changed kstat interface?)");

 479     kstat_close(kc);
 480   }
 481 
 482   bool is_sun4v = (features & sun4v_m) != 0;
 483   if (use_solaris_12_api && is_sun4v) {
 484     // If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
 485     Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
 486     if (l1_dcache_line_size.valid()) {
 487       _L1_data_cache_line_size =  l1_dcache_line_size.value();
 488     }
 489 
 490     Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
 491     if (l2_dcache_line_size.valid()) {
 492       _L2_data_cache_line_size = l2_dcache_line_size.value();
 493     }
 494   } else {
 495     // Otherwise figure out the cache line sizes using PICL
 496     bool is_fujitsu = (features & sparc64_family_m) != 0;
 497     PICL picl(is_fujitsu, is_sun4v);
 498     _L1_data_cache_line_size = picl.L1_data_cache_line_size();
 499     _L2_data_cache_line_size = picl.L2_data_cache_line_size();
 500   }
 501   return features;
 502 }
src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File