8202579: Revisit VM_Version and VM_Version_ext for overlap and consolidation
Reviewed-by: dholmes, hseigel
This commit is contained in:
parent
7adf7f3353
commit
1e3ae3be02
@ -488,3 +488,22 @@ void VM_Version::initialize() {
|
||||
|
||||
_spin_wait = get_spin_wait_desc();
|
||||
}
|
||||
|
||||
void VM_Version::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "AArch64");
|
||||
|
||||
int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 ");
|
||||
get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len);
|
||||
desc_len = (int)strlen(_cpu_desc);
|
||||
snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _features_string);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -153,6 +153,9 @@ public:
|
||||
// Is the CPU running emulated (for example macOS Rosetta running x86_64 code on M1 ARM (aarch64)
|
||||
static bool is_cpu_emulated();
|
||||
#endif
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
|
||||
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "vm_version_ext_aarch64.hpp"
|
||||
|
||||
// VM_Version_Ext statics
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_sockets = 0;
|
||||
bool VM_Version_Ext::_initialized = false;
|
||||
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
void VM_Version_Ext::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
int core_id = -1;
|
||||
int chip_id = -1;
|
||||
int len = 0;
|
||||
char* src_string = NULL;
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "AArch64");
|
||||
|
||||
int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 ");
|
||||
VM_Version::get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len);
|
||||
desc_len = (int)strlen(_cpu_desc);
|
||||
snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _features_string);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP
|
||||
#define CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
private:
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
public:
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_AARCH64_VM_VERSION_EXT_AARCH64_HPP
|
@ -106,6 +106,7 @@ class VM_Version: public Abstract_VM_Version {
|
||||
|
||||
friend class VM_Version_StubGenerator;
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_ARM_VM_VERSION_ARM_HPP
|
||||
|
@ -347,3 +347,17 @@ void VM_Version::initialize() {
|
||||
|
||||
_is_initialized = true;
|
||||
}
|
||||
|
||||
void VM_Version::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "ARM%d", _arm_arch);
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string);
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "vm_version_ext_arm.hpp"
|
||||
|
||||
// VM_Version_Ext statics
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_sockets = 0;
|
||||
bool VM_Version_Ext::_initialized = false;
|
||||
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
void VM_Version_Ext::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
int core_id = -1;
|
||||
int chip_id = -1;
|
||||
int len = 0;
|
||||
char* src_string = NULL;
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "ARM%d", _arm_arch);
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_ARM_VM_VERSION_EXT_ARM_HPP
|
||||
#define CPU_ARM_VM_VERSION_EXT_ARM_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
private:
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
public:
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_ARM_VM_VERSION_EXT_ARM_HPP
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "vm_version_ext_ppc.hpp"
|
||||
|
||||
// VM_Version_Ext statics
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_sockets = 0;
|
||||
bool VM_Version_Ext::_initialized = false;
|
||||
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
// get cpu information.
|
||||
void VM_Version_Ext::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string());
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_PPC_VM_VERSION_EXT_PPC_HPP
|
||||
#define CPU_PPC_VM_VERSION_EXT_PPC_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#define CPU_INFO "cpu_info"
|
||||
#define CPU_TYPE "fpu_type"
|
||||
#define CPU_DESCRIPTION "implementation"
|
||||
#define CHIP_ID "chip_id"
|
||||
#define CORE_ID "core_id"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
private:
|
||||
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
public:
|
||||
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
};
|
||||
|
||||
#endif // CPU_PPC_VM_VERSION_EXT_PPC_HPP
|
@ -767,3 +767,18 @@ void VM_Version::allow_all() {
|
||||
void VM_Version::revert() {
|
||||
_features = saved_features;
|
||||
}
|
||||
|
||||
// get cpu information.
|
||||
void VM_Version::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "PowerPC POWER%lu", PowerArchitecturePPC64);
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "PPC %s", features_string());
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -128,6 +128,8 @@ public:
|
||||
|
||||
// POWER 8: DSCR current value.
|
||||
static uint64_t _dscr_val;
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_PPC_VM_VERSION_PPC_HPP
|
||||
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "vm_version_ext_s390.hpp"
|
||||
|
||||
// VM_Version_Ext statics
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_sockets = 0;
|
||||
bool VM_Version_Ext::_initialized = false;
|
||||
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
// get cpu information.
|
||||
void VM_Version_Ext::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "s390 %s", VM_Version::get_model_string());
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", features_string());
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_S390_VM_VERSION_EXT_S390_HPP
|
||||
#define CPU_S390_VM_VERSION_EXT_S390_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#define CPU_INFO "cpu_info"
|
||||
#define CPU_TYPE "fpu_type"
|
||||
#define CPU_DESCRIPTION "implementation"
|
||||
#define CHIP_ID "chip_id"
|
||||
#define CORE_ID "core_id"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
private:
|
||||
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
public:
|
||||
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
};
|
||||
|
||||
#endif // CPU_S390_VM_VERSION_EXT_S390_HPP
|
@ -1490,3 +1490,19 @@ unsigned long VM_Version::z_SIGSEGV() {
|
||||
);
|
||||
return ZeroBuffer;
|
||||
}
|
||||
|
||||
|
||||
// get cpu information.
|
||||
void VM_Version::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE, "s390 %s", VM_Version::get_model_string());
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "s390 %s", features_string());
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -533,6 +533,8 @@ class VM_Version: public Abstract_VM_Version {
|
||||
// Sometimes helpful for debugging.
|
||||
static unsigned long z_SIGILL();
|
||||
static unsigned long z_SIGSEGV();
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_S390_VM_VERSION_S390_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. 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
|
||||
@ -27,7 +27,7 @@
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "vm_version_ext_x86.hpp"
|
||||
#include "vm_version_x86.hpp"
|
||||
|
||||
// The following header contains the implementations of rdtsc()
|
||||
#include OS_CPU_HEADER_INLINE(os)
|
||||
@ -101,9 +101,9 @@ static jlong initialize_frequency() {
|
||||
|
||||
// if platform supports invariant tsc,
|
||||
// apply higher resolution and granularity for conversion calculations
|
||||
if (VM_Version_Ext::supports_tscinv_ext()) {
|
||||
if (VM_Version::supports_tscinv_ext()) {
|
||||
// for invariant tsc platforms, take the maximum qualified cpu frequency
|
||||
tsc_freq = (double)VM_Version_Ext::maximum_qualified_cpu_frequency();
|
||||
tsc_freq = (double)VM_Version::maximum_qualified_cpu_frequency();
|
||||
os_to_tsc_conv_factor = tsc_freq / os_freq;
|
||||
} else {
|
||||
// use measurements to estimate
|
||||
@ -171,7 +171,7 @@ static bool ergonomics() {
|
||||
}
|
||||
|
||||
bool Rdtsc::is_supported() {
|
||||
return VM_Version_Ext::supports_tscinv_ext();
|
||||
return VM_Version::supports_tscinv_ext();
|
||||
}
|
||||
|
||||
bool Rdtsc::is_elapsed_counter_enabled() {
|
||||
@ -198,7 +198,7 @@ bool Rdtsc::initialize() {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
assert(!rdtsc_elapsed_counter_enabled, "invariant");
|
||||
VM_Version_Ext::initialize();
|
||||
VM_Version::initialize_tsc();
|
||||
assert(0 == tsc_frequency, "invariant");
|
||||
assert(0 == _epoch, "invariant");
|
||||
bool result = initialize_elapsed_counter(); // init hw
|
||||
|
@ -1,982 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "jvm.h"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/stubCodeGenerator.hpp"
|
||||
#include "vm_version_ext_x86.hpp"
|
||||
|
||||
typedef enum {
|
||||
CPU_FAMILY_8086_8088 = 0,
|
||||
CPU_FAMILY_INTEL_286 = 2,
|
||||
CPU_FAMILY_INTEL_386 = 3,
|
||||
CPU_FAMILY_INTEL_486 = 4,
|
||||
CPU_FAMILY_PENTIUM = 5,
|
||||
CPU_FAMILY_PENTIUMPRO = 6, // Same family several models
|
||||
CPU_FAMILY_PENTIUM_4 = 0xF
|
||||
} FamilyFlag;
|
||||
|
||||
typedef enum {
|
||||
RDTSCP_FLAG = 0x08000000, // bit 27
|
||||
INTEL64_FLAG = 0x20000000 // bit 29
|
||||
} _featureExtendedEdxFlag;
|
||||
|
||||
#define CPUID_STANDARD_FN 0x0
|
||||
#define CPUID_STANDARD_FN_1 0x1
|
||||
#define CPUID_STANDARD_FN_4 0x4
|
||||
#define CPUID_STANDARD_FN_B 0xb
|
||||
|
||||
#define CPUID_EXTENDED_FN 0x80000000
|
||||
#define CPUID_EXTENDED_FN_1 0x80000001
|
||||
#define CPUID_EXTENDED_FN_2 0x80000002
|
||||
#define CPUID_EXTENDED_FN_3 0x80000003
|
||||
#define CPUID_EXTENDED_FN_4 0x80000004
|
||||
#define CPUID_EXTENDED_FN_7 0x80000007
|
||||
#define CPUID_EXTENDED_FN_8 0x80000008
|
||||
|
||||
typedef enum {
|
||||
FPU_FLAG = 0x00000001,
|
||||
VME_FLAG = 0x00000002,
|
||||
DE_FLAG = 0x00000004,
|
||||
PSE_FLAG = 0x00000008,
|
||||
TSC_FLAG = 0x00000010,
|
||||
MSR_FLAG = 0x00000020,
|
||||
PAE_FLAG = 0x00000040,
|
||||
MCE_FLAG = 0x00000080,
|
||||
CX8_FLAG = 0x00000100,
|
||||
APIC_FLAG = 0x00000200,
|
||||
SEP_FLAG = 0x00000800,
|
||||
MTRR_FLAG = 0x00001000,
|
||||
PGE_FLAG = 0x00002000,
|
||||
MCA_FLAG = 0x00004000,
|
||||
CMOV_FLAG = 0x00008000,
|
||||
PAT_FLAG = 0x00010000,
|
||||
PSE36_FLAG = 0x00020000,
|
||||
PSNUM_FLAG = 0x00040000,
|
||||
CLFLUSH_FLAG = 0x00080000,
|
||||
DTS_FLAG = 0x00200000,
|
||||
ACPI_FLAG = 0x00400000,
|
||||
MMX_FLAG = 0x00800000,
|
||||
FXSR_FLAG = 0x01000000,
|
||||
SSE_FLAG = 0x02000000,
|
||||
SSE2_FLAG = 0x04000000,
|
||||
SS_FLAG = 0x08000000,
|
||||
HTT_FLAG = 0x10000000,
|
||||
TM_FLAG = 0x20000000
|
||||
} FeatureEdxFlag;
|
||||
|
||||
static BufferBlob* cpuid_brand_string_stub_blob;
|
||||
static const int cpuid_brand_string_stub_size = 550;
|
||||
|
||||
extern "C" {
|
||||
typedef void (*getCPUIDBrandString_stub_t)(void*);
|
||||
}
|
||||
|
||||
static getCPUIDBrandString_stub_t getCPUIDBrandString_stub = NULL;
|
||||
|
||||
class VM_Version_Ext_StubGenerator: public StubCodeGenerator {
|
||||
public:
|
||||
|
||||
VM_Version_Ext_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
|
||||
|
||||
address generate_getCPUIDBrandString(void) {
|
||||
// Flags to test CPU type.
|
||||
const uint32_t HS_EFL_AC = 0x40000;
|
||||
const uint32_t HS_EFL_ID = 0x200000;
|
||||
// Values for when we don't have a CPUID instruction.
|
||||
const int CPU_FAMILY_SHIFT = 8;
|
||||
const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT);
|
||||
const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
|
||||
|
||||
Label detect_486, cpu486, detect_586, done, ext_cpuid;
|
||||
|
||||
StubCodeMark mark(this, "VM_Version_Ext", "getCPUIDNameInfo_stub");
|
||||
# define __ _masm->
|
||||
|
||||
address start = __ pc();
|
||||
|
||||
//
|
||||
// void getCPUIDBrandString(VM_Version::CpuidInfo* cpuid_info);
|
||||
//
|
||||
// LP64: rcx and rdx are first and second argument registers on windows
|
||||
|
||||
__ push(rbp);
|
||||
#ifdef _LP64
|
||||
__ mov(rbp, c_rarg0); // cpuid_info address
|
||||
#else
|
||||
__ movptr(rbp, Address(rsp, 8)); // cpuid_info address
|
||||
#endif
|
||||
__ push(rbx);
|
||||
__ push(rsi);
|
||||
__ pushf(); // preserve rbx, and flags
|
||||
__ pop(rax);
|
||||
__ push(rax);
|
||||
__ mov(rcx, rax);
|
||||
//
|
||||
// if we are unable to change the AC flag, we have a 386
|
||||
//
|
||||
__ xorl(rax, HS_EFL_AC);
|
||||
__ push(rax);
|
||||
__ popf();
|
||||
__ pushf();
|
||||
__ pop(rax);
|
||||
__ cmpptr(rax, rcx);
|
||||
__ jccb(Assembler::notEqual, detect_486);
|
||||
|
||||
__ movl(rax, CPU_FAMILY_386);
|
||||
__ jmp(done);
|
||||
|
||||
//
|
||||
// If we are unable to change the ID flag, we have a 486 which does
|
||||
// not support the "cpuid" instruction.
|
||||
//
|
||||
__ bind(detect_486);
|
||||
__ mov(rax, rcx);
|
||||
__ xorl(rax, HS_EFL_ID);
|
||||
__ push(rax);
|
||||
__ popf();
|
||||
__ pushf();
|
||||
__ pop(rax);
|
||||
__ cmpptr(rcx, rax);
|
||||
__ jccb(Assembler::notEqual, detect_586);
|
||||
|
||||
__ bind(cpu486);
|
||||
__ movl(rax, CPU_FAMILY_486);
|
||||
__ jmp(done);
|
||||
|
||||
//
|
||||
// At this point, we have a chip which supports the "cpuid" instruction
|
||||
//
|
||||
__ bind(detect_586);
|
||||
__ xorl(rax, rax);
|
||||
__ cpuid();
|
||||
__ orl(rax, rax);
|
||||
__ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input
|
||||
// value of at least 1, we give up and
|
||||
// assume a 486
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000000) for processor brand string detection
|
||||
//
|
||||
__ bind(ext_cpuid);
|
||||
__ movl(rax, CPUID_EXTENDED_FN);
|
||||
__ cpuid();
|
||||
__ cmpl(rax, CPUID_EXTENDED_FN_4);
|
||||
__ jcc(Assembler::below, done);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000002) // first 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_2);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_0_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_1_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_2_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_3_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000003) // next 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_3);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_4_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_5_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_6_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_7_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000004) // last 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_4);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_8_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_9_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_10_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version_Ext::proc_name_11_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// return
|
||||
//
|
||||
__ bind(done);
|
||||
__ popf();
|
||||
__ pop(rsi);
|
||||
__ pop(rbx);
|
||||
__ pop(rbp);
|
||||
__ ret(0);
|
||||
|
||||
# undef __
|
||||
|
||||
return start;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// VM_Version_Ext statics
|
||||
const size_t VM_Version_Ext::VENDOR_LENGTH = 13;
|
||||
const size_t VM_Version_Ext::CPU_EBS_MAX_LENGTH = (3 * 4 * 4 + 1);
|
||||
const size_t VM_Version_Ext::CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
const size_t VM_Version_Ext::CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
char* VM_Version_Ext::_cpu_brand_string = NULL;
|
||||
int64_t VM_Version_Ext::_max_qualified_cpu_frequency = 0;
|
||||
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_packages = 0;
|
||||
|
||||
void VM_Version_Ext::initialize(void) {
|
||||
ResourceMark rm;
|
||||
|
||||
cpuid_brand_string_stub_blob = BufferBlob::create("getCPUIDBrandString_stub", cpuid_brand_string_stub_size);
|
||||
if (cpuid_brand_string_stub_blob == NULL) {
|
||||
vm_exit_during_initialization("Unable to allocate getCPUIDBrandString_stub");
|
||||
}
|
||||
CodeBuffer c(cpuid_brand_string_stub_blob);
|
||||
VM_Version_Ext_StubGenerator g(&c);
|
||||
getCPUIDBrandString_stub = CAST_TO_FN_PTR(getCPUIDBrandString_stub_t,
|
||||
g.generate_getCPUIDBrandString());
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_model_description(void) {
|
||||
uint32_t cpu_family = extended_cpu_family();
|
||||
uint32_t cpu_model = extended_cpu_model();
|
||||
const char* model = NULL;
|
||||
|
||||
if (cpu_family == CPU_FAMILY_PENTIUMPRO) {
|
||||
for (uint32_t i = 0; i <= cpu_model; i++) {
|
||||
model = _model_id_pentium_pro[i];
|
||||
if (model == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_brand_string(void) {
|
||||
if (_cpu_brand_string == NULL) {
|
||||
_cpu_brand_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_EBS_MAX_LENGTH, mtInternal);
|
||||
if (NULL == _cpu_brand_string) {
|
||||
return NULL;
|
||||
}
|
||||
int ret_val = cpu_extended_brand_string(_cpu_brand_string, CPU_EBS_MAX_LENGTH);
|
||||
if (ret_val != OS_OK) {
|
||||
FREE_C_HEAP_ARRAY(char, _cpu_brand_string);
|
||||
_cpu_brand_string = NULL;
|
||||
}
|
||||
}
|
||||
return _cpu_brand_string;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_brand(void) {
|
||||
const char* brand = NULL;
|
||||
|
||||
if ((_cpuid_info.std_cpuid1_ebx.value & 0xFF) > 0) {
|
||||
int brand_num = _cpuid_info.std_cpuid1_ebx.value & 0xFF;
|
||||
brand = _brand_id[0];
|
||||
for (int i = 0; brand != NULL && i <= brand_num; i += 1) {
|
||||
brand = _brand_id[i];
|
||||
}
|
||||
}
|
||||
return brand;
|
||||
}
|
||||
|
||||
bool VM_Version_Ext::cpu_is_em64t(void) {
|
||||
return ((_cpuid_info.ext_cpuid1_edx.value & INTEL64_FLAG) == INTEL64_FLAG);
|
||||
}
|
||||
|
||||
bool VM_Version_Ext::is_netburst(void) {
|
||||
return (is_intel() && (extended_cpu_family() == CPU_FAMILY_PENTIUM_4));
|
||||
}
|
||||
|
||||
bool VM_Version_Ext::supports_tscinv_ext(void) {
|
||||
if (!supports_tscinv_bit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_intel()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_amd()) {
|
||||
return !is_amd_Barcelona();
|
||||
}
|
||||
|
||||
if (is_hygon()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VM_Version_Ext::resolve_cpu_information_details(void) {
|
||||
|
||||
// in future we want to base this information on proper cpu
|
||||
// and cache topology enumeration such as:
|
||||
// Intel 64 Architecture Processor Topology Enumeration
|
||||
// which supports system cpu and cache topology enumeration
|
||||
// either using 2xAPICIDs or initial APICIDs
|
||||
|
||||
// currently only rough cpu information estimates
|
||||
// which will not necessarily reflect the exact configuration of the system
|
||||
|
||||
// this is the number of logical hardware threads
|
||||
// visible to the operating system
|
||||
_no_of_threads = os::processor_count();
|
||||
|
||||
// find out number of threads per cpu package
|
||||
int threads_per_package = threads_per_core() * cores_per_cpu();
|
||||
|
||||
// use amount of threads visible to the process in order to guess number of sockets
|
||||
_no_of_packages = _no_of_threads / threads_per_package;
|
||||
|
||||
// process might only see a subset of the total number of threads
|
||||
// from a single processor package. Virtualization/resource management for example.
|
||||
// If so then just write a hard 1 as num of pkgs.
|
||||
if (0 == _no_of_packages) {
|
||||
_no_of_packages = 1;
|
||||
}
|
||||
|
||||
// estimate the number of cores
|
||||
_no_of_cores = cores_per_cpu() * _no_of_packages;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
if (_no_of_threads == 0) {
|
||||
resolve_cpu_information_details();
|
||||
}
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
if (_no_of_cores == 0) {
|
||||
resolve_cpu_information_details();
|
||||
}
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
if (_no_of_packages == 0) {
|
||||
resolve_cpu_information_details();
|
||||
}
|
||||
return _no_of_packages;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_family_description(void) {
|
||||
int cpu_family_id = extended_cpu_family();
|
||||
if (is_amd()) {
|
||||
if (cpu_family_id < ExtendedFamilyIdLength_AMD) {
|
||||
return _family_id_amd[cpu_family_id];
|
||||
}
|
||||
}
|
||||
if (is_intel()) {
|
||||
if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) {
|
||||
return cpu_model_description();
|
||||
}
|
||||
if (cpu_family_id < ExtendedFamilyIdLength_INTEL) {
|
||||
return _family_id_intel[cpu_family_id];
|
||||
}
|
||||
}
|
||||
if (is_hygon()) {
|
||||
return "Dhyana";
|
||||
}
|
||||
return "Unknown x86";
|
||||
}
|
||||
|
||||
int VM_Version_Ext::cpu_type_description(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_TYPE_DESC_BUF_SIZE, "buffer len should at least be == CPU_TYPE_DESC_BUF_SIZE!");
|
||||
|
||||
const char* cpu_type = NULL;
|
||||
const char* x64 = NULL;
|
||||
|
||||
if (is_intel()) {
|
||||
cpu_type = "Intel";
|
||||
x64 = cpu_is_em64t() ? " Intel64" : "";
|
||||
} else if (is_amd()) {
|
||||
cpu_type = "AMD";
|
||||
x64 = cpu_is_em64t() ? " AMD64" : "";
|
||||
} else if (is_hygon()) {
|
||||
cpu_type = "Hygon";
|
||||
x64 = cpu_is_em64t() ? " AMD64" : "";
|
||||
} else {
|
||||
cpu_type = "Unknown x86";
|
||||
x64 = cpu_is_em64t() ? " x86_64" : "";
|
||||
}
|
||||
|
||||
jio_snprintf(buf, buf_len, "%s %s%s SSE SSE2%s%s%s%s%s%s%s%s",
|
||||
cpu_type,
|
||||
cpu_family_description(),
|
||||
supports_ht() ? " (HT)" : "",
|
||||
supports_sse3() ? " SSE3" : "",
|
||||
supports_ssse3() ? " SSSE3" : "",
|
||||
supports_sse4_1() ? " SSE4.1" : "",
|
||||
supports_sse4_2() ? " SSE4.2" : "",
|
||||
supports_sse4a() ? " SSE4A" : "",
|
||||
is_netburst() ? " Netburst" : "",
|
||||
is_intel_family_core() ? " Core" : "",
|
||||
x64);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::cpu_extended_brand_string(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_EBS_MAX_LENGTH, "buffer len should at least be == CPU_EBS_MAX_LENGTH!");
|
||||
assert(getCPUIDBrandString_stub != NULL, "not initialized");
|
||||
|
||||
// invoke newly generated asm code to fetch CPU Brand String
|
||||
getCPUIDBrandString_stub(&_cpuid_info);
|
||||
|
||||
// fetch results into buffer
|
||||
*((uint32_t*) &buf[0]) = _cpuid_info.proc_name_0;
|
||||
*((uint32_t*) &buf[4]) = _cpuid_info.proc_name_1;
|
||||
*((uint32_t*) &buf[8]) = _cpuid_info.proc_name_2;
|
||||
*((uint32_t*) &buf[12]) = _cpuid_info.proc_name_3;
|
||||
*((uint32_t*) &buf[16]) = _cpuid_info.proc_name_4;
|
||||
*((uint32_t*) &buf[20]) = _cpuid_info.proc_name_5;
|
||||
*((uint32_t*) &buf[24]) = _cpuid_info.proc_name_6;
|
||||
*((uint32_t*) &buf[28]) = _cpuid_info.proc_name_7;
|
||||
*((uint32_t*) &buf[32]) = _cpuid_info.proc_name_8;
|
||||
*((uint32_t*) &buf[36]) = _cpuid_info.proc_name_9;
|
||||
*((uint32_t*) &buf[40]) = _cpuid_info.proc_name_10;
|
||||
*((uint32_t*) &buf[44]) = _cpuid_info.proc_name_11;
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
size_t VM_Version_Ext::cpu_write_support_string(char* const buf, size_t buf_len) {
|
||||
guarantee(buf != NULL, "buffer is NULL!");
|
||||
guarantee(buf_len > 0, "buffer len not enough!");
|
||||
|
||||
unsigned int flag = 0;
|
||||
unsigned int fi = 0;
|
||||
size_t written = 0;
|
||||
const char* prefix = "";
|
||||
|
||||
#define WRITE_TO_BUF(string) \
|
||||
{ \
|
||||
int res = jio_snprintf(&buf[written], buf_len - written, "%s%s", prefix, string); \
|
||||
if (res < 0) { \
|
||||
return buf_len - 1; \
|
||||
} \
|
||||
written += res; \
|
||||
if (prefix[0] == '\0') { \
|
||||
prefix = ", "; \
|
||||
} \
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
|
||||
if (flag == HTT_FLAG && (((_cpuid_info.std_cpuid1_ebx.value >> 16) & 0xff) <= 1)) {
|
||||
continue; /* no hyperthreading */
|
||||
} else if (flag == SEP_FLAG && (cpu_family() == CPU_FAMILY_PENTIUMPRO && ((_cpuid_info.std_cpuid1_eax.value & 0xff) < 0x33))) {
|
||||
continue; /* no fast system call */
|
||||
}
|
||||
if ((_cpuid_info.std_cpuid1_edx.value & flag) && strlen(_feature_edx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_edx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.std_cpuid1_ecx.value & flag) && strlen(_feature_ecx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_ecx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.ext_cpuid1_ecx.value & flag) && strlen(_feature_extended_ecx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_extended_ecx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.ext_cpuid1_edx.value & flag) && strlen(_feature_extended_edx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_extended_edx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
if (supports_tscinv_bit()) {
|
||||
WRITE_TO_BUF("Invariant TSC");
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a detailed description of the cpu to a given buffer, including
|
||||
* feature set.
|
||||
*/
|
||||
int VM_Version_Ext::cpu_detailed_description(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_DETAILED_DESC_BUF_SIZE, "buffer len should at least be == CPU_DETAILED_DESC_BUF_SIZE!");
|
||||
|
||||
static const char* unknown = "<unknown>";
|
||||
char vendor_id[VENDOR_LENGTH];
|
||||
const char* family = NULL;
|
||||
const char* model = NULL;
|
||||
const char* brand = NULL;
|
||||
int outputLen = 0;
|
||||
|
||||
family = cpu_family_description();
|
||||
if (family == NULL) {
|
||||
family = unknown;
|
||||
}
|
||||
|
||||
model = cpu_model_description();
|
||||
if (model == NULL) {
|
||||
model = unknown;
|
||||
}
|
||||
|
||||
brand = cpu_brand_string();
|
||||
|
||||
if (brand == NULL) {
|
||||
brand = cpu_brand();
|
||||
if (brand == NULL) {
|
||||
brand = unknown;
|
||||
}
|
||||
}
|
||||
|
||||
*((uint32_t*) &vendor_id[0]) = _cpuid_info.std_vendor_name_0;
|
||||
*((uint32_t*) &vendor_id[4]) = _cpuid_info.std_vendor_name_2;
|
||||
*((uint32_t*) &vendor_id[8]) = _cpuid_info.std_vendor_name_1;
|
||||
vendor_id[VENDOR_LENGTH-1] = '\0';
|
||||
|
||||
outputLen = jio_snprintf(buf, buf_len, "Brand: %s, Vendor: %s\n"
|
||||
"Family: %s (0x%x), Model: %s (0x%x), Stepping: 0x%x\n"
|
||||
"Ext. family: 0x%x, Ext. model: 0x%x, Type: 0x%x, Signature: 0x%8.8x\n"
|
||||
"Features: ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
|
||||
"Ext. features: eax: 0x%8.8x, ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
|
||||
"Supports: ",
|
||||
brand,
|
||||
vendor_id,
|
||||
family,
|
||||
extended_cpu_family(),
|
||||
model,
|
||||
extended_cpu_model(),
|
||||
cpu_stepping(),
|
||||
_cpuid_info.std_cpuid1_eax.bits.ext_family,
|
||||
_cpuid_info.std_cpuid1_eax.bits.ext_model,
|
||||
_cpuid_info.std_cpuid1_eax.bits.proc_type,
|
||||
_cpuid_info.std_cpuid1_eax.value,
|
||||
_cpuid_info.std_cpuid1_ebx.value,
|
||||
_cpuid_info.std_cpuid1_ecx.value,
|
||||
_cpuid_info.std_cpuid1_edx.value,
|
||||
_cpuid_info.ext_cpuid1_eax,
|
||||
_cpuid_info.ext_cpuid1_ebx,
|
||||
_cpuid_info.ext_cpuid1_ecx,
|
||||
_cpuid_info.ext_cpuid1_edx);
|
||||
|
||||
if (outputLen < 0 || (size_t) outputLen >= buf_len - 1) {
|
||||
if (buf_len > 0) { buf[buf_len-1] = '\0'; }
|
||||
return OS_ERR;
|
||||
}
|
||||
|
||||
cpu_write_support_string(&buf[outputLen], buf_len - outputLen);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
char cpu_type_desc[CPU_TYPE_DESC_BUF_SIZE];
|
||||
size_t cpu_desc_len = sizeof(cpu_type_desc);
|
||||
|
||||
cpu_type_description(cpu_type_desc, cpu_desc_len);
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_desc_len, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, cpu_type_desc, cpu_desc_len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
char cpu_detailed_desc_buffer[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
size_t cpu_detailed_desc_len = sizeof(cpu_detailed_desc_buffer);
|
||||
|
||||
cpu_detailed_description(cpu_detailed_desc_buffer, cpu_detailed_desc_len);
|
||||
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, cpu_detailed_desc_len, mtTracing);
|
||||
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(tmp, cpu_detailed_desc_buffer, cpu_detailed_desc_len);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* For information about extracting the frequency from the cpu brand string, please see:
|
||||
*
|
||||
* Intel Processor Identification and the CPUID Instruction
|
||||
* Application Note 485
|
||||
* May 2012
|
||||
*
|
||||
* The return value is the frequency in Hz.
|
||||
*/
|
||||
int64_t VM_Version_Ext::max_qualified_cpu_freq_from_brand_string(void) {
|
||||
const char* const brand_string = cpu_brand_string();
|
||||
if (brand_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
const int64_t MEGA = 1000000;
|
||||
int64_t multiplier = 0;
|
||||
int64_t frequency = 0;
|
||||
uint8_t idx = 0;
|
||||
// The brand string buffer is at most 48 bytes.
|
||||
// -2 is to prevent buffer overrun when looking for y in yHz, as z is +2 from y.
|
||||
for (; idx < 48-2; ++idx) {
|
||||
// Format is either "x.xxyHz" or "xxxxyHz", where y=M, G, T and x are digits.
|
||||
// Search brand string for "yHz" where y is M, G, or T.
|
||||
if (brand_string[idx+1] == 'H' && brand_string[idx+2] == 'z') {
|
||||
if (brand_string[idx] == 'M') {
|
||||
multiplier = MEGA;
|
||||
} else if (brand_string[idx] == 'G') {
|
||||
multiplier = MEGA * 1000;
|
||||
} else if (brand_string[idx] == 'T') {
|
||||
multiplier = MEGA * MEGA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (multiplier > 0) {
|
||||
// Compute freqency (in Hz) from brand string.
|
||||
if (brand_string[idx-3] == '.') { // if format is "x.xx"
|
||||
frequency = (brand_string[idx-4] - '0') * multiplier;
|
||||
frequency += (brand_string[idx-2] - '0') * multiplier / 10;
|
||||
frequency += (brand_string[idx-1] - '0') * multiplier / 100;
|
||||
} else { // format is "xxxx"
|
||||
frequency = (brand_string[idx-4] - '0') * 1000;
|
||||
frequency += (brand_string[idx-3] - '0') * 100;
|
||||
frequency += (brand_string[idx-2] - '0') * 10;
|
||||
frequency += (brand_string[idx-1] - '0');
|
||||
frequency *= multiplier;
|
||||
}
|
||||
}
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
int64_t VM_Version_Ext::maximum_qualified_cpu_frequency(void) {
|
||||
if (_max_qualified_cpu_frequency == 0) {
|
||||
_max_qualified_cpu_frequency = max_qualified_cpu_freq_from_brand_string();
|
||||
}
|
||||
return _max_qualified_cpu_frequency;
|
||||
}
|
||||
|
||||
const char* const VM_Version_Ext::_family_id_intel[ExtendedFamilyIdLength_INTEL] = {
|
||||
"8086/8088",
|
||||
"",
|
||||
"286",
|
||||
"386",
|
||||
"486",
|
||||
"Pentium",
|
||||
"Pentium Pro", //or Pentium-M/Woodcrest depeding on model
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Pentium 4"
|
||||
};
|
||||
|
||||
const char* const VM_Version_Ext::_family_id_amd[ExtendedFamilyIdLength_AMD] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"5x86",
|
||||
"K5/K6",
|
||||
"Athlon/AthlonXP",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Opteron/Athlon64",
|
||||
"Opteron QC/Phenom", // Barcelona et.al.
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Zen"
|
||||
};
|
||||
// Partially from Intel 64 and IA-32 Architecture Software Developer's Manual,
|
||||
// September 2013, Vol 3C Table 35-1
|
||||
const char* const VM_Version_Ext::_model_id_pentium_pro[] = {
|
||||
"",
|
||||
"Pentium Pro",
|
||||
"",
|
||||
"Pentium II model 3",
|
||||
"",
|
||||
"Pentium II model 5/Xeon/Celeron",
|
||||
"Celeron",
|
||||
"Pentium III/Pentium III Xeon",
|
||||
"Pentium III/Pentium III Xeon",
|
||||
"Pentium M model 9", // Yonah
|
||||
"Pentium III, model A",
|
||||
"Pentium III, model B",
|
||||
"",
|
||||
"Pentium M model D", // Dothan
|
||||
"",
|
||||
"Core 2", // 0xf Woodcrest/Conroe/Merom/Kentsfield/Clovertown
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Celeron", // 0x16 Celeron 65nm
|
||||
"Core 2", // 0x17 Penryn / Harpertown
|
||||
"",
|
||||
"",
|
||||
"Core i7", // 0x1A CPU_MODEL_NEHALEM_EP
|
||||
"Atom", // 0x1B Z5xx series Silverthorn
|
||||
"",
|
||||
"Core 2", // 0x1D Dunnington (6-core)
|
||||
"Nehalem", // 0x1E CPU_MODEL_NEHALEM
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Westmere", // 0x25 CPU_MODEL_WESTMERE
|
||||
"",
|
||||
"",
|
||||
"", // 0x28
|
||||
"",
|
||||
"Sandy Bridge", // 0x2a "2nd Generation Intel Core i7, i5, i3"
|
||||
"",
|
||||
"Westmere-EP", // 0x2c CPU_MODEL_WESTMERE_EP
|
||||
"Sandy Bridge-EP", // 0x2d CPU_MODEL_SANDYBRIDGE_EP
|
||||
"Nehalem-EX", // 0x2e CPU_MODEL_NEHALEM_EX
|
||||
"Westmere-EX", // 0x2f CPU_MODEL_WESTMERE_EX
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Ivy Bridge", // 0x3a
|
||||
"",
|
||||
"Haswell", // 0x3c "4th Generation Intel Core Processor"
|
||||
"", // 0x3d "Next Generation Intel Core Processor"
|
||||
"Ivy Bridge-EP", // 0x3e "Next Generation Intel Xeon Processor E7 Family"
|
||||
"", // 0x3f "Future Generation Intel Xeon Processor"
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Haswell", // 0x45 "4th Generation Intel Core Processor"
|
||||
"Haswell", // 0x46 "4th Generation Intel Core Processor"
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Brand ID is for back compability
|
||||
* Newer CPUs uses the extended brand string */
|
||||
const char* const VM_Version_Ext::_brand_id[] = {
|
||||
"",
|
||||
"Celeron processor",
|
||||
"Pentium III processor",
|
||||
"Intel Pentium III Xeon processor",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Intel Pentium 4 processor",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const char* const VM_Version_Ext::_feature_edx_id[] = {
|
||||
"On-Chip FPU",
|
||||
"Virtual Mode Extensions",
|
||||
"Debugging Extensions",
|
||||
"Page Size Extensions",
|
||||
"Time Stamp Counter",
|
||||
"Model Specific Registers",
|
||||
"Physical Address Extension",
|
||||
"Machine Check Exceptions",
|
||||
"CMPXCHG8B Instruction",
|
||||
"On-Chip APIC",
|
||||
"",
|
||||
"Fast System Call",
|
||||
"Memory Type Range Registers",
|
||||
"Page Global Enable",
|
||||
"Machine Check Architecture",
|
||||
"Conditional Mov Instruction",
|
||||
"Page Attribute Table",
|
||||
"36-bit Page Size Extension",
|
||||
"Processor Serial Number",
|
||||
"CLFLUSH Instruction",
|
||||
"",
|
||||
"Debug Trace Store feature",
|
||||
"ACPI registers in MSR space",
|
||||
"Intel Architecture MMX Technology",
|
||||
"Fast Float Point Save and Restore",
|
||||
"Streaming SIMD extensions",
|
||||
"Streaming SIMD extensions 2",
|
||||
"Self-Snoop",
|
||||
"Hyper Threading",
|
||||
"Thermal Monitor",
|
||||
"",
|
||||
"Pending Break Enable"
|
||||
};
|
||||
|
||||
const char* const VM_Version_Ext::_feature_extended_edx_id[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"SYSCALL/SYSRET",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Execute Disable Bit",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"RDTSCP",
|
||||
"",
|
||||
"Intel 64 Architecture",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
const char* const VM_Version_Ext::_feature_ecx_id[] = {
|
||||
"Streaming SIMD Extensions 3",
|
||||
"PCLMULQDQ",
|
||||
"64-bit DS Area",
|
||||
"MONITOR/MWAIT instructions",
|
||||
"CPL Qualified Debug Store",
|
||||
"Virtual Machine Extensions",
|
||||
"Safer Mode Extensions",
|
||||
"Enhanced Intel SpeedStep technology",
|
||||
"Thermal Monitor 2",
|
||||
"Supplemental Streaming SIMD Extensions 3",
|
||||
"L1 Context ID",
|
||||
"",
|
||||
"Fused Multiply-Add",
|
||||
"CMPXCHG16B",
|
||||
"xTPR Update Control",
|
||||
"Perfmon and Debug Capability",
|
||||
"",
|
||||
"Process-context identifiers",
|
||||
"Direct Cache Access",
|
||||
"Streaming SIMD extensions 4.1",
|
||||
"Streaming SIMD extensions 4.2",
|
||||
"x2APIC",
|
||||
"MOVBE",
|
||||
"Popcount instruction",
|
||||
"TSC-Deadline",
|
||||
"AESNI",
|
||||
"XSAVE",
|
||||
"OSXSAVE",
|
||||
"AVX",
|
||||
"F16C",
|
||||
"RDRAND",
|
||||
""
|
||||
};
|
||||
|
||||
const char* const VM_Version_Ext::_feature_extended_ecx_id[] = {
|
||||
"LAHF/SAHF instruction support",
|
||||
"Core multi-processor legacy mode",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Advanced Bit Manipulations: LZCNT",
|
||||
"SSE4A: MOVNTSS, MOVNTSD, EXTRQ, INSERTQ",
|
||||
"Misaligned SSE mode",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_X86_VM_VERSION_EXT_X86_HPP
|
||||
#define CPU_X86_VM_VERSION_EXT_X86_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/sizes.hpp"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
|
||||
enum {
|
||||
ExtendedFamilyIdLength_INTEL = 16,
|
||||
ExtendedFamilyIdLength_AMD = 24
|
||||
};
|
||||
|
||||
private:
|
||||
static const size_t VENDOR_LENGTH;
|
||||
static const size_t CPU_EBS_MAX_LENGTH;
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE;
|
||||
|
||||
static const char* const _family_id_intel[ExtendedFamilyIdLength_INTEL];
|
||||
static const char* const _family_id_amd[ExtendedFamilyIdLength_AMD];
|
||||
static const char* const _brand_id[];
|
||||
static const char* const _model_id_pentium_pro[];
|
||||
|
||||
static const char* const _feature_edx_id[];
|
||||
static const char* const _feature_extended_edx_id[];
|
||||
static const char* const _feature_ecx_id[];
|
||||
static const char* const _feature_extended_ecx_id[];
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_packages;
|
||||
static char* _cpu_brand_string;
|
||||
static int64_t _max_qualified_cpu_frequency;
|
||||
|
||||
static const char* cpu_family_description(void);
|
||||
static const char* cpu_model_description(void);
|
||||
static const char* cpu_brand(void);
|
||||
static const char* cpu_brand_string(void);
|
||||
|
||||
static int cpu_type_description(char* const buf, size_t buf_len);
|
||||
static int cpu_detailed_description(char* const buf, size_t buf_len);
|
||||
static int cpu_extended_brand_string(char* const buf, size_t buf_len);
|
||||
|
||||
static bool cpu_is_em64t(void);
|
||||
static bool is_netburst(void);
|
||||
|
||||
// Returns bytes written excluding termninating null byte.
|
||||
static size_t cpu_write_support_string(char* const buf, size_t buf_len);
|
||||
static void resolve_cpu_information_details(void);
|
||||
static int64_t max_qualified_cpu_freq_from_brand_string(void);
|
||||
|
||||
public:
|
||||
// Offsets for cpuid asm stub brand string
|
||||
static ByteSize proc_name_0_offset() { return byte_offset_of(CpuidInfo, proc_name_0); }
|
||||
static ByteSize proc_name_1_offset() { return byte_offset_of(CpuidInfo, proc_name_1); }
|
||||
static ByteSize proc_name_2_offset() { return byte_offset_of(CpuidInfo, proc_name_2); }
|
||||
static ByteSize proc_name_3_offset() { return byte_offset_of(CpuidInfo, proc_name_3); }
|
||||
static ByteSize proc_name_4_offset() { return byte_offset_of(CpuidInfo, proc_name_4); }
|
||||
static ByteSize proc_name_5_offset() { return byte_offset_of(CpuidInfo, proc_name_5); }
|
||||
static ByteSize proc_name_6_offset() { return byte_offset_of(CpuidInfo, proc_name_6); }
|
||||
static ByteSize proc_name_7_offset() { return byte_offset_of(CpuidInfo, proc_name_7); }
|
||||
static ByteSize proc_name_8_offset() { return byte_offset_of(CpuidInfo, proc_name_8); }
|
||||
static ByteSize proc_name_9_offset() { return byte_offset_of(CpuidInfo, proc_name_9); }
|
||||
static ByteSize proc_name_10_offset() { return byte_offset_of(CpuidInfo, proc_name_10); }
|
||||
static ByteSize proc_name_11_offset() { return byte_offset_of(CpuidInfo, proc_name_11); }
|
||||
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static int64_t maximum_qualified_cpu_frequency(void);
|
||||
|
||||
static bool supports_tscinv_ext(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
|
||||
static void initialize();
|
||||
};
|
||||
|
||||
#endif // CPU_X86_VM_VERSION_EXT_X86_HPP
|
@ -83,6 +83,19 @@ bool VM_Version::supports_clflush() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CPUID_STANDARD_FN 0x0
|
||||
#define CPUID_STANDARD_FN_1 0x1
|
||||
#define CPUID_STANDARD_FN_4 0x4
|
||||
#define CPUID_STANDARD_FN_B 0xb
|
||||
|
||||
#define CPUID_EXTENDED_FN 0x80000000
|
||||
#define CPUID_EXTENDED_FN_1 0x80000001
|
||||
#define CPUID_EXTENDED_FN_2 0x80000002
|
||||
#define CPUID_EXTENDED_FN_3 0x80000003
|
||||
#define CPUID_EXTENDED_FN_4 0x80000004
|
||||
#define CPUID_EXTENDED_FN_7 0x80000007
|
||||
#define CPUID_EXTENDED_FN_8 0x80000008
|
||||
|
||||
class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
public:
|
||||
|
||||
@ -626,6 +639,149 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ pop(rbp);
|
||||
__ ret(0);
|
||||
|
||||
# undef __
|
||||
|
||||
return start;
|
||||
};
|
||||
|
||||
|
||||
address generate_getCPUIDBrandString(void) {
|
||||
// Flags to test CPU type.
|
||||
const uint32_t HS_EFL_AC = 0x40000;
|
||||
const uint32_t HS_EFL_ID = 0x200000;
|
||||
// Values for when we don't have a CPUID instruction.
|
||||
const int CPU_FAMILY_SHIFT = 8;
|
||||
const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT);
|
||||
const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
|
||||
|
||||
Label detect_486, cpu486, detect_586, done, ext_cpuid;
|
||||
|
||||
StubCodeMark mark(this, "VM_Version", "getCPUIDNameInfo_stub");
|
||||
# define __ _masm->
|
||||
|
||||
address start = __ pc();
|
||||
|
||||
//
|
||||
// void getCPUIDBrandString(VM_Version::CpuidInfo* cpuid_info);
|
||||
//
|
||||
// LP64: rcx and rdx are first and second argument registers on windows
|
||||
|
||||
__ push(rbp);
|
||||
#ifdef _LP64
|
||||
__ mov(rbp, c_rarg0); // cpuid_info address
|
||||
#else
|
||||
__ movptr(rbp, Address(rsp, 8)); // cpuid_info address
|
||||
#endif
|
||||
__ push(rbx);
|
||||
__ push(rsi);
|
||||
__ pushf(); // preserve rbx, and flags
|
||||
__ pop(rax);
|
||||
__ push(rax);
|
||||
__ mov(rcx, rax);
|
||||
//
|
||||
// if we are unable to change the AC flag, we have a 386
|
||||
//
|
||||
__ xorl(rax, HS_EFL_AC);
|
||||
__ push(rax);
|
||||
__ popf();
|
||||
__ pushf();
|
||||
__ pop(rax);
|
||||
__ cmpptr(rax, rcx);
|
||||
__ jccb(Assembler::notEqual, detect_486);
|
||||
|
||||
__ movl(rax, CPU_FAMILY_386);
|
||||
__ jmp(done);
|
||||
|
||||
//
|
||||
// If we are unable to change the ID flag, we have a 486 which does
|
||||
// not support the "cpuid" instruction.
|
||||
//
|
||||
__ bind(detect_486);
|
||||
__ mov(rax, rcx);
|
||||
__ xorl(rax, HS_EFL_ID);
|
||||
__ push(rax);
|
||||
__ popf();
|
||||
__ pushf();
|
||||
__ pop(rax);
|
||||
__ cmpptr(rcx, rax);
|
||||
__ jccb(Assembler::notEqual, detect_586);
|
||||
|
||||
__ bind(cpu486);
|
||||
__ movl(rax, CPU_FAMILY_486);
|
||||
__ jmp(done);
|
||||
|
||||
//
|
||||
// At this point, we have a chip which supports the "cpuid" instruction
|
||||
//
|
||||
__ bind(detect_586);
|
||||
__ xorl(rax, rax);
|
||||
__ cpuid();
|
||||
__ orl(rax, rax);
|
||||
__ jcc(Assembler::equal, cpu486); // if cpuid doesn't support an input
|
||||
// value of at least 1, we give up and
|
||||
// assume a 486
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000000) for processor brand string detection
|
||||
//
|
||||
__ bind(ext_cpuid);
|
||||
__ movl(rax, CPUID_EXTENDED_FN);
|
||||
__ cpuid();
|
||||
__ cmpl(rax, CPUID_EXTENDED_FN_4);
|
||||
__ jcc(Assembler::below, done);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000002) // first 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_2);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_0_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_1_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_2_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_3_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000003) // next 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_3);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_4_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_5_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_6_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_7_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// Extended cpuid(0x80000004) // last 16 bytes in brand string
|
||||
//
|
||||
__ movl(rax, CPUID_EXTENDED_FN_4);
|
||||
__ cpuid();
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_8_offset())));
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_9_offset())));
|
||||
__ movl(Address(rsi, 0), rbx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_10_offset())));
|
||||
__ movl(Address(rsi, 0), rcx);
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::proc_name_11_offset())));
|
||||
__ movl(Address(rsi,0), rdx);
|
||||
|
||||
//
|
||||
// return
|
||||
//
|
||||
__ bind(done);
|
||||
__ popf();
|
||||
__ pop(rsi);
|
||||
__ pop(rbx);
|
||||
__ pop(rbp);
|
||||
__ ret(0);
|
||||
|
||||
# undef __
|
||||
|
||||
return start;
|
||||
@ -1889,6 +2045,8 @@ int VM_Version::avx3_threshold() {
|
||||
FLAG_IS_DEFAULT(AVX3Threshold)) ? 0 : AVX3Threshold;
|
||||
}
|
||||
|
||||
static bool _vm_version_initialized = false;
|
||||
|
||||
void VM_Version::initialize() {
|
||||
ResourceMark rm;
|
||||
// Making this stub must be FIRST use of assembler
|
||||
@ -1911,4 +2069,757 @@ void VM_Version::initialize() {
|
||||
if (VM_Version::supports_hv()) { // Supports hypervisor
|
||||
check_virtualizations();
|
||||
}
|
||||
_vm_version_initialized = true;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
CPU_FAMILY_8086_8088 = 0,
|
||||
CPU_FAMILY_INTEL_286 = 2,
|
||||
CPU_FAMILY_INTEL_386 = 3,
|
||||
CPU_FAMILY_INTEL_486 = 4,
|
||||
CPU_FAMILY_PENTIUM = 5,
|
||||
CPU_FAMILY_PENTIUMPRO = 6, // Same family several models
|
||||
CPU_FAMILY_PENTIUM_4 = 0xF
|
||||
} FamilyFlag;
|
||||
|
||||
typedef enum {
|
||||
RDTSCP_FLAG = 0x08000000, // bit 27
|
||||
INTEL64_FLAG = 0x20000000 // bit 29
|
||||
} _featureExtendedEdxFlag;
|
||||
|
||||
typedef enum {
|
||||
FPU_FLAG = 0x00000001,
|
||||
VME_FLAG = 0x00000002,
|
||||
DE_FLAG = 0x00000004,
|
||||
PSE_FLAG = 0x00000008,
|
||||
TSC_FLAG = 0x00000010,
|
||||
MSR_FLAG = 0x00000020,
|
||||
PAE_FLAG = 0x00000040,
|
||||
MCE_FLAG = 0x00000080,
|
||||
CX8_FLAG = 0x00000100,
|
||||
APIC_FLAG = 0x00000200,
|
||||
SEP_FLAG = 0x00000800,
|
||||
MTRR_FLAG = 0x00001000,
|
||||
PGE_FLAG = 0x00002000,
|
||||
MCA_FLAG = 0x00004000,
|
||||
CMOV_FLAG = 0x00008000,
|
||||
PAT_FLAG = 0x00010000,
|
||||
PSE36_FLAG = 0x00020000,
|
||||
PSNUM_FLAG = 0x00040000,
|
||||
CLFLUSH_FLAG = 0x00080000,
|
||||
DTS_FLAG = 0x00200000,
|
||||
ACPI_FLAG = 0x00400000,
|
||||
MMX_FLAG = 0x00800000,
|
||||
FXSR_FLAG = 0x01000000,
|
||||
SSE_FLAG = 0x02000000,
|
||||
SSE2_FLAG = 0x04000000,
|
||||
SS_FLAG = 0x08000000,
|
||||
HTT_FLAG = 0x10000000,
|
||||
TM_FLAG = 0x20000000
|
||||
} FeatureEdxFlag;
|
||||
|
||||
static BufferBlob* cpuid_brand_string_stub_blob;
|
||||
static const int cpuid_brand_string_stub_size = 550;
|
||||
|
||||
extern "C" {
|
||||
typedef void (*getCPUIDBrandString_stub_t)(void*);
|
||||
}
|
||||
|
||||
static getCPUIDBrandString_stub_t getCPUIDBrandString_stub = NULL;
|
||||
|
||||
// VM_Version statics
|
||||
enum {
|
||||
ExtendedFamilyIdLength_INTEL = 16,
|
||||
ExtendedFamilyIdLength_AMD = 24
|
||||
};
|
||||
|
||||
const size_t VENDOR_LENGTH = 13;
|
||||
const size_t CPU_EBS_MAX_LENGTH = (3 * 4 * 4 + 1);
|
||||
static char* _cpu_brand_string = NULL;
|
||||
static int64_t _max_qualified_cpu_frequency = 0;
|
||||
|
||||
static int _no_of_threads = 0;
|
||||
static int _no_of_cores = 0;
|
||||
|
||||
const char* const _family_id_intel[ExtendedFamilyIdLength_INTEL] = {
|
||||
"8086/8088",
|
||||
"",
|
||||
"286",
|
||||
"386",
|
||||
"486",
|
||||
"Pentium",
|
||||
"Pentium Pro", //or Pentium-M/Woodcrest depeding on model
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Pentium 4"
|
||||
};
|
||||
|
||||
const char* const _family_id_amd[ExtendedFamilyIdLength_AMD] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"5x86",
|
||||
"K5/K6",
|
||||
"Athlon/AthlonXP",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Opteron/Athlon64",
|
||||
"Opteron QC/Phenom", // Barcelona et.al.
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Zen"
|
||||
};
|
||||
// Partially from Intel 64 and IA-32 Architecture Software Developer's Manual,
|
||||
// September 2013, Vol 3C Table 35-1
|
||||
const char* const _model_id_pentium_pro[] = {
|
||||
"",
|
||||
"Pentium Pro",
|
||||
"",
|
||||
"Pentium II model 3",
|
||||
"",
|
||||
"Pentium II model 5/Xeon/Celeron",
|
||||
"Celeron",
|
||||
"Pentium III/Pentium III Xeon",
|
||||
"Pentium III/Pentium III Xeon",
|
||||
"Pentium M model 9", // Yonah
|
||||
"Pentium III, model A",
|
||||
"Pentium III, model B",
|
||||
"",
|
||||
"Pentium M model D", // Dothan
|
||||
"",
|
||||
"Core 2", // 0xf Woodcrest/Conroe/Merom/Kentsfield/Clovertown
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Celeron", // 0x16 Celeron 65nm
|
||||
"Core 2", // 0x17 Penryn / Harpertown
|
||||
"",
|
||||
"",
|
||||
"Core i7", // 0x1A CPU_MODEL_NEHALEM_EP
|
||||
"Atom", // 0x1B Z5xx series Silverthorn
|
||||
"",
|
||||
"Core 2", // 0x1D Dunnington (6-core)
|
||||
"Nehalem", // 0x1E CPU_MODEL_NEHALEM
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Westmere", // 0x25 CPU_MODEL_WESTMERE
|
||||
"",
|
||||
"",
|
||||
"", // 0x28
|
||||
"",
|
||||
"Sandy Bridge", // 0x2a "2nd Generation Intel Core i7, i5, i3"
|
||||
"",
|
||||
"Westmere-EP", // 0x2c CPU_MODEL_WESTMERE_EP
|
||||
"Sandy Bridge-EP", // 0x2d CPU_MODEL_SANDYBRIDGE_EP
|
||||
"Nehalem-EX", // 0x2e CPU_MODEL_NEHALEM_EX
|
||||
"Westmere-EX", // 0x2f CPU_MODEL_WESTMERE_EX
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Ivy Bridge", // 0x3a
|
||||
"",
|
||||
"Haswell", // 0x3c "4th Generation Intel Core Processor"
|
||||
"", // 0x3d "Next Generation Intel Core Processor"
|
||||
"Ivy Bridge-EP", // 0x3e "Next Generation Intel Xeon Processor E7 Family"
|
||||
"", // 0x3f "Future Generation Intel Xeon Processor"
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Haswell", // 0x45 "4th Generation Intel Core Processor"
|
||||
"Haswell", // 0x46 "4th Generation Intel Core Processor"
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Brand ID is for back compability
|
||||
* Newer CPUs uses the extended brand string */
|
||||
const char* const _brand_id[] = {
|
||||
"",
|
||||
"Celeron processor",
|
||||
"Pentium III processor",
|
||||
"Intel Pentium III Xeon processor",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Intel Pentium 4 processor",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const char* const _feature_edx_id[] = {
|
||||
"On-Chip FPU",
|
||||
"Virtual Mode Extensions",
|
||||
"Debugging Extensions",
|
||||
"Page Size Extensions",
|
||||
"Time Stamp Counter",
|
||||
"Model Specific Registers",
|
||||
"Physical Address Extension",
|
||||
"Machine Check Exceptions",
|
||||
"CMPXCHG8B Instruction",
|
||||
"On-Chip APIC",
|
||||
"",
|
||||
"Fast System Call",
|
||||
"Memory Type Range Registers",
|
||||
"Page Global Enable",
|
||||
"Machine Check Architecture",
|
||||
"Conditional Mov Instruction",
|
||||
"Page Attribute Table",
|
||||
"36-bit Page Size Extension",
|
||||
"Processor Serial Number",
|
||||
"CLFLUSH Instruction",
|
||||
"",
|
||||
"Debug Trace Store feature",
|
||||
"ACPI registers in MSR space",
|
||||
"Intel Architecture MMX Technology",
|
||||
"Fast Float Point Save and Restore",
|
||||
"Streaming SIMD extensions",
|
||||
"Streaming SIMD extensions 2",
|
||||
"Self-Snoop",
|
||||
"Hyper Threading",
|
||||
"Thermal Monitor",
|
||||
"",
|
||||
"Pending Break Enable"
|
||||
};
|
||||
|
||||
const char* const _feature_extended_edx_id[] = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"SYSCALL/SYSRET",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Execute Disable Bit",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"RDTSCP",
|
||||
"",
|
||||
"Intel 64 Architecture",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
const char* const _feature_ecx_id[] = {
|
||||
"Streaming SIMD Extensions 3",
|
||||
"PCLMULQDQ",
|
||||
"64-bit DS Area",
|
||||
"MONITOR/MWAIT instructions",
|
||||
"CPL Qualified Debug Store",
|
||||
"Virtual Machine Extensions",
|
||||
"Safer Mode Extensions",
|
||||
"Enhanced Intel SpeedStep technology",
|
||||
"Thermal Monitor 2",
|
||||
"Supplemental Streaming SIMD Extensions 3",
|
||||
"L1 Context ID",
|
||||
"",
|
||||
"Fused Multiply-Add",
|
||||
"CMPXCHG16B",
|
||||
"xTPR Update Control",
|
||||
"Perfmon and Debug Capability",
|
||||
"",
|
||||
"Process-context identifiers",
|
||||
"Direct Cache Access",
|
||||
"Streaming SIMD extensions 4.1",
|
||||
"Streaming SIMD extensions 4.2",
|
||||
"x2APIC",
|
||||
"MOVBE",
|
||||
"Popcount instruction",
|
||||
"TSC-Deadline",
|
||||
"AESNI",
|
||||
"XSAVE",
|
||||
"OSXSAVE",
|
||||
"AVX",
|
||||
"F16C",
|
||||
"RDRAND",
|
||||
""
|
||||
};
|
||||
|
||||
const char* const _feature_extended_ecx_id[] = {
|
||||
"LAHF/SAHF instruction support",
|
||||
"Core multi-processor legacy mode",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Advanced Bit Manipulations: LZCNT",
|
||||
"SSE4A: MOVNTSS, MOVNTSD, EXTRQ, INSERTQ",
|
||||
"Misaligned SSE mode",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
void VM_Version::initialize_tsc(void) {
|
||||
ResourceMark rm;
|
||||
|
||||
cpuid_brand_string_stub_blob = BufferBlob::create("getCPUIDBrandString_stub", cpuid_brand_string_stub_size);
|
||||
if (cpuid_brand_string_stub_blob == NULL) {
|
||||
vm_exit_during_initialization("Unable to allocate getCPUIDBrandString_stub");
|
||||
}
|
||||
CodeBuffer c(cpuid_brand_string_stub_blob);
|
||||
VM_Version_StubGenerator g(&c);
|
||||
getCPUIDBrandString_stub = CAST_TO_FN_PTR(getCPUIDBrandString_stub_t,
|
||||
g.generate_getCPUIDBrandString());
|
||||
}
|
||||
|
||||
const char* VM_Version::cpu_model_description(void) {
|
||||
uint32_t cpu_family = extended_cpu_family();
|
||||
uint32_t cpu_model = extended_cpu_model();
|
||||
const char* model = NULL;
|
||||
|
||||
if (cpu_family == CPU_FAMILY_PENTIUMPRO) {
|
||||
for (uint32_t i = 0; i <= cpu_model; i++) {
|
||||
model = _model_id_pentium_pro[i];
|
||||
if (model == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
const char* VM_Version::cpu_brand_string(void) {
|
||||
if (_cpu_brand_string == NULL) {
|
||||
_cpu_brand_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_EBS_MAX_LENGTH, mtInternal);
|
||||
if (NULL == _cpu_brand_string) {
|
||||
return NULL;
|
||||
}
|
||||
int ret_val = cpu_extended_brand_string(_cpu_brand_string, CPU_EBS_MAX_LENGTH);
|
||||
if (ret_val != OS_OK) {
|
||||
FREE_C_HEAP_ARRAY(char, _cpu_brand_string);
|
||||
_cpu_brand_string = NULL;
|
||||
}
|
||||
}
|
||||
return _cpu_brand_string;
|
||||
}
|
||||
|
||||
const char* VM_Version::cpu_brand(void) {
|
||||
const char* brand = NULL;
|
||||
|
||||
if ((_cpuid_info.std_cpuid1_ebx.value & 0xFF) > 0) {
|
||||
int brand_num = _cpuid_info.std_cpuid1_ebx.value & 0xFF;
|
||||
brand = _brand_id[0];
|
||||
for (int i = 0; brand != NULL && i <= brand_num; i += 1) {
|
||||
brand = _brand_id[i];
|
||||
}
|
||||
}
|
||||
return brand;
|
||||
}
|
||||
|
||||
bool VM_Version::cpu_is_em64t(void) {
|
||||
return ((_cpuid_info.ext_cpuid1_edx.value & INTEL64_FLAG) == INTEL64_FLAG);
|
||||
}
|
||||
|
||||
bool VM_Version::is_netburst(void) {
|
||||
return (is_intel() && (extended_cpu_family() == CPU_FAMILY_PENTIUM_4));
|
||||
}
|
||||
|
||||
bool VM_Version::supports_tscinv_ext(void) {
|
||||
if (!supports_tscinv_bit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_intel()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_amd()) {
|
||||
return !is_amd_Barcelona();
|
||||
}
|
||||
|
||||
if (is_hygon()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VM_Version::resolve_cpu_information_details(void) {
|
||||
|
||||
// in future we want to base this information on proper cpu
|
||||
// and cache topology enumeration such as:
|
||||
// Intel 64 Architecture Processor Topology Enumeration
|
||||
// which supports system cpu and cache topology enumeration
|
||||
// either using 2xAPICIDs or initial APICIDs
|
||||
|
||||
// currently only rough cpu information estimates
|
||||
// which will not necessarily reflect the exact configuration of the system
|
||||
|
||||
// this is the number of logical hardware threads
|
||||
// visible to the operating system
|
||||
_no_of_threads = os::processor_count();
|
||||
|
||||
// find out number of threads per cpu package
|
||||
int threads_per_package = threads_per_core() * cores_per_cpu();
|
||||
|
||||
// use amount of threads visible to the process in order to guess number of sockets
|
||||
_no_of_sockets = _no_of_threads / threads_per_package;
|
||||
|
||||
// process might only see a subset of the total number of threads
|
||||
// from a single processor package. Virtualization/resource management for example.
|
||||
// If so then just write a hard 1 as num of pkgs.
|
||||
if (0 == _no_of_sockets) {
|
||||
_no_of_sockets = 1;
|
||||
}
|
||||
|
||||
// estimate the number of cores
|
||||
_no_of_cores = cores_per_cpu() * _no_of_sockets;
|
||||
}
|
||||
|
||||
|
||||
const char* VM_Version::cpu_family_description(void) {
|
||||
int cpu_family_id = extended_cpu_family();
|
||||
if (is_amd()) {
|
||||
if (cpu_family_id < ExtendedFamilyIdLength_AMD) {
|
||||
return _family_id_amd[cpu_family_id];
|
||||
}
|
||||
}
|
||||
if (is_intel()) {
|
||||
if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) {
|
||||
return cpu_model_description();
|
||||
}
|
||||
if (cpu_family_id < ExtendedFamilyIdLength_INTEL) {
|
||||
return _family_id_intel[cpu_family_id];
|
||||
}
|
||||
}
|
||||
if (is_hygon()) {
|
||||
return "Dhyana";
|
||||
}
|
||||
return "Unknown x86";
|
||||
}
|
||||
|
||||
int VM_Version::cpu_type_description(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_TYPE_DESC_BUF_SIZE, "buffer len should at least be == CPU_TYPE_DESC_BUF_SIZE!");
|
||||
|
||||
const char* cpu_type = NULL;
|
||||
const char* x64 = NULL;
|
||||
|
||||
if (is_intel()) {
|
||||
cpu_type = "Intel";
|
||||
x64 = cpu_is_em64t() ? " Intel64" : "";
|
||||
} else if (is_amd()) {
|
||||
cpu_type = "AMD";
|
||||
x64 = cpu_is_em64t() ? " AMD64" : "";
|
||||
} else if (is_hygon()) {
|
||||
cpu_type = "Hygon";
|
||||
x64 = cpu_is_em64t() ? " AMD64" : "";
|
||||
} else {
|
||||
cpu_type = "Unknown x86";
|
||||
x64 = cpu_is_em64t() ? " x86_64" : "";
|
||||
}
|
||||
|
||||
jio_snprintf(buf, buf_len, "%s %s%s SSE SSE2%s%s%s%s%s%s%s%s",
|
||||
cpu_type,
|
||||
cpu_family_description(),
|
||||
supports_ht() ? " (HT)" : "",
|
||||
supports_sse3() ? " SSE3" : "",
|
||||
supports_ssse3() ? " SSSE3" : "",
|
||||
supports_sse4_1() ? " SSE4.1" : "",
|
||||
supports_sse4_2() ? " SSE4.2" : "",
|
||||
supports_sse4a() ? " SSE4A" : "",
|
||||
is_netburst() ? " Netburst" : "",
|
||||
is_intel_family_core() ? " Core" : "",
|
||||
x64);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
int VM_Version::cpu_extended_brand_string(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_EBS_MAX_LENGTH, "buffer len should at least be == CPU_EBS_MAX_LENGTH!");
|
||||
assert(getCPUIDBrandString_stub != NULL, "not initialized");
|
||||
|
||||
// invoke newly generated asm code to fetch CPU Brand String
|
||||
getCPUIDBrandString_stub(&_cpuid_info);
|
||||
|
||||
// fetch results into buffer
|
||||
*((uint32_t*) &buf[0]) = _cpuid_info.proc_name_0;
|
||||
*((uint32_t*) &buf[4]) = _cpuid_info.proc_name_1;
|
||||
*((uint32_t*) &buf[8]) = _cpuid_info.proc_name_2;
|
||||
*((uint32_t*) &buf[12]) = _cpuid_info.proc_name_3;
|
||||
*((uint32_t*) &buf[16]) = _cpuid_info.proc_name_4;
|
||||
*((uint32_t*) &buf[20]) = _cpuid_info.proc_name_5;
|
||||
*((uint32_t*) &buf[24]) = _cpuid_info.proc_name_6;
|
||||
*((uint32_t*) &buf[28]) = _cpuid_info.proc_name_7;
|
||||
*((uint32_t*) &buf[32]) = _cpuid_info.proc_name_8;
|
||||
*((uint32_t*) &buf[36]) = _cpuid_info.proc_name_9;
|
||||
*((uint32_t*) &buf[40]) = _cpuid_info.proc_name_10;
|
||||
*((uint32_t*) &buf[44]) = _cpuid_info.proc_name_11;
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
size_t VM_Version::cpu_write_support_string(char* const buf, size_t buf_len) {
|
||||
guarantee(buf != NULL, "buffer is NULL!");
|
||||
guarantee(buf_len > 0, "buffer len not enough!");
|
||||
|
||||
unsigned int flag = 0;
|
||||
unsigned int fi = 0;
|
||||
size_t written = 0;
|
||||
const char* prefix = "";
|
||||
|
||||
#define WRITE_TO_BUF(string) \
|
||||
{ \
|
||||
int res = jio_snprintf(&buf[written], buf_len - written, "%s%s", prefix, string); \
|
||||
if (res < 0) { \
|
||||
return buf_len - 1; \
|
||||
} \
|
||||
written += res; \
|
||||
if (prefix[0] == '\0') { \
|
||||
prefix = ", "; \
|
||||
} \
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
|
||||
if (flag == HTT_FLAG && (((_cpuid_info.std_cpuid1_ebx.value >> 16) & 0xff) <= 1)) {
|
||||
continue; /* no hyperthreading */
|
||||
} else if (flag == SEP_FLAG && (cpu_family() == CPU_FAMILY_PENTIUMPRO && ((_cpuid_info.std_cpuid1_eax.value & 0xff) < 0x33))) {
|
||||
continue; /* no fast system call */
|
||||
}
|
||||
if ((_cpuid_info.std_cpuid1_edx.value & flag) && strlen(_feature_edx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_edx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.std_cpuid1_ecx.value & flag) && strlen(_feature_ecx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_ecx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000 ; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.ext_cpuid1_ecx.value & flag) && strlen(_feature_extended_ecx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_extended_ecx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
for (flag = 1, fi = 0; flag <= 0x20000000; flag <<= 1, fi++) {
|
||||
if ((_cpuid_info.ext_cpuid1_edx.value & flag) && strlen(_feature_extended_edx_id[fi]) > 0) {
|
||||
WRITE_TO_BUF(_feature_extended_edx_id[fi]);
|
||||
}
|
||||
}
|
||||
|
||||
if (supports_tscinv_bit()) {
|
||||
WRITE_TO_BUF("Invariant TSC");
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a detailed description of the cpu to a given buffer, including
|
||||
* feature set.
|
||||
*/
|
||||
int VM_Version::cpu_detailed_description(char* const buf, size_t buf_len) {
|
||||
assert(buf != NULL, "buffer is NULL!");
|
||||
assert(buf_len >= CPU_DETAILED_DESC_BUF_SIZE, "buffer len should at least be == CPU_DETAILED_DESC_BUF_SIZE!");
|
||||
|
||||
static const char* unknown = "<unknown>";
|
||||
char vendor_id[VENDOR_LENGTH];
|
||||
const char* family = NULL;
|
||||
const char* model = NULL;
|
||||
const char* brand = NULL;
|
||||
int outputLen = 0;
|
||||
|
||||
family = cpu_family_description();
|
||||
if (family == NULL) {
|
||||
family = unknown;
|
||||
}
|
||||
|
||||
model = cpu_model_description();
|
||||
if (model == NULL) {
|
||||
model = unknown;
|
||||
}
|
||||
|
||||
brand = cpu_brand_string();
|
||||
|
||||
if (brand == NULL) {
|
||||
brand = cpu_brand();
|
||||
if (brand == NULL) {
|
||||
brand = unknown;
|
||||
}
|
||||
}
|
||||
|
||||
*((uint32_t*) &vendor_id[0]) = _cpuid_info.std_vendor_name_0;
|
||||
*((uint32_t*) &vendor_id[4]) = _cpuid_info.std_vendor_name_2;
|
||||
*((uint32_t*) &vendor_id[8]) = _cpuid_info.std_vendor_name_1;
|
||||
vendor_id[VENDOR_LENGTH-1] = '\0';
|
||||
|
||||
outputLen = jio_snprintf(buf, buf_len, "Brand: %s, Vendor: %s\n"
|
||||
"Family: %s (0x%x), Model: %s (0x%x), Stepping: 0x%x\n"
|
||||
"Ext. family: 0x%x, Ext. model: 0x%x, Type: 0x%x, Signature: 0x%8.8x\n"
|
||||
"Features: ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
|
||||
"Ext. features: eax: 0x%8.8x, ebx: 0x%8.8x, ecx: 0x%8.8x, edx: 0x%8.8x\n"
|
||||
"Supports: ",
|
||||
brand,
|
||||
vendor_id,
|
||||
family,
|
||||
extended_cpu_family(),
|
||||
model,
|
||||
extended_cpu_model(),
|
||||
cpu_stepping(),
|
||||
_cpuid_info.std_cpuid1_eax.bits.ext_family,
|
||||
_cpuid_info.std_cpuid1_eax.bits.ext_model,
|
||||
_cpuid_info.std_cpuid1_eax.bits.proc_type,
|
||||
_cpuid_info.std_cpuid1_eax.value,
|
||||
_cpuid_info.std_cpuid1_ebx.value,
|
||||
_cpuid_info.std_cpuid1_ecx.value,
|
||||
_cpuid_info.std_cpuid1_edx.value,
|
||||
_cpuid_info.ext_cpuid1_eax,
|
||||
_cpuid_info.ext_cpuid1_ebx,
|
||||
_cpuid_info.ext_cpuid1_ecx,
|
||||
_cpuid_info.ext_cpuid1_edx);
|
||||
|
||||
if (outputLen < 0 || (size_t) outputLen >= buf_len - 1) {
|
||||
if (buf_len > 0) { buf[buf_len-1] = '\0'; }
|
||||
return OS_ERR;
|
||||
}
|
||||
|
||||
cpu_write_support_string(&buf[outputLen], buf_len - outputLen);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Fill in Abstract_VM_Version statics
|
||||
void VM_Version::initialize_cpu_information() {
|
||||
assert(_vm_version_initialized, "should have initialized VM_Version long ago");
|
||||
assert(!_initialized, "shouldn't be initialized yet");
|
||||
resolve_cpu_information_details();
|
||||
|
||||
// initialize cpu_name and cpu_desc
|
||||
cpu_type_description(_cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
cpu_detailed_description(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For information about extracting the frequency from the cpu brand string, please see:
|
||||
*
|
||||
* Intel Processor Identification and the CPUID Instruction
|
||||
* Application Note 485
|
||||
* May 2012
|
||||
*
|
||||
* The return value is the frequency in Hz.
|
||||
*/
|
||||
int64_t VM_Version::max_qualified_cpu_freq_from_brand_string(void) {
|
||||
const char* const brand_string = cpu_brand_string();
|
||||
if (brand_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
const int64_t MEGA = 1000000;
|
||||
int64_t multiplier = 0;
|
||||
int64_t frequency = 0;
|
||||
uint8_t idx = 0;
|
||||
// The brand string buffer is at most 48 bytes.
|
||||
// -2 is to prevent buffer overrun when looking for y in yHz, as z is +2 from y.
|
||||
for (; idx < 48-2; ++idx) {
|
||||
// Format is either "x.xxyHz" or "xxxxyHz", where y=M, G, T and x are digits.
|
||||
// Search brand string for "yHz" where y is M, G, or T.
|
||||
if (brand_string[idx+1] == 'H' && brand_string[idx+2] == 'z') {
|
||||
if (brand_string[idx] == 'M') {
|
||||
multiplier = MEGA;
|
||||
} else if (brand_string[idx] == 'G') {
|
||||
multiplier = MEGA * 1000;
|
||||
} else if (brand_string[idx] == 'T') {
|
||||
multiplier = MEGA * MEGA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (multiplier > 0) {
|
||||
// Compute freqency (in Hz) from brand string.
|
||||
if (brand_string[idx-3] == '.') { // if format is "x.xx"
|
||||
frequency = (brand_string[idx-4] - '0') * multiplier;
|
||||
frequency += (brand_string[idx-2] - '0') * multiplier / 10;
|
||||
frequency += (brand_string[idx-1] - '0') * multiplier / 100;
|
||||
} else { // format is "xxxx"
|
||||
frequency = (brand_string[idx-4] - '0') * 1000;
|
||||
frequency += (brand_string[idx-3] - '0') * 100;
|
||||
frequency += (brand_string[idx-2] - '0') * 10;
|
||||
frequency += (brand_string[idx-1] - '0');
|
||||
frequency *= multiplier;
|
||||
}
|
||||
}
|
||||
return frequency;
|
||||
}
|
||||
|
||||
|
||||
int64_t VM_Version::maximum_qualified_cpu_frequency(void) {
|
||||
if (_max_qualified_cpu_frequency == 0) {
|
||||
_max_qualified_cpu_frequency = max_qualified_cpu_freq_from_brand_string();
|
||||
}
|
||||
return _max_qualified_cpu_frequency;
|
||||
}
|
||||
|
||||
|
@ -371,7 +371,7 @@ protected:
|
||||
|
||||
static const char* _features_names[];
|
||||
|
||||
enum Extended_Family {
|
||||
enum Extended_Family {
|
||||
// AMD
|
||||
CPU_FAMILY_AMD_11H = 0x11,
|
||||
// ZX
|
||||
@ -1053,6 +1053,45 @@ public:
|
||||
// support functions for virtualization detection
|
||||
private:
|
||||
static void check_virtualizations();
|
||||
|
||||
static const char* cpu_family_description(void);
|
||||
static const char* cpu_model_description(void);
|
||||
static const char* cpu_brand(void);
|
||||
static const char* cpu_brand_string(void);
|
||||
|
||||
static int cpu_type_description(char* const buf, size_t buf_len);
|
||||
static int cpu_detailed_description(char* const buf, size_t buf_len);
|
||||
static int cpu_extended_brand_string(char* const buf, size_t buf_len);
|
||||
|
||||
static bool cpu_is_em64t(void);
|
||||
static bool is_netburst(void);
|
||||
|
||||
// Returns bytes written excluding termninating null byte.
|
||||
static size_t cpu_write_support_string(char* const buf, size_t buf_len);
|
||||
static void resolve_cpu_information_details(void);
|
||||
static int64_t max_qualified_cpu_freq_from_brand_string(void);
|
||||
|
||||
public:
|
||||
// Offsets for cpuid asm stub brand string
|
||||
static ByteSize proc_name_0_offset() { return byte_offset_of(CpuidInfo, proc_name_0); }
|
||||
static ByteSize proc_name_1_offset() { return byte_offset_of(CpuidInfo, proc_name_1); }
|
||||
static ByteSize proc_name_2_offset() { return byte_offset_of(CpuidInfo, proc_name_2); }
|
||||
static ByteSize proc_name_3_offset() { return byte_offset_of(CpuidInfo, proc_name_3); }
|
||||
static ByteSize proc_name_4_offset() { return byte_offset_of(CpuidInfo, proc_name_4); }
|
||||
static ByteSize proc_name_5_offset() { return byte_offset_of(CpuidInfo, proc_name_5); }
|
||||
static ByteSize proc_name_6_offset() { return byte_offset_of(CpuidInfo, proc_name_6); }
|
||||
static ByteSize proc_name_7_offset() { return byte_offset_of(CpuidInfo, proc_name_7); }
|
||||
static ByteSize proc_name_8_offset() { return byte_offset_of(CpuidInfo, proc_name_8); }
|
||||
static ByteSize proc_name_9_offset() { return byte_offset_of(CpuidInfo, proc_name_9); }
|
||||
static ByteSize proc_name_10_offset() { return byte_offset_of(CpuidInfo, proc_name_10); }
|
||||
static ByteSize proc_name_11_offset() { return byte_offset_of(CpuidInfo, proc_name_11); }
|
||||
|
||||
static int64_t maximum_qualified_cpu_frequency(void);
|
||||
|
||||
static bool supports_tscinv_ext(void);
|
||||
|
||||
static void initialize_tsc();
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_X86_VM_VERSION_X86_HPP
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2021, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "vm_version_ext_zero.hpp"
|
||||
|
||||
// VM_Version_Ext statics
|
||||
int VM_Version_Ext::_no_of_threads = 0;
|
||||
int VM_Version_Ext::_no_of_cores = 0;
|
||||
int VM_Version_Ext::_no_of_sockets = 0;
|
||||
bool VM_Version_Ext::_initialized = false;
|
||||
char VM_Version_Ext::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char VM_Version_Ext::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
void VM_Version_Ext::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
int core_id = -1;
|
||||
int chip_id = -1;
|
||||
int len = 0;
|
||||
char* src_string = NULL;
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "Zero VM");
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string);
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_threads(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_cores(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int VM_Version_Ext::number_of_sockets(void) {
|
||||
initialize_cpu_information();
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_name(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* VM_Version_Ext::cpu_description(void) {
|
||||
initialize_cpu_information();
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_ZERO_VM_VERSION_EXT_ZERO_HPP
|
||||
#define CPU_ZERO_VM_VERSION_EXT_ZERO_HPP
|
||||
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class VM_Version_Ext : public VM_Version {
|
||||
private:
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
public:
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
static void initialize_cpu_information(void);
|
||||
|
||||
};
|
||||
|
||||
#endif // CPU_ZERO_VM_VERSION_EXT_ZERO_HPP
|
@ -121,3 +121,17 @@ void VM_Version::initialize() {
|
||||
UNSUPPORTED_OPTION(CountCompiledCalls);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VM_Version::initialize_cpu_information(void) {
|
||||
// do nothing if cpu info has been initialized
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_no_of_cores = os::processor_count();
|
||||
_no_of_threads = _no_of_cores;
|
||||
_no_of_sockets = _no_of_cores;
|
||||
snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "Zero VM");
|
||||
snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "%s", _features_string);
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -34,6 +34,8 @@ class VM_Version : public Abstract_VM_Version {
|
||||
static void initialize();
|
||||
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_ZERO_VM_VERSION_ZERO_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. 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
|
||||
@ -28,10 +28,9 @@
|
||||
#include "os_aix.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/os_perf.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include CPU_HEADER(vm_version_ext)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
@ -863,11 +862,12 @@ CPUInformationInterface::CPUInformationInterface() {
|
||||
|
||||
bool CPUInformationInterface::initialize() {
|
||||
_cpu_info = new CPUInformation();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version_Ext::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version_Ext::cpu_description());
|
||||
VM_Version::initialize_cpu_information();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version::cpu_description());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/os_perf.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include CPU_HEADER(vm_version_ext)
|
||||
|
||||
#ifdef __APPLE__
|
||||
#import <libproc.h>
|
||||
@ -371,11 +371,12 @@ CPUInformationInterface::CPUInformationInterface() {
|
||||
|
||||
bool CPUInformationInterface::initialize() {
|
||||
_cpu_info = new CPUInformation();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version_Ext::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version_Ext::cpu_description());
|
||||
VM_Version::initialize_cpu_information();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version::cpu_description());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. 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
|
||||
@ -28,10 +28,9 @@
|
||||
#include "os_linux.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/os_perf.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include CPU_HEADER(vm_version_ext)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
@ -927,11 +926,12 @@ CPUInformationInterface::CPUInformationInterface() {
|
||||
|
||||
bool CPUInformationInterface::initialize() {
|
||||
_cpu_info = new CPUInformation();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version_Ext::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version_Ext::cpu_description());
|
||||
VM_Version::initialize_cpu_information();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version::cpu_description());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -32,9 +32,9 @@
|
||||
#include "runtime/os_perf.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/semaphore.inline.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include CPU_HEADER(vm_version_ext)
|
||||
#include <math.h>
|
||||
#include <psapi.h>
|
||||
#include <TlHelp32.h>
|
||||
@ -1434,11 +1434,12 @@ CPUInformationInterface::CPUInformationInterface() : _cpu_info(NULL) {}
|
||||
|
||||
bool CPUInformationInterface::initialize() {
|
||||
_cpu_info = new CPUInformation();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version_Ext::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version_Ext::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version_Ext::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version_Ext::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version_Ext::cpu_description());
|
||||
VM_Version::initialize_cpu_information();
|
||||
_cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads());
|
||||
_cpu_info->set_number_of_cores(VM_Version::number_of_cores());
|
||||
_cpu_info->set_number_of_sockets(VM_Version::number_of_sockets());
|
||||
_cpu_info->set_cpu_name(VM_Version::cpu_name());
|
||||
_cpu_info->set_cpu_description(VM_Version::cpu_description());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3648,16 +3648,16 @@ JVM_END
|
||||
|
||||
JVM_ENTRY_NO_ENV(jlong, JVM_GetRandomSeedForDumping())
|
||||
if (DumpSharedSpaces) {
|
||||
const char* release = Abstract_VM_Version::vm_release();
|
||||
const char* dbg_level = Abstract_VM_Version::jdk_debug_level();
|
||||
const char* release = VM_Version::vm_release();
|
||||
const char* dbg_level = VM_Version::jdk_debug_level();
|
||||
const char* version = VM_Version::internal_vm_info_string();
|
||||
jlong seed = (jlong)(java_lang_String::hash_code((const jbyte*)release, (int)strlen(release)) ^
|
||||
java_lang_String::hash_code((const jbyte*)dbg_level, (int)strlen(dbg_level)) ^
|
||||
java_lang_String::hash_code((const jbyte*)version, (int)strlen(version)));
|
||||
seed += (jlong)Abstract_VM_Version::vm_major_version();
|
||||
seed += (jlong)Abstract_VM_Version::vm_minor_version();
|
||||
seed += (jlong)Abstract_VM_Version::vm_security_version();
|
||||
seed += (jlong)Abstract_VM_Version::vm_patch_version();
|
||||
seed += (jlong)VM_Version::vm_major_version();
|
||||
seed += (jlong)VM_Version::vm_minor_version();
|
||||
seed += (jlong)VM_Version::vm_security_version();
|
||||
seed += (jlong)VM_Version::vm_patch_version();
|
||||
if (seed == 0) { // don't let this ever be zero.
|
||||
seed = 0x87654321;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
|
||||
break;
|
||||
default:
|
||||
// Starting from 13 we do not care about minor version anymore
|
||||
if (major < 13 || major > Abstract_VM_Version::vm_major_version()) {
|
||||
if (major < 13 || major > VM_Version::vm_major_version()) {
|
||||
return JNI_EVERSION; // unsupported major version number
|
||||
}
|
||||
}
|
||||
|
@ -337,3 +337,46 @@ bool Abstract_VM_Version::print_matching_lines_from_file(const char* filename, o
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Abstract_VM_Version statics
|
||||
int Abstract_VM_Version::_no_of_threads = 0;
|
||||
int Abstract_VM_Version::_no_of_cores = 0;
|
||||
int Abstract_VM_Version::_no_of_sockets = 0;
|
||||
bool Abstract_VM_Version::_initialized = false;
|
||||
char Abstract_VM_Version::_cpu_name[CPU_TYPE_DESC_BUF_SIZE] = {0};
|
||||
char Abstract_VM_Version::_cpu_desc[CPU_DETAILED_DESC_BUF_SIZE] = {0};
|
||||
|
||||
int Abstract_VM_Version::number_of_threads(void) {
|
||||
assert(_initialized, "should be initialized");
|
||||
return _no_of_threads;
|
||||
}
|
||||
|
||||
int Abstract_VM_Version::number_of_cores(void) {
|
||||
assert(_initialized, "should be initialized");
|
||||
return _no_of_cores;
|
||||
}
|
||||
|
||||
int Abstract_VM_Version::number_of_sockets(void) {
|
||||
assert(_initialized, "should be initialized");
|
||||
return _no_of_sockets;
|
||||
}
|
||||
|
||||
const char* Abstract_VM_Version::cpu_name(void) {
|
||||
assert(_initialized, "should be initialized");
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_TYPE_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_name, CPU_TYPE_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
const char* Abstract_VM_Version::cpu_description(void) {
|
||||
assert(_initialized, "should be initialized");
|
||||
char* tmp = NEW_C_HEAP_ARRAY_RETURN_NULL(char, CPU_DETAILED_DESC_BUF_SIZE, mtTracing);
|
||||
if (NULL == tmp) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(tmp, _cpu_desc, CPU_DETAILED_DESC_BUF_SIZE);
|
||||
return tmp;
|
||||
}
|
||||
|
@ -186,6 +186,26 @@ class Abstract_VM_Version: AllStatic {
|
||||
constexpr static bool supports_stack_watermark_barrier() { return false; }
|
||||
|
||||
static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
|
||||
|
||||
protected:
|
||||
// VM_Version statics
|
||||
static const size_t CPU_TYPE_DESC_BUF_SIZE = 256;
|
||||
static const size_t CPU_DETAILED_DESC_BUF_SIZE = 4096;
|
||||
|
||||
static int _no_of_threads;
|
||||
static int _no_of_cores;
|
||||
static int _no_of_sockets;
|
||||
static bool _initialized;
|
||||
static char _cpu_name[CPU_TYPE_DESC_BUF_SIZE];
|
||||
static char _cpu_desc[CPU_DETAILED_DESC_BUF_SIZE];
|
||||
|
||||
public:
|
||||
static int number_of_threads(void);
|
||||
static int number_of_cores(void);
|
||||
static int number_of_sockets(void);
|
||||
|
||||
static const char* cpu_name(void);
|
||||
static const char* cpu_description(void);
|
||||
};
|
||||
|
||||
#endif // SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP
|
||||
|
Loading…
x
Reference in New Issue
Block a user