diff -r 2f2f54ed12ce -r 6af0a709d52b src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp --- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Tue Mar 10 08:52:16 2009 -0700 +++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Wed Mar 11 14:16:13 2009 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2006-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,58 +25,106 @@ # include "incls/_precompiled.incl" # include "incls/_vm_version_solaris_sparc.cpp.incl" +# include +# include # include +// We need to keep these here as long as we have to build on Solaris +// versions before 10. +#ifndef SI_ARCHITECTURE_32 +#define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ +#endif + +#ifndef SI_ARCHITECTURE_64 +#define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */ +#endif + +static void do_sysinfo(int si, const char* string, int* features, int mask) { + char tmp; + size_t bufsize = sysinfo(si, &tmp, 1); + + // All SI defines used below must be supported. + guarantee(bufsize != -1, "must be supported"); + + char* buf = (char*) malloc(bufsize); + + if (buf == NULL) + return; + + if (sysinfo(si, buf, bufsize) == bufsize) { + // Compare the string. + if (strcmp(buf, string) == 0) { + *features |= mask; + } + } + + free(buf); +} + int VM_Version::platform_features(int features) { - // We determine what sort of hardware we have via sysinfo(SI_ISALIST, ...). - // This isn't the best of all possible ways because there's not enough - // detail in the isa list it returns, but it's a bit less arcane than - // generating assembly code and an illegal instruction handler. We used - // to generate a getpsr trap, but that's even more arcane. - // - // Another possibility would be to use sysinfo(SI_PLATFORM, ...), but - // that would require more knowledge here than is wise. + // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are + // supported on Solaris 10 and later. + if (os::Solaris::supports_getisax()) { +#ifndef PRODUCT + if (PrintMiscellaneous && Verbose) + tty->print_cr("getisax(2) supported."); +#endif - // isalist spec via 'man isalist' as of 01-Aug-2001 + // Check 32-bit architecture. + do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m); - char tmp; - size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); - char* buf = (char*)malloc(bufsize); + // Check 64-bit architecture. + do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m); - if (buf != NULL) { - if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) { - // Figure out what kind of sparc we have - char *sparc_string = strstr(buf, "sparc"); - if (sparc_string != NULL) { features |= v8_instructions_m; - if (sparc_string[5] == 'v') { - if (sparc_string[6] == '8') { - if (sparc_string[7] == '-') features |= hardware_int_muldiv_m; - else if (sparc_string[7] == 'p') features |= generic_v9_m; - else features |= generic_v8_m; - } else if (sparc_string[6] == '9') features |= generic_v9_m; + // Extract valid instruction set extensions. + uint_t av; + uint_t avn = os::Solaris::getisax(&av, 1); + assert(avn == 1, "should only return one av"); + + if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; + if (av & AV_SPARC_DIV32) features |= hardware_div32_m; + if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m; + if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m; + if (av & AV_SPARC_VIS) features |= vis1_instructions_m; + if (av & AV_SPARC_VIS2) features |= vis2_instructions_m; + } else { + // getisax(2) failed, use the old legacy code. +#ifndef PRODUCT + if (PrintMiscellaneous && Verbose) + tty->print_cr("getisax(2) not supported."); +#endif + + char tmp; + size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); + char* buf = (char*) malloc(bufsize); + + if (buf != NULL) { + if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) { + // Figure out what kind of sparc we have + char *sparc_string = strstr(buf, "sparc"); + if (sparc_string != NULL) { features |= v8_instructions_m; + if (sparc_string[5] == 'v') { + if (sparc_string[6] == '8') { + if (sparc_string[7] == '-') { features |= hardware_mul32_m; + features |= hardware_div32_m; + } else if (sparc_string[7] == 'p') features |= generic_v9_m; + else features |= generic_v8_m; + } else if (sparc_string[6] == '9') features |= generic_v9_m; + } + } + + // Check for visualization instructions + char *vis = strstr(buf, "vis"); + if (vis != NULL) { features |= vis1_instructions_m; + if (vis[3] == '2') features |= vis2_instructions_m; } } - - // Check for visualization instructions - char *vis = strstr(buf, "vis"); - if (vis != NULL) { features |= vis1_instructions_m; - if (vis[3] == '2') features |= vis2_instructions_m; - } + free(buf); } - free(buf); } - bufsize = sysinfo(SI_MACHINE, &tmp, 1); - buf = (char*)malloc(bufsize); - - if (buf != NULL) { - if (sysinfo(SI_MACHINE, buf, bufsize) == bufsize) { - if (strstr(buf, "sun4v") != NULL) { - features |= sun4v_m; - } - } - free(buf); - } + // Determine the machine type. + do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m); return features; }