6812587: Use auxv to determine SPARC hardware features on Solaris
A similar function to getisax(2) should be used to determine all possible instruction set extensions. Reviewed-by: never, kvn
This commit is contained in:
parent
7a871160ec
commit
66cecec230
@ -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 @@ void VM_Version::initialize() {
|
||||
}
|
||||
|
||||
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 @@ void VM_Version::initialize() {
|
||||
(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
|
||||
|
@ -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 @@ protected:
|
||||
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 @@ public:
|
||||
// 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; }
|
||||
|
@ -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_i os::Solaris::_thr_setmutator;
|
||||
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 @@ os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
|
||||
// (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 @@ bool os::Solaris::liblgrp_init() {
|
||||
}
|
||||
|
||||
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 @@ void os::init(void) {
|
||||
|
||||
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 @@ jint os::init_2(void) {
|
||||
}
|
||||
}
|
||||
|
||||
Solaris::misc_sym_init();
|
||||
Solaris::signal_sets_init();
|
||||
Solaris::init_signal_mem();
|
||||
Solaris::install_signal_handlers();
|
||||
|
@ -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 @@ class Solaris {
|
||||
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 @@ class Solaris {
|
||||
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 @@ class Solaris {
|
||||
}
|
||||
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,
|
||||
|
@ -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>
|
||||
|
||||
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.
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
|
||||
char* buf = (char*)malloc(bufsize);
|
||||
size_t bufsize = sysinfo(si, &tmp, 1);
|
||||
|
||||
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;
|
||||
// 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) {
|
||||
// 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
|
||||
|
||||
// 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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -4598,6 +4598,7 @@ vm_version_<arch>.cpp vm_version_<arch>.hpp
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user