提交 5dd170c6 编写于 作者: T twisti

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
上级 00872c6d
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -90,7 +90,7 @@ void VM_Version::initialize() { ...@@ -90,7 +90,7 @@ void VM_Version::initialize() {
} }
char buf[512]; 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_v8() ? ", has_v8" : ""),
(has_v9() ? ", has_v9" : ""), (has_v9() ? ", has_v9" : ""),
(has_vis1() ? ", has_vis1" : ""), (has_vis1() ? ", has_vis1" : ""),
...@@ -98,7 +98,9 @@ void VM_Version::initialize() { ...@@ -98,7 +98,9 @@ void VM_Version::initialize() {
(is_ultra3() ? ", is_ultra3" : ""), (is_ultra3() ? ", is_ultra3" : ""),
(is_sun4v() ? ", is_sun4v" : ""), (is_sun4v() ? ", is_sun4v" : ""),
(is_niagara1() ? ", is_niagara1" : ""), (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" : "")); (!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
// buf is started with ", " or is empty // buf is started with ", " or is empty
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,34 +25,36 @@ ...@@ -25,34 +25,36 @@
class VM_Version: public Abstract_VM_Version { class VM_Version: public Abstract_VM_Version {
protected: protected:
enum Feature_Flag { enum Feature_Flag {
v8_instructions = 0, v8_instructions = 0,
hardware_int_muldiv = 1, hardware_mul32 = 1,
hardware_fsmuld = 2, hardware_div32 = 2,
v9_instructions = 3, hardware_fsmuld = 3,
vis1_instructions = 4, v9_instructions = 4,
vis2_instructions = 5, vis1_instructions = 5,
sun4v_instructions = 6 vis2_instructions = 6,
sun4v_instructions = 7
}; };
enum Feature_Flag_Set { enum Feature_Flag_Set {
unknown_m = 0, unknown_m = 0,
all_features_m = -1, all_features_m = -1,
v8_instructions_m = 1 << v8_instructions, v8_instructions_m = 1 << v8_instructions,
hardware_int_muldiv_m = 1 << hardware_int_muldiv, hardware_mul32_m = 1 << hardware_mul32,
hardware_fsmuld_m = 1 << hardware_fsmuld, hardware_div32_m = 1 << hardware_div32,
v9_instructions_m = 1 << v9_instructions, hardware_fsmuld_m = 1 << hardware_fsmuld,
vis1_instructions_m = 1 << vis1_instructions, v9_instructions_m = 1 << v9_instructions,
vis2_instructions_m = 1 << vis2_instructions, vis1_instructions_m = 1 << vis1_instructions,
sun4v_m = 1 << sun4v_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, generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
ultra3_m = generic_v9_m | vis2_instructions_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 // Temporary until we have something more accurate
niagara1_unique_m = sun4v_m, niagara1_unique_m = sun4v_m,
niagara1_m = generic_v9_m | niagara1_unique_m niagara1_m = generic_v9_m | niagara1_unique_m
}; };
static int _features; static int _features;
...@@ -62,7 +64,7 @@ protected: ...@@ -62,7 +64,7 @@ protected:
static int determine_features(); static int determine_features();
static int platform_features(int 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; } static int maximum_niagara1_processor_count() { return 32; }
// Returns true if the platform is in the niagara line and // Returns true if the platform is in the niagara line and
...@@ -76,7 +78,8 @@ public: ...@@ -76,7 +78,8 @@ public:
// Instruction support // Instruction support
static bool has_v8() { return (_features & v8_instructions_m) != 0; } static bool has_v8() { return (_features & v8_instructions_m) != 0; }
static bool has_v9() { return (_features & v9_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_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
static bool has_vis1() { return (_features & vis1_instructions_m) != 0; } static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; } static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -4451,6 +4451,9 @@ int_fnP_thread_t_i os::Solaris::_thr_setmutator; ...@@ -4451,6 +4451,9 @@ int_fnP_thread_t_i os::Solaris::_thr_setmutator;
int_fnP_thread_t os::Solaris::_thr_suspend_mutator; int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
int_fnP_thread_t os::Solaris::_thr_continue_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 // (Static) wrappers for the liblgrp API
os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home; os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init; os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
...@@ -4465,16 +4468,19 @@ os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0; ...@@ -4465,16 +4468,19 @@ os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
// (Static) wrapper for meminfo() call. // (Static) wrapper for meminfo() call.
os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0; os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
static address resolve_symbol(const char *name) { static address resolve_symbol_lazy(const char* name) {
address addr; address addr = (address) dlsym(RTLD_DEFAULT, name);
addr = (address) dlsym(RTLD_DEFAULT, name);
if(addr == NULL) { if(addr == NULL) {
// RTLD_DEFAULT was not defined on some early versions of 2.5.1 // RTLD_DEFAULT was not defined on some early versions of 2.5.1
addr = (address) dlsym(RTLD_NEXT, name); 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; return addr;
} }
...@@ -4673,15 +4679,26 @@ bool os::Solaris::liblgrp_init() { ...@@ -4673,15 +4679,26 @@ bool os::Solaris::liblgrp_init() {
} }
void os::Solaris::misc_sym_init() { void os::Solaris::misc_sym_init() {
address func = (address)dlsym(RTLD_DEFAULT, "meminfo"); address func;
if(func == NULL) {
func = (address) dlsym(RTLD_NEXT, "meminfo"); // 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) { if (func != NULL) {
os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func)); 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 // Symbol doesn't exist in Solaris 8 pset.h
#ifndef PS_MYID #ifndef PS_MYID
#define PS_MYID -3 #define PS_MYID -3
...@@ -4716,6 +4733,10 @@ void os::init(void) { ...@@ -4716,6 +4733,10 @@ void os::init(void) {
Solaris::initialize_system_info(); 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); int fd = open("/dev/zero", O_RDWR);
if (fd < 0) { if (fd < 0) {
fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno)); fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno));
...@@ -4857,7 +4878,6 @@ jint os::init_2(void) { ...@@ -4857,7 +4878,6 @@ jint os::init_2(void) {
} }
} }
Solaris::misc_sym_init();
Solaris::signal_sets_init(); Solaris::signal_sets_init();
Solaris::init_signal_mem(); Solaris::init_signal_mem();
Solaris::install_signal_handlers(); Solaris::install_signal_handlers();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,6 +72,8 @@ class Solaris { ...@@ -72,6 +72,8 @@ class Solaris {
LGRP_VIEW_OS /* what's available to operating system */ LGRP_VIEW_OS /* what's available to operating system */
} lgrp_view_t; } 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_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 lgrp_cookie_t (*lgrp_init_func_t)(lgrp_view_t view);
typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie); typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie);
...@@ -87,6 +89,8 @@ class Solaris { ...@@ -87,6 +89,8 @@ class Solaris {
const uint_t info_req[], int info_count, const uint_t info_req[], int info_count,
uint64_t outdata[], uint_t validity[]); uint64_t outdata[], uint_t validity[]);
static getisax_func_t _getisax;
static lgrp_home_func_t _lgrp_home; static lgrp_home_func_t _lgrp_home;
static lgrp_init_func_t _lgrp_init; static lgrp_init_func_t _lgrp_init;
static lgrp_fini_func_t _lgrp_fini; static lgrp_fini_func_t _lgrp_fini;
...@@ -283,6 +287,9 @@ class Solaris { ...@@ -283,6 +287,9 @@ class Solaris {
} }
static lgrp_cookie_t lgrp_cookie() { return _lgrp_cookie; } 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 void set_meminfo(meminfo_func_t func) { _meminfo = func; }
static int meminfo (const uint64_t inaddr[], int addr_count, static int meminfo (const uint64_t inaddr[], int addr_count,
const uint_t info_req[], int info_count, const uint_t info_req[], int info_count,
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,58 +25,106 @@ ...@@ -25,58 +25,106 @@
# include "incls/_precompiled.incl" # include "incls/_precompiled.incl"
# include "incls/_vm_version_solaris_sparc.cpp.incl" # include "incls/_vm_version_solaris_sparc.cpp.incl"
# include <sys/auxv.h>
# include <sys/auxv_SPARC.h>
# include <sys/systeminfo.h> # include <sys/systeminfo.h>
int VM_Version::platform_features(int features) { // We need to keep these here as long as we have to build on Solaris
// We determine what sort of hardware we have via sysinfo(SI_ISALIST, ...). // versions before 10.
// This isn't the best of all possible ways because there's not enough #ifndef SI_ARCHITECTURE_32
// detail in the isa list it returns, but it's a bit less arcane than #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
// generating assembly code and an illegal instruction handler. We used #endif
// 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.
// isalist spec via 'man isalist' as of 01-Aug-2001 #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; char tmp;
size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); size_t bufsize = sysinfo(si, &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;
}
}
// Check for visualization instructions // All SI defines used below must be supported.
char *vis = strstr(buf, "vis"); guarantee(bufsize != -1, "must be supported");
if (vis != NULL) { features |= vis1_instructions_m;
if (vis[3] == '2') features |= vis2_instructions_m; 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);
} }
bufsize = sysinfo(SI_MACHINE, &tmp, 1); free(buf);
buf = (char*)malloc(bufsize); }
int VM_Version::platform_features(int features) {
// 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
if (buf != NULL) { // Check 32-bit architecture.
if (sysinfo(SI_MACHINE, buf, bufsize) == bufsize) { do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);
if (strstr(buf, "sun4v") != NULL) {
features |= sun4v_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");
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;
}
} }
free(buf);
} }
free(buf);
} }
// Determine the machine type.
do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
return features; return features;
} }
...@@ -4598,6 +4598,7 @@ vm_version_<arch>.cpp vm_version_<arch>.hpp ...@@ -4598,6 +4598,7 @@ vm_version_<arch>.cpp vm_version_<arch>.hpp
vm_version_<arch>.hpp globals_extension.hpp vm_version_<arch>.hpp globals_extension.hpp
vm_version_<arch>.hpp vm_version.hpp vm_version_<arch>.hpp vm_version.hpp
vm_version_<os_arch>.cpp os.hpp
vm_version_<os_arch>.cpp vm_version_<arch>.hpp vm_version_<os_arch>.cpp vm_version_<arch>.hpp
vmreg.cpp assembler.hpp vmreg.cpp assembler.hpp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册