6812587: Use auxv to determine SPARC hardware features on Solaris
Summary: A similar function to getisax(2) should be used to determine all possible instruction set extensions.
Reviewed-by: never, kvn
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Mar 11 14:16:13 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -90,7 +90,7 @@
}
char buf[512];
- jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s",
+ jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s",
(has_v8() ? ", has_v8" : ""),
(has_v9() ? ", has_v9" : ""),
(has_vis1() ? ", has_vis1" : ""),
@@ -98,7 +98,9 @@
(is_ultra3() ? ", is_ultra3" : ""),
(is_sun4v() ? ", is_sun4v" : ""),
(is_niagara1() ? ", is_niagara1" : ""),
- (!has_hardware_int_muldiv() ? ", no-muldiv" : ""),
+ (is_niagara1_plus() ? ", is_niagara1_plus" : ""),
+ (!has_hardware_mul32() ? ", no-mul32" : ""),
+ (!has_hardware_div32() ? ", no-div32" : ""),
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
// buf is started with ", " or is empty
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Mar 11 14:16:13 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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,34 +25,36 @@
class VM_Version: public Abstract_VM_Version {
protected:
enum Feature_Flag {
- v8_instructions = 0,
- hardware_int_muldiv = 1,
- hardware_fsmuld = 2,
- v9_instructions = 3,
- vis1_instructions = 4,
- vis2_instructions = 5,
- sun4v_instructions = 6
+ v8_instructions = 0,
+ hardware_mul32 = 1,
+ hardware_div32 = 2,
+ hardware_fsmuld = 3,
+ v9_instructions = 4,
+ vis1_instructions = 5,
+ vis2_instructions = 6,
+ sun4v_instructions = 7
};
enum Feature_Flag_Set {
- unknown_m = 0,
- all_features_m = -1,
+ unknown_m = 0,
+ all_features_m = -1,
- v8_instructions_m = 1 << v8_instructions,
- hardware_int_muldiv_m = 1 << hardware_int_muldiv,
- hardware_fsmuld_m = 1 << hardware_fsmuld,
- v9_instructions_m = 1 << v9_instructions,
- vis1_instructions_m = 1 << vis1_instructions,
- vis2_instructions_m = 1 << vis2_instructions,
- sun4v_m = 1 << sun4v_instructions,
+ v8_instructions_m = 1 << v8_instructions,
+ hardware_mul32_m = 1 << hardware_mul32,
+ hardware_div32_m = 1 << hardware_div32,
+ hardware_fsmuld_m = 1 << hardware_fsmuld,
+ v9_instructions_m = 1 << v9_instructions,
+ vis1_instructions_m = 1 << vis1_instructions,
+ vis2_instructions_m = 1 << vis2_instructions,
+ sun4v_m = 1 << sun4v_instructions,
- generic_v8_m = v8_instructions_m | hardware_int_muldiv_m | hardware_fsmuld_m,
- generic_v9_m = generic_v8_m | v9_instructions_m | vis1_instructions_m,
- ultra3_m = generic_v9_m | vis2_instructions_m,
+ generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
+ generic_v9_m = generic_v8_m | v9_instructions_m,
+ ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
// Temporary until we have something more accurate
- niagara1_unique_m = sun4v_m,
- niagara1_m = generic_v9_m | niagara1_unique_m
+ niagara1_unique_m = sun4v_m,
+ niagara1_m = generic_v9_m | niagara1_unique_m
};
static int _features;
@@ -62,7 +64,7 @@
static int determine_features();
static int platform_features(int features);
- static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; }
+ static bool is_niagara1(int features) { return (features & sun4v_m) != 0; }
static int maximum_niagara1_processor_count() { return 32; }
// Returns true if the platform is in the niagara line and
@@ -76,7 +78,8 @@
// Instruction support
static bool has_v8() { return (_features & v8_instructions_m) != 0; }
static bool has_v9() { return (_features & v9_instructions_m) != 0; }
- static bool has_hardware_int_muldiv() { return (_features & hardware_int_muldiv_m) != 0; }
+ static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
+ static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Mar 11 14:16:13 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -4451,6 +4451,9 @@
int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
int_fnP_thread_t os::Solaris::_thr_continue_mutator;
+// (Static) wrapper for getisax(2) call.
+os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
+
// (Static) wrappers for the liblgrp API
os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
@@ -4465,16 +4468,19 @@
// (Static) wrapper for meminfo() call.
os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
-static address resolve_symbol(const char *name) {
- address addr;
-
- addr = (address) dlsym(RTLD_DEFAULT, name);
+static address resolve_symbol_lazy(const char* name) {
+ address addr = (address) dlsym(RTLD_DEFAULT, name);
if(addr == NULL) {
// RTLD_DEFAULT was not defined on some early versions of 2.5.1
addr = (address) dlsym(RTLD_NEXT, name);
- if(addr == NULL) {
- fatal(dlerror());
- }
+ }
+ return addr;
+}
+
+static address resolve_symbol(const char* name) {
+ address addr = resolve_symbol_lazy(name);
+ if(addr == NULL) {
+ fatal(dlerror());
}
return addr;
}
@@ -4673,15 +4679,26 @@
}
void os::Solaris::misc_sym_init() {
- address func = (address)dlsym(RTLD_DEFAULT, "meminfo");
- if(func == NULL) {
- func = (address) dlsym(RTLD_NEXT, "meminfo");
- }
+ address func;
+
+ // getisax
+ func = resolve_symbol_lazy("getisax");
+ if (func != NULL) {
+ os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func);
+ }
+
+ // meminfo
+ func = resolve_symbol_lazy("meminfo");
if (func != NULL) {
os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
}
}
+uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
+ assert(_getisax != NULL, "_getisax not set");
+ return _getisax(array, n);
+}
+
// Symbol doesn't exist in Solaris 8 pset.h
#ifndef PS_MYID
#define PS_MYID -3
@@ -4716,6 +4733,10 @@
Solaris::initialize_system_info();
+ // Initialize misc. symbols as soon as possible, so we can use them
+ // if we need them.
+ Solaris::misc_sym_init();
+
int fd = open("/dev/zero", O_RDWR);
if (fd < 0) {
fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno));
@@ -4857,7 +4878,6 @@
}
}
- Solaris::misc_sym_init();
Solaris::signal_sets_init();
Solaris::init_signal_mem();
Solaris::install_signal_handlers();
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Wed Mar 11 14:16:13 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -72,6 +72,8 @@
LGRP_VIEW_OS /* what's available to operating system */
} lgrp_view_t;
+ typedef uint_t (*getisax_func_t)(uint32_t* array, uint_t n);
+
typedef lgrp_id_t (*lgrp_home_func_t)(idtype_t idtype, id_t id);
typedef lgrp_cookie_t (*lgrp_init_func_t)(lgrp_view_t view);
typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie);
@@ -87,6 +89,8 @@
const uint_t info_req[], int info_count,
uint64_t outdata[], uint_t validity[]);
+ static getisax_func_t _getisax;
+
static lgrp_home_func_t _lgrp_home;
static lgrp_init_func_t _lgrp_init;
static lgrp_fini_func_t _lgrp_fini;
@@ -283,6 +287,9 @@
}
static lgrp_cookie_t lgrp_cookie() { return _lgrp_cookie; }
+ static bool supports_getisax() { return _getisax != NULL; }
+ static uint_t getisax(uint32_t* array, uint_t n);
+
static void set_meminfo(meminfo_func_t func) { _meminfo = func; }
static int meminfo (const uint64_t inaddr[], int addr_count,
const uint_t info_req[], int info_count,
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/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 <sys/auxv.h>
+# include <sys/auxv_SPARC.h>
# include <sys/systeminfo.h>
+// 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);
+
+ // Check 64-bit architecture.
+ do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &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");
- char tmp;
- size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
- char* buf = (char*)malloc(bufsize);
+ 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_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;
+ 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;
}
--- a/hotspot/src/share/vm/includeDB_core Tue Mar 10 08:52:16 2009 -0700
+++ b/hotspot/src/share/vm/includeDB_core Wed Mar 11 14:16:13 2009 -0700
@@ -4598,6 +4598,7 @@
vm_version_<arch>.hpp globals_extension.hpp
vm_version_<arch>.hpp vm_version.hpp
+vm_version_<os_arch>.cpp os.hpp
vm_version_<os_arch>.cpp vm_version_<arch>.hpp
vmreg.cpp assembler.hpp