Merge
This commit is contained in:
commit
46c02f0d3b
2
.hgtags
2
.hgtags
@ -340,3 +340,5 @@ f242d4332f563648426a1b0fa02d8741beba19ef jdk9-b92
|
|||||||
5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95
|
5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95
|
||||||
139f19d70350238e15e107945cea75082b6380b3 jdk-9+96
|
139f19d70350238e15e107945cea75082b6380b3 jdk-9+96
|
||||||
4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97
|
4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97
|
||||||
|
d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98
|
||||||
|
f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99
|
||||||
|
@ -340,3 +340,5 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
|
|||||||
12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
|
12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
|
||||||
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
|
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
|
||||||
75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97
|
75c3897541ecb52ee16d001ea605b12971df7303 jdk-9+97
|
||||||
|
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
|
||||||
|
7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
|
||||||
|
@ -32,7 +32,7 @@ installed_jib_script=${mydir}/../../.jib/jib
|
|||||||
install_data=${mydir}/../../.jib/.data
|
install_data=${mydir}/../../.jib/.data
|
||||||
|
|
||||||
setup_url() {
|
setup_url() {
|
||||||
if [ -f "~/.config/jib/jib.conf" ]; then
|
if [ -f ~/.config/jib/jib.conf ]; then
|
||||||
source ~/.config/jib/jib.conf
|
source ~/.config/jib/jib.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -50,6 +50,9 @@ setup_url() {
|
|||||||
if [ -n "${JIB_SERVER}" ]; then
|
if [ -n "${JIB_SERVER}" ]; then
|
||||||
jib_server="${JIB_SERVER}"
|
jib_server="${JIB_SERVER}"
|
||||||
fi
|
fi
|
||||||
|
if [ -n "${JIB_SERVER_MIRRORS}" ]; then
|
||||||
|
jib_server_mirrors="${JIB_SERVER_MIRRORS}"
|
||||||
|
fi
|
||||||
if [ -n "${JIB_REPOSITORY}" ]; then
|
if [ -n "${JIB_REPOSITORY}" ]; then
|
||||||
jib_repository="${JIB_REPOSITORY}"
|
jib_repository="${JIB_REPOSITORY}"
|
||||||
fi
|
fi
|
||||||
@ -70,8 +73,9 @@ setup_url() {
|
|||||||
jib_url="${JIB_URL}"
|
jib_url="${JIB_URL}"
|
||||||
data_string="${jib_url}"
|
data_string="${jib_url}"
|
||||||
else
|
else
|
||||||
data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
|
jib_path="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
|
||||||
jib_url="${jib_server}/${data_string}"
|
data_string="${jib_path}"
|
||||||
|
jib_url="${jib_server}/${jib_path}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +108,25 @@ install_jib() {
|
|||||||
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
|
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
|
||||||
if [ ! -s "${installed_jib_script}.gz" ]; then
|
if [ ! -s "${installed_jib_script}.gz" ]; then
|
||||||
echo "Failed to download ${jib_url}"
|
echo "Failed to download ${jib_url}"
|
||||||
exit 1
|
if [ -n "${jib_path}" -a -n "${jib_server_mirrors}" ]; then
|
||||||
|
OLD_IFS="${IFS}"
|
||||||
|
IFS=" ,"
|
||||||
|
for mirror in ${jib_server_mirrors}; do
|
||||||
|
echo "Trying mirror ${mirror}"
|
||||||
|
jib_url="${mirror}/${jib_path}"
|
||||||
|
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
|
||||||
|
if [ -s "${installed_jib_script}.gz" ]; then
|
||||||
|
echo "Download from mirror successful"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Failed to download ${jib_url}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="${OLD_IFS}"
|
||||||
|
fi
|
||||||
|
if [ ! -s "${installed_jib_script}.gz" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
echo "Extracting JIB bootstrap script"
|
echo "Extracting JIB bootstrap script"
|
||||||
rm -f "${installed_jib_script}"
|
rm -f "${installed_jib_script}"
|
||||||
|
@ -340,3 +340,5 @@ f7d70caad89ad0c43bb057bca0aad6f17ce05a6a jdk9-b92
|
|||||||
fd038e8a16eec80d0d6b337d74a582790ed4b3ee jdk-9+95
|
fd038e8a16eec80d0d6b337d74a582790ed4b3ee jdk-9+95
|
||||||
feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
|
feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
|
||||||
10a482b863582376d4ca229090334b23b05159fc jdk-9+97
|
10a482b863582376d4ca229090334b23b05159fc jdk-9+97
|
||||||
|
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
|
||||||
|
180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
|
||||||
|
@ -500,3 +500,5 @@ a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
|
|||||||
0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
|
0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
|
||||||
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
|
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
|
||||||
de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
|
de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
|
||||||
|
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
|
||||||
|
f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
|
||||||
|
@ -1446,7 +1446,7 @@ public class CommandProcessor {
|
|||||||
if (type.equals("threads")) {
|
if (type.equals("threads")) {
|
||||||
Threads threads = VM.getVM().getThreads();
|
Threads threads = VM.getVM().getThreads();
|
||||||
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
||||||
Address base = thread.getBaseOfStackPointer();
|
Address base = thread.getStackBase();
|
||||||
Address end = thread.getLastJavaSP();
|
Address end = thread.getLastJavaSP();
|
||||||
if (end == null) continue;
|
if (end == null) continue;
|
||||||
if (end.lessThan(base)) {
|
if (end.lessThan(base)) {
|
||||||
@ -1454,11 +1454,13 @@ public class CommandProcessor {
|
|||||||
base = end;
|
base = end;
|
||||||
end = tmp;
|
end = tmp;
|
||||||
}
|
}
|
||||||
out.println("Searching " + base + " " + end);
|
//out.println("Searching " + base + " " + end);
|
||||||
while (base != null && base.lessThan(end)) {
|
while (base != null && base.lessThan(end)) {
|
||||||
Address val = base.getAddressAt(0);
|
Address val = base.getAddressAt(0);
|
||||||
if (AddressOps.equal(val, value)) {
|
if (AddressOps.equal(val, value)) {
|
||||||
out.println(base);
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
thread.printThreadIDOn(new PrintStream(bos));
|
||||||
|
out.println("found on the stack of thread " + bos.toString() + " at " + base);
|
||||||
}
|
}
|
||||||
base = base.addOffsetTo(stride);
|
base = base.addOffsetTo(stride);
|
||||||
}
|
}
|
||||||
@ -1601,6 +1603,8 @@ public class CommandProcessor {
|
|||||||
thread.printThreadIDOn(new PrintStream(bos));
|
thread.printThreadIDOn(new PrintStream(bos));
|
||||||
if (all || bos.toString().equals(name)) {
|
if (all || bos.toString().equals(name)) {
|
||||||
out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
|
out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
|
||||||
|
thread.printInfoOn(out);
|
||||||
|
out.println(" ");
|
||||||
if (!all) return;
|
if (!all) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1618,6 +1622,8 @@ public class CommandProcessor {
|
|||||||
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
||||||
thread.printThreadIDOn(out);
|
thread.printThreadIDOn(out);
|
||||||
out.println(" " + thread.getThreadName());
|
out.println(" " + thread.getThreadName());
|
||||||
|
thread.printInfoOn(out);
|
||||||
|
out.println("\n...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ public class JavaThread extends Thread {
|
|||||||
} else {
|
} else {
|
||||||
tty.println("No Java frames present");
|
tty.println("No Java frames present");
|
||||||
}
|
}
|
||||||
tty.println("Base of Stack: " + getBaseOfStackPointer());
|
tty.println("Base of Stack: " + getStackBase());
|
||||||
tty.println("Last_Java_SP: " + getLastJavaSP());
|
tty.println("Last_Java_SP: " + getLastJavaSP());
|
||||||
tty.println("Last_Java_FP: " + getLastJavaFP());
|
tty.println("Last_Java_FP: " + getLastJavaFP());
|
||||||
tty.println("Last_Java_PC: " + getLastJavaPC());
|
tty.println("Last_Java_PC: " + getLastJavaPC());
|
||||||
|
@ -74,6 +74,9 @@ CFLAGS += $(VM_PICFLAG)
|
|||||||
CFLAGS += -qnortti
|
CFLAGS += -qnortti
|
||||||
CFLAGS += -qnoeh
|
CFLAGS += -qnoeh
|
||||||
|
|
||||||
|
# for compiler-level tls
|
||||||
|
CFLAGS += -qtls=default
|
||||||
|
|
||||||
CFLAGS += -D_REENTRANT
|
CFLAGS += -D_REENTRANT
|
||||||
# no xlc counterpart for -fcheck-new
|
# no xlc counterpart for -fcheck-new
|
||||||
# CFLAGS += -fcheck-new
|
# CFLAGS += -fcheck-new
|
||||||
|
@ -71,7 +71,7 @@ else ifeq ($(OPENJDK_TARGET_OS), solaris)
|
|||||||
-DSOLARIS_11_B159_OR_LATER
|
-DSOLARIS_11_B159_OR_LATER
|
||||||
SA_CFLAGS := $(CFLAGS_JDKLIB) $(COMMON_CFLAGS)
|
SA_CFLAGS := $(CFLAGS_JDKLIB) $(COMMON_CFLAGS)
|
||||||
SA_CXXFLAGS := $(CXXFLAGS_JDKLIB) $(COMMON_CFLAGS)
|
SA_CXXFLAGS := $(CXXFLAGS_JDKLIB) $(COMMON_CFLAGS)
|
||||||
SA_LDFLAGS := $(subst -z defs,, $(LDFLAGS_JDKLIB)) \
|
SA_LDFLAGS := $(subst -Wl$(COMMA)-z$(COMMA)defs,, $(LDFLAGS_JDKLIB)) \
|
||||||
-mt $(LDFLAGS_CXX_JDK)
|
-mt $(LDFLAGS_CXX_JDK)
|
||||||
SA_LIBS := -ldl -ldemangle -lthread -lc
|
SA_LIBS := -ldl -ldemangle -lthread -lc
|
||||||
|
|
||||||
|
@ -260,6 +260,13 @@ endif
|
|||||||
|
|
||||||
OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS)
|
OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS)
|
||||||
|
|
||||||
|
# Variable tracking size limit exceeded for VMStructs::init()
|
||||||
|
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "1"
|
||||||
|
# GCC >= 4.3
|
||||||
|
# Gcc 4.1.2 does not support this flag, nor does it have problems compiling the file.
|
||||||
|
OPT_CFLAGS/vmStructs.o += -fno-var-tracking-assignments
|
||||||
|
endif
|
||||||
|
|
||||||
# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp
|
# The gcc compiler segv's on ia64 when compiling bytecodeInterpreter.cpp
|
||||||
# if we use expensive-optimizations
|
# if we use expensive-optimizations
|
||||||
ifeq ($(BUILDARCH), ia64)
|
ifeq ($(BUILDARCH), ia64)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -39,7 +39,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -259,20 +258,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
|||||||
|
|
||||||
return entry_point;
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
|
||||||
|
|
||||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
|
||||||
// the days we had adapter frames. When we deoptimize a situation where a
|
|
||||||
// compiled caller calls a compiled caller will have registers it expects
|
|
||||||
// to survive the call to the callee. If we deoptimize the callee the only
|
|
||||||
// way we can restore these registers is to have the oldest interpreter
|
|
||||||
// frame that we create restore these values. That is what this routine
|
|
||||||
// will accomplish.
|
|
||||||
|
|
||||||
// At the moment we have modified c2 to not have any callee save registers
|
|
||||||
// so this problem does not exist and this routine is just a place holder.
|
|
||||||
|
|
||||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
|
||||||
}
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "runtime/icache.hpp"
|
#include "runtime/icache.hpp"
|
||||||
#include "runtime/interfaceSupport.hpp"
|
#include "runtime/interfaceSupport.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
|
#include "runtime/thread.hpp"
|
||||||
|
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||||
@ -4653,3 +4654,23 @@ void MacroAssembler::encode_iso_array(Register src, Register dst,
|
|||||||
BIND(DONE);
|
BIND(DONE);
|
||||||
sub(result, result, len); // Return index where we stopped
|
sub(result, result, len); // Return index where we stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_thread() can be called anywhere inside generated code so we
|
||||||
|
// need to save whatever non-callee save context might get clobbered
|
||||||
|
// by the call to JavaThread::aarch64_get_thread_helper() or, indeed,
|
||||||
|
// the call setup code.
|
||||||
|
//
|
||||||
|
// aarch64_get_thread_helper() clobbers only r0, r1, and flags.
|
||||||
|
//
|
||||||
|
void MacroAssembler::get_thread(Register dst) {
|
||||||
|
RegSet saved_regs = RegSet::range(r0, r1) + lr - dst;
|
||||||
|
push(saved_regs, sp);
|
||||||
|
|
||||||
|
mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper));
|
||||||
|
blrt(lr, 1, 0, 1);
|
||||||
|
if (dst != c_rarg0) {
|
||||||
|
mov(dst, c_rarg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pop(saved_regs, sp);
|
||||||
|
}
|
||||||
|
@ -1973,7 +1973,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
//
|
//
|
||||||
// Output:
|
// Output:
|
||||||
// rax - input length
|
// x0 - input length
|
||||||
//
|
//
|
||||||
address generate_cipherBlockChaining_decryptAESCrypt() {
|
address generate_cipherBlockChaining_decryptAESCrypt() {
|
||||||
assert(UseAES, "need AES instructions and misaligned SSE support");
|
assert(UseAES, "need AES instructions and misaligned SSE support");
|
||||||
@ -2035,7 +2035,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
__ br(Assembler::EQ, L_rounds_52);
|
__ br(Assembler::EQ, L_rounds_52);
|
||||||
|
|
||||||
__ aesd(v0, v17); __ aesimc(v0, v0);
|
__ aesd(v0, v17); __ aesimc(v0, v0);
|
||||||
__ aesd(v0, v17); __ aesimc(v0, v0);
|
__ aesd(v0, v18); __ aesimc(v0, v0);
|
||||||
__ BIND(L_rounds_52);
|
__ BIND(L_rounds_52);
|
||||||
__ aesd(v0, v19); __ aesimc(v0, v0);
|
__ aesd(v0, v19); __ aesimc(v0, v0);
|
||||||
__ aesd(v0, v20); __ aesimc(v0, v0);
|
__ aesd(v0, v20); __ aesimc(v0, v0);
|
||||||
|
1925
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
Normal file
1925
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -61,26 +60,6 @@
|
|||||||
|
|
||||||
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
|
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
|
||||||
|
|
||||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
|
||||||
int i = 0;
|
|
||||||
switch (type) {
|
|
||||||
case T_BOOLEAN: i = 0; break;
|
|
||||||
case T_CHAR : i = 1; break;
|
|
||||||
case T_BYTE : i = 2; break;
|
|
||||||
case T_SHORT : i = 3; break;
|
|
||||||
case T_INT : i = 4; break;
|
|
||||||
case T_LONG : i = 5; break;
|
|
||||||
case T_VOID : i = 6; break;
|
|
||||||
case T_FLOAT : i = 7; break;
|
|
||||||
case T_DOUBLE : i = 8; break;
|
|
||||||
case T_OBJECT : i = 9; break;
|
|
||||||
case T_ARRAY : i = 9; break;
|
|
||||||
default : ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
||||||
// Slow_signature handler that respects the PPC C calling conventions.
|
// Slow_signature handler that respects the PPC C calling conventions.
|
||||||
//
|
//
|
||||||
@ -579,18 +558,3 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
|
||||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
|
||||||
// the days we had adapter frames. When we deoptimize a situation where a
|
|
||||||
// compiled caller calls a compiled caller will have registers it expects
|
|
||||||
// to survive the call to the callee. If we deoptimize the callee the only
|
|
||||||
// way we can restore these registers is to have the oldest interpreter
|
|
||||||
// frame that we create restore these values. That is what this routine
|
|
||||||
// will accomplish.
|
|
||||||
|
|
||||||
// At the moment we have modified c2 to not have any callee save registers
|
|
||||||
// so this problem does not exist and this routine is just a place holder.
|
|
||||||
|
|
||||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
|
||||||
}
|
|
||||||
|
1802
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
Normal file
1802
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2013, 2015 SAP AG. All rights reserved.
|
* Copyright (c) 2013, 2015 SAP AG. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,14 +28,17 @@
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Size of interpreter code. Increase if too small. Interpreter will
|
// Size of interpreter code. Increase if too small. Interpreter will
|
||||||
// fail with a guarantee ("not enough space for interpreter generation");
|
// fail with a guarantee ("not enough space for interpreter generation");
|
||||||
// if too small.
|
// if too small.
|
||||||
// Run with +PrintInterpreter to get the VM to print out the size.
|
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||||
// Max size with JVMTI
|
// Max size with JVMTI
|
||||||
|
|
||||||
const static int InterpreterCodeSize = 230*K;
|
const static int InterpreterCodeSize = 230*K;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Support abs and sqrt like in compiler.
|
||||||
|
// For others we can use a normal (native) entry.
|
||||||
|
static bool math_entry_available(AbstractInterpreter::MethodKind kind);
|
||||||
#endif // CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
|
#endif // CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,7 +38,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -62,30 +61,6 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
|
||||||
int i = 0;
|
|
||||||
switch (type) {
|
|
||||||
case T_BOOLEAN: i = 0; break;
|
|
||||||
case T_CHAR : i = 1; break;
|
|
||||||
case T_BYTE : i = 2; break;
|
|
||||||
case T_SHORT : i = 3; break;
|
|
||||||
case T_INT : i = 4; break;
|
|
||||||
case T_LONG : i = 5; break;
|
|
||||||
case T_VOID : i = 6; break;
|
|
||||||
case T_FLOAT : i = 7; break;
|
|
||||||
case T_DOUBLE : i = 8; break;
|
|
||||||
case T_OBJECT : i = 9; break;
|
|
||||||
case T_ARRAY : i = 9; break;
|
|
||||||
default : ShouldNotReachHere();
|
|
||||||
}
|
|
||||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _LP64
|
#ifndef _LP64
|
||||||
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
||||||
address entry = __ pc();
|
address entry = __ pc();
|
||||||
@ -254,28 +229,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
|||||||
return entry;
|
return entry;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
|
||||||
// No special entry points that preclude compilation
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
|
||||||
|
|
||||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
|
||||||
// the days we had adapter frames. When we deoptimize a situation where a
|
|
||||||
// compiled caller calls a compiled caller will have registers it expects
|
|
||||||
// to survive the call to the callee. If we deoptimize the callee the only
|
|
||||||
// way we can restore these registers is to have the oldest interpreter
|
|
||||||
// frame that we create restore these values. That is what this routine
|
|
||||||
// will accomplish.
|
|
||||||
|
|
||||||
// At the moment we have modified c2 to not have any callee save registers
|
|
||||||
// so this problem does not exist and this routine is just a place holder.
|
|
||||||
|
|
||||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Exceptions
|
|
||||||
|
@ -360,10 +360,10 @@ void MacroAssembler::leave() {
|
|||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// a hook for debugging
|
// a hook for debugging
|
||||||
static Thread* reinitialize_thread() {
|
static Thread* reinitialize_thread() {
|
||||||
return ThreadLocalStorage::thread();
|
return Thread::current();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define reinitialize_thread ThreadLocalStorage::thread
|
#define reinitialize_thread Thread::current
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -393,7 +393,7 @@ void MacroAssembler::get_thread() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Thread* verify_thread_subroutine(Thread* gthread_value) {
|
static Thread* verify_thread_subroutine(Thread* gthread_value) {
|
||||||
Thread* correct_value = ThreadLocalStorage::thread();
|
Thread* correct_value = Thread::current();
|
||||||
guarantee(gthread_value == correct_value, "G2_thread value must be the thread");
|
guarantee(gthread_value == correct_value, "G2_thread value must be the thread");
|
||||||
return correct_value;
|
return correct_value;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
inline void fill_subword(void* start, void* end, int value) {
|
inline void fill_subword(void* start, void* end, int value) {
|
||||||
STATIC_ASSERT(BytesPerWord == 8);
|
STATIC_ASSERT(BytesPerWord == 8);
|
||||||
assert(pointer_delta(end, start, 1) < BytesPerWord, "precondition");
|
assert(pointer_delta(end, start, 1) < (size_t)BytesPerWord, "precondition");
|
||||||
// Dispatch on (end - start).
|
// Dispatch on (end - start).
|
||||||
void* pc;
|
void* pc;
|
||||||
__asm__ volatile(
|
__asm__ volatile(
|
||||||
@ -73,10 +73,10 @@ inline void fill_subword(void* start, void* end, int value) {
|
|||||||
" stb %[value], [%[end]-3]\n\t"
|
" stb %[value], [%[end]-3]\n\t"
|
||||||
" stb %[value], [%[end]-2]\n\t"
|
" stb %[value], [%[end]-2]\n\t"
|
||||||
" stb %[value], [%[end]-1]\n\t" // end[-1] = value
|
" stb %[value], [%[end]-1]\n\t" // end[-1] = value
|
||||||
: /* no outputs */
|
: /* only temporaries/overwritten outputs */
|
||||||
[pc] "&=r" (pc) // temp
|
[pc] "=&r" (pc), // temp
|
||||||
: [offset] "&+r" (start),
|
[offset] "+&r" (start)
|
||||||
[end] "r" (end),
|
: [end] "r" (end),
|
||||||
[value] "r" (value)
|
[value] "r" (value)
|
||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ inline void fill_subword(void* start, void* end, int value) {
|
|||||||
void memset_with_concurrent_readers(void* to, int value, size_t size) {
|
void memset_with_concurrent_readers(void* to, int value, size_t size) {
|
||||||
Prefetch::write(to, 0);
|
Prefetch::write(to, 0);
|
||||||
void* end = static_cast<char*>(to) + size;
|
void* end = static_cast<char*>(to) + size;
|
||||||
if (size >= BytesPerWord) {
|
if (size >= (size_t)BytesPerWord) {
|
||||||
// Fill any partial word prefix.
|
// Fill any partial word prefix.
|
||||||
uintx* aligned_to = static_cast<uintx*>(align_ptr_up(to, BytesPerWord));
|
uintx* aligned_to = static_cast<uintx*>(align_ptr_up(to, BytesPerWord));
|
||||||
fill_subword(to, aligned_to, value);
|
fill_subword(to, aligned_to, value);
|
||||||
@ -144,10 +144,10 @@ void memset_with_concurrent_readers(void* to, int value, size_t size) {
|
|||||||
" stx %[xvalue], [%[aend]-24]\n\t"
|
" stx %[xvalue], [%[aend]-24]\n\t"
|
||||||
" stx %[xvalue], [%[aend]-16]\n\t"
|
" stx %[xvalue], [%[aend]-16]\n\t"
|
||||||
" stx %[xvalue], [%[aend]-8]\n\t" // aligned_end[-1] = xvalue
|
" stx %[xvalue], [%[aend]-8]\n\t" // aligned_end[-1] = xvalue
|
||||||
: /* no outputs */
|
: /* only temporaries/overwritten outputs */
|
||||||
[temp] "&=r" (temp)
|
[temp] "=&r" (temp),
|
||||||
: [ato] "&+r" (aligned_to),
|
[ato] "+&r" (aligned_to)
|
||||||
[aend] "r" (aligned_end),
|
: [aend] "r" (aligned_end),
|
||||||
[xvalue] "r" (xvalue)
|
[xvalue] "r" (xvalue)
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
to = aligned_end; // setup for suffix
|
to = aligned_end; // setup for suffix
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -433,7 +433,7 @@ void NativeMovConstReg32::verify() {
|
|||||||
|
|
||||||
|
|
||||||
void NativeMovConstReg32::print() {
|
void NativeMovConstReg32::print() {
|
||||||
tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data());
|
tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1651,6 +1651,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
|
|||||||
#endif // !_LP64
|
#endif // !_LP64
|
||||||
|
|
||||||
Unimplemented();
|
Unimplemented();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -36,7 +36,7 @@ extern "C" {
|
|||||||
address _flush_reg_windows(); // in .s file.
|
address _flush_reg_windows(); // in .s file.
|
||||||
// Flush registers to stack. In case of error we will need to stack walk.
|
// Flush registers to stack. In case of error we will need to stack walk.
|
||||||
address bootstrap_flush_windows(void) {
|
address bootstrap_flush_windows(void) {
|
||||||
Thread* thread = ThreadLocalStorage::get_thread_slow();
|
Thread* thread = Thread::current_or_null();
|
||||||
// Very early in process there is no thread.
|
// Very early in process there is no thread.
|
||||||
if (thread != NULL) {
|
if (thread != NULL) {
|
||||||
guarantee(thread->is_Java_thread(), "Not a Java thread.");
|
guarantee(thread->is_Java_thread(), "Not a Java thread.");
|
||||||
|
1832
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
Normal file
1832
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -175,6 +175,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
|||||||
movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
||||||
// NULL last_sp until next java call
|
// NULL last_sp until next java call
|
||||||
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
|
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
|
||||||
|
NOT_LP64(empty_FPU_stack());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helpers for swap and dup
|
// Helpers for swap and dup
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,7 +38,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -184,20 +183,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
|||||||
|
|
||||||
return entry_point;
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
|
||||||
|
|
||||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
|
||||||
// the days we had adapter frames. When we deoptimize a situation where a
|
|
||||||
// compiled caller calls a compiled caller will have registers it expects
|
|
||||||
// to survive the call to the callee. If we deoptimize the callee the only
|
|
||||||
// way we can restore these registers is to have the oldest interpreter
|
|
||||||
// frame that we create restore these values. That is what this routine
|
|
||||||
// will accomplish.
|
|
||||||
|
|
||||||
// At the moment we have modified c2 to not have any callee save registers
|
|
||||||
// so this problem does not exist and this routine is just a place holder.
|
|
||||||
|
|
||||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -38,7 +38,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -298,19 +297,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
|||||||
|
|
||||||
return entry_point;
|
return entry_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
|
||||||
|
|
||||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
|
||||||
// the days we had adapter frames. When we deoptimize a situation where a
|
|
||||||
// compiled caller calls a compiled caller will have registers it expects
|
|
||||||
// to survive the call to the callee. If we deoptimize the callee the only
|
|
||||||
// way we can restore these registers is to have the oldest interpreter
|
|
||||||
// frame that we create restore these values. That is what this routine
|
|
||||||
// will accomplish.
|
|
||||||
|
|
||||||
// At the moment we have modified c2 to not have any callee save registers
|
|
||||||
// so this problem does not exist and this routine is just a place holder.
|
|
||||||
|
|
||||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
|
||||||
}
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
|
#include "runtime/thread.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||||
@ -10834,3 +10835,43 @@ SkipIfEqual::SkipIfEqual(
|
|||||||
SkipIfEqual::~SkipIfEqual() {
|
SkipIfEqual::~SkipIfEqual() {
|
||||||
_masm->bind(_label);
|
_masm->bind(_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 32-bit Windows has its own fast-path implementation
|
||||||
|
// of get_thread
|
||||||
|
#if !defined(WIN32) || defined(_LP64)
|
||||||
|
|
||||||
|
// This is simply a call to Thread::current()
|
||||||
|
void MacroAssembler::get_thread(Register thread) {
|
||||||
|
if (thread != rax) {
|
||||||
|
push(rax);
|
||||||
|
}
|
||||||
|
LP64_ONLY(push(rdi);)
|
||||||
|
LP64_ONLY(push(rsi);)
|
||||||
|
push(rdx);
|
||||||
|
push(rcx);
|
||||||
|
#ifdef _LP64
|
||||||
|
push(r8);
|
||||||
|
push(r9);
|
||||||
|
push(r10);
|
||||||
|
push(r11);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, Thread::current), 0);
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
pop(r11);
|
||||||
|
pop(r10);
|
||||||
|
pop(r9);
|
||||||
|
pop(r8);
|
||||||
|
#endif
|
||||||
|
pop(rcx);
|
||||||
|
pop(rdx);
|
||||||
|
LP64_ONLY(pop(rsi);)
|
||||||
|
LP64_ONLY(pop(rdi);)
|
||||||
|
if (thread != rax) {
|
||||||
|
mov(thread, rax);
|
||||||
|
pop(rax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
305
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp
Normal file
305
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1997, 2015, 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 "asm/macroAssembler.hpp"
|
||||||
|
#include "interpreter/interpreter.hpp"
|
||||||
|
#include "interpreter/interpreterGenerator.hpp"
|
||||||
|
#include "runtime/arguments.hpp"
|
||||||
|
|
||||||
|
#define __ _masm->
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CC_INTERP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32.update(int crc, int b)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32_update_entry() {
|
||||||
|
if (UseCRC32Intrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rbx: Method*
|
||||||
|
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||||
|
// rdx: scratch
|
||||||
|
// rdi: scratch
|
||||||
|
|
||||||
|
Label slow_path;
|
||||||
|
// If we need a safepoint check, generate full interpreter entry.
|
||||||
|
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||||
|
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||||
|
SafepointSynchronize::_not_synchronized);
|
||||||
|
__ jcc(Assembler::notEqual, slow_path);
|
||||||
|
|
||||||
|
// We don't generate local frame and don't align stack because
|
||||||
|
// we call stub code and there is no safepoint on this path.
|
||||||
|
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = rax; // crc
|
||||||
|
const Register val = rdx; // source java byte value
|
||||||
|
const Register tbl = rdi; // scratch
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||||
|
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||||
|
|
||||||
|
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||||
|
__ notl(crc); // ~crc
|
||||||
|
__ update_byte_crc32(crc, val, tbl);
|
||||||
|
__ notl(crc); // ~crc
|
||||||
|
// result in rax
|
||||||
|
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
// generate a vanilla native entry as the slow path
|
||||||
|
__ bind(slow_path);
|
||||||
|
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||||
|
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||||
|
if (UseCRC32Intrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rbx,: Method*
|
||||||
|
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||||
|
// rdx: scratch
|
||||||
|
// rdi: scratch
|
||||||
|
|
||||||
|
Label slow_path;
|
||||||
|
// If we need a safepoint check, generate full interpreter entry.
|
||||||
|
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||||
|
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||||
|
SafepointSynchronize::_not_synchronized);
|
||||||
|
__ jcc(Assembler::notEqual, slow_path);
|
||||||
|
|
||||||
|
// We don't generate local frame and don't align stack because
|
||||||
|
// we call stub code and there is no safepoint on this path.
|
||||||
|
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = rax; // crc
|
||||||
|
const Register buf = rdx; // source java byte array address
|
||||||
|
const Register len = rdi; // length
|
||||||
|
|
||||||
|
// value x86_32
|
||||||
|
// interp. arg ptr ESP + 4
|
||||||
|
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||||
|
// 3 2 1 0
|
||||||
|
// int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||||
|
// 4 2,3 1 0
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
__ movl(len, Address(rsp, 4 + 0)); // Length
|
||||||
|
// Calculate address of start element
|
||||||
|
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||||
|
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
|
||||||
|
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||||
|
} else {
|
||||||
|
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||||
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
|
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||||
|
}
|
||||||
|
|
||||||
|
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||||
|
// result in rax
|
||||||
|
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
// generate a vanilla native entry as the slow path
|
||||||
|
__ bind(slow_path);
|
||||||
|
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
|
||||||
|
* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||||
|
if (UseCRC32CIntrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = rax; // crc
|
||||||
|
const Register buf = rcx; // source java byte array address
|
||||||
|
const Register len = rdx; // length
|
||||||
|
const Register end = len;
|
||||||
|
|
||||||
|
// value x86_32
|
||||||
|
// interp. arg ptr ESP + 4
|
||||||
|
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
|
||||||
|
// 3 2 1 0
|
||||||
|
// int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
|
||||||
|
// 4 2,3 1 0
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
__ movl(end, Address(rsp, 4 + 0)); // end
|
||||||
|
__ subl(len, Address(rsp, 4 + 1 * wordSize)); // end - offset == length
|
||||||
|
// Calculate address of start element
|
||||||
|
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||||
|
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
|
||||||
|
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||||
|
} else {
|
||||||
|
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||||
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
|
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||||
|
}
|
||||||
|
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||||
|
// result in rax
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native method:
|
||||||
|
* java.lang.Float.intBitsToFloat(int bits)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_Float_intBitsToFloat_entry() {
|
||||||
|
if (UseSSE >= 1) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rsi: the sender's SP
|
||||||
|
|
||||||
|
// Skip safepoint check (compiler intrinsic versions of this method
|
||||||
|
// do not perform safepoint checks either).
|
||||||
|
|
||||||
|
// Load 'bits' into xmm0 (interpreter returns results in xmm0)
|
||||||
|
__ movflt(xmm0, Address(rsp, wordSize));
|
||||||
|
|
||||||
|
// Return
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||||
|
__ jmp(rdi);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native method:
|
||||||
|
* java.lang.Float.floatToRawIntBits(float value)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
|
||||||
|
if (UseSSE >= 1) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rsi: the sender's SP
|
||||||
|
|
||||||
|
// Skip safepoint check (compiler intrinsic versions of this method
|
||||||
|
// do not perform safepoint checks either).
|
||||||
|
|
||||||
|
// Load the parameter (a floating-point value) into rax.
|
||||||
|
__ movl(rax, Address(rsp, wordSize));
|
||||||
|
|
||||||
|
// Return
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||||
|
__ jmp(rdi);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native method:
|
||||||
|
* java.lang.Double.longBitsToDouble(long bits)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_Double_longBitsToDouble_entry() {
|
||||||
|
if (UseSSE >= 2) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rsi: the sender's SP
|
||||||
|
|
||||||
|
// Skip safepoint check (compiler intrinsic versions of this method
|
||||||
|
// do not perform safepoint checks either).
|
||||||
|
|
||||||
|
// Load 'bits' into xmm0 (interpreter returns results in xmm0)
|
||||||
|
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||||
|
|
||||||
|
// Return
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||||
|
__ jmp(rdi);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native method:
|
||||||
|
* java.lang.Double.doubleToRawLongBits(double value)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
|
||||||
|
if (UseSSE >= 2) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rsi: the sender's SP
|
||||||
|
|
||||||
|
// Skip safepoint check (compiler intrinsic versions of this method
|
||||||
|
// do not perform safepoint checks either).
|
||||||
|
|
||||||
|
// Load the parameter (a floating-point value) into rax.
|
||||||
|
__ movl(rdx, Address(rsp, 2*wordSize));
|
||||||
|
__ movl(rax, Address(rsp, wordSize));
|
||||||
|
|
||||||
|
// Return
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||||
|
__ jmp(rdi);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif // CC_INTERP
|
197
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp
Normal file
197
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2015, 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 "asm/macroAssembler.hpp"
|
||||||
|
#include "interpreter/interpreter.hpp"
|
||||||
|
#include "interpreter/interpreterGenerator.hpp"
|
||||||
|
#include "runtime/arguments.hpp"
|
||||||
|
|
||||||
|
#define __ _masm->
|
||||||
|
|
||||||
|
#ifndef CC_INTERP
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32.update(int crc, int b)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32_update_entry() {
|
||||||
|
if (UseCRC32Intrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rbx,: Method*
|
||||||
|
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||||
|
// c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
|
||||||
|
// c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
|
||||||
|
|
||||||
|
Label slow_path;
|
||||||
|
// If we need a safepoint check, generate full interpreter entry.
|
||||||
|
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||||
|
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||||
|
SafepointSynchronize::_not_synchronized);
|
||||||
|
__ jcc(Assembler::notEqual, slow_path);
|
||||||
|
|
||||||
|
// We don't generate local frame and don't align stack because
|
||||||
|
// we call stub code and there is no safepoint on this path.
|
||||||
|
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = rax; // crc
|
||||||
|
const Register val = c_rarg0; // source java byte value
|
||||||
|
const Register tbl = c_rarg1; // scratch
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||||
|
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||||
|
|
||||||
|
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||||
|
__ notl(crc); // ~crc
|
||||||
|
__ update_byte_crc32(crc, val, tbl);
|
||||||
|
__ notl(crc); // ~crc
|
||||||
|
// result in rax
|
||||||
|
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, r13); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
// generate a vanilla native entry as the slow path
|
||||||
|
__ bind(slow_path);
|
||||||
|
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||||
|
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||||
|
if (UseCRC32Intrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
|
||||||
|
// rbx,: Method*
|
||||||
|
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||||
|
|
||||||
|
Label slow_path;
|
||||||
|
// If we need a safepoint check, generate full interpreter entry.
|
||||||
|
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||||
|
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||||
|
SafepointSynchronize::_not_synchronized);
|
||||||
|
__ jcc(Assembler::notEqual, slow_path);
|
||||||
|
|
||||||
|
// We don't generate local frame and don't align stack because
|
||||||
|
// we call stub code and there is no safepoint on this path.
|
||||||
|
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = c_rarg0; // crc
|
||||||
|
const Register buf = c_rarg1; // source java byte array address
|
||||||
|
const Register len = c_rarg2; // length
|
||||||
|
const Register off = len; // offset (never overlaps with 'len')
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
// Calculate address of start element
|
||||||
|
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||||
|
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
|
||||||
|
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||||
|
__ addq(buf, off); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
||||||
|
} else {
|
||||||
|
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
||||||
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
|
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||||
|
__ addq(buf, off); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
|
||||||
|
}
|
||||||
|
// Can now load 'len' since we're finished with 'off'
|
||||||
|
__ movl(len, Address(rsp, wordSize)); // Length
|
||||||
|
|
||||||
|
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||||
|
// result in rax
|
||||||
|
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, r13); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
// generate a vanilla native entry as the slow path
|
||||||
|
__ bind(slow_path);
|
||||||
|
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method entry for static native methods:
|
||||||
|
* int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
|
||||||
|
* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||||
|
*/
|
||||||
|
address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||||
|
if (UseCRC32CIntrinsics) {
|
||||||
|
address entry = __ pc();
|
||||||
|
// Load parameters
|
||||||
|
const Register crc = c_rarg0; // crc
|
||||||
|
const Register buf = c_rarg1; // source java byte array address
|
||||||
|
const Register len = c_rarg2;
|
||||||
|
const Register off = c_rarg3; // offset
|
||||||
|
const Register end = len;
|
||||||
|
|
||||||
|
// Arguments are reversed on java expression stack
|
||||||
|
// Calculate address of start element
|
||||||
|
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||||
|
__ movptr(buf, Address(rsp, 3 * wordSize)); // long buf
|
||||||
|
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||||
|
__ addq(buf, off); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
|
||||||
|
// Note on 5 * wordSize vs. 4 * wordSize:
|
||||||
|
// * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||||
|
// 4 2,3 1 0
|
||||||
|
// end starts at SP + 8
|
||||||
|
// The Java(R) Virtual Machine Specification Java SE 7 Edition
|
||||||
|
// 4.10.2.3. Values of Types long and double
|
||||||
|
// "When calculating operand stack length, values of type long and double have length two."
|
||||||
|
} else {
|
||||||
|
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
||||||
|
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||||
|
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||||
|
__ addq(buf, off); // + offset
|
||||||
|
__ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC
|
||||||
|
}
|
||||||
|
__ movl(end, Address(rsp, wordSize)); // end
|
||||||
|
__ subl(end, off); // end - off
|
||||||
|
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||||
|
// result in rax
|
||||||
|
// _areturn
|
||||||
|
__ pop(rdi); // get return address
|
||||||
|
__ mov(rsp, r13); // set sp to sender sp
|
||||||
|
__ jmp(rdi);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif // ! CC_INTERP
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -116,4 +116,87 @@ void AbstractInterpreter::layout_activation(Method* method,
|
|||||||
method->constants()->cache();
|
method->constants()->cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _LP64
|
||||||
|
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||||
|
int i = 0;
|
||||||
|
switch (type) {
|
||||||
|
case T_BOOLEAN: i = 0; break;
|
||||||
|
case T_CHAR : i = 1; break;
|
||||||
|
case T_BYTE : i = 2; break;
|
||||||
|
case T_SHORT : i = 3; break;
|
||||||
|
case T_INT : // fall through
|
||||||
|
case T_LONG : // fall through
|
||||||
|
case T_VOID : i = 4; break;
|
||||||
|
case T_FLOAT : i = 5; break; // have to treat float and double separately for SSE
|
||||||
|
case T_DOUBLE : i = 6; break;
|
||||||
|
case T_OBJECT : // fall through
|
||||||
|
case T_ARRAY : i = 7; break;
|
||||||
|
default : ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||||
|
int i = 0;
|
||||||
|
switch (type) {
|
||||||
|
case T_BOOLEAN: i = 0; break;
|
||||||
|
case T_CHAR : i = 1; break;
|
||||||
|
case T_BYTE : i = 2; break;
|
||||||
|
case T_SHORT : i = 3; break;
|
||||||
|
case T_INT : i = 4; break;
|
||||||
|
case T_LONG : i = 5; break;
|
||||||
|
case T_VOID : i = 6; break;
|
||||||
|
case T_FLOAT : i = 7; break;
|
||||||
|
case T_DOUBLE : i = 8; break;
|
||||||
|
case T_OBJECT : i = 9; break;
|
||||||
|
case T_ARRAY : i = 9; break;
|
||||||
|
default : ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers,
|
||||||
|
"index out of bounds");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#endif // _LP64
|
||||||
|
|
||||||
|
// These should never be compiled since the interpreter will prefer
|
||||||
|
// the compiled version to the intrinsic version.
|
||||||
|
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||||
|
switch (method_kind(m)) {
|
||||||
|
case Interpreter::java_lang_math_sin : // fall thru
|
||||||
|
case Interpreter::java_lang_math_cos : // fall thru
|
||||||
|
case Interpreter::java_lang_math_tan : // fall thru
|
||||||
|
case Interpreter::java_lang_math_abs : // fall thru
|
||||||
|
case Interpreter::java_lang_math_log : // fall thru
|
||||||
|
case Interpreter::java_lang_math_log10 : // fall thru
|
||||||
|
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||||
|
case Interpreter::java_lang_math_pow : // fall thru
|
||||||
|
case Interpreter::java_lang_math_exp :
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// How much stack a method activation needs in words.
|
||||||
|
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||||
|
const int entry_size = frame::interpreter_frame_monitor_size();
|
||||||
|
|
||||||
|
// total overhead size: entry_size + (saved rbp thru expr stack
|
||||||
|
// bottom). be sure to change this if you add/subtract anything
|
||||||
|
// to/from the overhead area
|
||||||
|
const int overhead_size =
|
||||||
|
-(frame::interpreter_frame_initial_sp_offset) + entry_size;
|
||||||
|
|
||||||
|
#ifndef _LP64
|
||||||
|
const int stub_code = 4; // see generate_call_stub
|
||||||
|
#else
|
||||||
|
const int stub_code = frame::entry_frame_after_call_words;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||||
|
Interpreter::stackElementWords;
|
||||||
|
return (overhead_size + method_stack + stub_code);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CC_INTERP
|
#endif // CC_INTERP
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,8 @@
|
|||||||
#define __ _masm->
|
#define __ _masm->
|
||||||
|
|
||||||
// Global Register Names
|
// Global Register Names
|
||||||
Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
static const Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
||||||
Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
static const Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
||||||
|
|
||||||
// Platform-dependent initialization
|
// Platform-dependent initialization
|
||||||
void TemplateTable::pd_initialize() {
|
void TemplateTable::pd_initialize() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -38,7 +38,6 @@
|
|||||||
#include "prims/jvmtiThreadState.hpp"
|
#include "prims/jvmtiThreadState.hpp"
|
||||||
#include "prims/methodHandles.hpp"
|
#include "prims/methodHandles.hpp"
|
||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/deoptimization.hpp"
|
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
@ -74,7 +73,3 @@ address InterpreterGenerator::generate_abstract_entry() {
|
|||||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deoptimization::unwind_callee_save_values(frame* f,
|
|
||||||
vframeArray* vframe_array) {
|
|
||||||
}
|
|
||||||
|
@ -29,37 +29,61 @@
|
|||||||
//
|
//
|
||||||
// Defines Aix specific flags. They are not available on other platforms.
|
// Defines Aix specific flags. They are not available on other platforms.
|
||||||
//
|
//
|
||||||
|
// (Please keep the switches sorted alphabetically.)
|
||||||
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
|
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
|
||||||
\
|
\
|
||||||
|
/* Whether to allow the VM to run if EXTSHM=ON. EXTSHM is an environment */ \
|
||||||
|
/* variable used on AIX to activate certain hacks which allow more shm segments */\
|
||||||
|
/* for 32bit processes. For 64bit processes, it is pointless and may have */ \
|
||||||
|
/* harmful side effects (e.g. for some reasonn prevents allocation of 64k pages */\
|
||||||
|
/* via shmctl). */ \
|
||||||
|
/* Per default we quit with an error if that variable is found; for certain */ \
|
||||||
|
/* customer scenarios, we may want to be able to run despite that variable. */ \
|
||||||
|
product(bool, AllowExtshm, false, \
|
||||||
|
"Allow VM to run with EXTSHM=ON.") \
|
||||||
|
\
|
||||||
|
product(intx, AttachListenerTimeout, 1000, \
|
||||||
|
"Timeout in ms the attach listener waits for a request") \
|
||||||
|
range(0, 2147483) \
|
||||||
|
\
|
||||||
|
/* Maximum expected size of the data segment. That correlates with the */ \
|
||||||
|
/* to the maximum C Heap consumption we expect. */ \
|
||||||
|
/* We need to know this because we need to leave "breathing space" for the */ \
|
||||||
|
/* data segment when placing the java heap. If that space is too small, we */ \
|
||||||
|
/* reduce our chance of getting a low heap address (needed for compressed */ \
|
||||||
|
/* Oops). */ \
|
||||||
|
product(uintx, MaxExpectedDataSegmentSize, (SIZE_4G * 2), \
|
||||||
|
"Maximum expected Data Segment Size.") \
|
||||||
|
\
|
||||||
|
/* Use optimized addresses for the polling page. */ \
|
||||||
|
product(bool, OptimizePollingPageLocation, true, \
|
||||||
|
"Optimize the location of the polling page used for Safepoints") \
|
||||||
|
\
|
||||||
/* Use 64K pages for virtual memory (shmat). */ \
|
/* Use 64K pages for virtual memory (shmat). */ \
|
||||||
product(bool, Use64KPages, true, \
|
product(bool, Use64KPages, true, \
|
||||||
"Use 64K pages if available.") \
|
"Use 64K pages if available.") \
|
||||||
\
|
\
|
||||||
/* If UseLargePages == true allow or deny usage of 16M pages. 16M pages are */ \
|
/* If VM uses 64K paged memory (shmat) for virtual memory: threshold below */ \
|
||||||
/* a scarce resource and there may be situations where we do not want the VM */ \
|
/* which virtual memory allocations are done with 4K memory (mmap). This is */ \
|
||||||
/* to run with 16M pages. (Will fall back to 64K pages). */ \
|
/* mainly for test purposes. */ \
|
||||||
product_pd(bool, Use16MPages, \
|
develop(uintx, Use64KPagesThreshold, 0, \
|
||||||
"Use 16M pages if available.") \
|
"4K/64K page allocation threshold.") \
|
||||||
\
|
\
|
||||||
/* use optimized addresses for the polling page, */ \
|
/* Normally AIX commits memory on touch, but sometimes it is helpful to have */ \
|
||||||
/* e.g. map it to a special 32-bit address. */ \
|
/* explicit commit behaviour. This flag, if true, causes the VM to touch */ \
|
||||||
product_pd(bool, OptimizePollingPageLocation, \
|
/* memory on os::commit_memory() (which normally is a noop). */ \
|
||||||
"Optimize the location of the polling page used for Safepoints") \
|
product(bool, UseExplicitCommit, false, \
|
||||||
\
|
"Explicit commit for virtual memory.") \
|
||||||
product_pd(intx, AttachListenerTimeout, \
|
|
||||||
"Timeout in ms the attach listener waits for a request") \
|
|
||||||
range(0, 2147483) \
|
|
||||||
\
|
\
|
||||||
|
|
||||||
// Per default, do not allow 16M pages. 16M pages have to be switched on specifically.
|
|
||||||
define_pd_global(bool, Use16MPages, false);
|
|
||||||
define_pd_global(bool, OptimizePollingPageLocation, true);
|
|
||||||
define_pd_global(intx, AttachListenerTimeout, 1000);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Defines Aix-specific default values. The flags are available on all
|
// Defines Aix-specific default values. The flags are available on all
|
||||||
// platforms, but they may have different default values on other platforms.
|
// platforms, but they may have different default values on other platforms.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// UseLargePages means nothing, for now, on AIX.
|
||||||
|
// Use Use64KPages or Use16MPages instead.
|
||||||
define_pd_global(bool, UseLargePages, false);
|
define_pd_global(bool, UseLargePages, false);
|
||||||
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
|
define_pd_global(bool, UseLargePagesIndividualAllocation, false);
|
||||||
define_pd_global(bool, UseOSErrorReporting, false);
|
define_pd_global(bool, UseOSErrorReporting, false);
|
||||||
|
@ -109,92 +109,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
|||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
/*
|
|
||||||
All the defined signal names for Linux.
|
|
||||||
|
|
||||||
NOTE that not all of these names are accepted by our Java implementation
|
|
||||||
|
|
||||||
Via an existing claim by the VM, sigaction restrictions, or
|
|
||||||
the "rules of Unix" some of these names will be rejected at runtime.
|
|
||||||
For example the VM sets up to handle USR1, sigaction returns EINVAL for
|
|
||||||
STOP, and Linux simply doesn't allow catching of KILL.
|
|
||||||
|
|
||||||
Here are the names currently accepted by a user of sun.misc.Signal with
|
|
||||||
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
|
||||||
|
|
||||||
HUP, INT, TRAP, ABRT, IOT, BUS, USR2, PIPE, ALRM, TERM, STKFLT,
|
|
||||||
CLD, CHLD, CONT, TSTP, TTIN, TTOU, URG, XCPU, XFSZ, VTALRM, PROF,
|
|
||||||
WINCH, POLL, IO, PWR, SYS
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct siglabel {
|
|
||||||
const char *name;
|
|
||||||
int number;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct siglabel siglabels[] = {
|
|
||||||
/* derived from /usr/include/bits/signum.h on RH7.2 */
|
|
||||||
"HUP", SIGHUP, /* Hangup (POSIX). */
|
|
||||||
"INT", SIGINT, /* Interrupt (ANSI). */
|
|
||||||
"QUIT", SIGQUIT, /* Quit (POSIX). */
|
|
||||||
"ILL", SIGILL, /* Illegal instruction (ANSI). */
|
|
||||||
"TRAP", SIGTRAP, /* Trace trap (POSIX). */
|
|
||||||
"ABRT", SIGABRT, /* Abort (ANSI). */
|
|
||||||
"IOT", SIGIOT, /* IOT trap (4.2 BSD). */
|
|
||||||
"BUS", SIGBUS, /* BUS error (4.2 BSD). */
|
|
||||||
"FPE", SIGFPE, /* Floating-point exception (ANSI). */
|
|
||||||
"KILL", SIGKILL, /* Kill, unblockable (POSIX). */
|
|
||||||
"USR1", SIGUSR1, /* User-defined signal 1 (POSIX). */
|
|
||||||
"SEGV", SIGSEGV, /* Segmentation violation (ANSI). */
|
|
||||||
"USR2", SIGUSR2, /* User-defined signal 2 (POSIX). */
|
|
||||||
"PIPE", SIGPIPE, /* Broken pipe (POSIX). */
|
|
||||||
"ALRM", SIGALRM, /* Alarm clock (POSIX). */
|
|
||||||
"TERM", SIGTERM, /* Termination (ANSI). */
|
|
||||||
#ifdef SIGSTKFLT
|
|
||||||
"STKFLT", SIGSTKFLT, /* Stack fault. */
|
|
||||||
#endif
|
|
||||||
"CLD", SIGCLD, /* Same as SIGCHLD (System V). */
|
|
||||||
"CHLD", SIGCHLD, /* Child status has changed (POSIX). */
|
|
||||||
"CONT", SIGCONT, /* Continue (POSIX). */
|
|
||||||
"STOP", SIGSTOP, /* Stop, unblockable (POSIX). */
|
|
||||||
"TSTP", SIGTSTP, /* Keyboard stop (POSIX). */
|
|
||||||
"TTIN", SIGTTIN, /* Background read from tty (POSIX). */
|
|
||||||
"TTOU", SIGTTOU, /* Background write to tty (POSIX). */
|
|
||||||
"URG", SIGURG, /* Urgent condition on socket (4.2 BSD). */
|
|
||||||
"XCPU", SIGXCPU, /* CPU limit exceeded (4.2 BSD). */
|
|
||||||
"XFSZ", SIGXFSZ, /* File size limit exceeded (4.2 BSD). */
|
|
||||||
"DANGER", SIGDANGER, /* System crash imminent; free up some page space (AIX). */
|
|
||||||
"VTALRM", SIGVTALRM, /* Virtual alarm clock (4.2 BSD). */
|
|
||||||
"PROF", SIGPROF, /* Profiling alarm clock (4.2 BSD). */
|
|
||||||
"WINCH", SIGWINCH, /* Window size change (4.3 BSD, Sun). */
|
|
||||||
"POLL", SIGPOLL, /* Pollable event occurred (System V). */
|
|
||||||
"IO", SIGIO, /* I/O now possible (4.2 BSD). */
|
|
||||||
"PWR", SIGPWR, /* Power failure restart (System V). */
|
|
||||||
#ifdef SIGSYS
|
|
||||||
"SYS", SIGSYS /* Bad system call. Only on some Linuxen! */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
|
||||||
|
|
||||||
/* find and return the named signal's number */
|
|
||||||
|
|
||||||
for(uint i=0; i<ARRAY_SIZE(siglabels); i++)
|
|
||||||
if(!strcmp(name, siglabels[i].name))
|
|
||||||
return siglabels[i].number;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
JVM_END
|
|
||||||
|
|
||||||
// used by os::exception_name()
|
|
||||||
extern bool signal_name(int signo, char* buf, size_t len) {
|
|
||||||
for(uint i = 0; i < ARRAY_SIZE(siglabels); i++) {
|
|
||||||
if (signo == siglabels[i].number) {
|
|
||||||
jio_snprintf(buf, len, "SIG%s", siglabels[i].name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright 2012, 2015 SAP AG. All rights reserved.
|
||||||
* Copyright 2012, 2014 SAP AG. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,18 +22,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
// This is only a stub. Will flesh out later when/if we add further support
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
// for PASE.
|
||||||
#include "runtime/thread.hpp"
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
#include "libo4.hpp"
|
||||||
// Nothing we can do here for user-level thread.
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
bool libo4::init() { return false; }
|
||||||
// Nothing to do.
|
void libo4::cleanup() {}
|
||||||
|
bool libo4::get_memory_info (unsigned long long* p_virt_total, unsigned long long* p_real_total,
|
||||||
|
unsigned long long* p_real_free, unsigned long long* p_pgsp_total, unsigned long long* p_pgsp_free) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
bool libo4::get_load_avg (double* p_avg1, double* p_avg5, double* p_avg15) { return false; }
|
||||||
|
bool libo4::realpath (const char* file_name, char* resolved_name, int resolved_name_len) { return false; }
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
77
hotspot/src/os/aix/vm/libo4.hpp
Normal file
77
hotspot/src/os/aix/vm/libo4.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, 2015 SAP AG. 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A C++ wrapper around the libo4 porting library. The libo4 porting library
|
||||||
|
// is a set of bridge functions into native AS/400 functionality.
|
||||||
|
|
||||||
|
#ifndef OS_AIX_VM_LIBO4_HPP
|
||||||
|
#define OS_AIX_VM_LIBO4_HPP
|
||||||
|
|
||||||
|
|
||||||
|
class libo4 {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Initialize the libo4 porting library.
|
||||||
|
// Returns true if succeeded, false if error.
|
||||||
|
static bool init();
|
||||||
|
|
||||||
|
// cleanup of the libo4 porting library.
|
||||||
|
static void cleanup();
|
||||||
|
|
||||||
|
// returns a number of memory statistics from the
|
||||||
|
// AS/400.
|
||||||
|
//
|
||||||
|
// Specify NULL for numbers you are not interested in.
|
||||||
|
//
|
||||||
|
// returns false if an error happened. Activate OsMisc trace for
|
||||||
|
// trace output.
|
||||||
|
//
|
||||||
|
static bool get_memory_info (unsigned long long* p_virt_total, unsigned long long* p_real_total,
|
||||||
|
unsigned long long* p_real_free, unsigned long long* p_pgsp_total, unsigned long long* p_pgsp_free);
|
||||||
|
|
||||||
|
// returns information about system load
|
||||||
|
// (similar to "loadavg()" under other Unices)
|
||||||
|
//
|
||||||
|
// Specify NULL for numbers you are not interested in.
|
||||||
|
//
|
||||||
|
// returns false if an error happened. Activate OsMisc trace for
|
||||||
|
// trace output.
|
||||||
|
//
|
||||||
|
static bool get_load_avg (double* p_avg1, double* p_avg5, double* p_avg15);
|
||||||
|
|
||||||
|
// this is a replacement for the "realpath()" API which does not really work
|
||||||
|
// on PASE
|
||||||
|
//
|
||||||
|
// Specify NULL for numbers you are not interested in.
|
||||||
|
//
|
||||||
|
// returns false if an error happened. Activate OsMisc trace for
|
||||||
|
// trace output.
|
||||||
|
//
|
||||||
|
static bool realpath (const char* file_name,
|
||||||
|
char* resolved_name, int resolved_name_len);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OS_AIX_VM_LIBO4_HPP
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
* Copyright 2012, 2015 SAP AG. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,49 +22,50 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "runtime/arguments.hpp"
|
|
||||||
#include "libperfstat_aix.hpp"
|
#include "libperfstat_aix.hpp"
|
||||||
|
#include "misc_aix.hpp"
|
||||||
|
|
||||||
// For dlopen and friends
|
#include <dlfcn.h>
|
||||||
#include <fcntl.h>
|
#include <sys/systemcfg.h>
|
||||||
|
|
||||||
// handle to the libperfstat
|
// Handle to the libperfstat.
|
||||||
static void* g_libhandle = NULL;
|
static void* g_libhandle = NULL;
|
||||||
|
|
||||||
// whether initialization worked
|
typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,
|
||||||
static bool g_initialized = false;
|
|
||||||
|
|
||||||
|
|
||||||
typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, perfstat_cpu_total_t* userbuff,
|
|
||||||
int sizeof_userbuff, int desired_number);
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
||||||
int sizeof_userbuff, int desired_number);
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
|
typedef int (*fun_perfstat_partition_total_t) (perfstat_id_t *name,
|
||||||
|
PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff, int sizeof_userbuff,
|
||||||
|
int desired_number);
|
||||||
|
|
||||||
|
typedef int (*fun_perfstat_wpar_total_t) (perfstat_id_wpar_t *name,
|
||||||
|
PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff, int sizeof_userbuff,
|
||||||
|
int desired_number);
|
||||||
|
|
||||||
typedef void (*fun_perfstat_reset_t) ();
|
typedef void (*fun_perfstat_reset_t) ();
|
||||||
|
|
||||||
|
typedef cid_t (*fun_wpar_getcid_t) ();
|
||||||
|
|
||||||
static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL;
|
static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL;
|
||||||
static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL;
|
static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL;
|
||||||
|
static fun_perfstat_partition_total_t g_fun_perfstat_partition_total = NULL;
|
||||||
|
static fun_perfstat_wpar_total_t g_fun_perfstat_wpar_total = NULL;
|
||||||
static fun_perfstat_reset_t g_fun_perfstat_reset = NULL;
|
static fun_perfstat_reset_t g_fun_perfstat_reset = NULL;
|
||||||
|
static fun_wpar_getcid_t g_fun_wpar_getcid = NULL;
|
||||||
|
|
||||||
bool libperfstat::init() {
|
bool libperfstat::init() {
|
||||||
|
|
||||||
if (g_initialized) {
|
// Dynamically load the libperfstat porting library.
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_initialized = false;
|
|
||||||
|
|
||||||
// dynamically load the libperfstat porting library.
|
|
||||||
g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW);
|
g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW);
|
||||||
if (!g_libhandle) {
|
if (!g_libhandle) {
|
||||||
if (Verbose) {
|
trcVerbose("Cannot load libperfstat.a (dlerror: %s)", dlerror());
|
||||||
fprintf(stderr, "Cannot load libperfstat.a (dlerror: %s)", dlerror());
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve function pointers
|
// Resolve function pointers
|
||||||
|
|
||||||
#define RESOLVE_FUN_NO_ERROR(name) \
|
#define RESOLVE_FUN_NO_ERROR(name) \
|
||||||
g_fun_##name = (fun_##name##_t) dlsym(g_libhandle, #name);
|
g_fun_##name = (fun_##name##_t) dlsym(g_libhandle, #name);
|
||||||
@ -72,26 +73,28 @@ bool libperfstat::init() {
|
|||||||
#define RESOLVE_FUN(name) \
|
#define RESOLVE_FUN(name) \
|
||||||
RESOLVE_FUN_NO_ERROR(name) \
|
RESOLVE_FUN_NO_ERROR(name) \
|
||||||
if (!g_fun_##name) { \
|
if (!g_fun_##name) { \
|
||||||
if (Verbose) { \
|
trcVerbose("Cannot resolve " #name "() from libperfstat.a\n" \
|
||||||
fprintf(stderr, "Cannot resolve " #name "() from libperfstat.a\n" \
|
|
||||||
" (dlerror: %s)", dlerror()); \
|
" (dlerror: %s)", dlerror()); \
|
||||||
} \
|
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These functions may or may not be there depending on the OS release.
|
||||||
|
RESOLVE_FUN_NO_ERROR(perfstat_partition_total);
|
||||||
|
RESOLVE_FUN_NO_ERROR(perfstat_wpar_total);
|
||||||
|
RESOLVE_FUN_NO_ERROR(wpar_getcid);
|
||||||
|
|
||||||
|
// These functions are required for every release.
|
||||||
RESOLVE_FUN(perfstat_cpu_total);
|
RESOLVE_FUN(perfstat_cpu_total);
|
||||||
RESOLVE_FUN(perfstat_memory_total);
|
RESOLVE_FUN(perfstat_memory_total);
|
||||||
RESOLVE_FUN(perfstat_reset);
|
RESOLVE_FUN(perfstat_reset);
|
||||||
|
|
||||||
g_initialized = true;
|
trcVerbose("libperfstat loaded.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void libperfstat::cleanup() {
|
void libperfstat::cleanup() {
|
||||||
|
|
||||||
g_initialized = false;
|
|
||||||
|
|
||||||
if (g_libhandle) {
|
if (g_libhandle) {
|
||||||
dlclose(g_libhandle);
|
dlclose(g_libhandle);
|
||||||
g_libhandle = NULL;
|
g_libhandle = NULL;
|
||||||
@ -99,26 +102,250 @@ void libperfstat::cleanup() {
|
|||||||
|
|
||||||
g_fun_perfstat_cpu_total = NULL;
|
g_fun_perfstat_cpu_total = NULL;
|
||||||
g_fun_perfstat_memory_total = NULL;
|
g_fun_perfstat_memory_total = NULL;
|
||||||
|
g_fun_perfstat_partition_total = NULL;
|
||||||
|
g_fun_perfstat_wpar_total = NULL;
|
||||||
g_fun_perfstat_reset = NULL;
|
g_fun_perfstat_reset = NULL;
|
||||||
|
g_fun_wpar_getcid = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int libperfstat::perfstat_memory_total(perfstat_id_t *name,
|
int libperfstat::perfstat_memory_total(perfstat_id_t *name,
|
||||||
perfstat_memory_total_t* userbuff,
|
perfstat_memory_total_t* userbuff,
|
||||||
int sizeof_userbuff, int desired_number) {
|
int sizeof_userbuff, int desired_number) {
|
||||||
assert(g_initialized, "libperfstat not initialized");
|
if (g_fun_perfstat_memory_total == NULL) {
|
||||||
assert(g_fun_perfstat_memory_total, "");
|
return -1;
|
||||||
|
}
|
||||||
return g_fun_perfstat_memory_total(name, userbuff, sizeof_userbuff, desired_number);
|
return g_fun_perfstat_memory_total(name, userbuff, sizeof_userbuff, desired_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
int libperfstat::perfstat_cpu_total(perfstat_id_t *name, perfstat_cpu_total_t* userbuff,
|
int libperfstat::perfstat_cpu_total(perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,
|
||||||
int sizeof_userbuff, int desired_number) {
|
int sizeof_userbuff, int desired_number) {
|
||||||
assert(g_initialized, "libperfstat not initialized");
|
if (g_fun_perfstat_cpu_total == NULL) {
|
||||||
assert(g_fun_perfstat_cpu_total, "");
|
return -1;
|
||||||
|
}
|
||||||
return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number);
|
return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void libperfstat::perfstat_reset() {
|
int libperfstat::perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff,
|
||||||
assert(g_initialized, "libperfstat not initialized");
|
int sizeof_userbuff, int desired_number) {
|
||||||
assert(g_fun_perfstat_reset, "");
|
if (g_fun_perfstat_partition_total == NULL) {
|
||||||
g_fun_perfstat_reset();
|
return -1;
|
||||||
|
}
|
||||||
|
return g_fun_perfstat_partition_total(name, userbuff, sizeof_userbuff, desired_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
int libperfstat::perfstat_wpar_total(perfstat_id_wpar_t *name, PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff,
|
||||||
|
int sizeof_userbuff, int desired_number) {
|
||||||
|
if (g_fun_perfstat_wpar_total == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return g_fun_perfstat_wpar_total(name, userbuff, sizeof_userbuff, desired_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
void libperfstat::perfstat_reset() {
|
||||||
|
if (g_fun_perfstat_reset != NULL) {
|
||||||
|
g_fun_perfstat_reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cid_t libperfstat::wpar_getcid() {
|
||||||
|
if (g_fun_wpar_getcid == NULL) {
|
||||||
|
return (cid_t) -1;
|
||||||
|
}
|
||||||
|
return g_fun_wpar_getcid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////// convenience functions, release-independent /////////////////////////////
|
||||||
|
|
||||||
|
// Excerpts from systemcfg.h definitions newer than AIX 5.3 (our oldest build platform)
|
||||||
|
|
||||||
|
#define PV_6 0x100000 /* Power PC 6 */
|
||||||
|
#define PV_6_1 0x100001 /* Power PC 6 DD1.x */
|
||||||
|
#define PV_7 0x200000 /* Power PC 7 */
|
||||||
|
#define PV_5_Compat 0x0F8000 /* Power PC 5 */
|
||||||
|
#define PV_6_Compat 0x108000 /* Power PC 6 */
|
||||||
|
#define PV_7_Compat 0x208000 /* Power PC 7 */
|
||||||
|
#define PV_8 0x300000 /* Power PC 8 */
|
||||||
|
#define PV_8_Compat 0x308000 /* Power PC 8 */
|
||||||
|
|
||||||
|
|
||||||
|
// Retrieve global cpu information.
|
||||||
|
bool libperfstat::get_cpuinfo(cpuinfo_t* pci) {
|
||||||
|
|
||||||
|
assert(pci, "get_cpuinfo: invalid parameter");
|
||||||
|
memset(pci, 0, sizeof(cpuinfo_t));
|
||||||
|
|
||||||
|
PERFSTAT_CPU_TOTAL_T_LATEST psct;
|
||||||
|
memset (&psct, '\0', sizeof(psct));
|
||||||
|
|
||||||
|
if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(PERFSTAT_CPU_TOTAL_T_LATEST), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t_61), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t_53), 1)) {
|
||||||
|
trcVerbose("perfstat_cpu_total() failed (errno=%d)", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global cpu information.
|
||||||
|
strcpy (pci->description, psct.description);
|
||||||
|
pci->processorHZ = psct.processorHZ;
|
||||||
|
pci->ncpus = psct.ncpus;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
pci->user_clock_ticks = psct.user;
|
||||||
|
pci->sys_clock_ticks = psct.sys;
|
||||||
|
pci->idle_clock_ticks = psct.idle;
|
||||||
|
pci->wait_clock_ticks = psct.wait;
|
||||||
|
|
||||||
|
// Get the processor version from _system_configuration.
|
||||||
|
switch (_system_configuration.version) {
|
||||||
|
case PV_8:
|
||||||
|
strcpy(pci->version, "Power PC 8");
|
||||||
|
break;
|
||||||
|
case PV_7:
|
||||||
|
strcpy(pci->version, "Power PC 7");
|
||||||
|
break;
|
||||||
|
case PV_6_1:
|
||||||
|
strcpy(pci->version, "Power PC 6 DD1.x");
|
||||||
|
break;
|
||||||
|
case PV_6:
|
||||||
|
strcpy(pci->version, "Power PC 6");
|
||||||
|
break;
|
||||||
|
case PV_5:
|
||||||
|
strcpy(pci->version, "Power PC 5");
|
||||||
|
break;
|
||||||
|
case PV_5_2:
|
||||||
|
strcpy(pci->version, "Power PC 5_2");
|
||||||
|
break;
|
||||||
|
case PV_5_3:
|
||||||
|
strcpy(pci->version, "Power PC 5_3");
|
||||||
|
break;
|
||||||
|
case PV_5_Compat:
|
||||||
|
strcpy(pci->version, "PV_5_Compat");
|
||||||
|
break;
|
||||||
|
case PV_6_Compat:
|
||||||
|
strcpy(pci->version, "PV_6_Compat");
|
||||||
|
break;
|
||||||
|
case PV_7_Compat:
|
||||||
|
strcpy(pci->version, "PV_7_Compat");
|
||||||
|
break;
|
||||||
|
case PV_8_Compat:
|
||||||
|
strcpy(pci->version, "PV_8_Compat");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(pci->version, "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve partition information.
|
||||||
|
bool libperfstat::get_partitioninfo(partitioninfo_t* ppi) {
|
||||||
|
|
||||||
|
assert(ppi, "get_partitioninfo: invalid parameter");
|
||||||
|
memset(ppi, 0, sizeof(partitioninfo_t));
|
||||||
|
|
||||||
|
PERFSTAT_PARTITON_TOTAL_T_LATEST pspt;
|
||||||
|
memset(&pspt, '\0', sizeof(pspt));
|
||||||
|
|
||||||
|
bool ame_details = true;
|
||||||
|
|
||||||
|
if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(PERFSTAT_PARTITON_TOTAL_T_LATEST), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_71), 1)) {
|
||||||
|
ame_details = false;
|
||||||
|
if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_61), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_53), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_partition_total(NULL, &pspt, sizeof(perfstat_partition_total_t_53_5), 1)) {
|
||||||
|
trcVerbose("perfstat_partition_total() failed (errno=%d)", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// partition type info
|
||||||
|
ppi->shared_enabled = pspt.type.b.shared_enabled;
|
||||||
|
ppi->smt_capable = pspt.type.b.smt_capable;
|
||||||
|
ppi->smt_enabled = pspt.type.b.smt_enabled;
|
||||||
|
ppi->lpar_capable = pspt.type.b.lpar_capable;
|
||||||
|
ppi->lpar_enabled = pspt.type.b.lpar_enabled;
|
||||||
|
ppi->dlpar_capable = pspt.type.b.dlpar_capable;
|
||||||
|
ppi->capped = pspt.type.b.capped;
|
||||||
|
ppi->kernel_is_64 = pspt.type.b.kernel_is_64;
|
||||||
|
ppi->pool_util_authority = pspt.type.b.pool_util_authority;
|
||||||
|
ppi->donate_capable = pspt.type.b.donate_capable;
|
||||||
|
ppi->donate_enabled = pspt.type.b.donate_enabled;
|
||||||
|
ppi->ams_capable = pspt.type.b.ams_capable;
|
||||||
|
ppi->ams_enabled = pspt.type.b.ams_enabled;
|
||||||
|
ppi->power_save = pspt.type.b.power_save;
|
||||||
|
ppi->ame_enabled = pspt.type.b.ame_enabled;
|
||||||
|
|
||||||
|
// partition total info
|
||||||
|
ppi->online_cpus = pspt.online_cpus;
|
||||||
|
ppi->entitled_proc_capacity = pspt.entitled_proc_capacity;
|
||||||
|
ppi->var_proc_capacity_weight = pspt.var_proc_capacity_weight;
|
||||||
|
ppi->phys_cpus_pool = pspt.phys_cpus_pool;
|
||||||
|
ppi->pool_id = pspt.pool_id;
|
||||||
|
ppi->entitled_pool_capacity = pspt.entitled_pool_capacity;
|
||||||
|
strcpy(ppi->name, pspt.name);
|
||||||
|
|
||||||
|
// Added values to ppi that we need for later computation of cpu utilization
|
||||||
|
// ( pool authorization needed for pool_idle_time ??? )
|
||||||
|
ppi->timebase_last = pspt.timebase_last;
|
||||||
|
ppi->pool_idle_time = pspt.pool_idle_time;
|
||||||
|
ppi->pcpu_tics_user = pspt.puser;
|
||||||
|
ppi->pcpu_tics_sys = pspt.psys;
|
||||||
|
ppi->pcpu_tics_idle = pspt.pidle;
|
||||||
|
ppi->pcpu_tics_wait = pspt.pwait;
|
||||||
|
|
||||||
|
// Additional AME information.
|
||||||
|
if (ame_details) {
|
||||||
|
ppi->true_memory = pspt.true_memory * 4096;
|
||||||
|
ppi->expanded_memory = pspt.expanded_memory * 4096;
|
||||||
|
ppi->target_memexp_factr = pspt.target_memexp_factr;
|
||||||
|
ppi->current_memexp_factr = pspt.current_memexp_factr;
|
||||||
|
ppi->cmcs_total_time = pspt.cmcs_total_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve wpar information.
|
||||||
|
bool libperfstat::get_wparinfo(wparinfo_t* pwi) {
|
||||||
|
|
||||||
|
assert(pwi, "get_wparinfo: invalid parameter");
|
||||||
|
memset(pwi, 0, sizeof(wparinfo_t));
|
||||||
|
|
||||||
|
if (libperfstat::wpar_getcid() <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PERFSTAT_WPAR_TOTAL_T_LATEST pswt;
|
||||||
|
memset (&pswt, '\0', sizeof(pswt));
|
||||||
|
|
||||||
|
if (-1 == libperfstat::perfstat_wpar_total(NULL, &pswt, sizeof(PERFSTAT_WPAR_TOTAL_T_LATEST), 1)) {
|
||||||
|
if (-1 == libperfstat::perfstat_wpar_total(NULL, &pswt, sizeof(perfstat_wpar_total_t_61), 1)) {
|
||||||
|
trcVerbose("perfstat_wpar_total() failed (errno=%d)", errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WPAR type info.
|
||||||
|
pwi->app_wpar = pswt.type.b.app_wpar;
|
||||||
|
pwi->cpu_rset = pswt.type.b.cpu_rset;
|
||||||
|
pwi->cpu_xrset = pswt.type.b.cpu_xrset;
|
||||||
|
pwi->cpu_limits = pswt.type.b.cpu_limits;
|
||||||
|
pwi->mem_limits = pswt.type.b.mem_limits;
|
||||||
|
// WPAR total info.
|
||||||
|
strcpy(pwi->name, pswt.name);
|
||||||
|
pwi->wpar_id = pswt.wpar_id;
|
||||||
|
pwi->cpu_limit = pswt.cpu_limit;
|
||||||
|
pwi->mem_limit = pswt.mem_limit;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// encapsulates the libperfstat library.
|
// Encapsulates the libperfstat library.
|
||||||
//
|
//
|
||||||
// The purpose of this code is to dynamically load the libperfstat library
|
// The purpose of this code is to dynamically load the libperfstat library
|
||||||
// instead of statically linking against it. The libperfstat library is an
|
// instead of statically linking against it. The libperfstat library is an
|
||||||
@ -32,7 +32,732 @@
|
|||||||
#ifndef OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
#ifndef OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
||||||
#define OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
#define OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
||||||
|
|
||||||
#include <libperfstat.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// These are excerpts from the AIX 5.3, 6.1, 7.1 libperfstat.h -
|
||||||
|
// this is all we need from libperfstat.h and I want to avoid having to include <libperfstat.h>
|
||||||
|
//
|
||||||
|
// Note: I define all structures as if I were to include libperfstat.h on an AIX 5.2
|
||||||
|
// build machine.
|
||||||
|
//
|
||||||
|
// The ratio behind that is that if I would build on an AIX 5.2 build machine,
|
||||||
|
// include libperfstat.h and hard-link against libperfstat.a, the program should
|
||||||
|
// work without recompilation on all newer AIX versions.
|
||||||
|
//
|
||||||
|
|
||||||
|
#define IDENTIFIER_LENGTH 64 /* length of strings included in the structures */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct { /* structure element identifier */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the identifier */
|
||||||
|
} perfstat_id_t;
|
||||||
|
|
||||||
|
#define CEC_ID_LEN 40 /* CEC identifier length */
|
||||||
|
#define MAXCORRALNAMELEN 25 /* length of the wpar name */
|
||||||
|
#define FIRST_WPARNAME "" /* pseudo-name for the first WPAR */
|
||||||
|
#define FIRST_WPARID -1 /* pseudo-id for the first WPAR */
|
||||||
|
|
||||||
|
typedef unsigned short cid_t; /* workload partition identifier */
|
||||||
|
|
||||||
|
typedef struct { /* Virtual memory utilization */
|
||||||
|
u_longlong_t virt_total; /* total virtual memory (in 4KB pages) */
|
||||||
|
u_longlong_t real_total; /* total real memory (in 4KB pages) */
|
||||||
|
u_longlong_t real_free; /* free real memory (in 4KB pages) */
|
||||||
|
u_longlong_t real_pinned; /* real memory which is pinned (in 4KB pages) */
|
||||||
|
u_longlong_t real_inuse; /* real memory which is in use (in 4KB pages) */
|
||||||
|
u_longlong_t pgbad; /* number of bad pages */
|
||||||
|
u_longlong_t pgexct; /* number of page faults */
|
||||||
|
u_longlong_t pgins; /* number of pages paged in */
|
||||||
|
u_longlong_t pgouts; /* number of pages paged out */
|
||||||
|
u_longlong_t pgspins; /* number of page ins from paging space */
|
||||||
|
u_longlong_t pgspouts; /* number of page outs from paging space */
|
||||||
|
u_longlong_t scans; /* number of page scans by clock */
|
||||||
|
u_longlong_t cycles; /* number of page replacement cycles */
|
||||||
|
u_longlong_t pgsteals; /* number of page steals */
|
||||||
|
u_longlong_t numperm; /* number of frames used for files (in 4KB pages) */
|
||||||
|
u_longlong_t pgsp_total; /* total paging space (in 4KB pages) */
|
||||||
|
u_longlong_t pgsp_free; /* free paging space (in 4KB pages) */
|
||||||
|
u_longlong_t pgsp_rsvd; /* reserved paging space (in 4KB pages) */
|
||||||
|
u_longlong_t real_system; /* real memory used by system segments (in 4KB pages). This is the sum of all the used pages in segment marked for system usage.
|
||||||
|
* Since segment classifications are not always guaranteed to be accurate, this number is only an approximation. */
|
||||||
|
u_longlong_t real_user; /* real memory used by non-system segments (in 4KB pages). This is the sum of all pages used in segments not marked for system usage.
|
||||||
|
* Since segment classifications are not always guaranteed to be accurate, this number is only an approximation. */
|
||||||
|
u_longlong_t real_process; /* real memory used by process segments (in 4KB pages). This is real_total-real_free-numperm-real_system. Since real_system is an
|
||||||
|
* approximation, this number is too. */
|
||||||
|
u_longlong_t virt_active; /* Active virtual pages. Virtual pages are considered active if they have been accessed */
|
||||||
|
|
||||||
|
} perfstat_memory_total_t;
|
||||||
|
|
||||||
|
typedef struct { /* global cpu information AIX 5.3 < TL10 */
|
||||||
|
int ncpus; /* number of active logical processors */
|
||||||
|
int ncpus_cfg; /* number of configured processors */
|
||||||
|
char description[IDENTIFIER_LENGTH]; /* processor description (type/official name) */
|
||||||
|
u_longlong_t processorHZ; /* processor speed in Hz */
|
||||||
|
u_longlong_t user; /* raw total number of clock ticks spent in user mode */
|
||||||
|
u_longlong_t sys; /* raw total number of clock ticks spent in system mode */
|
||||||
|
u_longlong_t idle; /* raw total number of clock ticks spent idle */
|
||||||
|
u_longlong_t wait; /* raw total number of clock ticks spent waiting for I/O */
|
||||||
|
u_longlong_t pswitch; /* number of process switches (change in currently running process) */
|
||||||
|
u_longlong_t syscall; /* number of system calls executed */
|
||||||
|
u_longlong_t sysread; /* number of read system calls executed */
|
||||||
|
u_longlong_t syswrite; /* number of write system calls executed */
|
||||||
|
u_longlong_t sysfork; /* number of forks system calls executed */
|
||||||
|
u_longlong_t sysexec; /* number of execs system calls executed */
|
||||||
|
u_longlong_t readch; /* number of characters tranferred with read system call */
|
||||||
|
u_longlong_t writech; /* number of characters tranferred with write system call */
|
||||||
|
u_longlong_t devintrs; /* number of device interrupts */
|
||||||
|
u_longlong_t softintrs; /* number of software interrupts */
|
||||||
|
time_t lbolt; /* number of ticks since last reboot */
|
||||||
|
u_longlong_t loadavg[3]; /* (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes.
|
||||||
|
* To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>. */
|
||||||
|
u_longlong_t runque; /* length of the run queue (processes ready) */
|
||||||
|
u_longlong_t swpque; /* ength of the swap queue (processes waiting to be paged in) */
|
||||||
|
u_longlong_t bread; /* number of blocks read */
|
||||||
|
u_longlong_t bwrite; /* number of blocks written */
|
||||||
|
u_longlong_t lread; /* number of logical read requests */
|
||||||
|
u_longlong_t lwrite; /* number of logical write requests */
|
||||||
|
u_longlong_t phread; /* number of physical reads (reads on raw devices) */
|
||||||
|
u_longlong_t phwrite; /* number of physical writes (writes on raw devices) */
|
||||||
|
u_longlong_t runocc; /* updated whenever runque is updated, i.e. the runqueue is occupied.
|
||||||
|
* This can be used to compute the simple average of ready processes */
|
||||||
|
u_longlong_t swpocc; /* updated whenever swpque is updated. i.e. the swpqueue is occupied.
|
||||||
|
* This can be used to compute the simple average processes waiting to be paged in */
|
||||||
|
u_longlong_t iget; /* number of inode lookups */
|
||||||
|
u_longlong_t namei; /* number of vnode lookup from a path name */
|
||||||
|
u_longlong_t dirblk; /* number of 512-byte block reads by the directory search routine to locate an entry for a file */
|
||||||
|
u_longlong_t msg; /* number of IPC message operations */
|
||||||
|
u_longlong_t sema; /* number of IPC semaphore operations */
|
||||||
|
u_longlong_t rcvint; /* number of tty receive interrupts */
|
||||||
|
u_longlong_t xmtint; /* number of tyy transmit interrupts */
|
||||||
|
u_longlong_t mdmint; /* number of modem interrupts */
|
||||||
|
u_longlong_t tty_rawinch; /* number of raw input characters */
|
||||||
|
u_longlong_t tty_caninch; /* number of canonical input characters (always zero) */
|
||||||
|
u_longlong_t tty_rawoutch; /* number of raw output characters */
|
||||||
|
u_longlong_t ksched; /* number of kernel processes created */
|
||||||
|
u_longlong_t koverf; /* kernel process creation attempts where:
|
||||||
|
* -the user has forked to their maximum limit
|
||||||
|
* -the configuration limit of processes has been reached */
|
||||||
|
u_longlong_t kexit; /* number of kernel processes that became zombies */
|
||||||
|
u_longlong_t rbread; /* number of remote read requests */
|
||||||
|
u_longlong_t rcread; /* number of cached remote reads */
|
||||||
|
u_longlong_t rbwrt; /* number of remote writes */
|
||||||
|
u_longlong_t rcwrt; /* number of cached remote writes */
|
||||||
|
u_longlong_t traps; /* number of traps */
|
||||||
|
int ncpus_high; /* index of highest processor online */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t decrintrs; /* number of decrementer tics interrupts */
|
||||||
|
u_longlong_t mpcrintrs; /* number of mpc's received interrupts */
|
||||||
|
u_longlong_t mpcsintrs; /* number of mpc's sent interrupts */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
short iowait; /* number of processes that are asleep waiting for buffered I/O */
|
||||||
|
short physio; /* number of processes waiting for raw I/O */
|
||||||
|
longlong_t twait; /* number of threads that are waiting for filesystem direct(cio) */
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds) */
|
||||||
|
} perfstat_cpu_total_t_53;
|
||||||
|
|
||||||
|
typedef struct { /* global cpu information AIX 6.1|5.3 > TL09 */
|
||||||
|
int ncpus; /* number of active logical processors */
|
||||||
|
int ncpus_cfg; /* number of configured processors */
|
||||||
|
char description[IDENTIFIER_LENGTH]; /* processor description (type/official name) */
|
||||||
|
u_longlong_t processorHZ; /* processor speed in Hz */
|
||||||
|
u_longlong_t user; /* raw total number of clock ticks spent in user mode */
|
||||||
|
u_longlong_t sys; /* raw total number of clock ticks spent in system mode */
|
||||||
|
u_longlong_t idle; /* raw total number of clock ticks spent idle */
|
||||||
|
u_longlong_t wait; /* raw total number of clock ticks spent waiting for I/O */
|
||||||
|
u_longlong_t pswitch; /* number of process switches (change in currently running process) */
|
||||||
|
u_longlong_t syscall; /* number of system calls executed */
|
||||||
|
u_longlong_t sysread; /* number of read system calls executed */
|
||||||
|
u_longlong_t syswrite; /* number of write system calls executed */
|
||||||
|
u_longlong_t sysfork; /* number of forks system calls executed */
|
||||||
|
u_longlong_t sysexec; /* number of execs system calls executed */
|
||||||
|
u_longlong_t readch; /* number of characters tranferred with read system call */
|
||||||
|
u_longlong_t writech; /* number of characters tranferred with write system call */
|
||||||
|
u_longlong_t devintrs; /* number of device interrupts */
|
||||||
|
u_longlong_t softintrs; /* number of software interrupts */
|
||||||
|
time_t lbolt; /* number of ticks since last reboot */
|
||||||
|
u_longlong_t loadavg[3]; /* (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes.
|
||||||
|
* To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>. */
|
||||||
|
u_longlong_t runque; /* length of the run queue (processes ready) */
|
||||||
|
u_longlong_t swpque; /* length of the swap queue (processes waiting to be paged in) */
|
||||||
|
u_longlong_t bread; /* number of blocks read */
|
||||||
|
u_longlong_t bwrite; /* number of blocks written */
|
||||||
|
u_longlong_t lread; /* number of logical read requests */
|
||||||
|
u_longlong_t lwrite; /* number of logical write requests */
|
||||||
|
u_longlong_t phread; /* number of physical reads (reads on raw devices) */
|
||||||
|
u_longlong_t phwrite; /* number of physical writes (writes on raw devices) */
|
||||||
|
u_longlong_t runocc; /* updated whenever runque is updated, i.e. the runqueue is occupied.
|
||||||
|
* This can be used to compute the simple average of ready processes */
|
||||||
|
u_longlong_t swpocc; /* updated whenever swpque is updated. i.e. the swpqueue is occupied.
|
||||||
|
* This can be used to compute the simple average processes waiting to be paged in */
|
||||||
|
u_longlong_t iget; /* number of inode lookups */
|
||||||
|
u_longlong_t namei; /* number of vnode lookup from a path name */
|
||||||
|
u_longlong_t dirblk; /* number of 512-byte block reads by the directory search routine to locate an entry for a file */
|
||||||
|
u_longlong_t msg; /* number of IPC message operations */
|
||||||
|
u_longlong_t sema; /* number of IPC semaphore operations */
|
||||||
|
u_longlong_t rcvint; /* number of tty receive interrupts */
|
||||||
|
u_longlong_t xmtint; /* number of tyy transmit interrupts */
|
||||||
|
u_longlong_t mdmint; /* number of modem interrupts */
|
||||||
|
u_longlong_t tty_rawinch; /* number of raw input characters */
|
||||||
|
u_longlong_t tty_caninch; /* number of canonical input characters (always zero) */
|
||||||
|
u_longlong_t tty_rawoutch; /* number of raw output characters */
|
||||||
|
u_longlong_t ksched; /* number of kernel processes created */
|
||||||
|
u_longlong_t koverf; /* kernel process creation attempts where:
|
||||||
|
* -the user has forked to their maximum limit
|
||||||
|
* -the configuration limit of processes has been reached */
|
||||||
|
u_longlong_t kexit; /* number of kernel processes that became zombies */
|
||||||
|
u_longlong_t rbread; /* number of remote read requests */
|
||||||
|
u_longlong_t rcread; /* number of cached remote reads */
|
||||||
|
u_longlong_t rbwrt; /* number of remote writes */
|
||||||
|
u_longlong_t rcwrt; /* number of cached remote writes */
|
||||||
|
u_longlong_t traps; /* number of traps */
|
||||||
|
int ncpus_high; /* index of highest processor online */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t decrintrs; /* number of decrementer tics interrupts */
|
||||||
|
u_longlong_t mpcrintrs; /* number of mpc's received interrupts */
|
||||||
|
u_longlong_t mpcsintrs; /* number of mpc's sent interrupts */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
short iowait; /* number of processes that are asleep waiting for buffered I/O */
|
||||||
|
short physio; /* number of processes waiting for raw I/O */
|
||||||
|
longlong_t twait; /* number of threads that are waiting for filesystem direct(cio) */
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds) */
|
||||||
|
u_longlong_t puser_spurr; /* number of spurr cycles spent in user mode */
|
||||||
|
u_longlong_t psys_spurr; /* number of spurr cycles spent in kernel mode */
|
||||||
|
u_longlong_t pidle_spurr; /* number of spurr cycles spent in idle mode */
|
||||||
|
u_longlong_t pwait_spurr; /* number of spurr cycles spent in wait mode */
|
||||||
|
int spurrflag; /* set if running in spurr mode */
|
||||||
|
} perfstat_cpu_total_t_61;
|
||||||
|
|
||||||
|
typedef struct { /* global cpu information AIX 7.1 */
|
||||||
|
int ncpus; /* number of active logical processors */
|
||||||
|
int ncpus_cfg; /* number of configured processors */
|
||||||
|
char description[IDENTIFIER_LENGTH]; /* processor description (type/official name) */
|
||||||
|
u_longlong_t processorHZ; /* processor speed in Hz */
|
||||||
|
u_longlong_t user; /* raw total number of clock ticks spent in user mode */
|
||||||
|
u_longlong_t sys; /* raw total number of clock ticks spent in system mode */
|
||||||
|
u_longlong_t idle; /* raw total number of clock ticks spent idle */
|
||||||
|
u_longlong_t wait; /* raw total number of clock ticks spent waiting for I/O */
|
||||||
|
u_longlong_t pswitch; /* number of process switches (change in currently running process) */
|
||||||
|
u_longlong_t syscall; /* number of system calls executed */
|
||||||
|
u_longlong_t sysread; /* number of read system calls executed */
|
||||||
|
u_longlong_t syswrite; /* number of write system calls executed */
|
||||||
|
u_longlong_t sysfork; /* number of forks system calls executed */
|
||||||
|
u_longlong_t sysexec; /* number of execs system calls executed */
|
||||||
|
u_longlong_t readch; /* number of characters tranferred with read system call */
|
||||||
|
u_longlong_t writech; /* number of characters tranferred with write system call */
|
||||||
|
u_longlong_t devintrs; /* number of device interrupts */
|
||||||
|
u_longlong_t softintrs; /* number of software interrupts */
|
||||||
|
time_t lbolt; /* number of ticks since last reboot */
|
||||||
|
u_longlong_t loadavg[3]; /* (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes.
|
||||||
|
* To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>. */
|
||||||
|
u_longlong_t runque; /* length of the run queue (processes ready) */
|
||||||
|
u_longlong_t swpque; /* ength of the swap queue (processes waiting to be paged in) */
|
||||||
|
u_longlong_t bread; /* number of blocks read */
|
||||||
|
u_longlong_t bwrite; /* number of blocks written */
|
||||||
|
u_longlong_t lread; /* number of logical read requests */
|
||||||
|
u_longlong_t lwrite; /* number of logical write requests */
|
||||||
|
u_longlong_t phread; /* number of physical reads (reads on raw devices) */
|
||||||
|
u_longlong_t phwrite; /* number of physical writes (writes on raw devices) */
|
||||||
|
u_longlong_t runocc; /* updated whenever runque is updated, i.e. the runqueue is occupied.
|
||||||
|
* This can be used to compute the simple average of ready processes */
|
||||||
|
u_longlong_t swpocc; /* updated whenever swpque is updated. i.e. the swpqueue is occupied.
|
||||||
|
* This can be used to compute the simple average processes waiting to be paged in */
|
||||||
|
u_longlong_t iget; /* number of inode lookups */
|
||||||
|
u_longlong_t namei; /* number of vnode lookup from a path name */
|
||||||
|
u_longlong_t dirblk; /* number of 512-byte block reads by the directory search routine to locate an entry for a file */
|
||||||
|
u_longlong_t msg; /* number of IPC message operations */
|
||||||
|
u_longlong_t sema; /* number of IPC semaphore operations */
|
||||||
|
u_longlong_t rcvint; /* number of tty receive interrupts */
|
||||||
|
u_longlong_t xmtint; /* number of tyy transmit interrupts */
|
||||||
|
u_longlong_t mdmint; /* number of modem interrupts */
|
||||||
|
u_longlong_t tty_rawinch; /* number of raw input characters */
|
||||||
|
u_longlong_t tty_caninch; /* number of canonical input characters (always zero) */
|
||||||
|
u_longlong_t tty_rawoutch; /* number of raw output characters */
|
||||||
|
u_longlong_t ksched; /* number of kernel processes created */
|
||||||
|
u_longlong_t koverf; /* kernel process creation attempts where:
|
||||||
|
* -the user has forked to their maximum limit
|
||||||
|
* -the configuration limit of processes has been reached */
|
||||||
|
u_longlong_t kexit; /* number of kernel processes that became zombies */
|
||||||
|
u_longlong_t rbread; /* number of remote read requests */
|
||||||
|
u_longlong_t rcread; /* number of cached remote reads */
|
||||||
|
u_longlong_t rbwrt; /* number of remote writes */
|
||||||
|
u_longlong_t rcwrt; /* number of cached remote writes */
|
||||||
|
u_longlong_t traps; /* number of traps */
|
||||||
|
int ncpus_high; /* index of highest processor online */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t decrintrs; /* number of decrementer tics interrupts */
|
||||||
|
u_longlong_t mpcrintrs; /* number of mpc's received interrupts */
|
||||||
|
u_longlong_t mpcsintrs; /* number of mpc's sent interrupts */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
short iowait; /* number of processes that are asleep waiting for buffered I/O */
|
||||||
|
short physio; /* number of processes waiting for raw I/O */
|
||||||
|
longlong_t twait; /* number of threads that are waiting for filesystem direct(cio) */
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds) */
|
||||||
|
u_longlong_t puser_spurr; /* number of spurr cycles spent in user mode */
|
||||||
|
u_longlong_t psys_spurr; /* number of spurr cycles spent in kernel mode */
|
||||||
|
u_longlong_t pidle_spurr; /* number of spurr cycles spent in idle mode */
|
||||||
|
u_longlong_t pwait_spurr; /* number of spurr cycles spent in wait mode */
|
||||||
|
int spurrflag; /* set if running in spurr mode */
|
||||||
|
u_longlong_t version; /* version number (1, 2, etc.,) */
|
||||||
|
/* >>>>> END OF STRUCTURE DEFINITION <<<<< */
|
||||||
|
#define CURR_VERSION_CPU_TOTAL 1 /* Incremented by one for every new release *
|
||||||
|
* of perfstat_cpu_total_t data structure */
|
||||||
|
} perfstat_cpu_total_t_71;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
uint w;
|
||||||
|
struct {
|
||||||
|
unsigned smt_capable :1; /* OS supports SMT mode */
|
||||||
|
unsigned smt_enabled :1; /* SMT mode is on */
|
||||||
|
unsigned lpar_capable :1; /* OS supports logical partitioning */
|
||||||
|
unsigned lpar_enabled :1; /* logical partitioning is on */
|
||||||
|
unsigned shared_capable :1; /* OS supports shared processor LPAR */
|
||||||
|
unsigned shared_enabled :1; /* partition runs in shared mode */
|
||||||
|
unsigned dlpar_capable :1; /* OS supports dynamic LPAR */
|
||||||
|
unsigned capped :1; /* partition is capped */
|
||||||
|
unsigned kernel_is_64 :1; /* kernel is 64 bit */
|
||||||
|
unsigned pool_util_authority :1; /* pool utilization available */
|
||||||
|
unsigned donate_capable :1; /* capable of donating cycles */
|
||||||
|
unsigned donate_enabled :1; /* enabled for donating cycles */
|
||||||
|
unsigned ams_capable:1; /* 1 = AMS(Active Memory Sharing) capable, 0 = Not AMS capable */
|
||||||
|
unsigned ams_enabled:1; /* 1 = AMS(Active Memory Sharing) enabled, 0 = Not AMS enabled */
|
||||||
|
unsigned power_save:1; /* 1 = Power saving mode is enabled */
|
||||||
|
unsigned ame_enabled:1; /* Active Memory Expansion is enabled */
|
||||||
|
unsigned shared_extended :1;
|
||||||
|
unsigned spare :15; /* reserved for future usage */
|
||||||
|
} b;
|
||||||
|
} perfstat_partition_type_t;
|
||||||
|
|
||||||
|
typedef struct { /* partition total information AIX 5.3 < TL6 */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
perfstat_partition_type_t type; /* set of bits describing the partition */
|
||||||
|
int lpar_id; /* logical partition identifier */
|
||||||
|
int group_id; /* identifier of the LPAR group this partition is a member of */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int max_cpus; /* maximum number of virtual CPUs this parition can ever have */
|
||||||
|
int min_cpus; /* minimum number of virtual CPUs this partition must have */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online */
|
||||||
|
u_longlong_t max_memory; /* maximum amount of memory this partition can ever have */
|
||||||
|
u_longlong_t min_memory; /* minimum amount of memory this partition must have */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int max_proc_capacity; /* maximum number of processor units this partition can ever have */
|
||||||
|
int min_proc_capacity; /* minimum number of processor units this partition must have */
|
||||||
|
int proc_capacity_increment; /* increment value to the entitled capacity */
|
||||||
|
int unalloc_proc_capacity; /* number of processor units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int unalloc_var_proc_capacity_weight; /* number of variable processor capacity weight units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int online_phys_cpus_sys; /* number of physical CPUs currently active in the system containing this partition */
|
||||||
|
int max_phys_cpus_sys; /* maximum possible number of physical CPUs in the system containing this partition */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t pool_idle_time; /* number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts received by the partition */
|
||||||
|
u_longlong_t invol_virt_cswitch; /* number involuntary virtual CPU context switches */
|
||||||
|
u_longlong_t vol_virt_cswitch; /* number voluntary virtual CPU context switches */
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base */
|
||||||
|
u_longlong_t reserved_pages; /* Currenlty number of 16GB pages. Cannot participate in DR operations */
|
||||||
|
u_longlong_t reserved_pagesize; /* Currently 16GB pagesize Cannot participate in DR operations */
|
||||||
|
} perfstat_partition_total_t_53_5;
|
||||||
|
|
||||||
|
typedef struct { /* partition total information AIX 5.3 < TL10 */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
perfstat_partition_type_t type; /* set of bits describing the partition */
|
||||||
|
int lpar_id; /* logical partition identifier */
|
||||||
|
int group_id; /* identifier of the LPAR group this partition is a member of */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int max_cpus; /* maximum number of virtual CPUs this parition can ever have */
|
||||||
|
int min_cpus; /* minimum number of virtual CPUs this partition must have */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online */
|
||||||
|
u_longlong_t max_memory; /* maximum amount of memory this partition can ever have */
|
||||||
|
u_longlong_t min_memory; /* minimum amount of memory this partition must have */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int max_proc_capacity; /* maximum number of processor units this partition can ever have */
|
||||||
|
int min_proc_capacity; /* minimum number of processor units this partition must have */
|
||||||
|
int proc_capacity_increment; /* increment value to the entitled capacity */
|
||||||
|
int unalloc_proc_capacity; /* number of processor units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int unalloc_var_proc_capacity_weight; /* number of variable processor capacity weight units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int online_phys_cpus_sys; /* number of physical CPUs currently active in the system containing this partition */
|
||||||
|
int max_phys_cpus_sys; /* maximum possible number of physical CPUs in the system containing this partition */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t pool_idle_time; /* number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts received by the partition */
|
||||||
|
u_longlong_t invol_virt_cswitch; /* number involuntary virtual CPU context switches */
|
||||||
|
u_longlong_t vol_virt_cswitch; /* number voluntary virtual CPU context switches */
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base */
|
||||||
|
u_longlong_t reserved_pages; /* Currenlty number of 16GB pages. Cannot participate in DR operations */
|
||||||
|
u_longlong_t reserved_pagesize; /* Currently 16GB pagesize Cannot participate in DR operations */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t shcpus_in_sys; /* Number of physical processors allocated for shared processor use */
|
||||||
|
u_longlong_t max_pool_capacity; /* Maximum processor capacity of partitions pool */
|
||||||
|
u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partitions pool */
|
||||||
|
u_longlong_t pool_max_time; /* Summation of maximum time that could be consumed by the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_busy_time; /* Summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_scaled_busy_time; /* Scaled summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t shcpu_tot_time; /* Summation of total time across all physical processors allocated for shared processor use (nano seconds) */
|
||||||
|
u_longlong_t shcpu_busy_time; /* Summation of busy (non-idle) time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
u_longlong_t shcpu_scaled_busy_time; /* Scaled summation of busy time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
int ams_pool_id; /* AMS pool id of the pool the LPAR belongs to */
|
||||||
|
int var_mem_weight; /* variable memory capacity weight */
|
||||||
|
u_longlong_t iome; /* I/O memory entitlement of the partition in bytes*/
|
||||||
|
u_longlong_t pmem; /* Physical memory currently backing the partition's logical memory in bytes*/
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds)*/
|
||||||
|
u_longlong_t hypv_pagesize; /* Hypervisor page size in KB*/
|
||||||
|
} perfstat_partition_total_t_53;
|
||||||
|
|
||||||
|
typedef struct { /* partition total information AIX 6.1|5.3 > TL09 */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
perfstat_partition_type_t type; /* set of bits describing the partition */
|
||||||
|
int lpar_id; /* logical partition identifier */
|
||||||
|
int group_id; /* identifier of the LPAR group this partition is a member of */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int max_cpus; /* maximum number of virtual CPUs this parition can ever have */
|
||||||
|
int min_cpus; /* minimum number of virtual CPUs this partition must have */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online */
|
||||||
|
u_longlong_t max_memory; /* maximum amount of memory this partition can ever have */
|
||||||
|
u_longlong_t min_memory; /* minimum amount of memory this partition must have */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int max_proc_capacity; /* maximum number of processor units this partition can ever have */
|
||||||
|
int min_proc_capacity; /* minimum number of processor units this partition must have */
|
||||||
|
int proc_capacity_increment; /* increment value to the entitled capacity */
|
||||||
|
int unalloc_proc_capacity; /* number of processor units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int unalloc_var_proc_capacity_weight; /* number of variable processor capacity weight units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int online_phys_cpus_sys; /* number of physical CPUs currently active in the system containing this partition */
|
||||||
|
int max_phys_cpus_sys; /* maximum possible number of physical CPUs in the system containing this partition */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t pool_idle_time; /* number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts received by the partition */
|
||||||
|
u_longlong_t invol_virt_cswitch; /* number involuntary virtual CPU context switches */
|
||||||
|
u_longlong_t vol_virt_cswitch; /* number voluntary virtual CPU context switches */
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base */
|
||||||
|
u_longlong_t reserved_pages; /* Currenlty number of 16GB pages. Cannot participate in DR operations */
|
||||||
|
u_longlong_t reserved_pagesize; /* Currently 16GB pagesize Cannot participate in DR operations */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t shcpus_in_sys; /* Number of physical processors allocated for shared processor use */
|
||||||
|
u_longlong_t max_pool_capacity; /* Maximum processor capacity of partitions pool */
|
||||||
|
u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partitions pool */
|
||||||
|
u_longlong_t pool_max_time; /* Summation of maximum time that could be consumed by the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_busy_time; /* Summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_scaled_busy_time; /* Scaled summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t shcpu_tot_time; /* Summation of total time across all physical processors allocated for shared processor use (nano seconds) */
|
||||||
|
u_longlong_t shcpu_busy_time; /* Summation of busy (non-idle) time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
u_longlong_t shcpu_scaled_busy_time; /* Scaled summation of busy time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
int ams_pool_id; /* AMS pool id of the pool the LPAR belongs to */
|
||||||
|
int var_mem_weight; /* variable memory capacity weight */
|
||||||
|
u_longlong_t iome; /* I/O memory entitlement of the partition in bytes*/
|
||||||
|
u_longlong_t pmem; /* Physical memory currently backing the partition's logical memory in bytes*/
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds)*/
|
||||||
|
u_longlong_t hypv_pagesize; /* Hypervisor page size in KB*/
|
||||||
|
uint online_lcpus; /* number of online logical cpus */
|
||||||
|
uint smt_thrds; /* number of hardware threads that are running */
|
||||||
|
u_longlong_t puser_spurr; /* number of spurr cycles spent in user mode */
|
||||||
|
u_longlong_t psys_spurr; /* number of spurr cycles spent in kernel mode */
|
||||||
|
u_longlong_t pidle_spurr; /* number of spurr cycles spent in idle mode */
|
||||||
|
u_longlong_t pwait_spurr; /* number of spurr cycles spent in wait mode */
|
||||||
|
int spurrflag; /* set if running in spurr mode */
|
||||||
|
} perfstat_partition_total_t_61;
|
||||||
|
|
||||||
|
typedef struct { /* partition total information AIX 7.1 */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
perfstat_partition_type_t type; /* set of bits describing the partition */
|
||||||
|
int lpar_id; /* logical partition identifier */
|
||||||
|
int group_id; /* identifier of the LPAR group this partition is a member of */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int max_cpus; /* maximum number of virtual CPUs this parition can ever have */
|
||||||
|
int min_cpus; /* minimum number of virtual CPUs this partition must have */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online */
|
||||||
|
u_longlong_t max_memory; /* maximum amount of memory this partition can ever have */
|
||||||
|
u_longlong_t min_memory; /* minimum amount of memory this partition must have */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int max_proc_capacity; /* maximum number of processor units this partition can ever have */
|
||||||
|
int min_proc_capacity; /* minimum number of processor units this partition must have */
|
||||||
|
int proc_capacity_increment; /* increment value to the entitled capacity */
|
||||||
|
int unalloc_proc_capacity; /* number of processor units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int unalloc_var_proc_capacity_weight; /* number of variable processor capacity weight units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int online_phys_cpus_sys; /* number of physical CPUs currently active in the system containing this partition */
|
||||||
|
int max_phys_cpus_sys; /* maximum possible number of physical CPUs in the system containing this partition */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t pool_idle_time; /* number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts received by the partition */
|
||||||
|
u_longlong_t invol_virt_cswitch; /* number involuntary virtual CPU context switches */
|
||||||
|
u_longlong_t vol_virt_cswitch; /* number voluntary virtual CPU context switches */
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base */
|
||||||
|
u_longlong_t reserved_pages; /* Currenlty number of 16GB pages. Cannot participate in DR operations */
|
||||||
|
u_longlong_t reserved_pagesize; /* Currently 16GB pagesize Cannot participate in DR operations */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t shcpus_in_sys; /* Number of physical processors allocated for shared processor use */
|
||||||
|
u_longlong_t max_pool_capacity; /* Maximum processor capacity of partitions pool */
|
||||||
|
u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partitions pool */
|
||||||
|
u_longlong_t pool_max_time; /* Summation of maximum time that could be consumed by the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_busy_time; /* Summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_scaled_busy_time; /* Scaled summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t shcpu_tot_time; /* Summation of total time across all physical processors allocated for shared processor use (nano seconds) */
|
||||||
|
u_longlong_t shcpu_busy_time; /* Summation of busy (non-idle) time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
u_longlong_t shcpu_scaled_busy_time; /* Scaled summation of busy time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
int ams_pool_id; /* AMS pool id of the pool the LPAR belongs to */
|
||||||
|
int var_mem_weight; /* variable memory capacity weight */
|
||||||
|
u_longlong_t iome; /* I/O memory entitlement of the partition in bytes*/
|
||||||
|
u_longlong_t pmem; /* Physical memory currently backing the partition's logical memory in bytes*/
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds)*/
|
||||||
|
u_longlong_t hypv_pagesize; /* Hypervisor page size in KB*/
|
||||||
|
uint online_lcpus; /* number of online logical cpus */
|
||||||
|
uint smt_thrds; /* number of hardware threads that are running */
|
||||||
|
u_longlong_t puser_spurr; /* number of spurr cycles spent in user mode */
|
||||||
|
u_longlong_t psys_spurr; /* number of spurr cycles spent in kernel mode */
|
||||||
|
u_longlong_t pidle_spurr; /* number of spurr cycles spent in idle mode */
|
||||||
|
u_longlong_t pwait_spurr; /* number of spurr cycles spent in wait mode */
|
||||||
|
int spurrflag; /* set if running in spurr mode */
|
||||||
|
char hardwareid[CEC_ID_LEN]; /* CEC Identifier */
|
||||||
|
uint power_save_mode; /* Power save mode for the LPAR. Introduced through LI 53K PRF : Feature 728 292*/
|
||||||
|
ushort ame_version; /* AME Version */
|
||||||
|
u_longlong_t true_memory; /* True Memory Size in 4KB pages */
|
||||||
|
u_longlong_t expanded_memory; /* Expanded Memory Size in 4KB pages */
|
||||||
|
u_longlong_t target_memexp_factr; /* Target Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t current_memexp_factr; /* Current Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t target_cpool_size; /* Target Compressed Pool Size in bytes */
|
||||||
|
u_longlong_t max_cpool_size; /* Max Size of Compressed Pool in bytes */
|
||||||
|
u_longlong_t min_ucpool_size; /* Min Size of Uncompressed Pool in bytes */
|
||||||
|
u_longlong_t ame_deficit_size; /*Deficit memory size in bytes */
|
||||||
|
u_longlong_t version; /* version number (1, 2, etc.,) */
|
||||||
|
u_longlong_t cmcs_total_time; /* Total CPU time spent due to active memory expansion */
|
||||||
|
} perfstat_partition_total_t_71;
|
||||||
|
|
||||||
|
typedef struct { /* partition total information AIX 7.1 >= TL1*/
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
perfstat_partition_type_t type; /* set of bits describing the partition */
|
||||||
|
int lpar_id; /* logical partition identifier */
|
||||||
|
int group_id; /* identifier of the LPAR group this partition is a member of */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int max_cpus; /* maximum number of virtual CPUs this parition can ever have */
|
||||||
|
int min_cpus; /* minimum number of virtual CPUs this partition must have */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online */
|
||||||
|
u_longlong_t max_memory; /* maximum amount of memory this partition can ever have */
|
||||||
|
u_longlong_t min_memory; /* minimum amount of memory this partition must have */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int max_proc_capacity; /* maximum number of processor units this partition can ever have */
|
||||||
|
int min_proc_capacity; /* minimum number of processor units this partition must have */
|
||||||
|
int proc_capacity_increment; /* increment value to the entitled capacity */
|
||||||
|
int unalloc_proc_capacity; /* number of processor units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int unalloc_var_proc_capacity_weight; /* number of variable processor capacity weight units currently unallocated in the shared processor pool this partition belongs to */
|
||||||
|
int online_phys_cpus_sys; /* number of physical CPUs currently active in the system containing this partition */
|
||||||
|
int max_phys_cpus_sys; /* maximum possible number of physical CPUs in the system containing this partition */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
u_longlong_t puser; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t psys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pidle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pwait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
u_longlong_t pool_idle_time; /* number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t phantintrs; /* number of phantom interrupts received by the partition */
|
||||||
|
u_longlong_t invol_virt_cswitch; /* number involuntary virtual CPU context switches */
|
||||||
|
u_longlong_t vol_virt_cswitch; /* number voluntary virtual CPU context switches */
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base */
|
||||||
|
u_longlong_t reserved_pages; /* Currenlty number of 16GB pages. Cannot participate in DR operations */
|
||||||
|
u_longlong_t reserved_pagesize; /* Currently 16GB pagesize Cannot participate in DR operations */
|
||||||
|
u_longlong_t idle_donated_purr; /* number of idle cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_donated_spurr; /* number of idle spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_purr; /* number of busy cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t busy_donated_spurr; /* number of busy spurr cycles donated by a dedicated partition enabled for donation */
|
||||||
|
u_longlong_t idle_stolen_purr; /* number of idle cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t idle_stolen_spurr; /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_purr; /* number of busy cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t busy_stolen_spurr; /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */
|
||||||
|
u_longlong_t shcpus_in_sys; /* Number of physical processors allocated for shared processor use */
|
||||||
|
u_longlong_t max_pool_capacity; /* Maximum processor capacity of partitions pool */
|
||||||
|
u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partitions pool */
|
||||||
|
u_longlong_t pool_max_time; /* Summation of maximum time that could be consumed by the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_busy_time; /* Summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t pool_scaled_busy_time; /* Scaled summation of busy (non-idle) time accumulated across all partitions in the pool (nano seconds) */
|
||||||
|
u_longlong_t shcpu_tot_time; /* Summation of total time across all physical processors allocated for shared processor use (nano seconds) */
|
||||||
|
u_longlong_t shcpu_busy_time; /* Summation of busy (non-idle) time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
u_longlong_t shcpu_scaled_busy_time; /* Scaled summation of busy time accumulated across all shared processor partitions (nano seconds) */
|
||||||
|
int ams_pool_id; /* AMS pool id of the pool the LPAR belongs to */
|
||||||
|
int var_mem_weight; /* variable memory capacity weight */
|
||||||
|
u_longlong_t iome; /* I/O memory entitlement of the partition in bytes*/
|
||||||
|
u_longlong_t pmem; /* Physical memory currently backing the partition's logical memory in bytes*/
|
||||||
|
u_longlong_t hpi; /* number of hypervisor page-ins */
|
||||||
|
u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds)*/
|
||||||
|
u_longlong_t hypv_pagesize; /* Hypervisor page size in KB*/
|
||||||
|
uint online_lcpus; /* number of online logical cpus */
|
||||||
|
uint smt_thrds; /* number of hardware threads that are running */
|
||||||
|
u_longlong_t puser_spurr; /* number of spurr cycles spent in user mode */
|
||||||
|
u_longlong_t psys_spurr; /* number of spurr cycles spent in kernel mode */
|
||||||
|
u_longlong_t pidle_spurr; /* number of spurr cycles spent in idle mode */
|
||||||
|
u_longlong_t pwait_spurr; /* number of spurr cycles spent in wait mode */
|
||||||
|
int spurrflag; /* set if running in spurr mode */
|
||||||
|
char hardwareid[CEC_ID_LEN]; /* CEC Identifier */
|
||||||
|
uint power_save_mode; /* Power save mode for the LPAR. Introduced through LI 53K PRF : Feature 728 292*/
|
||||||
|
ushort ame_version; /* AME Version */
|
||||||
|
u_longlong_t true_memory; /* True Memory Size in 4KB pages */
|
||||||
|
u_longlong_t expanded_memory; /* Expanded Memory Size in 4KB pages */
|
||||||
|
u_longlong_t target_memexp_factr; /* Target Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t current_memexp_factr; /* Current Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t target_cpool_size; /* Target Compressed Pool Size in bytes */
|
||||||
|
u_longlong_t max_cpool_size; /* Max Size of Compressed Pool in bytes */
|
||||||
|
u_longlong_t min_ucpool_size; /* Min Size of Uncompressed Pool in bytes */
|
||||||
|
u_longlong_t ame_deficit_size; /*Deficit memory size in bytes */
|
||||||
|
u_longlong_t version; /* version number (1, 2, etc.,) */
|
||||||
|
u_longlong_t cmcs_total_time; /* Total CPU time spent due to active memory expansion */
|
||||||
|
u_longlong_t purr_coalescing; /* If the calling partition is authorized to see pool wide statistics then PURR cycles consumed to coalesce data else set to zero.*/
|
||||||
|
u_longlong_t spurr_coalescing; /* If the calling partition is authorized to see pool wide statistics then SPURR cycles consumed to coalesce data else set to zero.*/
|
||||||
|
u_longlong_t MemPoolSize; /* Indicates the memory pool size of the pool that the partition belongs to (in bytes)., mpsz */
|
||||||
|
u_longlong_t IOMemEntInUse; /* I/O memory entitlement of the LPAR in use in bytes. iomu */
|
||||||
|
u_longlong_t IOMemEntFree; /* free I/O memory entitlement in bytes. iomf */
|
||||||
|
u_longlong_t IOHighWaterMark; /* high water mark of I/O memory entitlement usage in bytes. iohwn */
|
||||||
|
u_longlong_t purr_counter; /* number of purr cycles spent in user + kernel mode */
|
||||||
|
u_longlong_t spurr_counter; /* number of spurr cycles spent in user + kernel mode */
|
||||||
|
|
||||||
|
/* Marketing Requirement(MR): MR1124083744 */
|
||||||
|
u_longlong_t real_free; /* free real memory (in 4KB pages) */
|
||||||
|
u_longlong_t real_avail; /* number of pages available for user application (memfree + numperm - minperm - minfree) */
|
||||||
|
/* >>>>> END OF STRUCTURE DEFINITION <<<<< */
|
||||||
|
#define CURR_VERSION_PARTITION_TOTAL 5 /* Incremented by one for every new release *
|
||||||
|
* of perfstat_partition_total_t data structure */
|
||||||
|
} perfstat_partition_total_t_71_1;
|
||||||
|
|
||||||
|
typedef union { /* WPAR Type & Flags */
|
||||||
|
uint w;
|
||||||
|
struct {
|
||||||
|
unsigned app_wpar :1; /* Application WPAR */
|
||||||
|
unsigned cpu_rset :1; /* WPAR restricted to CPU resource set */
|
||||||
|
unsigned cpu_xrset:1; /* WPAR restricted to CPU Exclusive resource set */
|
||||||
|
unsigned cpu_limits :1; /* CPU resource limits enforced */
|
||||||
|
unsigned mem_limits :1; /* Memory resource limits enforced */
|
||||||
|
unsigned spare :27; /* reserved for future usage */
|
||||||
|
} b;
|
||||||
|
} perfstat_wpar_type_t;
|
||||||
|
|
||||||
|
typedef struct { /* Workload partition Information AIX 5.3 & 6.1*/
|
||||||
|
char name[MAXCORRALNAMELEN+1]; /* name of the Workload Partition */
|
||||||
|
perfstat_wpar_type_t type; /* set of bits describing the wpar */
|
||||||
|
cid_t wpar_id; /* workload partition identifier */
|
||||||
|
uint online_cpus; /* Number of Virtual CPUs in partition rset or number of virtual CPUs currently online on the Global partition*/
|
||||||
|
int cpu_limit; /* CPU limit in 100ths of % - 1..10000 */
|
||||||
|
int mem_limit; /* Memory limit in 100ths of % - 1..10000 */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online in Global Partition */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
} perfstat_wpar_total_t_61;
|
||||||
|
|
||||||
|
typedef struct { /* Workload partition Information AIX 7.1*/
|
||||||
|
char name[MAXCORRALNAMELEN+1]; /* name of the Workload Partition */
|
||||||
|
perfstat_wpar_type_t type; /* set of bits describing the wpar */
|
||||||
|
cid_t wpar_id; /* workload partition identifier */
|
||||||
|
uint online_cpus; /* Number of Virtual CPUs in partition rset or number of virtual CPUs currently online on the Global partition*/
|
||||||
|
int cpu_limit; /* CPU limit in 100ths of % - 1..10000 */
|
||||||
|
int mem_limit; /* Memory limit in 100ths of % - 1..10000 */
|
||||||
|
u_longlong_t online_memory; /* amount of memory currently online in Global Partition */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
u_longlong_t version; /* version number (1, 2, etc.,) */
|
||||||
|
/* >>>>> END OF STRUCTURE DEFINITION <<<<< */
|
||||||
|
#define CURR_VERSION_WPAR_TOTAL 1 /* Incremented by one for every new release *
|
||||||
|
* of perfstat_wpar_total_t data structure */
|
||||||
|
} perfstat_wpar_total_t_71;
|
||||||
|
|
||||||
|
typedef void * rsethandle_t; /* Type to identify a resource set handle: rsethandle_t */
|
||||||
|
|
||||||
|
typedef enum { WPARNAME, WPARID, RSETHANDLE } wparid_specifier; /* Type of wparid_specifier */
|
||||||
|
|
||||||
|
typedef struct { /* WPAR identifier */
|
||||||
|
wparid_specifier spec; /* Specifier to choose wpar id or name */
|
||||||
|
union {
|
||||||
|
cid_t wpar_id; /* WPAR ID */
|
||||||
|
rsethandle_t rset; /* Rset Handle */
|
||||||
|
char wparname[MAXCORRALNAMELEN+1]; /* WPAR NAME */
|
||||||
|
} u;
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the structure element identifier */
|
||||||
|
} perfstat_id_wpar_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// end: libperfstat.h (AIX 5.2, 5.3, 6.1, 7.1)
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define PERFSTAT_PARTITON_TOTAL_T_LATEST perfstat_partition_total_t_71_1/* latest perfstat_partition_total_t structure */
|
||||||
|
#define PERFSTAT_CPU_TOTAL_T_LATEST perfstat_cpu_total_t_71 /* latest perfstat_cpu_total_t structure */
|
||||||
|
#define PERFSTAT_WPAR_TOTAL_T_LATEST perfstat_wpar_total_t_71 /* latest perfstat_wpar_total_t structure */
|
||||||
|
|
||||||
class libperfstat {
|
class libperfstat {
|
||||||
|
|
||||||
@ -41,19 +766,107 @@ public:
|
|||||||
// Load the libperfstat library (must be in LIBPATH).
|
// Load the libperfstat library (must be in LIBPATH).
|
||||||
// Returns true if succeeded, false if error.
|
// Returns true if succeeded, false if error.
|
||||||
static bool init();
|
static bool init();
|
||||||
|
|
||||||
// cleanup of the libo4 porting library.
|
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
|
||||||
// direct wrappers for the libperfstat functionality. All they do is
|
// Direct wrappers for the libperfstat functionality. All they do is
|
||||||
// to call the functions with the same name via function pointers.
|
// to call the functions with the same name via function pointers.
|
||||||
static int perfstat_cpu_total(perfstat_id_t *name, perfstat_cpu_total_t* userbuff,
|
// Get all available data also on newer AIX versions (PERFSTAT_CPU_TOTAL_T_LATEST).
|
||||||
|
static int perfstat_cpu_total(perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,
|
||||||
int sizeof_userbuff, int desired_number);
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
static int perfstat_memory_total(perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
static int perfstat_memory_total(perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
||||||
int sizeof_userbuff, int desired_number);
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
|
static int perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff,
|
||||||
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
static void perfstat_reset();
|
static void perfstat_reset();
|
||||||
|
|
||||||
|
static int perfstat_wpar_total(perfstat_id_wpar_t *name, PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff,
|
||||||
|
int sizeof_userbuff, int desired_number);
|
||||||
|
|
||||||
|
static cid_t wpar_getcid();
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// The convenience functions get_partitioninfo(), get_cpuinfo(), get_wparinfo() return
|
||||||
|
// information about partition, cpu and wpars, respectivly. They can be used without
|
||||||
|
// regard for which OS release we are on. On older AIX release, some output structure
|
||||||
|
// members will be 0.
|
||||||
|
|
||||||
|
// Result struct for get_partitioninfo().
|
||||||
|
struct partitioninfo_t {
|
||||||
|
// partition type info
|
||||||
|
unsigned smt_capable :1; /* OS supports SMT mode */
|
||||||
|
unsigned smt_enabled :1; /* SMT mode is on */
|
||||||
|
unsigned lpar_capable :1; /* OS supports logical partitioning */
|
||||||
|
unsigned lpar_enabled :1; /* logical partitioning is on */
|
||||||
|
unsigned shared_capable :1; /* OS supports shared processor LPAR */
|
||||||
|
unsigned shared_enabled :1; /* partition runs in shared mode */
|
||||||
|
unsigned dlpar_capable :1; /* OS supports dynamic LPAR */
|
||||||
|
unsigned capped :1; /* partition is capped */
|
||||||
|
unsigned kernel_is_64 :1; /* kernel is 64 bit */
|
||||||
|
unsigned pool_util_authority :1; /* pool utilization available */
|
||||||
|
unsigned donate_capable :1; /* capable of donating cycles */
|
||||||
|
unsigned donate_enabled :1; /* enabled for donating cycles */
|
||||||
|
unsigned ams_capable:1; /* 1 = AMS(Active Memory Sharing) capable, 0 = Not AMS capable */
|
||||||
|
unsigned ams_enabled:1; /* 1 = AMS(Active Memory Sharing) enabled, 0 = Not AMS enabled */
|
||||||
|
unsigned power_save:1; /* 1 = Power saving mode is enabled */
|
||||||
|
unsigned ame_enabled:1; /* Active Memory Expansion is enabled */
|
||||||
|
// partition total info
|
||||||
|
int online_cpus; /* number of virtual CPUs currently online on the partition */
|
||||||
|
int entitled_proc_capacity; /* number of processor units this partition is entitled to receive */
|
||||||
|
int var_proc_capacity_weight; /* partition priority weight to receive extra capacity */
|
||||||
|
int phys_cpus_pool; /* number of the physical CPUs currently in the shared processor pool this partition belong to */
|
||||||
|
int pool_id; /* identifier of the shared pool of physical processors this partition is a member of */
|
||||||
|
u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partitions pool */
|
||||||
|
char name[IDENTIFIER_LENGTH]; /* name of the logical partition */
|
||||||
|
|
||||||
|
u_longlong_t timebase_last; /* most recently cpu time base (an incremented long int on PowerPC) */
|
||||||
|
u_longlong_t pool_idle_time; /* pool idle time = number of clock tics a processor in the shared pool was idle */
|
||||||
|
u_longlong_t pcpu_tics_user; /* raw number of physical processor tics in user mode */
|
||||||
|
u_longlong_t pcpu_tics_sys; /* raw number of physical processor tics in system mode */
|
||||||
|
u_longlong_t pcpu_tics_idle; /* raw number of physical processor tics idle */
|
||||||
|
u_longlong_t pcpu_tics_wait; /* raw number of physical processor tics waiting for I/O */
|
||||||
|
|
||||||
|
u_longlong_t true_memory; /* True Memory Size in 4KB pages */
|
||||||
|
u_longlong_t expanded_memory; /* Expanded Memory Size in 4KB pages */
|
||||||
|
u_longlong_t target_memexp_factr; /* Target Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t current_memexp_factr; /* Current Memory Expansion Factor scaled by 100 */
|
||||||
|
u_longlong_t cmcs_total_time; /* Total CPU time spent due to active memory expansion */
|
||||||
|
};
|
||||||
|
|
||||||
|
// Result struct for get_cpuinfo().
|
||||||
|
struct cpuinfo_t {
|
||||||
|
char description[IDENTIFIER_LENGTH]; // processor description (type/official name)
|
||||||
|
u_longlong_t processorHZ; // processor speed in Hz
|
||||||
|
int ncpus; // number of active logical processors
|
||||||
|
double loadavg[3]; // (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes.
|
||||||
|
// To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>.
|
||||||
|
char version[20]; // processor version from _system_configuration (sys/systemcfg.h)
|
||||||
|
unsigned long long user_clock_ticks; // raw total number of clock ticks spent in user mode
|
||||||
|
unsigned long long sys_clock_ticks; // raw total number of clock ticks spent in system mode
|
||||||
|
unsigned long long idle_clock_ticks; // raw total number of clock ticks spent idle
|
||||||
|
unsigned long long wait_clock_ticks; // raw total number of clock ticks spent waiting for I/O
|
||||||
|
};
|
||||||
|
|
||||||
|
// Result struct for get_wparinfo().
|
||||||
|
struct wparinfo_t {
|
||||||
|
char name[MAXCORRALNAMELEN+1]; /* name of the Workload Partition */
|
||||||
|
unsigned short wpar_id; /* workload partition identifier */
|
||||||
|
unsigned app_wpar :1; /* Application WPAR */
|
||||||
|
unsigned cpu_rset :1; /* WPAR restricted to CPU resource set */
|
||||||
|
unsigned cpu_xrset:1; /* WPAR restricted to CPU Exclusive resource set */
|
||||||
|
unsigned cpu_limits :1; /* CPU resource limits enforced */
|
||||||
|
unsigned mem_limits :1; /* Memory resource limits enforced */
|
||||||
|
int cpu_limit; /* CPU limit in 100ths of % - 1..10000 */
|
||||||
|
int mem_limit; /* Memory limit in 100ths of % - 1..10000 */
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool get_partitioninfo(partitioninfo_t* ppi);
|
||||||
|
static bool get_cpuinfo(cpuinfo_t* pci);
|
||||||
|
static bool get_wparinfo(wparinfo_t* pwi);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
#endif // OS_AIX_VM_LIBPERFSTAT_AIX_HPP
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
* Copyright 2012, 2015 SAP AG. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,7 +35,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "loadlib_aix.hpp"
|
#include "loadlib_aix.hpp"
|
||||||
// for CritSect
|
|
||||||
#include "misc_aix.hpp"
|
#include "misc_aix.hpp"
|
||||||
#include "porting_aix.hpp"
|
#include "porting_aix.hpp"
|
||||||
#include "utilities/debug.hpp"
|
#include "utilities/debug.hpp"
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
void MiscUtils::init_critsect(MiscUtils::critsect_t* cs) {
|
void MiscUtils::init_critsect(MiscUtils::critsect_t* cs) {
|
||||||
const int rc = pthread_mutex_init(cs, NULL);
|
const int rc = pthread_mutex_init(cs, NULL);
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
// misc_aix.hpp, misc_aix.cpp: convenience functions needed for the OpenJDK AIX
|
// misc_aix.hpp, misc_aix.cpp: convenience functions needed for the OpenJDK AIX
|
||||||
// port.
|
// port.
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
#include "runtime/globals.hpp"
|
||||||
|
#include "utilities/debug.hpp"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
@ -40,7 +42,6 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define ERRBYE(s) { trcVerbose(s); return -1; }
|
#define ERRBYE(s) { trcVerbose(s); return -1; }
|
||||||
#define trc(fmt, ...)
|
|
||||||
|
|
||||||
#define assert0(b) assert((b), "")
|
#define assert0(b) assert((b), "")
|
||||||
#define guarantee0(b) guarantee((b), "")
|
#define guarantee0(b) guarantee((b), "")
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
void OSThread::pd_initialize() {
|
void OSThread::pd_initialize() {
|
||||||
assert(this != NULL, "check");
|
assert(this != NULL, "check");
|
||||||
_thread_id = 0;
|
_thread_id = 0;
|
||||||
_pthread_id = 0;
|
_kernel_thread_id = 0;
|
||||||
_siginfo = NULL;
|
_siginfo = NULL;
|
||||||
_ucontext = NULL;
|
_ucontext = NULL;
|
||||||
_expanding_stack = 0;
|
_expanding_stack = 0;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#define OS_AIX_VM_OSTHREAD_AIX_HPP
|
#define OS_AIX_VM_OSTHREAD_AIX_HPP
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef pid_t thread_id_t;
|
typedef pthread_t thread_id_t;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _thread_type;
|
int _thread_type;
|
||||||
@ -43,9 +43,13 @@
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// _pthread_id is the pthread id, which is used by library calls
|
// On AIX, we use the pthread id as OSThread::thread_id and keep the kernel thread id
|
||||||
// (e.g. pthread_kill).
|
// separately for diagnostic purposes.
|
||||||
pthread_t _pthread_id;
|
//
|
||||||
|
// Note: this kernel thread id is saved at thread start. Depending on the
|
||||||
|
// AIX scheduling mode, this may not be the current thread id (usually not
|
||||||
|
// a problem though as we run with AIXTHREAD_SCOPE=S).
|
||||||
|
tid_t _kernel_thread_id;
|
||||||
|
|
||||||
sigset_t _caller_sigmask; // Caller's signal mask
|
sigset_t _caller_sigmask; // Caller's signal mask
|
||||||
|
|
||||||
@ -66,11 +70,16 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
pthread_t pthread_id() const {
|
tid_t kernel_thread_id() const {
|
||||||
return _pthread_id;
|
return _kernel_thread_id;
|
||||||
}
|
}
|
||||||
void set_pthread_id(pthread_t tid) {
|
void set_kernel_thread_id(tid_t tid) {
|
||||||
_pthread_id = tid;
|
_kernel_thread_id = tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t pthread_id() const {
|
||||||
|
// Here: same as OSThread::thread_id()
|
||||||
|
return _thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************
|
// ***************************************************************
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,9 +34,6 @@ static bool zero_page_read_protected() { return false; }
|
|||||||
class Aix {
|
class Aix {
|
||||||
friend class os;
|
friend class os;
|
||||||
|
|
||||||
// Length of strings included in the libperfstat structures.
|
|
||||||
#define IDENTIFIER_LENGTH 64
|
|
||||||
|
|
||||||
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
||||||
// __sigaction(), signal() is loaded
|
// __sigaction(), signal() is loaded
|
||||||
static struct sigaction *(*get_signal_action)(int);
|
static struct sigaction *(*get_signal_action)(int);
|
||||||
@ -45,13 +42,15 @@ class Aix {
|
|||||||
|
|
||||||
static void check_signal_handler(int sig);
|
static void check_signal_handler(int sig);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
static julong _physical_memory;
|
static julong _physical_memory;
|
||||||
static pthread_t _main_thread;
|
static pthread_t _main_thread;
|
||||||
static Mutex* _createThread_lock;
|
static Mutex* _createThread_lock;
|
||||||
static int _page_size;
|
static int _page_size;
|
||||||
static int _logical_cpus;
|
|
||||||
|
// Page size of newly created pthreads.
|
||||||
|
static int _stack_page_size;
|
||||||
|
|
||||||
// -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
|
// -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
|
||||||
static int _on_pase;
|
static int _on_pase;
|
||||||
@ -63,6 +62,9 @@ class Aix {
|
|||||||
// for OS/400 e.g. 0x0504 for OS/400 V5R4
|
// for OS/400 e.g. 0x0504 for OS/400 V5R4
|
||||||
static int _os_version;
|
static int _os_version;
|
||||||
|
|
||||||
|
// 4 Byte kernel version: Version, Release, Tech Level, Service Pack.
|
||||||
|
static unsigned int _os_kernel_version;
|
||||||
|
|
||||||
// -1 = uninitialized,
|
// -1 = uninitialized,
|
||||||
// 0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set)
|
// 0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set)
|
||||||
// 1 - SPEC1170 requested (XPG_SUS_ENV is ON)
|
// 1 - SPEC1170 requested (XPG_SUS_ENV is ON)
|
||||||
@ -73,35 +75,6 @@ class Aix {
|
|||||||
// 1 - EXTSHM=ON
|
// 1 - EXTSHM=ON
|
||||||
static int _extshm;
|
static int _extshm;
|
||||||
|
|
||||||
// page sizes on AIX.
|
|
||||||
//
|
|
||||||
// AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The latter two
|
|
||||||
// (16M "large" resp. 16G "huge" pages) require special setup and are normally
|
|
||||||
// not available.
|
|
||||||
//
|
|
||||||
// AIX supports multiple page sizes per process, for:
|
|
||||||
// - Stack (of the primordial thread, so not relevant for us)
|
|
||||||
// - Data - data, bss, heap, for us also pthread stacks
|
|
||||||
// - Text - text code
|
|
||||||
// - shared memory
|
|
||||||
//
|
|
||||||
// Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...)
|
|
||||||
// and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...)
|
|
||||||
//
|
|
||||||
// For shared memory, page size can be set dynamically via shmctl(). Different shared memory
|
|
||||||
// regions can have different page sizes.
|
|
||||||
//
|
|
||||||
// More information can be found at AIBM info center:
|
|
||||||
// http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm
|
|
||||||
//
|
|
||||||
// -----
|
|
||||||
// We want to support 4K and 64K and, if the machine is set up correctly, 16MB pages.
|
|
||||||
//
|
|
||||||
|
|
||||||
// page size of the stack of newly created pthreads
|
|
||||||
// (should be LDR_CNTRL DATAPSIZE because stack is allocated on heap by pthread lib)
|
|
||||||
static int _stack_page_size;
|
|
||||||
|
|
||||||
static julong available_memory();
|
static julong available_memory();
|
||||||
static julong physical_memory() { return _physical_memory; }
|
static julong physical_memory() { return _physical_memory; }
|
||||||
static void initialize_system_info();
|
static void initialize_system_info();
|
||||||
@ -125,9 +98,6 @@ class Aix {
|
|||||||
public:
|
public:
|
||||||
static void init_thread_fpu_state();
|
static void init_thread_fpu_state();
|
||||||
static pthread_t main_thread(void) { return _main_thread; }
|
static pthread_t main_thread(void) { return _main_thread; }
|
||||||
// returns kernel thread id (similar to LWP id on Solaris), which can be
|
|
||||||
// used to access /proc
|
|
||||||
static pid_t gettid();
|
|
||||||
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
|
static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }
|
||||||
static Mutex* createThread_lock(void) { return _createThread_lock; }
|
static Mutex* createThread_lock(void) { return _createThread_lock; }
|
||||||
static void hotspot_sigmask(Thread* thread);
|
static void hotspot_sigmask(Thread* thread);
|
||||||
@ -215,6 +185,14 @@ class Aix {
|
|||||||
return _os_version;
|
return _os_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get 4 byte AIX kernel version number:
|
||||||
|
// highest 2 bytes: Version, Release
|
||||||
|
// if available: lowest 2 bytes: Tech Level, Service Pack.
|
||||||
|
static unsigned int os_kernel_version() {
|
||||||
|
if (_os_kernel_version) return _os_kernel_version;
|
||||||
|
return os_version() << 16;
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience method: returns true if running on PASE V5R4 or older.
|
// Convenience method: returns true if running on PASE V5R4 or older.
|
||||||
static bool on_pase_V5R4_or_older() {
|
static bool on_pase_V5R4_or_older() {
|
||||||
return on_pase() && os_version() <= 0x0504;
|
return on_pase() && os_version() <= 0x0504;
|
||||||
@ -257,27 +235,12 @@ class Aix {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Result struct for get_cpuinfo().
|
|
||||||
struct cpuinfo_t {
|
|
||||||
char description[IDENTIFIER_LENGTH]; // processor description (type/official name)
|
|
||||||
u_longlong_t processorHZ; // processor speed in Hz
|
|
||||||
int ncpus; // number of active logical processors
|
|
||||||
double loadavg[3]; // (1<<SBITS) times the average number of runnables processes during the last 1, 5 and 15 minutes.
|
|
||||||
// To calculate the load average, divide the numbers by (1<<SBITS). SBITS is defined in <sys/proc.h>.
|
|
||||||
char version[20]; // processor version from _system_configuration (sys/systemcfg.h)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Functions to retrieve memory information on AIX, PASE.
|
// Functions to retrieve memory information on AIX, PASE.
|
||||||
// (on AIX, using libperfstat, on PASE with libo4.so).
|
// (on AIX, using libperfstat, on PASE with libo4.so).
|
||||||
// Returns true if ok, false if error.
|
// Returns true if ok, false if error.
|
||||||
static bool get_meminfo(meminfo_t* pmi);
|
static bool get_meminfo(meminfo_t* pmi);
|
||||||
|
|
||||||
// Function to retrieve cpu information on AIX
|
};
|
||||||
// (on AIX, using libperfstat)
|
|
||||||
// Returns true if ok, false if error.
|
|
||||||
static bool get_cpuinfo(cpuinfo_t* pci);
|
|
||||||
|
|
||||||
}; // os::Aix class
|
|
||||||
|
|
||||||
|
|
||||||
class PlatformEvent : public CHeapObj<mtInternal> {
|
class PlatformEvent : public CHeapObj<mtInternal> {
|
||||||
|
@ -36,10 +36,6 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
inline void* os::thread_local_storage_at(int index) {
|
|
||||||
return pthread_getspecific((pthread_key_t)index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// File names are case-sensitive on windows only.
|
// File names are case-sensitive on windows only.
|
||||||
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
||||||
return strcmp(s1, s2);
|
return strcmp(s1, s2);
|
||||||
@ -64,6 +60,8 @@ inline bool os::allocate_stack_guard_pages() {
|
|||||||
// On Aix, reservations are made on a page by page basis, nothing to do.
|
// On Aix, reservations are made on a page by page basis, nothing to do.
|
||||||
inline void os::pd_split_reserved_memory(char *base, size_t size,
|
inline void os::pd_split_reserved_memory(char *base, size_t size,
|
||||||
size_t split, bool realloc) {
|
size_t split, bool realloc) {
|
||||||
|
// TODO: Determine whether Sys V memory is split. If yes, we need to treat
|
||||||
|
// this the same way Windows treats its VirtualAlloc allocations.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bang the shadow pages if they need to be touched to be mapped.
|
// Bang the shadow pages if they need to be touched to be mapped.
|
||||||
|
@ -108,84 +108,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
|||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
/*
|
|
||||||
All the defined signal names for Bsd.
|
|
||||||
|
|
||||||
NOTE that not all of these names are accepted by our Java implementation
|
|
||||||
|
|
||||||
Via an existing claim by the VM, sigaction restrictions, or
|
|
||||||
the "rules of Unix" some of these names will be rejected at runtime.
|
|
||||||
For example the VM sets up to handle USR1, sigaction returns EINVAL for
|
|
||||||
STOP, and Bsd simply doesn't allow catching of KILL.
|
|
||||||
|
|
||||||
Here are the names currently accepted by a user of sun.misc.Signal with
|
|
||||||
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
|
||||||
|
|
||||||
HUP, INT, TRAP, ABRT, IOT, BUS, USR2, PIPE, ALRM, TERM, STKFLT,
|
|
||||||
CLD, CHLD, CONT, TSTP, TTIN, TTOU, URG, XCPU, XFSZ, VTALRM, PROF,
|
|
||||||
WINCH, POLL, IO, PWR, SYS
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct siglabel {
|
|
||||||
const char *name;
|
|
||||||
int number;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct siglabel siglabels[] = {
|
|
||||||
/* derived from /usr/include/bits/signum.h on RH7.2 */
|
|
||||||
"HUP", SIGHUP, /* Hangup (POSIX). */
|
|
||||||
"INT", SIGINT, /* Interrupt (ANSI). */
|
|
||||||
"QUIT", SIGQUIT, /* Quit (POSIX). */
|
|
||||||
"ILL", SIGILL, /* Illegal instruction (ANSI). */
|
|
||||||
"TRAP", SIGTRAP, /* Trace trap (POSIX). */
|
|
||||||
"ABRT", SIGABRT, /* Abort (ANSI). */
|
|
||||||
"EMT", SIGEMT, /* EMT trap */
|
|
||||||
"FPE", SIGFPE, /* Floating-point exception (ANSI). */
|
|
||||||
"KILL", SIGKILL, /* Kill, unblockable (POSIX). */
|
|
||||||
"BUS", SIGBUS, /* BUS error (4.2 BSD). */
|
|
||||||
"SEGV", SIGSEGV, /* Segmentation violation (ANSI). */
|
|
||||||
"SYS", SIGSYS, /* Bad system call. Only on some Bsden! */
|
|
||||||
"PIPE", SIGPIPE, /* Broken pipe (POSIX). */
|
|
||||||
"ALRM", SIGALRM, /* Alarm clock (POSIX). */
|
|
||||||
"TERM", SIGTERM, /* Termination (ANSI). */
|
|
||||||
"URG", SIGURG, /* Urgent condition on socket (4.2 BSD). */
|
|
||||||
"STOP", SIGSTOP, /* Stop, unblockable (POSIX). */
|
|
||||||
"TSTP", SIGTSTP, /* Keyboard stop (POSIX). */
|
|
||||||
"CONT", SIGCONT, /* Continue (POSIX). */
|
|
||||||
"CHLD", SIGCHLD, /* Child status has changed (POSIX). */
|
|
||||||
"TTIN", SIGTTIN, /* Background read from tty (POSIX). */
|
|
||||||
"TTOU", SIGTTOU, /* Background write to tty (POSIX). */
|
|
||||||
"IO", SIGIO, /* I/O now possible (4.2 BSD). */
|
|
||||||
"XCPU", SIGXCPU, /* CPU limit exceeded (4.2 BSD). */
|
|
||||||
"XFSZ", SIGXFSZ, /* File size limit exceeded (4.2 BSD). */
|
|
||||||
"VTALRM", SIGVTALRM, /* Virtual alarm clock (4.2 BSD). */
|
|
||||||
"PROF", SIGPROF, /* Profiling alarm clock (4.2 BSD). */
|
|
||||||
"WINCH", SIGWINCH, /* Window size change (4.3 BSD, Sun). */
|
|
||||||
"INFO", SIGINFO, /* Information request. */
|
|
||||||
"USR1", SIGUSR1, /* User-defined signal 1 (POSIX). */
|
|
||||||
"USR2", SIGUSR2 /* User-defined signal 2 (POSIX). */
|
|
||||||
};
|
|
||||||
|
|
||||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
|
||||||
|
|
||||||
/* find and return the named signal's number */
|
|
||||||
|
|
||||||
for(uint i=0; i<ARRAY_SIZE(siglabels); i++)
|
|
||||||
if(!strcmp(name, siglabels[i].name))
|
|
||||||
return siglabels[i].number;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
JVM_END
|
|
||||||
|
|
||||||
// used by os::exception_name()
|
|
||||||
extern bool signal_name(int signo, char* buf, size_t len) {
|
|
||||||
for(uint i = 0; i < ARRAY_SIZE(siglabels); i++) {
|
|
||||||
if (signo == siglabels[i].number) {
|
|
||||||
jio_snprintf(buf, len, "SIG%s", siglabels[i].name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -674,7 +674,7 @@ static void *java_start(Thread *thread) {
|
|||||||
int pid = os::current_process_id();
|
int pid = os::current_process_id();
|
||||||
alloca(((pid ^ counter++) & 7) * 128);
|
alloca(((pid ^ counter++) & 7) * 128);
|
||||||
|
|
||||||
ThreadLocalStorage::set_thread(thread);
|
thread->initialize_thread_current();
|
||||||
|
|
||||||
OSThread* osthread = thread->osthread();
|
OSThread* osthread = thread->osthread();
|
||||||
Monitor* sync = osthread->startThread_lock();
|
Monitor* sync = osthread->startThread_lock();
|
||||||
@ -882,44 +882,6 @@ void os::free_thread(OSThread* osthread) {
|
|||||||
delete osthread;
|
delete osthread;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// thread local storage
|
|
||||||
|
|
||||||
// Restore the thread pointer if the destructor is called. This is in case
|
|
||||||
// someone from JNI code sets up a destructor with pthread_key_create to run
|
|
||||||
// detachCurrentThread on thread death. Unless we restore the thread pointer we
|
|
||||||
// will hang or crash. When detachCurrentThread is called the key will be set
|
|
||||||
// to null and we will not be called again. If detachCurrentThread is never
|
|
||||||
// called we could loop forever depending on the pthread implementation.
|
|
||||||
static void restore_thread_pointer(void* p) {
|
|
||||||
Thread* thread = (Thread*) p;
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::allocate_thread_local_storage() {
|
|
||||||
pthread_key_t key;
|
|
||||||
int rslt = pthread_key_create(&key, restore_thread_pointer);
|
|
||||||
assert(rslt == 0, "cannot allocate thread local storage");
|
|
||||||
return (int)key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: This is currently not used by VM, as we don't destroy TLS key
|
|
||||||
// on VM exit.
|
|
||||||
void os::free_thread_local_storage(int index) {
|
|
||||||
int rslt = pthread_key_delete((pthread_key_t)index);
|
|
||||||
assert(rslt == 0, "invalid index");
|
|
||||||
}
|
|
||||||
|
|
||||||
void os::thread_local_storage_at_put(int index, void* value) {
|
|
||||||
int rslt = pthread_setspecific((pthread_key_t)index, value);
|
|
||||||
assert(rslt == 0, "pthread_setspecific failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" Thread* get_thread() {
|
|
||||||
return ThreadLocalStorage::thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// time support
|
// time support
|
||||||
|
|
||||||
@ -3420,8 +3382,12 @@ void os::Bsd::check_signal_handler(int sig) {
|
|||||||
}
|
}
|
||||||
} else if(os::Bsd::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Bsd::get_our_sigflags(sig)) {
|
} else if(os::Bsd::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Bsd::get_our_sigflags(sig)) {
|
||||||
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
||||||
tty->print("expected:" PTR32_FORMAT, os::Bsd::get_our_sigflags(sig));
|
tty->print("expected:");
|
||||||
tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
os::Posix::print_sa_flags(tty, os::Bsd::get_our_sigflags(sig));
|
||||||
|
tty->cr();
|
||||||
|
tty->print(" found:");
|
||||||
|
os::Posix::print_sa_flags(tty, act.sa_flags);
|
||||||
|
tty->cr();
|
||||||
// No need to check this sig any longer
|
// No need to check this sig any longer
|
||||||
sigaddset(&check_signal_done, sig);
|
sigaddset(&check_signal_done, sig);
|
||||||
}
|
}
|
||||||
@ -3435,20 +3401,6 @@ void os::Bsd::check_signal_handler(int sig) {
|
|||||||
extern void report_error(char* file_name, int line_no, char* title,
|
extern void report_error(char* file_name, int line_no, char* title,
|
||||||
char* format, ...);
|
char* format, ...);
|
||||||
|
|
||||||
extern bool signal_name(int signo, char* buf, size_t len);
|
|
||||||
|
|
||||||
const char* os::exception_name(int exception_code, char* buf, size_t size) {
|
|
||||||
if (0 < exception_code && exception_code <= SIGRTMAX) {
|
|
||||||
// signal
|
|
||||||
if (!signal_name(exception_code, buf, size)) {
|
|
||||||
jio_snprintf(buf, size, "SIG%d", exception_code);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is called _before_ the most of global arguments have been parsed
|
// this is called _before_ the most of global arguments have been parsed
|
||||||
void os::init(void) {
|
void os::init(void) {
|
||||||
char dummy; // used to get a guess on initial stack address
|
char dummy; // used to get a guess on initial stack address
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -34,10 +34,6 @@
|
|||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
inline void* os::thread_local_storage_at(int index) {
|
|
||||||
return pthread_getspecific((pthread_key_t)index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// File names are case-sensitive on windows only
|
// File names are case-sensitive on windows only
|
||||||
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
||||||
return strcmp(s1, s2);
|
return strcmp(s1, s2);
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002, 2011, 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 OS_BSD_VM_THREAD_BSD_INLINE_HPP
|
|
||||||
#define OS_BSD_VM_THREAD_BSD_INLINE_HPP
|
|
||||||
|
|
||||||
#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
|
|
||||||
#error "This file should only be included from thread.inline.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "runtime/thread.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Contains inlined functions for class Thread and ThreadLocalStorage
|
|
||||||
|
|
||||||
inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
|
|
||||||
|
|
||||||
#endif // OS_BSD_VM_THREAD_BSD_INLINE_HPP
|
|
@ -108,91 +108,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
|||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
/*
|
|
||||||
All the defined signal names for Linux.
|
|
||||||
|
|
||||||
NOTE that not all of these names are accepted by our Java implementation
|
|
||||||
|
|
||||||
Via an existing claim by the VM, sigaction restrictions, or
|
|
||||||
the "rules of Unix" some of these names will be rejected at runtime.
|
|
||||||
For example the VM sets up to handle USR1, sigaction returns EINVAL for
|
|
||||||
STOP, and Linux simply doesn't allow catching of KILL.
|
|
||||||
|
|
||||||
Here are the names currently accepted by a user of sun.misc.Signal with
|
|
||||||
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
|
||||||
|
|
||||||
HUP, INT, TRAP, ABRT, IOT, BUS, USR2, PIPE, ALRM, TERM, STKFLT,
|
|
||||||
CLD, CHLD, CONT, TSTP, TTIN, TTOU, URG, XCPU, XFSZ, VTALRM, PROF,
|
|
||||||
WINCH, POLL, IO, PWR, SYS
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct siglabel {
|
|
||||||
const char *name;
|
|
||||||
int number;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct siglabel siglabels[] = {
|
|
||||||
/* derived from /usr/include/bits/signum.h on RH7.2 */
|
|
||||||
"HUP", SIGHUP, /* Hangup (POSIX). */
|
|
||||||
"INT", SIGINT, /* Interrupt (ANSI). */
|
|
||||||
"QUIT", SIGQUIT, /* Quit (POSIX). */
|
|
||||||
"ILL", SIGILL, /* Illegal instruction (ANSI). */
|
|
||||||
"TRAP", SIGTRAP, /* Trace trap (POSIX). */
|
|
||||||
"ABRT", SIGABRT, /* Abort (ANSI). */
|
|
||||||
"IOT", SIGIOT, /* IOT trap (4.2 BSD). */
|
|
||||||
"BUS", SIGBUS, /* BUS error (4.2 BSD). */
|
|
||||||
"FPE", SIGFPE, /* Floating-point exception (ANSI). */
|
|
||||||
"KILL", SIGKILL, /* Kill, unblockable (POSIX). */
|
|
||||||
"USR1", SIGUSR1, /* User-defined signal 1 (POSIX). */
|
|
||||||
"SEGV", SIGSEGV, /* Segmentation violation (ANSI). */
|
|
||||||
"USR2", SIGUSR2, /* User-defined signal 2 (POSIX). */
|
|
||||||
"PIPE", SIGPIPE, /* Broken pipe (POSIX). */
|
|
||||||
"ALRM", SIGALRM, /* Alarm clock (POSIX). */
|
|
||||||
"TERM", SIGTERM, /* Termination (ANSI). */
|
|
||||||
#ifdef SIGSTKFLT
|
|
||||||
"STKFLT", SIGSTKFLT, /* Stack fault. */
|
|
||||||
#endif
|
|
||||||
"CLD", SIGCLD, /* Same as SIGCHLD (System V). */
|
|
||||||
"CHLD", SIGCHLD, /* Child status has changed (POSIX). */
|
|
||||||
"CONT", SIGCONT, /* Continue (POSIX). */
|
|
||||||
"STOP", SIGSTOP, /* Stop, unblockable (POSIX). */
|
|
||||||
"TSTP", SIGTSTP, /* Keyboard stop (POSIX). */
|
|
||||||
"TTIN", SIGTTIN, /* Background read from tty (POSIX). */
|
|
||||||
"TTOU", SIGTTOU, /* Background write to tty (POSIX). */
|
|
||||||
"URG", SIGURG, /* Urgent condition on socket (4.2 BSD). */
|
|
||||||
"XCPU", SIGXCPU, /* CPU limit exceeded (4.2 BSD). */
|
|
||||||
"XFSZ", SIGXFSZ, /* File size limit exceeded (4.2 BSD). */
|
|
||||||
"VTALRM", SIGVTALRM, /* Virtual alarm clock (4.2 BSD). */
|
|
||||||
"PROF", SIGPROF, /* Profiling alarm clock (4.2 BSD). */
|
|
||||||
"WINCH", SIGWINCH, /* Window size change (4.3 BSD, Sun). */
|
|
||||||
"POLL", SIGPOLL, /* Pollable event occurred (System V). */
|
|
||||||
"IO", SIGIO, /* I/O now possible (4.2 BSD). */
|
|
||||||
"PWR", SIGPWR, /* Power failure restart (System V). */
|
|
||||||
#ifdef SIGSYS
|
|
||||||
"SYS", SIGSYS /* Bad system call. Only on some Linuxen! */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
|
||||||
|
|
||||||
/* find and return the named signal's number */
|
|
||||||
|
|
||||||
for(uint i=0; i<ARRAY_SIZE(siglabels); i++)
|
|
||||||
if(!strcmp(name, siglabels[i].name))
|
|
||||||
return siglabels[i].number;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
JVM_END
|
|
||||||
|
|
||||||
// used by os::exception_name()
|
|
||||||
extern bool signal_name(int signo, char* buf, size_t len) {
|
|
||||||
for(uint i = 0; i < ARRAY_SIZE(siglabels); i++) {
|
|
||||||
if (signo == siglabels[i].number) {
|
|
||||||
jio_snprintf(buf, len, "SIG%s", siglabels[i].name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -646,7 +646,7 @@ static void *java_start(Thread *thread) {
|
|||||||
int pid = os::current_process_id();
|
int pid = os::current_process_id();
|
||||||
alloca(((pid ^ counter++) & 7) * 128);
|
alloca(((pid ^ counter++) & 7) * 128);
|
||||||
|
|
||||||
ThreadLocalStorage::set_thread(thread);
|
thread->initialize_thread_current();
|
||||||
|
|
||||||
OSThread* osthread = thread->osthread();
|
OSThread* osthread = thread->osthread();
|
||||||
Monitor* sync = osthread->startThread_lock();
|
Monitor* sync = osthread->startThread_lock();
|
||||||
@ -873,43 +873,6 @@ void os::free_thread(OSThread* osthread) {
|
|||||||
delete osthread;
|
delete osthread;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// thread local storage
|
|
||||||
|
|
||||||
// Restore the thread pointer if the destructor is called. This is in case
|
|
||||||
// someone from JNI code sets up a destructor with pthread_key_create to run
|
|
||||||
// detachCurrentThread on thread death. Unless we restore the thread pointer we
|
|
||||||
// will hang or crash. When detachCurrentThread is called the key will be set
|
|
||||||
// to null and we will not be called again. If detachCurrentThread is never
|
|
||||||
// called we could loop forever depending on the pthread implementation.
|
|
||||||
static void restore_thread_pointer(void* p) {
|
|
||||||
Thread* thread = (Thread*) p;
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::allocate_thread_local_storage() {
|
|
||||||
pthread_key_t key;
|
|
||||||
int rslt = pthread_key_create(&key, restore_thread_pointer);
|
|
||||||
assert(rslt == 0, "cannot allocate thread local storage");
|
|
||||||
return (int)key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: This is currently not used by VM, as we don't destroy TLS key
|
|
||||||
// on VM exit.
|
|
||||||
void os::free_thread_local_storage(int index) {
|
|
||||||
int rslt = pthread_key_delete((pthread_key_t)index);
|
|
||||||
assert(rslt == 0, "invalid index");
|
|
||||||
}
|
|
||||||
|
|
||||||
void os::thread_local_storage_at_put(int index, void* value) {
|
|
||||||
int rslt = pthread_setspecific((pthread_key_t)index, value);
|
|
||||||
assert(rslt == 0, "pthread_setspecific failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" Thread* get_thread() {
|
|
||||||
return ThreadLocalStorage::thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// initial thread
|
// initial thread
|
||||||
|
|
||||||
@ -4570,8 +4533,12 @@ void os::Linux::check_signal_handler(int sig) {
|
|||||||
}
|
}
|
||||||
} else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) {
|
} else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) {
|
||||||
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
||||||
tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
|
tty->print("expected:");
|
||||||
tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
os::Posix::print_sa_flags(tty, os::Linux::get_our_sigflags(sig));
|
||||||
|
tty->cr();
|
||||||
|
tty->print(" found:");
|
||||||
|
os::Posix::print_sa_flags(tty, act.sa_flags);
|
||||||
|
tty->cr();
|
||||||
// No need to check this sig any longer
|
// No need to check this sig any longer
|
||||||
sigaddset(&check_signal_done, sig);
|
sigaddset(&check_signal_done, sig);
|
||||||
}
|
}
|
||||||
@ -4585,20 +4552,6 @@ void os::Linux::check_signal_handler(int sig) {
|
|||||||
extern void report_error(char* file_name, int line_no, char* title,
|
extern void report_error(char* file_name, int line_no, char* title,
|
||||||
char* format, ...);
|
char* format, ...);
|
||||||
|
|
||||||
extern bool signal_name(int signo, char* buf, size_t len);
|
|
||||||
|
|
||||||
const char* os::exception_name(int exception_code, char* buf, size_t size) {
|
|
||||||
if (0 < exception_code && exception_code <= SIGRTMAX) {
|
|
||||||
// signal
|
|
||||||
if (!signal_name(exception_code, buf, size)) {
|
|
||||||
jio_snprintf(buf, size, "SIG%d", exception_code);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is called _before_ the most of global arguments have been parsed
|
// this is called _before_ the most of global arguments have been parsed
|
||||||
void os::init(void) {
|
void os::init(void) {
|
||||||
char dummy; // used to get a guess on initial stack address
|
char dummy; // used to get a guess on initial stack address
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -34,10 +34,6 @@
|
|||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
inline void* os::thread_local_storage_at(int index) {
|
|
||||||
return pthread_getspecific((pthread_key_t)index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// File names are case-sensitive on windows only
|
// File names are case-sensitive on windows only
|
||||||
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
inline int os::file_name_strcmp(const char* s1, const char* s2) {
|
||||||
return strcmp(s1, s2);
|
return strcmp(s1, s2);
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002, 2011, 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 OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
|
|
||||||
#define OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
|
|
||||||
|
|
||||||
#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
|
|
||||||
#error "This file should only be included from thread.inline.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "runtime/thread.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Contains inlined functions for class Thread and ThreadLocalStorage
|
|
||||||
|
|
||||||
inline void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
|
|
||||||
|
|
||||||
#endif // OS_LINUX_VM_THREAD_LINUX_INLINE_HPP
|
|
@ -493,166 +493,171 @@ bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
|
|||||||
return interrupted;
|
return interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returned string is a constant. For unknown signals "UNKNOWN" is returned.
|
|
||||||
const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
int sig; const char* name;
|
static const struct {
|
||||||
}
|
int sig; const char* name;
|
||||||
info[] =
|
}
|
||||||
|
g_signal_info[] =
|
||||||
{
|
{
|
||||||
{ SIGABRT, "SIGABRT" },
|
{ SIGABRT, "SIGABRT" },
|
||||||
#ifdef SIGAIO
|
#ifdef SIGAIO
|
||||||
{ SIGAIO, "SIGAIO" },
|
{ SIGAIO, "SIGAIO" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGALRM, "SIGALRM" },
|
{ SIGALRM, "SIGALRM" },
|
||||||
#ifdef SIGALRM1
|
#ifdef SIGALRM1
|
||||||
{ SIGALRM1, "SIGALRM1" },
|
{ SIGALRM1, "SIGALRM1" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGBUS, "SIGBUS" },
|
{ SIGBUS, "SIGBUS" },
|
||||||
#ifdef SIGCANCEL
|
#ifdef SIGCANCEL
|
||||||
{ SIGCANCEL, "SIGCANCEL" },
|
{ SIGCANCEL, "SIGCANCEL" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGCHLD, "SIGCHLD" },
|
{ SIGCHLD, "SIGCHLD" },
|
||||||
#ifdef SIGCLD
|
#ifdef SIGCLD
|
||||||
{ SIGCLD, "SIGCLD" },
|
{ SIGCLD, "SIGCLD" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGCONT, "SIGCONT" },
|
{ SIGCONT, "SIGCONT" },
|
||||||
#ifdef SIGCPUFAIL
|
#ifdef SIGCPUFAIL
|
||||||
{ SIGCPUFAIL, "SIGCPUFAIL" },
|
{ SIGCPUFAIL, "SIGCPUFAIL" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGDANGER
|
#ifdef SIGDANGER
|
||||||
{ SIGDANGER, "SIGDANGER" },
|
{ SIGDANGER, "SIGDANGER" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGDIL
|
#ifdef SIGDIL
|
||||||
{ SIGDIL, "SIGDIL" },
|
{ SIGDIL, "SIGDIL" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGEMT
|
#ifdef SIGEMT
|
||||||
{ SIGEMT, "SIGEMT" },
|
{ SIGEMT, "SIGEMT" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGFPE, "SIGFPE" },
|
{ SIGFPE, "SIGFPE" },
|
||||||
#ifdef SIGFREEZE
|
#ifdef SIGFREEZE
|
||||||
{ SIGFREEZE, "SIGFREEZE" },
|
{ SIGFREEZE, "SIGFREEZE" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGGFAULT
|
#ifdef SIGGFAULT
|
||||||
{ SIGGFAULT, "SIGGFAULT" },
|
{ SIGGFAULT, "SIGGFAULT" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGGRANT
|
#ifdef SIGGRANT
|
||||||
{ SIGGRANT, "SIGGRANT" },
|
{ SIGGRANT, "SIGGRANT" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGHUP, "SIGHUP" },
|
{ SIGHUP, "SIGHUP" },
|
||||||
{ SIGILL, "SIGILL" },
|
{ SIGILL, "SIGILL" },
|
||||||
{ SIGINT, "SIGINT" },
|
{ SIGINT, "SIGINT" },
|
||||||
#ifdef SIGIO
|
#ifdef SIGIO
|
||||||
{ SIGIO, "SIGIO" },
|
{ SIGIO, "SIGIO" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGIOINT
|
#ifdef SIGIOINT
|
||||||
{ SIGIOINT, "SIGIOINT" },
|
{ SIGIOINT, "SIGIOINT" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGIOT
|
#ifdef SIGIOT
|
||||||
// SIGIOT is there for BSD compatibility, but on most Unices just a
|
// SIGIOT is there for BSD compatibility, but on most Unices just a
|
||||||
// synonym for SIGABRT. The result should be "SIGABRT", not
|
// synonym for SIGABRT. The result should be "SIGABRT", not
|
||||||
// "SIGIOT".
|
// "SIGIOT".
|
||||||
#if (SIGIOT != SIGABRT )
|
#if (SIGIOT != SIGABRT )
|
||||||
{ SIGIOT, "SIGIOT" },
|
{ SIGIOT, "SIGIOT" },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGKAP
|
#ifdef SIGKAP
|
||||||
{ SIGKAP, "SIGKAP" },
|
{ SIGKAP, "SIGKAP" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGKILL, "SIGKILL" },
|
{ SIGKILL, "SIGKILL" },
|
||||||
#ifdef SIGLOST
|
#ifdef SIGLOST
|
||||||
{ SIGLOST, "SIGLOST" },
|
{ SIGLOST, "SIGLOST" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGLWP
|
#ifdef SIGLWP
|
||||||
{ SIGLWP, "SIGLWP" },
|
{ SIGLWP, "SIGLWP" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGLWPTIMER
|
#ifdef SIGLWPTIMER
|
||||||
{ SIGLWPTIMER, "SIGLWPTIMER" },
|
{ SIGLWPTIMER, "SIGLWPTIMER" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGMIGRATE
|
#ifdef SIGMIGRATE
|
||||||
{ SIGMIGRATE, "SIGMIGRATE" },
|
{ SIGMIGRATE, "SIGMIGRATE" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGMSG
|
#ifdef SIGMSG
|
||||||
{ SIGMSG, "SIGMSG" },
|
{ SIGMSG, "SIGMSG" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGPIPE, "SIGPIPE" },
|
{ SIGPIPE, "SIGPIPE" },
|
||||||
#ifdef SIGPOLL
|
#ifdef SIGPOLL
|
||||||
{ SIGPOLL, "SIGPOLL" },
|
{ SIGPOLL, "SIGPOLL" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPRE
|
#ifdef SIGPRE
|
||||||
{ SIGPRE, "SIGPRE" },
|
{ SIGPRE, "SIGPRE" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGPROF, "SIGPROF" },
|
{ SIGPROF, "SIGPROF" },
|
||||||
#ifdef SIGPTY
|
#ifdef SIGPTY
|
||||||
{ SIGPTY, "SIGPTY" },
|
{ SIGPTY, "SIGPTY" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPWR
|
#ifdef SIGPWR
|
||||||
{ SIGPWR, "SIGPWR" },
|
{ SIGPWR, "SIGPWR" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGQUIT, "SIGQUIT" },
|
{ SIGQUIT, "SIGQUIT" },
|
||||||
#ifdef SIGRECONFIG
|
#ifdef SIGRECONFIG
|
||||||
{ SIGRECONFIG, "SIGRECONFIG" },
|
{ SIGRECONFIG, "SIGRECONFIG" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGRECOVERY
|
#ifdef SIGRECOVERY
|
||||||
{ SIGRECOVERY, "SIGRECOVERY" },
|
{ SIGRECOVERY, "SIGRECOVERY" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGRESERVE
|
#ifdef SIGRESERVE
|
||||||
{ SIGRESERVE, "SIGRESERVE" },
|
{ SIGRESERVE, "SIGRESERVE" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGRETRACT
|
#ifdef SIGRETRACT
|
||||||
{ SIGRETRACT, "SIGRETRACT" },
|
{ SIGRETRACT, "SIGRETRACT" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGSAK
|
#ifdef SIGSAK
|
||||||
{ SIGSAK, "SIGSAK" },
|
{ SIGSAK, "SIGSAK" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGSEGV, "SIGSEGV" },
|
{ SIGSEGV, "SIGSEGV" },
|
||||||
#ifdef SIGSOUND
|
#ifdef SIGSOUND
|
||||||
{ SIGSOUND, "SIGSOUND" },
|
{ SIGSOUND, "SIGSOUND" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGSTOP, "SIGSTOP" },
|
#ifdef SIGSTKFLT
|
||||||
{ SIGSYS, "SIGSYS" },
|
{ SIGSTKFLT, "SIGSTKFLT" },
|
||||||
|
#endif
|
||||||
|
{ SIGSTOP, "SIGSTOP" },
|
||||||
|
{ SIGSYS, "SIGSYS" },
|
||||||
#ifdef SIGSYSERROR
|
#ifdef SIGSYSERROR
|
||||||
{ SIGSYSERROR, "SIGSYSERROR" },
|
{ SIGSYSERROR, "SIGSYSERROR" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTALRM
|
#ifdef SIGTALRM
|
||||||
{ SIGTALRM, "SIGTALRM" },
|
{ SIGTALRM, "SIGTALRM" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGTERM, "SIGTERM" },
|
{ SIGTERM, "SIGTERM" },
|
||||||
#ifdef SIGTHAW
|
#ifdef SIGTHAW
|
||||||
{ SIGTHAW, "SIGTHAW" },
|
{ SIGTHAW, "SIGTHAW" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGTRAP, "SIGTRAP" },
|
{ SIGTRAP, "SIGTRAP" },
|
||||||
#ifdef SIGTSTP
|
#ifdef SIGTSTP
|
||||||
{ SIGTSTP, "SIGTSTP" },
|
{ SIGTSTP, "SIGTSTP" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGTTIN, "SIGTTIN" },
|
{ SIGTTIN, "SIGTTIN" },
|
||||||
{ SIGTTOU, "SIGTTOU" },
|
{ SIGTTOU, "SIGTTOU" },
|
||||||
#ifdef SIGURG
|
#ifdef SIGURG
|
||||||
{ SIGURG, "SIGURG" },
|
{ SIGURG, "SIGURG" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGUSR1, "SIGUSR1" },
|
{ SIGUSR1, "SIGUSR1" },
|
||||||
{ SIGUSR2, "SIGUSR2" },
|
{ SIGUSR2, "SIGUSR2" },
|
||||||
#ifdef SIGVIRT
|
#ifdef SIGVIRT
|
||||||
{ SIGVIRT, "SIGVIRT" },
|
{ SIGVIRT, "SIGVIRT" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGVTALRM, "SIGVTALRM" },
|
{ SIGVTALRM, "SIGVTALRM" },
|
||||||
#ifdef SIGWAITING
|
#ifdef SIGWAITING
|
||||||
{ SIGWAITING, "SIGWAITING" },
|
{ SIGWAITING, "SIGWAITING" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGWINCH
|
#ifdef SIGWINCH
|
||||||
{ SIGWINCH, "SIGWINCH" },
|
{ SIGWINCH, "SIGWINCH" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGWINDOW
|
#ifdef SIGWINDOW
|
||||||
{ SIGWINDOW, "SIGWINDOW" },
|
{ SIGWINDOW, "SIGWINDOW" },
|
||||||
#endif
|
#endif
|
||||||
{ SIGXCPU, "SIGXCPU" },
|
{ SIGXCPU, "SIGXCPU" },
|
||||||
{ SIGXFSZ, "SIGXFSZ" },
|
{ SIGXFSZ, "SIGXFSZ" },
|
||||||
#ifdef SIGXRES
|
#ifdef SIGXRES
|
||||||
{ SIGXRES, "SIGXRES" },
|
{ SIGXRES, "SIGXRES" },
|
||||||
#endif
|
#endif
|
||||||
{ -1, NULL }
|
{ -1, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returned string is a constant. For unknown signals "UNKNOWN" is returned.
|
||||||
|
const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
||||||
|
|
||||||
const char* ret = NULL;
|
const char* ret = NULL;
|
||||||
|
|
||||||
@ -670,9 +675,9 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sig > 0) {
|
if (sig > 0) {
|
||||||
for (int idx = 0; info[idx].sig != -1; idx ++) {
|
for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {
|
||||||
if (info[idx].sig == sig) {
|
if (g_signal_info[idx].sig == sig) {
|
||||||
ret = info[idx].name;
|
ret = g_signal_info[idx].name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,6 +698,25 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int os::Posix::get_signal_number(const char* signal_name) {
|
||||||
|
char tmp[30];
|
||||||
|
const char* s = signal_name;
|
||||||
|
if (s[0] != 'S' || s[1] != 'I' || s[2] != 'G') {
|
||||||
|
jio_snprintf(tmp, sizeof(tmp), "SIG%s", signal_name);
|
||||||
|
s = tmp;
|
||||||
|
}
|
||||||
|
for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {
|
||||||
|
if (strcmp(g_signal_info[idx].name, s) == 0) {
|
||||||
|
return g_signal_info[idx].sig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int os::get_signal_number(const char* signal_name) {
|
||||||
|
return os::Posix::get_signal_number(signal_name);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if signal number is valid.
|
// Returns true if signal number is valid.
|
||||||
bool os::Posix::is_valid_signal(int sig) {
|
bool os::Posix::is_valid_signal(int sig) {
|
||||||
// MacOS not really POSIX compliant: sigaddset does not return
|
// MacOS not really POSIX compliant: sigaddset does not return
|
||||||
@ -711,6 +735,21 @@ bool os::Posix::is_valid_signal(int sig) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns:
|
||||||
|
// "invalid (<num>)" for an invalid signal number
|
||||||
|
// "SIG<num>" for a valid but unknown signal number
|
||||||
|
// signal name otherwise.
|
||||||
|
const char* os::exception_name(int sig, char* buf, size_t size) {
|
||||||
|
if (!os::Posix::is_valid_signal(sig)) {
|
||||||
|
jio_snprintf(buf, size, "invalid (%d)", sig);
|
||||||
|
}
|
||||||
|
const char* const name = os::Posix::get_signal_name(sig, buf, size);
|
||||||
|
if (strcmp(name, "UNKNOWN") == 0) {
|
||||||
|
jio_snprintf(buf, size, "SIG%d", sig);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#define NUM_IMPORTANT_SIGS 32
|
#define NUM_IMPORTANT_SIGS 32
|
||||||
// Returns one-line short description of a signal set in a user provided buffer.
|
// Returns one-line short description of a signal set in a user provided buffer.
|
||||||
const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) {
|
const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) {
|
||||||
|
@ -51,6 +51,12 @@ public:
|
|||||||
// Returned string is a constant. For unknown signals "UNKNOWN" is returned.
|
// Returned string is a constant. For unknown signals "UNKNOWN" is returned.
|
||||||
static const char* get_signal_name(int sig, char* out, size_t outlen);
|
static const char* get_signal_name(int sig, char* out, size_t outlen);
|
||||||
|
|
||||||
|
// Helper function, returns a signal number for a given signal name, e.g. 11
|
||||||
|
// for "SIGSEGV". Name can be given with or without "SIG" prefix, so both
|
||||||
|
// "SEGV" or "SIGSEGV" work. Name must be uppercase.
|
||||||
|
// Returns -1 for an unknown signal name.
|
||||||
|
static int get_signal_number(const char* signal_name);
|
||||||
|
|
||||||
// Returns one-line short description of a signal set in a user provided buffer.
|
// Returns one-line short description of a signal set in a user provided buffer.
|
||||||
static const char* describe_signal_set_short(const sigset_t* set, char* buffer, size_t size);
|
static const char* describe_signal_set_short(const sigset_t* set, char* buffer, size_t size);
|
||||||
|
|
||||||
|
68
hotspot/src/os/posix/vm/threadLocalStorage_posix.cpp
Normal file
68
hotspot/src/os/posix/vm/threadLocalStorage_posix.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, 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 "runtime/threadLocalStorage.hpp"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
static pthread_key_t _thread_key;
|
||||||
|
static bool _initialized = false;
|
||||||
|
|
||||||
|
// Restore the thread pointer if the destructor is called. This is in case
|
||||||
|
// someone from JNI code sets up a destructor with pthread_key_create to run
|
||||||
|
// detachCurrentThread on thread death. Unless we restore the thread pointer we
|
||||||
|
// will hang or crash. When detachCurrentThread is called the key will be set
|
||||||
|
// to null and we will not be called again. If detachCurrentThread is never
|
||||||
|
// called we could loop forever depending on the pthread implementation.
|
||||||
|
extern "C" void restore_thread_pointer(void* p) {
|
||||||
|
ThreadLocalStorage::set_thread((Thread*) p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadLocalStorage::init() {
|
||||||
|
assert(!_initialized, "initializing TLS more than once!");
|
||||||
|
int rslt = pthread_key_create(&_thread_key, restore_thread_pointer);
|
||||||
|
// If this assert fails we will get a recursive assertion failure
|
||||||
|
// and not see the actual error message or get a hs_err file
|
||||||
|
assert_status(rslt == 0, rslt, "pthread_key_create");
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadLocalStorage::is_initialized() {
|
||||||
|
return _initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread* ThreadLocalStorage::thread() {
|
||||||
|
// If this assert fails we will get a recursive assertion failure
|
||||||
|
// and not see the actual error message or get a hs_err file.
|
||||||
|
// Which most likely indicates we have taken an error path early in
|
||||||
|
// the initialization process, which is using Thread::current without
|
||||||
|
// checking TLS is initialized - see java.cpp vm_exit
|
||||||
|
assert(_initialized, "TLS not initialized yet!");
|
||||||
|
return (Thread*) pthread_getspecific(_thread_key); // may be NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadLocalStorage::set_thread(Thread* current) {
|
||||||
|
assert(_initialized, "TLS not initialized yet!");
|
||||||
|
int rslt = pthread_setspecific(_thread_key, current);
|
||||||
|
assert_status(rslt == 0, rslt, "pthread_setspecific");
|
||||||
|
}
|
@ -106,40 +106,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
|||||||
return JNI_TRUE;
|
return JNI_TRUE;
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
All the defined signal names for Solaris are defined by str2sig().
|
|
||||||
|
|
||||||
NOTE that not all of these names are accepted by our Java implementation
|
|
||||||
|
|
||||||
Via an existing claim by the VM, sigaction restrictions, or
|
|
||||||
the "rules of Unix" some of these names will be rejected at runtime.
|
|
||||||
For example the VM sets up to handle USR1, sigaction returns EINVAL for
|
|
||||||
CANCEL, and Solaris simply doesn't allow catching of KILL.
|
|
||||||
|
|
||||||
Here are the names currently accepted by a user of sun.misc.Signal with
|
|
||||||
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
|
||||||
|
|
||||||
HUP, INT, TRAP, IOT, ABRT, EMT, BUS, SYS, PIPE, ALRM, TERM, USR2,
|
|
||||||
CLD, CHLD, PWR, WINCH, URG, POLL, IO, TSTP, CONT, TTIN, TTOU, VTALRM,
|
|
||||||
PROF, XCPU, XFSZ, FREEZE, THAW, LOST
|
|
||||||
*/
|
|
||||||
|
|
||||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
|
||||||
|
|
||||||
int sig;
|
|
||||||
|
|
||||||
/* return the named signal's number */
|
|
||||||
|
|
||||||
if(str2sig(name, &sig))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return sig;
|
|
||||||
|
|
||||||
JVM_END
|
|
||||||
|
|
||||||
|
|
||||||
//Reconciliation History
|
|
||||||
// 1.4 98/10/07 13:39:41 jvm_win32.cpp
|
|
||||||
// 1.6 99/06/22 16:39:00 jvm_win32.cpp
|
|
||||||
//End
|
|
||||||
|
@ -728,6 +728,9 @@ extern "C" void* java_start(void* thread_addr) {
|
|||||||
|
|
||||||
int prio;
|
int prio;
|
||||||
Thread* thread = (Thread*)thread_addr;
|
Thread* thread = (Thread*)thread_addr;
|
||||||
|
|
||||||
|
thread->initialize_thread_current();
|
||||||
|
|
||||||
OSThread* osthr = thread->osthread();
|
OSThread* osthr = thread->osthread();
|
||||||
|
|
||||||
osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound
|
osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound
|
||||||
@ -4055,8 +4058,12 @@ void os::Solaris::check_signal_handler(int sig) {
|
|||||||
}
|
}
|
||||||
} else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
|
} else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
|
||||||
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
|
||||||
tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig));
|
tty->print("expected:");
|
||||||
tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
os::Posix::print_sa_flags(tty, os::Solaris::get_our_sigflags(sig));
|
||||||
|
tty->cr();
|
||||||
|
tty->print(" found:");
|
||||||
|
os::Posix::print_sa_flags(tty, act.sa_flags);
|
||||||
|
tty->cr();
|
||||||
// No need to check this sig any longer
|
// No need to check this sig any longer
|
||||||
sigaddset(&check_signal_done, sig);
|
sigaddset(&check_signal_done, sig);
|
||||||
}
|
}
|
||||||
@ -4144,32 +4151,6 @@ void os::Solaris::install_signal_handlers() {
|
|||||||
void report_error(const char* file_name, int line_no, const char* title,
|
void report_error(const char* file_name, int line_no, const char* title,
|
||||||
const char* format, ...);
|
const char* format, ...);
|
||||||
|
|
||||||
const char * signames[] = {
|
|
||||||
"SIG0",
|
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
|
|
||||||
"SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS",
|
|
||||||
"SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM",
|
|
||||||
"SIGUSR1", "SIGUSR2", "SIGCLD", "SIGPWR", "SIGWINCH",
|
|
||||||
"SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
|
|
||||||
"SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
|
|
||||||
"SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
|
|
||||||
"SIGCANCEL", "SIGLOST"
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* os::exception_name(int exception_code, char* buf, size_t size) {
|
|
||||||
if (0 < exception_code && exception_code <= SIGRTMAX) {
|
|
||||||
// signal
|
|
||||||
if (exception_code < sizeof(signames)/sizeof(const char*)) {
|
|
||||||
jio_snprintf(buf, size, "%s", signames[exception_code]);
|
|
||||||
} else {
|
|
||||||
jio_snprintf(buf, size, "SIG%d", exception_code);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Static) wrapper for getisax(2) call.
|
// (Static) wrapper for getisax(2) call.
|
||||||
os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
|
os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
|
||||||
|
|
||||||
@ -5605,7 +5586,7 @@ int os::fork_and_exec(char* cmd) {
|
|||||||
|
|
||||||
// fork is async-safe, fork1 is not so can't use in signal handler
|
// fork is async-safe, fork1 is not so can't use in signal handler
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
if (t != NULL && t->is_inside_signal_handler()) {
|
if (t != NULL && t->is_inside_signal_handler()) {
|
||||||
pid = fork();
|
pid = fork();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002, 2015, 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 OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
|
|
||||||
#define OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
|
|
||||||
|
|
||||||
#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
|
|
||||||
#error "This file should only be included from thread.inline.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "runtime/thread.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Thread::current is "hot" it's called > 128K times in the 1st 500 msecs of
|
|
||||||
// startup.
|
|
||||||
// ThreadLocalStorage::thread is warm -- it's called > 16K times in the same
|
|
||||||
// period. Thread::current() now calls ThreadLocalStorage::thread() directly.
|
|
||||||
// For SPARC, to avoid excessive register window spill-fill faults,
|
|
||||||
// we aggressively inline these routines.
|
|
||||||
|
|
||||||
inline void ThreadLocalStorage::set_thread(Thread* thread) {
|
|
||||||
_thr_current = thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Thread* ThreadLocalStorage::thread() {
|
|
||||||
return _thr_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
|
|
@ -89,39 +89,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
|||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
All the defined signal names for Windows.
|
|
||||||
|
|
||||||
NOTE that not all of these names are accepted by FindSignal!
|
|
||||||
|
|
||||||
For various reasons some of these may be rejected at runtime.
|
|
||||||
|
|
||||||
Here are the names currently accepted by a user of sun.misc.Signal with
|
|
||||||
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
|
||||||
|
|
||||||
(LIST TBD)
|
|
||||||
|
|
||||||
*/
|
|
||||||
struct siglabel {
|
|
||||||
char *name;
|
|
||||||
int number;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct siglabel siglabels[] =
|
|
||||||
/* derived from version 6.0 VC98/include/signal.h */
|
|
||||||
{"ABRT", SIGABRT, /* abnormal termination triggered by abort cl */
|
|
||||||
"FPE", SIGFPE, /* floating point exception */
|
|
||||||
"SEGV", SIGSEGV, /* segment violation */
|
|
||||||
"INT", SIGINT, /* interrupt */
|
|
||||||
"TERM", SIGTERM, /* software term signal from kill */
|
|
||||||
"BREAK", SIGBREAK, /* Ctrl-Break sequence */
|
|
||||||
"ILL", SIGILL}; /* illegal instruction */
|
|
||||||
|
|
||||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
|
||||||
/* find and return the named signal's number */
|
|
||||||
|
|
||||||
for(int i=0;i<sizeof(siglabels)/sizeof(struct siglabel);i++)
|
|
||||||
if(!strcmp(name, siglabels[i].name))
|
|
||||||
return siglabels[i].number;
|
|
||||||
return -1;
|
|
||||||
JVM_END
|
|
||||||
|
@ -419,6 +419,8 @@ static unsigned __stdcall java_start(Thread* thread) {
|
|||||||
int pid = os::current_process_id();
|
int pid = os::current_process_id();
|
||||||
_alloca(((pid ^ counter++) & 7) * 128);
|
_alloca(((pid ^ counter++) & 7) * 128);
|
||||||
|
|
||||||
|
thread->initialize_thread_current();
|
||||||
|
|
||||||
OSThread* osthr = thread->osthread();
|
OSThread* osthr = thread->osthread();
|
||||||
assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
|
assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
|
||||||
|
|
||||||
@ -1799,24 +1801,32 @@ void os::print_memory_info(outputStream* st) {
|
|||||||
void os::print_siginfo(outputStream *st, void *siginfo) {
|
void os::print_siginfo(outputStream *st, void *siginfo) {
|
||||||
EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
|
EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
|
||||||
st->print("siginfo:");
|
st->print("siginfo:");
|
||||||
st->print(" ExceptionCode=0x%x", er->ExceptionCode);
|
|
||||||
|
|
||||||
if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
|
char tmp[64];
|
||||||
er->NumberParameters >= 2) {
|
if (os::exception_name(er->ExceptionCode, tmp, sizeof(tmp)) == NULL) {
|
||||||
|
strcpy(tmp, "EXCEPTION_??");
|
||||||
|
}
|
||||||
|
st->print(" %s (0x%x)", tmp, er->ExceptionCode);
|
||||||
|
|
||||||
|
if ((er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
|
||||||
|
er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) &&
|
||||||
|
er->NumberParameters >= 2) {
|
||||||
switch (er->ExceptionInformation[0]) {
|
switch (er->ExceptionInformation[0]) {
|
||||||
case 0: st->print(", reading address"); break;
|
case 0: st->print(", reading address"); break;
|
||||||
case 1: st->print(", writing address"); break;
|
case 1: st->print(", writing address"); break;
|
||||||
|
case 8: st->print(", data execution prevention violation at address"); break;
|
||||||
default: st->print(", ExceptionInformation=" INTPTR_FORMAT,
|
default: st->print(", ExceptionInformation=" INTPTR_FORMAT,
|
||||||
er->ExceptionInformation[0]);
|
er->ExceptionInformation[0]);
|
||||||
}
|
}
|
||||||
st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);
|
st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);
|
||||||
} else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR &&
|
|
||||||
er->NumberParameters >= 2 && UseSharedSpaces) {
|
if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && UseSharedSpaces) {
|
||||||
FileMapInfo* mapinfo = FileMapInfo::current_info();
|
FileMapInfo* mapinfo = FileMapInfo::current_info();
|
||||||
if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
|
if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
|
||||||
st->print("\n\nError accessing class data sharing archive." \
|
st->print("\n\nError accessing class data sharing archive." \
|
||||||
" Mapped file inaccessible during execution, " \
|
" Mapped file inaccessible during execution, " \
|
||||||
" possible disk/network problem.");
|
" possible disk/network problem.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int num = er->NumberParameters;
|
int num = er->NumberParameters;
|
||||||
@ -2146,7 +2156,7 @@ int os::signal_wait() {
|
|||||||
|
|
||||||
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
|
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
|
||||||
address handler) {
|
address handler) {
|
||||||
JavaThread* thread = JavaThread::current();
|
JavaThread* thread = (JavaThread*) Thread::current_or_null();
|
||||||
// Save pc in thread
|
// Save pc in thread
|
||||||
#ifdef _M_IA64
|
#ifdef _M_IA64
|
||||||
// Do not blow up if no thread info available.
|
// Do not blow up if no thread info available.
|
||||||
@ -2384,7 +2394,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
|||||||
address pc = (address) exceptionInfo->ContextRecord->Eip;
|
address pc = (address) exceptionInfo->ContextRecord->Eip;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Handle SafeFetch32 and SafeFetchN exceptions.
|
// Handle SafeFetch32 and SafeFetchN exceptions.
|
||||||
if (StubRoutines::is_safefetch_fault(pc)) {
|
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||||
@ -4011,27 +4021,6 @@ bool os::message_box(const char* title, const char* message) {
|
|||||||
return result == IDYES;
|
return result == IDYES;
|
||||||
}
|
}
|
||||||
|
|
||||||
int os::allocate_thread_local_storage() {
|
|
||||||
return TlsAlloc();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void os::free_thread_local_storage(int index) {
|
|
||||||
TlsFree(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void os::thread_local_storage_at_put(int index, void* value) {
|
|
||||||
TlsSetValue(index, value);
|
|
||||||
assert(thread_local_storage_at(index) == value, "Just checking");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void* os::thread_local_storage_at(int index) {
|
|
||||||
return TlsGetValue(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
// Helpers to check whether NX protection is enabled
|
// Helpers to check whether NX protection is enabled
|
||||||
@ -4079,6 +4068,9 @@ void os::init(void) {
|
|||||||
fatal("DuplicateHandle failed\n");
|
fatal("DuplicateHandle failed\n");
|
||||||
}
|
}
|
||||||
main_thread_id = (int) GetCurrentThreadId();
|
main_thread_id = (int) GetCurrentThreadId();
|
||||||
|
|
||||||
|
// initialize fast thread access - only used for 32-bit
|
||||||
|
win32::initialize_thread_ptr_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// To install functions for atexit processing
|
// To install functions for atexit processing
|
||||||
@ -5177,9 +5169,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaThread* thread = (JavaThread*)(Thread::current());
|
JavaThread* thread = JavaThread::current();
|
||||||
assert(thread->is_Java_thread(), "Must be JavaThread");
|
|
||||||
JavaThread *jt = (JavaThread *)thread;
|
|
||||||
|
|
||||||
// Don't wait if interrupted or already triggered
|
// Don't wait if interrupted or already triggered
|
||||||
if (Thread::is_interrupted(thread, false) ||
|
if (Thread::is_interrupted(thread, false) ||
|
||||||
@ -5187,16 +5177,16 @@ void Parker::park(bool isAbsolute, jlong time) {
|
|||||||
ResetEvent(_ParkEvent);
|
ResetEvent(_ParkEvent);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
ThreadBlockInVM tbivm(jt);
|
ThreadBlockInVM tbivm(thread);
|
||||||
OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
|
OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
|
||||||
jt->set_suspend_equivalent();
|
thread->set_suspend_equivalent();
|
||||||
|
|
||||||
WaitForSingleObject(_ParkEvent, time);
|
WaitForSingleObject(_ParkEvent, time);
|
||||||
ResetEvent(_ParkEvent);
|
ResetEvent(_ParkEvent);
|
||||||
|
|
||||||
// If externally suspended while waiting, re-suspend
|
// If externally suspended while waiting, re-suspend
|
||||||
if (jt->handle_special_suspend_equivalent_condition()) {
|
if (thread->handle_special_suspend_equivalent_condition()) {
|
||||||
jt->java_suspend_self();
|
thread->java_suspend_self();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5299,7 +5289,7 @@ LONG WINAPI os::win32::serialize_fault_filter(struct _EXCEPTION_POINTERS* e) {
|
|||||||
DWORD exception_code = e->ExceptionRecord->ExceptionCode;
|
DWORD exception_code = e->ExceptionRecord->ExceptionCode;
|
||||||
|
|
||||||
if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
|
if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
|
||||||
JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
|
JavaThread* thread = JavaThread::current();
|
||||||
PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
|
PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
|
||||||
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
||||||
|
|
||||||
@ -6033,3 +6023,48 @@ void TestReserveMemorySpecial_test() {
|
|||||||
UseNUMAInterleaving = old_use_numa_interleaving;
|
UseNUMAInterleaving = old_use_numa_interleaving;
|
||||||
}
|
}
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
||||||
|
/*
|
||||||
|
All the defined signal names for Windows.
|
||||||
|
|
||||||
|
NOTE that not all of these names are accepted by FindSignal!
|
||||||
|
|
||||||
|
For various reasons some of these may be rejected at runtime.
|
||||||
|
|
||||||
|
Here are the names currently accepted by a user of sun.misc.Signal with
|
||||||
|
1.4.1 (ignoring potential interaction with use of chaining, etc):
|
||||||
|
|
||||||
|
(LIST TBD)
|
||||||
|
|
||||||
|
*/
|
||||||
|
int os::get_signal_number(const char* name) {
|
||||||
|
static const struct {
|
||||||
|
char* name;
|
||||||
|
int number;
|
||||||
|
} siglabels [] =
|
||||||
|
// derived from version 6.0 VC98/include/signal.h
|
||||||
|
{"ABRT", SIGABRT, // abnormal termination triggered by abort cl
|
||||||
|
"FPE", SIGFPE, // floating point exception
|
||||||
|
"SEGV", SIGSEGV, // segment violation
|
||||||
|
"INT", SIGINT, // interrupt
|
||||||
|
"TERM", SIGTERM, // software term signal from kill
|
||||||
|
"BREAK", SIGBREAK, // Ctrl-Break sequence
|
||||||
|
"ILL", SIGILL}; // illegal instruction
|
||||||
|
for(int i=0;i<sizeof(siglabels)/sizeof(struct siglabel);i++)
|
||||||
|
if(!strcmp(name, siglabels[i].name))
|
||||||
|
return siglabels[i].number;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast current thread access
|
||||||
|
|
||||||
|
int os::win32::_thread_ptr_offset = 0;
|
||||||
|
|
||||||
|
static void call_wrapper_dummy() {}
|
||||||
|
|
||||||
|
// We need to call the os_exception_wrapper once so that it sets
|
||||||
|
// up the offset from FS of the thread pointer.
|
||||||
|
void os::win32::initialize_thread_ptr_offset() {
|
||||||
|
os::os_exception_wrapper((java_call_t)call_wrapper_dummy,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
@ -117,6 +117,17 @@ class win32 {
|
|||||||
|
|
||||||
// filter function to ignore faults on serializations page
|
// filter function to ignore faults on serializations page
|
||||||
static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
|
static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
|
||||||
|
|
||||||
|
// Fast access to current thread
|
||||||
|
protected:
|
||||||
|
static int _thread_ptr_offset;
|
||||||
|
private:
|
||||||
|
static void initialize_thread_ptr_offset();
|
||||||
|
public:
|
||||||
|
static inline void set_thread_ptr_offset(int offset) {
|
||||||
|
_thread_ptr_offset = offset;
|
||||||
|
}
|
||||||
|
static inline int get_thread_ptr_offset() { return _thread_ptr_offset; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
63
hotspot/src/os/windows/vm/threadLocalStorage_windows.cpp
Normal file
63
hotspot/src/os/windows/vm/threadLocalStorage_windows.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, 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 "runtime/threadLocalStorage.hpp"
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static DWORD _thread_key;
|
||||||
|
static bool _initialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
void ThreadLocalStorage::init() {
|
||||||
|
assert(!_initialized, "initializing TLS more than once!");
|
||||||
|
_thread_key = TlsAlloc();
|
||||||
|
// If this assert fails we will get a recursive assertion failure
|
||||||
|
// and not see the actual error message or get a hs_err file
|
||||||
|
assert(_thread_key != TLS_OUT_OF_INDEXES, "TlsAlloc failed: out of indices");
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadLocalStorage::is_initialized() {
|
||||||
|
return _initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread* ThreadLocalStorage::thread() {
|
||||||
|
// If this assert fails we will get a recursive assertion failure
|
||||||
|
// and not see the actual error message or get a hs_err file.
|
||||||
|
// Which most likely indicates we have taken an error path early in
|
||||||
|
// the initialization process, which is using Thread::current without
|
||||||
|
// checking TLS is initialized - see java.cpp vm_exit
|
||||||
|
assert(_initialized, "TLS not initialized yet!");
|
||||||
|
Thread* current = (Thread*) TlsGetValue(_thread_key);
|
||||||
|
assert(current != 0 || GetLastError() == ERROR_SUCCESS,
|
||||||
|
"TlsGetValue failed with error code: %lu", GetLastError());
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadLocalStorage::set_thread(Thread* current) {
|
||||||
|
assert(_initialized, "TLS not initialized yet!");
|
||||||
|
BOOL res = TlsSetValue(_thread_key, current);
|
||||||
|
assert(res, "TlsSetValue failed with error code: %lu", GetLastError());
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2002, 2010, 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 OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
|
|
||||||
#define OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
|
|
||||||
|
|
||||||
#ifndef SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE
|
|
||||||
#error "This file should only be included from thread.inline.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "runtime/thread.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Contains inlined functions for class Thread and ThreadLocalStorage
|
|
||||||
|
|
||||||
inline void ThreadLocalStorage::pd_invalidate_all() { return; }
|
|
||||||
|
|
||||||
#endif // OS_WINDOWS_VM_THREAD_WINDOWS_INLINE_HPP
|
|
@ -28,6 +28,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -167,7 +168,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
|||||||
|
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
SignalHandlerMark shm(t);
|
SignalHandlerMark shm(t);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -35,8 +35,7 @@
|
|||||||
/******************************/ \
|
/******************************/ \
|
||||||
/* Threads (NOTE: incomplete) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
nonstatic_field(OSThread, _thread_id, pid_t) \
|
nonstatic_field(OSThread, _thread_id, pthread_t) \
|
||||||
nonstatic_field(OSThread, _pthread_id, pthread_t)
|
|
||||||
|
|
||||||
|
|
||||||
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
|
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
|
||||||
@ -45,7 +44,6 @@
|
|||||||
/* Posix Thread IDs */ \
|
/* Posix Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_integer_type(pid_t) \
|
|
||||||
declare_unsigned_integer_type(pthread_t)
|
declare_unsigned_integer_type(pthread_t)
|
||||||
|
|
||||||
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,62 +26,7 @@
|
|||||||
#include "asm/macroAssembler.hpp"
|
#include "asm/macroAssembler.hpp"
|
||||||
#include "asm/macroAssembler.inline.hpp"
|
#include "asm/macroAssembler.inline.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
#ifndef _LP64
|
|
||||||
void MacroAssembler::int3() {
|
void MacroAssembler::int3() {
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
movl(thread, rsp);
|
|
||||||
shrl(thread, PAGE_SHIFT);
|
|
||||||
|
|
||||||
ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr());
|
|
||||||
Address index(noreg, thread, Address::times_4);
|
|
||||||
ArrayAddress tls(tls_base, index);
|
|
||||||
|
|
||||||
movptr(thread, tls);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void MacroAssembler::int3() {
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
// call pthread_getspecific
|
|
||||||
// void * pthread_getspecific(pthread_key_t key);
|
|
||||||
if (thread != rax) {
|
|
||||||
push(rax);
|
|
||||||
}
|
|
||||||
push(rdi);
|
|
||||||
push(rsi);
|
|
||||||
push(rdx);
|
|
||||||
push(rcx);
|
|
||||||
push(r8);
|
|
||||||
push(r9);
|
|
||||||
push(r10);
|
|
||||||
// XXX
|
|
||||||
mov(r10, rsp);
|
|
||||||
andq(rsp, -16);
|
|
||||||
push(r10);
|
|
||||||
push(r11);
|
|
||||||
|
|
||||||
movl(rdi, ThreadLocalStorage::thread_index());
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
|
|
||||||
|
|
||||||
pop(r11);
|
|
||||||
pop(rsp);
|
|
||||||
pop(r10);
|
|
||||||
pop(r9);
|
|
||||||
pop(r8);
|
|
||||||
pop(rcx);
|
|
||||||
pop(rdx);
|
|
||||||
pop(rsi);
|
|
||||||
pop(rdi);
|
|
||||||
if (thread != rax) {
|
|
||||||
mov(thread, rax);
|
|
||||||
pop(rax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -405,7 +406,7 @@ JVM_handle_bsd_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999, 2010, 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Map stack pointer (%esp) to thread pointer for faster TLS access
|
|
||||||
//
|
|
||||||
// Here we use a flat table for better performance. Getting current thread
|
|
||||||
// is down to one memory access (read _sp_map[%esp>>12]) in generated code
|
|
||||||
// and two in runtime code (-fPIC code needs an extra load for _sp_map).
|
|
||||||
//
|
|
||||||
// This code assumes stack page is not shared by different threads. It works
|
|
||||||
// in 32-bit VM when page size is 4K (or a multiple of 4K, if that matters).
|
|
||||||
//
|
|
||||||
// Notice that _sp_map is allocated in the bss segment, which is ZFOD
|
|
||||||
// (zero-fill-on-demand). While it reserves 4M address space upfront,
|
|
||||||
// actual memory pages are committed on demand.
|
|
||||||
//
|
|
||||||
// If an application creates and destroys a lot of threads, usually the
|
|
||||||
// stack space freed by a thread will soon get reused by new thread
|
|
||||||
// (this is especially true in NPTL or BsdThreads in fixed-stack mode).
|
|
||||||
// No memory page in _sp_map is wasted.
|
|
||||||
//
|
|
||||||
// However, it's still possible that we might end up populating &
|
|
||||||
// committing a large fraction of the 4M table over time, but the actual
|
|
||||||
// amount of live data in the table could be quite small. The max wastage
|
|
||||||
// is less than 4M bytes. If it becomes an issue, we could use madvise()
|
|
||||||
// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
|
|
||||||
// MADV_DONTNEED on Bsd keeps the virtual memory mapping, but zaps the
|
|
||||||
// physical memory page (i.e. similar to MADV_FREE on Solaris).
|
|
||||||
|
|
||||||
#ifndef AMD64
|
|
||||||
Thread* ThreadLocalStorage::_sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
|
|
||||||
#endif // !AMD64
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
|
||||||
// nothing we can do here for user-level thread
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
|
||||||
#ifndef AMD64
|
|
||||||
assert(align_size_down(os::vm_page_size(), PAGE_SIZE) == os::vm_page_size(),
|
|
||||||
"page size must be multiple of PAGE_SIZE");
|
|
||||||
#endif // !AMD64
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
|
|
||||||
#ifndef AMD64
|
|
||||||
address stack_top = os::current_stack_base();
|
|
||||||
size_t stack_size = os::current_stack_size();
|
|
||||||
|
|
||||||
for (address p = stack_top - stack_size; p < stack_top; p += PAGE_SIZE) {
|
|
||||||
// pd_set_thread() is called with non-NULL value when a new thread is
|
|
||||||
// created/attached, or with NULL value when a thread is about to exit.
|
|
||||||
// If both "thread" and the corresponding _sp_map[] entry are non-NULL,
|
|
||||||
// they should have the same value. Otherwise it might indicate that the
|
|
||||||
// stack page is shared by multiple threads. However, a more likely cause
|
|
||||||
// for this assertion to fail is that an attached thread exited without
|
|
||||||
// detaching itself from VM, which is a program error and could cause VM
|
|
||||||
// to crash.
|
|
||||||
assert(thread == NULL || _sp_map[(uintptr_t)p >> PAGE_SHIFT] == NULL ||
|
|
||||||
thread == _sp_map[(uintptr_t)p >> PAGE_SHIFT],
|
|
||||||
"thread exited without detaching from VM??");
|
|
||||||
_sp_map[(uintptr_t)p >> PAGE_SHIFT] = thread;
|
|
||||||
}
|
|
||||||
#endif // !AMD64
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999, 2010, 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 OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
|
|
||||||
#define OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
|
|
||||||
|
|
||||||
// Processor dependent parts of ThreadLocalStorage
|
|
||||||
|
|
||||||
#ifndef AMD64
|
|
||||||
// map stack pointer to thread pointer - see notes in threadLS_bsd_x86.cpp
|
|
||||||
#define SP_BITLENGTH 32
|
|
||||||
#ifndef PAGE_SHIFT
|
|
||||||
#define PAGE_SHIFT 12
|
|
||||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
|
||||||
#endif
|
|
||||||
static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
|
|
||||||
#endif // !AMD64
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
#ifndef AMD64
|
|
||||||
static Thread** sp_map_addr() { return _sp_map; }
|
|
||||||
#endif // !AMD64
|
|
||||||
|
|
||||||
static Thread* thread() {
|
|
||||||
#ifdef AMD64
|
|
||||||
return (Thread*) os::thread_local_storage_at(thread_index());
|
|
||||||
#else
|
|
||||||
uintptr_t sp;
|
|
||||||
__asm__ volatile ("movl %%esp, %0" : "=r" (sp));
|
|
||||||
return _sp_map[sp >> PAGE_SHIFT];
|
|
||||||
#endif // AMD64
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2009 Red Hat, Inc.
|
* Copyright 2009 Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -23,10 +23,4 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
|
||||||
#include "asm/assembler.hpp"
|
|
||||||
#include "assembler_zero.inline.hpp"
|
|
||||||
#include "runtime/os.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// This file is intentionally empty
|
// This file is intentionally empty
|
||||||
|
@ -134,7 +134,7 @@ JVM_handle_bsd_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
SignalHandlerMark shm(t);
|
SignalHandlerMark shm(t);
|
||||||
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* Copyright 2007 Red Hat, Inc.
|
|
||||||
* 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -23,32 +23,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
// nothing required here
|
||||||
#include "asm/macroAssembler.hpp"
|
|
||||||
#include "asm/macroAssembler.inline.hpp"
|
|
||||||
#include "runtime/os.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
// get_thread can be called anywhere inside generated code so we need
|
|
||||||
// to save whatever non-callee save context might get clobbered by the
|
|
||||||
// call to the C thread_local lookup call or, indeed, the call setup
|
|
||||||
// code. x86 appears to save C arg registers.
|
|
||||||
|
|
||||||
void MacroAssembler::get_thread(Register dst) {
|
|
||||||
// call pthread_getspecific
|
|
||||||
// void * pthread_getspecific(pthread_key_t key);
|
|
||||||
|
|
||||||
// Save all call-clobbered regs except dst, plus r19 and r20.
|
|
||||||
RegSet saved_regs = RegSet::range(r0, r20) + lr - dst;
|
|
||||||
push(saved_regs, sp);
|
|
||||||
mov(c_rarg0, ThreadLocalStorage::thread_index());
|
|
||||||
mov(r19, CAST_FROM_FN_PTR(address, pthread_getspecific));
|
|
||||||
blrt(r19, 1, 0, 1);
|
|
||||||
if (dst != c_rarg0) {
|
|
||||||
mov(dst, c_rarg0);
|
|
||||||
}
|
|
||||||
// restore pushed registers
|
|
||||||
pop(saved_regs, sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "code/nativeInst.hpp"
|
#include "code/nativeInst.hpp"
|
||||||
@ -249,7 +250,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* 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 OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
|
|
||||||
#define OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
|
|
||||||
|
|
||||||
// Processor dependent parts of ThreadLocalStorage
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static Thread *thread() {
|
|
||||||
return aarch64_currentThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
|
|
44
hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.s
Normal file
44
hotspot/src/os_cpu/linux_aarch64/vm/threadLS_linux_aarch64.s
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2015, Red Hat Inc. All rights reserved.
|
||||||
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
//
|
||||||
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// JavaThread::aarch64_get_thread_helper()
|
||||||
|
//
|
||||||
|
// Return the current thread pointer in x0.
|
||||||
|
// Clobber x1, flags.
|
||||||
|
// All other registers are preserved,
|
||||||
|
|
||||||
|
.global _ZN10JavaThread25aarch64_get_thread_helperEv
|
||||||
|
.type _ZN10JavaThread25aarch64_get_thread_helperEv, %function
|
||||||
|
|
||||||
|
_ZN10JavaThread25aarch64_get_thread_helperEv:
|
||||||
|
stp x29, x30, [sp, -16]!
|
||||||
|
adrp x0, :tlsdesc:_ZN6Thread12_thr_currentE
|
||||||
|
ldr x1, [x0, #:tlsdesc_lo12:_ZN6Thread12_thr_currentE]
|
||||||
|
add x0, x0, :tlsdesc_lo12:_ZN6Thread12_thr_currentE
|
||||||
|
.tlsdesccall _ZN6Thread12_thr_currentE
|
||||||
|
blr x1
|
||||||
|
mrs x1, tpidr_el0
|
||||||
|
add x0, x1, x0
|
||||||
|
ldr x0, [x0]
|
||||||
|
ldp x29, x30, [sp], 16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.size _ZN10JavaThread25aarch64_get_thread_helperEv, .-_ZN10JavaThread25aarch64_get_thread_helperEv
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -77,6 +77,8 @@ private:
|
|||||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static Thread *aarch64_get_thread_helper();
|
||||||
|
|
||||||
// These routines are only used on cpu architectures that
|
// These routines are only used on cpu architectures that
|
||||||
// have separate register stacks (Itanium).
|
// have separate register stacks (Itanium).
|
||||||
static bool register_stack_overflow() { return false; }
|
static bool register_stack_overflow() { return false; }
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -182,7 +183,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
SignalHandlerMark shm(t);
|
SignalHandlerMark shm(t);
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -347,9 +348,9 @@ address os::Linux::ucontext_get_pc(ucontext_t* uc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void os::Linux::ucontext_set_pc(ucontext_t* uc, address pc) {
|
void os::Linux::ucontext_set_pc(ucontext_t* uc, address pc) {
|
||||||
sigcontext_t* ctx = (sigcontext_t*) uc;
|
sigcontext* ctx = (sigcontext*) uc;
|
||||||
SIG_PC(ctx) = (intptr_t)addr;
|
SIG_PC(ctx) = (intptr_t)pc;
|
||||||
SIG_NPC(ctx) = (intptr_t)(addr+4);
|
SIG_NPC(ctx) = (intptr_t)(pc+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
|
intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) {
|
||||||
@ -541,7 +542,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
ucontext_t* ucFake = (ucontext_t*) ucVoid;
|
ucontext_t* ucFake = (ucontext_t*) ucVoid;
|
||||||
sigcontext* uc = (sigcontext*)ucVoid;
|
sigcontext* uc = (sigcontext*)ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
@ -695,6 +696,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
VMError::report_and_die(t, sig, pc, info, ucVoid);
|
VMError::report_and_die(t, sig, pc, info, ucVoid);
|
||||||
|
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Linux::init_thread_fpu_state(void) {
|
void os::Linux::init_thread_fpu_state(void) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,85 +26,7 @@
|
|||||||
#include "asm/macroAssembler.hpp"
|
#include "asm/macroAssembler.hpp"
|
||||||
#include "asm/macroAssembler.inline.hpp"
|
#include "asm/macroAssembler.inline.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
#ifndef _LP64
|
|
||||||
void MacroAssembler::int3() {
|
void MacroAssembler::int3() {
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MINIMIZE_RAM_USAGE
|
|
||||||
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
// call pthread_getspecific
|
|
||||||
// void * pthread_getspecific(pthread_key_t key);
|
|
||||||
if (thread != rax) push(rax);
|
|
||||||
push(rcx);
|
|
||||||
push(rdx);
|
|
||||||
|
|
||||||
push(ThreadLocalStorage::thread_index());
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
|
|
||||||
increment(rsp, wordSize);
|
|
||||||
|
|
||||||
pop(rdx);
|
|
||||||
pop(rcx);
|
|
||||||
if (thread != rax) {
|
|
||||||
mov(thread, rax);
|
|
||||||
pop(rax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
movl(thread, rsp);
|
|
||||||
shrl(thread, PAGE_SHIFT);
|
|
||||||
|
|
||||||
ExternalAddress tls_base((address)ThreadLocalStorage::sp_map_addr());
|
|
||||||
Address index(noreg, thread, Address::times_4);
|
|
||||||
ArrayAddress tls(tls_base, index);
|
|
||||||
|
|
||||||
movptr(thread, tls);
|
|
||||||
}
|
|
||||||
#endif // MINIMIZE_RAM_USAGE
|
|
||||||
#else
|
|
||||||
void MacroAssembler::int3() {
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
// call pthread_getspecific
|
|
||||||
// void * pthread_getspecific(pthread_key_t key);
|
|
||||||
if (thread != rax) {
|
|
||||||
push(rax);
|
|
||||||
}
|
|
||||||
push(rdi);
|
|
||||||
push(rsi);
|
|
||||||
push(rdx);
|
|
||||||
push(rcx);
|
|
||||||
push(r8);
|
|
||||||
push(r9);
|
|
||||||
push(r10);
|
|
||||||
// XXX
|
|
||||||
mov(r10, rsp);
|
|
||||||
andq(rsp, -16);
|
|
||||||
push(r10);
|
|
||||||
push(r11);
|
|
||||||
|
|
||||||
movl(rdi, ThreadLocalStorage::thread_index());
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, pthread_getspecific)));
|
|
||||||
|
|
||||||
pop(r11);
|
|
||||||
pop(rsp);
|
|
||||||
pop(r10);
|
|
||||||
pop(r9);
|
|
||||||
pop(r8);
|
|
||||||
pop(rcx);
|
|
||||||
pop(rdx);
|
|
||||||
pop(rsi);
|
|
||||||
pop(rdi);
|
|
||||||
if (thread != rax) {
|
|
||||||
mov(thread, rax);
|
|
||||||
pop(rax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -221,7 +222,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999, 2015, 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// Map stack pointer (%esp) to thread pointer for faster TLS access
|
|
||||||
//
|
|
||||||
// Here we use a flat table for better performance. Getting current thread
|
|
||||||
// is down to one memory access (read _sp_map[%esp>>12]) in generated code
|
|
||||||
// and two in runtime code (-fPIC code needs an extra load for _sp_map).
|
|
||||||
//
|
|
||||||
// This code assumes stack page is not shared by different threads. It works
|
|
||||||
// in 32-bit VM when page size is 4K (or a multiple of 4K, if that matters).
|
|
||||||
//
|
|
||||||
// Notice that _sp_map is allocated in the bss segment, which is ZFOD
|
|
||||||
// (zero-fill-on-demand). While it reserves 4M address space upfront,
|
|
||||||
// actual memory pages are committed on demand.
|
|
||||||
//
|
|
||||||
// If an application creates and destroys a lot of threads, usually the
|
|
||||||
// stack space freed by a thread will soon get reused by new thread.
|
|
||||||
// No memory page in _sp_map is wasted.
|
|
||||||
//
|
|
||||||
// However, it's still possible that we might end up populating &
|
|
||||||
// committing a large fraction of the 4M table over time, but the actual
|
|
||||||
// amount of live data in the table could be quite small. The max wastage
|
|
||||||
// is less than 4M bytes. If it becomes an issue, we could use madvise()
|
|
||||||
// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
|
|
||||||
// MADV_DONTNEED on Linux keeps the virtual memory mapping, but zaps the
|
|
||||||
// physical memory page (i.e. similar to MADV_FREE on Solaris).
|
|
||||||
|
|
||||||
#if !defined(AMD64) && !defined(MINIMIZE_RAM_USAGE)
|
|
||||||
Thread* ThreadLocalStorage::_sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
|
||||||
// nothing we can do here for user-level thread
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
|
||||||
assert(align_size_down(os::vm_page_size(), PAGE_SIZE) == os::vm_page_size(),
|
|
||||||
"page size must be multiple of PAGE_SIZE");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
address stack_top = os::current_stack_base();
|
|
||||||
size_t stack_size = os::current_stack_size();
|
|
||||||
|
|
||||||
for (address p = stack_top - stack_size; p < stack_top; p += PAGE_SIZE) {
|
|
||||||
// pd_set_thread() is called with non-NULL value when a new thread is
|
|
||||||
// created/attached, or with NULL value when a thread is about to exit.
|
|
||||||
// If both "thread" and the corresponding _sp_map[] entry are non-NULL,
|
|
||||||
// they should have the same value. Otherwise it might indicate that the
|
|
||||||
// stack page is shared by multiple threads. However, a more likely cause
|
|
||||||
// for this assertion to fail is that an attached thread exited without
|
|
||||||
// detaching itself from VM, which is a program error and could cause VM
|
|
||||||
// to crash.
|
|
||||||
assert(thread == NULL || _sp_map[(uintptr_t)p >> PAGE_SHIFT] == NULL ||
|
|
||||||
thread == _sp_map[(uintptr_t)p >> PAGE_SHIFT],
|
|
||||||
"thread exited without detaching from VM??");
|
|
||||||
_sp_map[(uintptr_t)p >> PAGE_SHIFT] = thread;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
|
||||||
// nothing we can do here for user-level thread
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
||||||
#endif // !AMD64 && !MINIMIZE_RAM_USAGE
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1999, 2010, 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 OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
|
|
||||||
#define OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
|
|
||||||
|
|
||||||
// Processor dependent parts of ThreadLocalStorage
|
|
||||||
|
|
||||||
#if !defined(AMD64) && !defined(MINIMIZE_RAM_USAGE)
|
|
||||||
|
|
||||||
// map stack pointer to thread pointer - see notes in threadLS_linux_x86.cpp
|
|
||||||
#define SP_BITLENGTH 32
|
|
||||||
#define PAGE_SHIFT 12
|
|
||||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
|
||||||
static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static Thread** sp_map_addr() { return _sp_map; }
|
|
||||||
|
|
||||||
static Thread* thread() {
|
|
||||||
uintptr_t sp;
|
|
||||||
__asm__ volatile ("movl %%esp, %0" : "=r" (sp));
|
|
||||||
return _sp_map[sp >> PAGE_SHIFT];
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static Thread* thread() {
|
|
||||||
return (Thread*) os::thread_local_storage_at(thread_index());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // AMD64 || MINIMIZE_RAM_USAGE
|
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2009 Red Hat, Inc.
|
* Copyright 2009 Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -23,10 +23,4 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
|
||||||
#include "asm/assembler.hpp"
|
|
||||||
#include "assembler_zero.inline.hpp"
|
|
||||||
#include "runtime/os.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// This file is intentionally empty
|
// This file is intentionally empty
|
||||||
|
@ -125,7 +125,7 @@ JVM_handle_linux_signal(int sig,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
SignalHandlerMark shm(t);
|
SignalHandlerMark shm(t);
|
||||||
|
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* Copyright 2007 Red Hat, Inc.
|
|
||||||
* 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_init() {
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_set_thread(Thread* thread) {
|
|
||||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
|
||||||
}
|
|
@ -290,7 +290,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
|||||||
int abort_if_unrecognized) {
|
int abort_if_unrecognized) {
|
||||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
@ -551,6 +551,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
|||||||
VMError::report_and_die(t, sig, pc, info, ucVoid);
|
VMError::report_and_die(t, sig, pc, info, ucVoid);
|
||||||
|
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::print_context(outputStream *st, void *context) {
|
void os::print_context(outputStream *st, void *context) {
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998, 2015, 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// True thread-local variable
|
|
||||||
__thread Thread * ThreadLocalStorage::_thr_current = NULL;
|
|
||||||
|
|
||||||
// Implementations needed to support the shared API
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
|
|
||||||
|
|
||||||
bool ThreadLocalStorage::_initialized = false;
|
|
||||||
|
|
||||||
void ThreadLocalStorage::init() {
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadLocalStorage::is_initialized() {
|
|
||||||
return _initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread* ThreadLocalStorage::get_thread_slow() {
|
|
||||||
return thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" Thread* get_thread() {
|
|
||||||
return ThreadLocalStorage::thread();
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998, 2015, 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 OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
|
|
||||||
#define OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
|
|
||||||
|
|
||||||
// Solaris specific implementation involves simple, direct use
|
|
||||||
// of a compiler-based thread-local variable
|
|
||||||
|
|
||||||
private:
|
|
||||||
static __thread Thread * _thr_current;
|
|
||||||
|
|
||||||
static bool _initialized; // needed for shared API
|
|
||||||
|
|
||||||
public:
|
|
||||||
static inline Thread* thread();
|
|
||||||
|
|
||||||
#endif // OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
|
|
@ -25,8 +25,6 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "asm/macroAssembler.inline.hpp"
|
#include "asm/macroAssembler.inline.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
#include "runtime/thread.inline.hpp"
|
|
||||||
|
|
||||||
void MacroAssembler::int3() {
|
void MacroAssembler::int3() {
|
||||||
push(rax);
|
push(rax);
|
||||||
@ -37,33 +35,3 @@ void MacroAssembler::int3() {
|
|||||||
pop(rdx);
|
pop(rdx);
|
||||||
pop(rax);
|
pop(rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is simply a call to ThreadLocalStorage::thread()
|
|
||||||
void MacroAssembler::get_thread(Register thread) {
|
|
||||||
if (thread != rax) {
|
|
||||||
push(rax);
|
|
||||||
}
|
|
||||||
push(rdi);
|
|
||||||
push(rsi);
|
|
||||||
push(rdx);
|
|
||||||
push(rcx);
|
|
||||||
push(r8);
|
|
||||||
push(r9);
|
|
||||||
push(r10);
|
|
||||||
push(r11);
|
|
||||||
|
|
||||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, ThreadLocalStorage::thread)));
|
|
||||||
|
|
||||||
pop(r11);
|
|
||||||
pop(r10);
|
|
||||||
pop(r9);
|
|
||||||
pop(r8);
|
|
||||||
pop(rcx);
|
|
||||||
pop(rdx);
|
|
||||||
pop(rsi);
|
|
||||||
pop(rdi);
|
|
||||||
if (thread != rax) {
|
|
||||||
movl(thread, rax);
|
|
||||||
pop(rax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "classfile/classLoader.hpp"
|
#include "classfile/classLoader.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "classfile/vmSymbols.hpp"
|
#include "classfile/vmSymbols.hpp"
|
||||||
|
#include "code/codeCache.hpp"
|
||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -346,7 +347,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
|||||||
}
|
}
|
||||||
#endif // !AMD64
|
#endif // !AMD64
|
||||||
|
|
||||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
Thread* t = Thread::current_or_null_safe();
|
||||||
|
|
||||||
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
|
||||||
// (no destructors can be run)
|
// (no destructors can be run)
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 1998, 2015, 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 "runtime/thread.inline.hpp"
|
|
||||||
#include "runtime/threadLocalStorage.hpp"
|
|
||||||
|
|
||||||
// True thread-local variable
|
|
||||||
__thread Thread * ThreadLocalStorage::_thr_current = NULL;
|
|
||||||
|
|
||||||
// Implementations needed to support the shared API
|
|
||||||
|
|
||||||
void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
|
|
||||||
|
|
||||||
bool ThreadLocalStorage::_initialized = false;
|
|
||||||
|
|
||||||
void ThreadLocalStorage::init() {
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadLocalStorage::is_initialized() {
|
|
||||||
return _initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread* ThreadLocalStorage::get_thread_slow() {
|
|
||||||
return thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" Thread* get_thread() {
|
|
||||||
return ThreadLocalStorage::thread();
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user