Merge
This commit is contained in:
commit
46c02f0d3b
2
.hgtags
2
.hgtags
@ -340,3 +340,5 @@ f242d4332f563648426a1b0fa02d8741beba19ef jdk9-b92
|
||||
5ac6287ec71aafe021cc839d8bc828108d23aaba jdk-9+95
|
||||
139f19d70350238e15e107945cea75082b6380b3 jdk-9+96
|
||||
4edcff1b9a8875eb6380a2165dfec599e8e3f7c0 jdk-9+97
|
||||
d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98
|
||||
f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99
|
||||
|
@ -340,3 +340,5 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
|
||||
12a6fb4f070f8ca8fbca219ab9abf5da8908b317 jdk-9+95
|
||||
5582a79892596169ebddb3e2c2aa44939e4e3f40 jdk-9+96
|
||||
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
|
||||
|
||||
setup_url() {
|
||||
if [ -f "~/.config/jib/jib.conf" ]; then
|
||||
if [ -f ~/.config/jib/jib.conf ]; then
|
||||
source ~/.config/jib/jib.conf
|
||||
fi
|
||||
|
||||
@ -50,6 +50,9 @@ setup_url() {
|
||||
if [ -n "${JIB_SERVER}" ]; then
|
||||
jib_server="${JIB_SERVER}"
|
||||
fi
|
||||
if [ -n "${JIB_SERVER_MIRRORS}" ]; then
|
||||
jib_server_mirrors="${JIB_SERVER_MIRRORS}"
|
||||
fi
|
||||
if [ -n "${JIB_REPOSITORY}" ]; then
|
||||
jib_repository="${JIB_REPOSITORY}"
|
||||
fi
|
||||
@ -70,8 +73,9 @@ setup_url() {
|
||||
jib_url="${JIB_URL}"
|
||||
data_string="${jib_url}"
|
||||
else
|
||||
data_string="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
|
||||
jib_url="${jib_server}/${data_string}"
|
||||
jib_path="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
|
||||
data_string="${jib_path}"
|
||||
jib_url="${jib_server}/${jib_path}"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -104,7 +108,25 @@ install_jib() {
|
||||
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
|
||||
if [ ! -s "${installed_jib_script}.gz" ]; then
|
||||
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
|
||||
echo "Extracting JIB bootstrap script"
|
||||
rm -f "${installed_jib_script}"
|
||||
|
@ -340,3 +340,5 @@ f7d70caad89ad0c43bb057bca0aad6f17ce05a6a jdk9-b92
|
||||
fd038e8a16eec80d0d6b337d74a582790ed4b3ee jdk-9+95
|
||||
feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
|
||||
10a482b863582376d4ca229090334b23b05159fc jdk-9+97
|
||||
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
|
||||
180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
|
||||
|
@ -500,3 +500,5 @@ a22b7c80529f5f05c847e932e017456e83c46233 jdk9-b94
|
||||
0c79cf3cdf0904fc4a630b91b32904491e1ae430 jdk-9+95
|
||||
a94bb7203596dd632486f1e3655fa5f70541dc08 jdk-9+96
|
||||
de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
|
||||
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
|
||||
f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
|
||||
|
@ -1446,7 +1446,7 @@ public class CommandProcessor {
|
||||
if (type.equals("threads")) {
|
||||
Threads threads = VM.getVM().getThreads();
|
||||
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
||||
Address base = thread.getBaseOfStackPointer();
|
||||
Address base = thread.getStackBase();
|
||||
Address end = thread.getLastJavaSP();
|
||||
if (end == null) continue;
|
||||
if (end.lessThan(base)) {
|
||||
@ -1454,11 +1454,13 @@ public class CommandProcessor {
|
||||
base = end;
|
||||
end = tmp;
|
||||
}
|
||||
out.println("Searching " + base + " " + end);
|
||||
//out.println("Searching " + base + " " + end);
|
||||
while (base != null && base.lessThan(end)) {
|
||||
Address val = base.getAddressAt(0);
|
||||
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);
|
||||
}
|
||||
@ -1601,6 +1603,8 @@ public class CommandProcessor {
|
||||
thread.printThreadIDOn(new PrintStream(bos));
|
||||
if (all || bos.toString().equals(name)) {
|
||||
out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
|
||||
thread.printInfoOn(out);
|
||||
out.println(" ");
|
||||
if (!all) return;
|
||||
}
|
||||
}
|
||||
@ -1618,6 +1622,8 @@ public class CommandProcessor {
|
||||
for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
|
||||
thread.printThreadIDOn(out);
|
||||
out.println(" " + thread.getThreadName());
|
||||
thread.printInfoOn(out);
|
||||
out.println("\n...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ public class JavaThread extends Thread {
|
||||
} else {
|
||||
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_FP: " + getLastJavaFP());
|
||||
tty.println("Last_Java_PC: " + getLastJavaPC());
|
||||
|
@ -74,6 +74,9 @@ CFLAGS += $(VM_PICFLAG)
|
||||
CFLAGS += -qnortti
|
||||
CFLAGS += -qnoeh
|
||||
|
||||
# for compiler-level tls
|
||||
CFLAGS += -qtls=default
|
||||
|
||||
CFLAGS += -D_REENTRANT
|
||||
# no xlc counterpart for -fcheck-new
|
||||
# CFLAGS += -fcheck-new
|
||||
|
@ -71,7 +71,7 @@ else ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
-DSOLARIS_11_B159_OR_LATER
|
||||
SA_CFLAGS := $(CFLAGS_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)
|
||||
SA_LIBS := -ldl -ldemangle -lthread -lc
|
||||
|
||||
|
@ -260,6 +260,13 @@ endif
|
||||
|
||||
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
|
||||
# if we use expensive-optimizations
|
||||
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.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -39,7 +39,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -259,20 +258,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
|
||||
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/interfaceSupport.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||
@ -4653,3 +4654,23 @@ void MacroAssembler::encode_iso_array(Register src, Register dst,
|
||||
BIND(DONE);
|
||||
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
|
||||
//
|
||||
// Output:
|
||||
// rax - input length
|
||||
// x0 - input length
|
||||
//
|
||||
address generate_cipherBlockChaining_decryptAESCrypt() {
|
||||
assert(UseAES, "need AES instructions and misaligned SSE support");
|
||||
@ -2035,7 +2035,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ br(Assembler::EQ, L_rounds_52);
|
||||
|
||||
__ aesd(v0, v17); __ aesimc(v0, v0);
|
||||
__ aesd(v0, v17); __ aesimc(v0, v0);
|
||||
__ aesd(v0, v18); __ aesimc(v0, v0);
|
||||
__ BIND(L_rounds_52);
|
||||
__ aesd(v0, v19); __ 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/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -61,26 +60,6 @@
|
||||
|
||||
#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() {
|
||||
// Slow_signature handler that respects the PPC C calling conventions.
|
||||
//
|
||||
@ -579,18 +558,3 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
|
||||
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 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,14 +28,17 @@
|
||||
|
||||
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");
|
||||
// if too small.
|
||||
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||
// Max size with JVMTI
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.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
|
||||
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
||||
address entry = __ pc();
|
||||
@ -254,28 +229,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
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
|
||||
// a hook for debugging
|
||||
static Thread* reinitialize_thread() {
|
||||
return ThreadLocalStorage::thread();
|
||||
return Thread::current();
|
||||
}
|
||||
#else
|
||||
#define reinitialize_thread ThreadLocalStorage::thread
|
||||
#define reinitialize_thread Thread::current
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -393,7 +393,7 @@ void MacroAssembler::get_thread() {
|
||||
}
|
||||
|
||||
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");
|
||||
return correct_value;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
inline void fill_subword(void* start, void* end, int value) {
|
||||
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).
|
||||
void* pc;
|
||||
__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]-2]\n\t"
|
||||
" stb %[value], [%[end]-1]\n\t" // end[-1] = value
|
||||
: /* no outputs */
|
||||
[pc] "&=r" (pc) // temp
|
||||
: [offset] "&+r" (start),
|
||||
[end] "r" (end),
|
||||
: /* only temporaries/overwritten outputs */
|
||||
[pc] "=&r" (pc), // temp
|
||||
[offset] "+&r" (start)
|
||||
: [end] "r" (end),
|
||||
[value] "r" (value)
|
||||
: "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) {
|
||||
Prefetch::write(to, 0);
|
||||
void* end = static_cast<char*>(to) + size;
|
||||
if (size >= BytesPerWord) {
|
||||
if (size >= (size_t)BytesPerWord) {
|
||||
// Fill any partial word prefix.
|
||||
uintx* aligned_to = static_cast<uintx*>(align_ptr_up(to, BytesPerWord));
|
||||
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]-16]\n\t"
|
||||
" stx %[xvalue], [%[aend]-8]\n\t" // aligned_end[-1] = xvalue
|
||||
: /* no outputs */
|
||||
[temp] "&=r" (temp)
|
||||
: [ato] "&+r" (aligned_to),
|
||||
[aend] "r" (aligned_end),
|
||||
: /* only temporaries/overwritten outputs */
|
||||
[temp] "=&r" (temp),
|
||||
[ato] "+&r" (aligned_to)
|
||||
: [aend] "r" (aligned_end),
|
||||
[xvalue] "r" (xvalue)
|
||||
: "cc", "memory");
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -433,7 +433,7 @@ void NativeMovConstReg32::verify() {
|
||||
|
||||
|
||||
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
|
||||
|
||||
Unimplemented();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -36,7 +36,7 @@ extern "C" {
|
||||
address _flush_reg_windows(); // in .s file.
|
||||
// Flush registers to stack. In case of error we will need to stack walk.
|
||||
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.
|
||||
if (thread != NULL) {
|
||||
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));
|
||||
// NULL last_sp until next java call
|
||||
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
|
||||
NOT_LP64(empty_FPU_stack());
|
||||
}
|
||||
|
||||
// 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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -184,20 +183,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -298,19 +297,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
||||
|
||||
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/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||
@ -10834,3 +10835,43 @@ SkipIfEqual::SkipIfEqual(
|
||||
SkipIfEqual::~SkipIfEqual() {
|
||||
_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.
|
||||
*
|
||||
* 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();
|
||||
}
|
||||
|
||||
#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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,8 @@
|
||||
#define __ _masm->
|
||||
|
||||
// Global Register Names
|
||||
Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
||||
Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
||||
static const Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
||||
static const Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
||||
|
||||
// Platform-dependent initialization
|
||||
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.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -74,7 +73,3 @@ address InterpreterGenerator::generate_abstract_entry() {
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
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.
|
||||
//
|
||||
// (Please keep the switches sorted alphabetically.)
|
||||
#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). */ \
|
||||
product(bool, Use64KPages, true, \
|
||||
"Use 64K pages if available.") \
|
||||
\
|
||||
/* If UseLargePages == true allow or deny usage of 16M pages. 16M pages are */ \
|
||||
/* a scarce resource and there may be situations where we do not want the VM */ \
|
||||
/* to run with 16M pages. (Will fall back to 64K pages). */ \
|
||||
product_pd(bool, Use16MPages, \
|
||||
"Use 16M pages if available.") \
|
||||
/* If VM uses 64K paged memory (shmat) for virtual memory: threshold below */ \
|
||||
/* which virtual memory allocations are done with 4K memory (mmap). This is */ \
|
||||
/* mainly for test purposes. */ \
|
||||
develop(uintx, Use64KPagesThreshold, 0, \
|
||||
"4K/64K page allocation threshold.") \
|
||||
\
|
||||
/* use optimized addresses for the polling page, */ \
|
||||
/* e.g. map it to a special 32-bit address. */ \
|
||||
product_pd(bool, OptimizePollingPageLocation, \
|
||||
"Optimize the location of the polling page used for Safepoints") \
|
||||
\
|
||||
product_pd(intx, AttachListenerTimeout, \
|
||||
"Timeout in ms the attach listener waits for a request") \
|
||||
range(0, 2147483) \
|
||||
/* Normally AIX commits memory on touch, but sometimes it is helpful to have */ \
|
||||
/* explicit commit behaviour. This flag, if true, causes the VM to touch */ \
|
||||
/* memory on os::commit_memory() (which normally is a noop). */ \
|
||||
product(bool, UseExplicitCommit, false, \
|
||||
"Explicit commit for virtual memory.") \
|
||||
\
|
||||
|
||||
// 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
|
||||
// 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, UseLargePagesIndividualAllocation, false);
|
||||
define_pd_global(bool, UseOSErrorReporting, false);
|
||||
|
@ -109,92 +109,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
||||
return JNI_TRUE;
|
||||
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, 2014 SAP AG. All rights reserved.
|
||||
* 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
|
||||
@ -23,18 +22,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
// This is only a stub. Will flesh out later when/if we add further support
|
||||
// for PASE.
|
||||
|
||||
void ThreadLocalStorage::generate_code_for_get_thread() {
|
||||
// Nothing we can do here for user-level thread.
|
||||
}
|
||||
#include "libo4.hpp"
|
||||
|
||||
void ThreadLocalStorage::pd_init() {
|
||||
// Nothing to do.
|
||||
bool libo4::init() { return false; }
|
||||
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.
|
||||
*
|
||||
* 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 "misc_aix.hpp"
|
||||
|
||||
// For dlopen and friends
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
// handle to the libperfstat
|
||||
// Handle to the libperfstat.
|
||||
static void* g_libhandle = NULL;
|
||||
|
||||
// whether initialization worked
|
||||
static bool g_initialized = false;
|
||||
|
||||
|
||||
typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, perfstat_cpu_total_t* userbuff,
|
||||
typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff,
|
||||
int sizeof_userbuff, int desired_number);
|
||||
|
||||
typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
||||
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 cid_t (*fun_wpar_getcid_t) ();
|
||||
|
||||
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_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_wpar_getcid_t g_fun_wpar_getcid = NULL;
|
||||
|
||||
bool libperfstat::init() {
|
||||
|
||||
if (g_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
g_initialized = false;
|
||||
|
||||
// dynamically load the libperfstat porting library.
|
||||
// Dynamically load the libperfstat porting library.
|
||||
g_libhandle = dlopen("/usr/lib/libperfstat.a(shr_64.o)", RTLD_MEMBER | RTLD_NOW);
|
||||
if (!g_libhandle) {
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "Cannot load libperfstat.a (dlerror: %s)", dlerror());
|
||||
}
|
||||
trcVerbose("Cannot load libperfstat.a (dlerror: %s)", dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
// resolve function pointers
|
||||
// Resolve function pointers
|
||||
|
||||
#define RESOLVE_FUN_NO_ERROR(name) \
|
||||
g_fun_##name = (fun_##name##_t) dlsym(g_libhandle, #name);
|
||||
@ -72,26 +73,28 @@ bool libperfstat::init() {
|
||||
#define RESOLVE_FUN(name) \
|
||||
RESOLVE_FUN_NO_ERROR(name) \
|
||||
if (!g_fun_##name) { \
|
||||
if (Verbose) { \
|
||||
fprintf(stderr, "Cannot resolve " #name "() from libperfstat.a\n" \
|
||||
trcVerbose("Cannot resolve " #name "() from libperfstat.a\n" \
|
||||
" (dlerror: %s)", dlerror()); \
|
||||
} \
|
||||
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_memory_total);
|
||||
RESOLVE_FUN(perfstat_reset);
|
||||
|
||||
g_initialized = true;
|
||||
trcVerbose("libperfstat loaded.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void libperfstat::cleanup() {
|
||||
|
||||
g_initialized = false;
|
||||
|
||||
if (g_libhandle) {
|
||||
dlclose(g_libhandle);
|
||||
g_libhandle = NULL;
|
||||
@ -99,26 +102,250 @@ void libperfstat::cleanup() {
|
||||
|
||||
g_fun_perfstat_cpu_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_wpar_getcid = NULL;
|
||||
|
||||
}
|
||||
|
||||
int libperfstat::perfstat_memory_total(perfstat_id_t *name,
|
||||
perfstat_memory_total_t* userbuff,
|
||||
int sizeof_userbuff, int desired_number) {
|
||||
assert(g_initialized, "libperfstat not initialized");
|
||||
assert(g_fun_perfstat_memory_total, "");
|
||||
if (g_fun_perfstat_memory_total == NULL) {
|
||||
return -1;
|
||||
}
|
||||
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) {
|
||||
assert(g_initialized, "libperfstat not initialized");
|
||||
assert(g_fun_perfstat_cpu_total, "");
|
||||
if (g_fun_perfstat_cpu_total == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number);
|
||||
}
|
||||
|
||||
void libperfstat::perfstat_reset() {
|
||||
assert(g_initialized, "libperfstat not initialized");
|
||||
assert(g_fun_perfstat_reset, "");
|
||||
g_fun_perfstat_reset();
|
||||
int libperfstat::perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff,
|
||||
int sizeof_userbuff, int desired_number) {
|
||||
if (g_fun_perfstat_partition_total == NULL) {
|
||||
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
|
||||
// instead of statically linking against it. The libperfstat library is an
|
||||
@ -32,7 +32,732 @@
|
||||
#ifndef 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 {
|
||||
|
||||
@ -41,19 +766,107 @@ public:
|
||||
// Load the libperfstat library (must be in LIBPATH).
|
||||
// Returns true if succeeded, false if error.
|
||||
static bool init();
|
||||
|
||||
// cleanup of the libo4 porting library.
|
||||
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.
|
||||
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);
|
||||
|
||||
static int perfstat_memory_total(perfstat_id_t *name, perfstat_memory_total_t* userbuff,
|
||||
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 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
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,7 +35,6 @@
|
||||
#endif
|
||||
|
||||
#include "loadlib_aix.hpp"
|
||||
// for CritSect
|
||||
#include "misc_aix.hpp"
|
||||
#include "porting_aix.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
void MiscUtils::init_critsect(MiscUtils::critsect_t* cs) {
|
||||
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
|
||||
// port.
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
@ -40,7 +42,6 @@
|
||||
} \
|
||||
}
|
||||
#define ERRBYE(s) { trcVerbose(s); return -1; }
|
||||
#define trc(fmt, ...)
|
||||
|
||||
#define assert0(b) assert((b), "")
|
||||
#define guarantee0(b) guarantee((b), "")
|
||||
|
@ -35,7 +35,7 @@
|
||||
void OSThread::pd_initialize() {
|
||||
assert(this != NULL, "check");
|
||||
_thread_id = 0;
|
||||
_pthread_id = 0;
|
||||
_kernel_thread_id = 0;
|
||||
_siginfo = NULL;
|
||||
_ucontext = NULL;
|
||||
_expanding_stack = 0;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define OS_AIX_VM_OSTHREAD_AIX_HPP
|
||||
|
||||
public:
|
||||
typedef pid_t thread_id_t;
|
||||
typedef pthread_t thread_id_t;
|
||||
|
||||
private:
|
||||
int _thread_type;
|
||||
@ -43,9 +43,13 @@
|
||||
|
||||
private:
|
||||
|
||||
// _pthread_id is the pthread id, which is used by library calls
|
||||
// (e.g. pthread_kill).
|
||||
pthread_t _pthread_id;
|
||||
// On AIX, we use the pthread id as OSThread::thread_id and keep the kernel thread id
|
||||
// separately for diagnostic purposes.
|
||||
//
|
||||
// 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
|
||||
|
||||
@ -66,11 +70,16 @@
|
||||
return false;
|
||||
}
|
||||
#endif // ASSERT
|
||||
pthread_t pthread_id() const {
|
||||
return _pthread_id;
|
||||
tid_t kernel_thread_id() const {
|
||||
return _kernel_thread_id;
|
||||
}
|
||||
void set_pthread_id(pthread_t tid) {
|
||||
_pthread_id = tid;
|
||||
void set_kernel_thread_id(tid_t 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 {
|
||||
friend class os;
|
||||
|
||||
// Length of strings included in the libperfstat structures.
|
||||
#define IDENTIFIER_LENGTH 64
|
||||
|
||||
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
||||
// __sigaction(), signal() is loaded
|
||||
static struct sigaction *(*get_signal_action)(int);
|
||||
@ -45,13 +42,15 @@ class Aix {
|
||||
|
||||
static void check_signal_handler(int sig);
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
static julong _physical_memory;
|
||||
static pthread_t _main_thread;
|
||||
static Mutex* _createThread_lock;
|
||||
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)
|
||||
static int _on_pase;
|
||||
@ -63,6 +62,9 @@ class Aix {
|
||||
// for OS/400 e.g. 0x0504 for OS/400 V5R4
|
||||
static int _os_version;
|
||||
|
||||
// 4 Byte kernel version: Version, Release, Tech Level, Service Pack.
|
||||
static unsigned int _os_kernel_version;
|
||||
|
||||
// -1 = uninitialized,
|
||||
// 0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set)
|
||||
// 1 - SPEC1170 requested (XPG_SUS_ENV is ON)
|
||||
@ -73,35 +75,6 @@ class Aix {
|
||||
// 1 - EXTSHM=ON
|
||||
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 physical_memory() { return _physical_memory; }
|
||||
static void initialize_system_info();
|
||||
@ -125,9 +98,6 @@ class Aix {
|
||||
public:
|
||||
static void init_thread_fpu_state();
|
||||
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 Mutex* createThread_lock(void) { return _createThread_lock; }
|
||||
static void hotspot_sigmask(Thread* thread);
|
||||
@ -215,6 +185,14 @@ class Aix {
|
||||
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.
|
||||
static bool on_pase_V5R4_or_older() {
|
||||
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.
|
||||
// (on AIX, using libperfstat, on PASE with libo4.so).
|
||||
// Returns true if ok, false if error.
|
||||
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> {
|
||||
|
@ -36,10 +36,6 @@
|
||||
#include <sys/ioctl.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.
|
||||
inline int os::file_name_strcmp(const char* s1, const char* 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.
|
||||
inline void os::pd_split_reserved_memory(char *base, size_t size,
|
||||
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.
|
||||
|
@ -108,84 +108,3 @@ JVM_ENTRY_NO_ENV(jboolean, JVM_RaiseSignal(jint sig))
|
||||
return JNI_TRUE;
|
||||
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();
|
||||
alloca(((pid ^ counter++) & 7) * 128);
|
||||
|
||||
ThreadLocalStorage::set_thread(thread);
|
||||
thread->initialize_thread_current();
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
Monitor* sync = osthread->startThread_lock();
|
||||
@ -882,44 +882,6 @@ void os::free_thread(OSThread* 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
|
||||
|
||||
@ -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)) {
|
||||
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_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
||||
tty->print("expected:");
|
||||
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
|
||||
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,
|
||||
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
|
||||
void os::init(void) {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,10 +34,6 @@
|
||||
#include <sys/poll.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
|
||||
inline int os::file_name_strcmp(const char* s1, const char* 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;
|
||||
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();
|
||||
alloca(((pid ^ counter++) & 7) * 128);
|
||||
|
||||
ThreadLocalStorage::set_thread(thread);
|
||||
thread->initialize_thread_current();
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
Monitor* sync = osthread->startThread_lock();
|
||||
@ -873,43 +873,6 @@ void os::free_thread(OSThread* 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
|
||||
|
||||
@ -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)) {
|
||||
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_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
||||
tty->print("expected:");
|
||||
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
|
||||
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,
|
||||
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
|
||||
void os::init(void) {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,10 +34,6 @@
|
||||
#include <sys/poll.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
|
||||
inline int os::file_name_strcmp(const char* s1, const char* 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
info[] =
|
||||
|
||||
static const struct {
|
||||
int sig; const char* name;
|
||||
}
|
||||
g_signal_info[] =
|
||||
{
|
||||
{ SIGABRT, "SIGABRT" },
|
||||
{ SIGABRT, "SIGABRT" },
|
||||
#ifdef SIGAIO
|
||||
{ SIGAIO, "SIGAIO" },
|
||||
{ SIGAIO, "SIGAIO" },
|
||||
#endif
|
||||
{ SIGALRM, "SIGALRM" },
|
||||
{ SIGALRM, "SIGALRM" },
|
||||
#ifdef SIGALRM1
|
||||
{ SIGALRM1, "SIGALRM1" },
|
||||
{ SIGALRM1, "SIGALRM1" },
|
||||
#endif
|
||||
{ SIGBUS, "SIGBUS" },
|
||||
{ SIGBUS, "SIGBUS" },
|
||||
#ifdef SIGCANCEL
|
||||
{ SIGCANCEL, "SIGCANCEL" },
|
||||
{ SIGCANCEL, "SIGCANCEL" },
|
||||
#endif
|
||||
{ SIGCHLD, "SIGCHLD" },
|
||||
{ SIGCHLD, "SIGCHLD" },
|
||||
#ifdef SIGCLD
|
||||
{ SIGCLD, "SIGCLD" },
|
||||
{ SIGCLD, "SIGCLD" },
|
||||
#endif
|
||||
{ SIGCONT, "SIGCONT" },
|
||||
{ SIGCONT, "SIGCONT" },
|
||||
#ifdef SIGCPUFAIL
|
||||
{ SIGCPUFAIL, "SIGCPUFAIL" },
|
||||
{ SIGCPUFAIL, "SIGCPUFAIL" },
|
||||
#endif
|
||||
#ifdef SIGDANGER
|
||||
{ SIGDANGER, "SIGDANGER" },
|
||||
{ SIGDANGER, "SIGDANGER" },
|
||||
#endif
|
||||
#ifdef SIGDIL
|
||||
{ SIGDIL, "SIGDIL" },
|
||||
{ SIGDIL, "SIGDIL" },
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
{ SIGEMT, "SIGEMT" },
|
||||
{ SIGEMT, "SIGEMT" },
|
||||
#endif
|
||||
{ SIGFPE, "SIGFPE" },
|
||||
{ SIGFPE, "SIGFPE" },
|
||||
#ifdef SIGFREEZE
|
||||
{ SIGFREEZE, "SIGFREEZE" },
|
||||
{ SIGFREEZE, "SIGFREEZE" },
|
||||
#endif
|
||||
#ifdef SIGGFAULT
|
||||
{ SIGGFAULT, "SIGGFAULT" },
|
||||
{ SIGGFAULT, "SIGGFAULT" },
|
||||
#endif
|
||||
#ifdef SIGGRANT
|
||||
{ SIGGRANT, "SIGGRANT" },
|
||||
{ SIGGRANT, "SIGGRANT" },
|
||||
#endif
|
||||
{ SIGHUP, "SIGHUP" },
|
||||
{ SIGILL, "SIGILL" },
|
||||
{ SIGINT, "SIGINT" },
|
||||
{ SIGHUP, "SIGHUP" },
|
||||
{ SIGILL, "SIGILL" },
|
||||
{ SIGINT, "SIGINT" },
|
||||
#ifdef SIGIO
|
||||
{ SIGIO, "SIGIO" },
|
||||
{ SIGIO, "SIGIO" },
|
||||
#endif
|
||||
#ifdef SIGIOINT
|
||||
{ SIGIOINT, "SIGIOINT" },
|
||||
{ SIGIOINT, "SIGIOINT" },
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
// SIGIOT is there for BSD compatibility, but on most Unices just a
|
||||
// synonym for SIGABRT. The result should be "SIGABRT", not
|
||||
// "SIGIOT".
|
||||
#if (SIGIOT != SIGABRT )
|
||||
{ SIGIOT, "SIGIOT" },
|
||||
#endif
|
||||
// SIGIOT is there for BSD compatibility, but on most Unices just a
|
||||
// synonym for SIGABRT. The result should be "SIGABRT", not
|
||||
// "SIGIOT".
|
||||
#if (SIGIOT != SIGABRT )
|
||||
{ SIGIOT, "SIGIOT" },
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SIGKAP
|
||||
{ SIGKAP, "SIGKAP" },
|
||||
{ SIGKAP, "SIGKAP" },
|
||||
#endif
|
||||
{ SIGKILL, "SIGKILL" },
|
||||
{ SIGKILL, "SIGKILL" },
|
||||
#ifdef SIGLOST
|
||||
{ SIGLOST, "SIGLOST" },
|
||||
{ SIGLOST, "SIGLOST" },
|
||||
#endif
|
||||
#ifdef SIGLWP
|
||||
{ SIGLWP, "SIGLWP" },
|
||||
{ SIGLWP, "SIGLWP" },
|
||||
#endif
|
||||
#ifdef SIGLWPTIMER
|
||||
{ SIGLWPTIMER, "SIGLWPTIMER" },
|
||||
{ SIGLWPTIMER, "SIGLWPTIMER" },
|
||||
#endif
|
||||
#ifdef SIGMIGRATE
|
||||
{ SIGMIGRATE, "SIGMIGRATE" },
|
||||
{ SIGMIGRATE, "SIGMIGRATE" },
|
||||
#endif
|
||||
#ifdef SIGMSG
|
||||
{ SIGMSG, "SIGMSG" },
|
||||
{ SIGMSG, "SIGMSG" },
|
||||
#endif
|
||||
{ SIGPIPE, "SIGPIPE" },
|
||||
{ SIGPIPE, "SIGPIPE" },
|
||||
#ifdef SIGPOLL
|
||||
{ SIGPOLL, "SIGPOLL" },
|
||||
{ SIGPOLL, "SIGPOLL" },
|
||||
#endif
|
||||
#ifdef SIGPRE
|
||||
{ SIGPRE, "SIGPRE" },
|
||||
{ SIGPRE, "SIGPRE" },
|
||||
#endif
|
||||
{ SIGPROF, "SIGPROF" },
|
||||
{ SIGPROF, "SIGPROF" },
|
||||
#ifdef SIGPTY
|
||||
{ SIGPTY, "SIGPTY" },
|
||||
{ SIGPTY, "SIGPTY" },
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
{ SIGPWR, "SIGPWR" },
|
||||
{ SIGPWR, "SIGPWR" },
|
||||
#endif
|
||||
{ SIGQUIT, "SIGQUIT" },
|
||||
{ SIGQUIT, "SIGQUIT" },
|
||||
#ifdef SIGRECONFIG
|
||||
{ SIGRECONFIG, "SIGRECONFIG" },
|
||||
{ SIGRECONFIG, "SIGRECONFIG" },
|
||||
#endif
|
||||
#ifdef SIGRECOVERY
|
||||
{ SIGRECOVERY, "SIGRECOVERY" },
|
||||
{ SIGRECOVERY, "SIGRECOVERY" },
|
||||
#endif
|
||||
#ifdef SIGRESERVE
|
||||
{ SIGRESERVE, "SIGRESERVE" },
|
||||
{ SIGRESERVE, "SIGRESERVE" },
|
||||
#endif
|
||||
#ifdef SIGRETRACT
|
||||
{ SIGRETRACT, "SIGRETRACT" },
|
||||
{ SIGRETRACT, "SIGRETRACT" },
|
||||
#endif
|
||||
#ifdef SIGSAK
|
||||
{ SIGSAK, "SIGSAK" },
|
||||
{ SIGSAK, "SIGSAK" },
|
||||
#endif
|
||||
{ SIGSEGV, "SIGSEGV" },
|
||||
{ SIGSEGV, "SIGSEGV" },
|
||||
#ifdef SIGSOUND
|
||||
{ SIGSOUND, "SIGSOUND" },
|
||||
{ SIGSOUND, "SIGSOUND" },
|
||||
#endif
|
||||
{ SIGSTOP, "SIGSTOP" },
|
||||
{ SIGSYS, "SIGSYS" },
|
||||
#ifdef SIGSTKFLT
|
||||
{ SIGSTKFLT, "SIGSTKFLT" },
|
||||
#endif
|
||||
{ SIGSTOP, "SIGSTOP" },
|
||||
{ SIGSYS, "SIGSYS" },
|
||||
#ifdef SIGSYSERROR
|
||||
{ SIGSYSERROR, "SIGSYSERROR" },
|
||||
{ SIGSYSERROR, "SIGSYSERROR" },
|
||||
#endif
|
||||
#ifdef SIGTALRM
|
||||
{ SIGTALRM, "SIGTALRM" },
|
||||
{ SIGTALRM, "SIGTALRM" },
|
||||
#endif
|
||||
{ SIGTERM, "SIGTERM" },
|
||||
{ SIGTERM, "SIGTERM" },
|
||||
#ifdef SIGTHAW
|
||||
{ SIGTHAW, "SIGTHAW" },
|
||||
{ SIGTHAW, "SIGTHAW" },
|
||||
#endif
|
||||
{ SIGTRAP, "SIGTRAP" },
|
||||
{ SIGTRAP, "SIGTRAP" },
|
||||
#ifdef SIGTSTP
|
||||
{ SIGTSTP, "SIGTSTP" },
|
||||
{ SIGTSTP, "SIGTSTP" },
|
||||
#endif
|
||||
{ SIGTTIN, "SIGTTIN" },
|
||||
{ SIGTTOU, "SIGTTOU" },
|
||||
{ SIGTTIN, "SIGTTIN" },
|
||||
{ SIGTTOU, "SIGTTOU" },
|
||||
#ifdef SIGURG
|
||||
{ SIGURG, "SIGURG" },
|
||||
{ SIGURG, "SIGURG" },
|
||||
#endif
|
||||
{ SIGUSR1, "SIGUSR1" },
|
||||
{ SIGUSR2, "SIGUSR2" },
|
||||
{ SIGUSR1, "SIGUSR1" },
|
||||
{ SIGUSR2, "SIGUSR2" },
|
||||
#ifdef SIGVIRT
|
||||
{ SIGVIRT, "SIGVIRT" },
|
||||
{ SIGVIRT, "SIGVIRT" },
|
||||
#endif
|
||||
{ SIGVTALRM, "SIGVTALRM" },
|
||||
{ SIGVTALRM, "SIGVTALRM" },
|
||||
#ifdef SIGWAITING
|
||||
{ SIGWAITING, "SIGWAITING" },
|
||||
{ SIGWAITING, "SIGWAITING" },
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
{ SIGWINCH, "SIGWINCH" },
|
||||
{ SIGWINCH, "SIGWINCH" },
|
||||
#endif
|
||||
#ifdef SIGWINDOW
|
||||
{ SIGWINDOW, "SIGWINDOW" },
|
||||
{ SIGWINDOW, "SIGWINDOW" },
|
||||
#endif
|
||||
{ SIGXCPU, "SIGXCPU" },
|
||||
{ SIGXFSZ, "SIGXFSZ" },
|
||||
{ SIGXCPU, "SIGXCPU" },
|
||||
{ SIGXFSZ, "SIGXFSZ" },
|
||||
#ifdef SIGXRES
|
||||
{ SIGXRES, "SIGXRES" },
|
||||
{ SIGXRES, "SIGXRES" },
|
||||
#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;
|
||||
|
||||
@ -670,9 +675,9 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
||||
#endif
|
||||
|
||||
if (sig > 0) {
|
||||
for (int idx = 0; info[idx].sig != -1; idx ++) {
|
||||
if (info[idx].sig == sig) {
|
||||
ret = info[idx].name;
|
||||
for (int idx = 0; g_signal_info[idx].sig != -1; idx ++) {
|
||||
if (g_signal_info[idx].sig == sig) {
|
||||
ret = g_signal_info[idx].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -693,6 +698,25 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
||||
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.
|
||||
bool os::Posix::is_valid_signal(int sig) {
|
||||
// MacOS not really POSIX compliant: sigaddset does not return
|
||||
@ -711,6 +735,21 @@ bool os::Posix::is_valid_signal(int sig) {
|
||||
#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
|
||||
// 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) {
|
||||
|
@ -51,6 +51,12 @@ public:
|
||||
// Returned string is a constant. For unknown signals "UNKNOWN" is returned.
|
||||
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.
|
||||
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;
|
||||
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;
|
||||
Thread* thread = (Thread*)thread_addr;
|
||||
|
||||
thread->initialize_thread_current();
|
||||
|
||||
OSThread* osthr = thread->osthread();
|
||||
|
||||
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)) {
|
||||
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_cr(" found:" PTR32_FORMAT, act.sa_flags);
|
||||
tty->print("expected:");
|
||||
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
|
||||
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,
|
||||
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.
|
||||
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
|
||||
pid_t pid;
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
if (t != NULL && t->is_inside_signal_handler()) {
|
||||
pid = fork();
|
||||
} 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
|
||||
|
||||
|
||||
/*
|
||||
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();
|
||||
_alloca(((pid ^ counter++) & 7) * 128);
|
||||
|
||||
thread->initialize_thread_current();
|
||||
|
||||
OSThread* osthr = thread->osthread();
|
||||
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) {
|
||||
EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo;
|
||||
st->print("siginfo:");
|
||||
st->print(" ExceptionCode=0x%x", er->ExceptionCode);
|
||||
|
||||
if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
|
||||
er->NumberParameters >= 2) {
|
||||
char tmp[64];
|
||||
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]) {
|
||||
case 0: st->print(", reading 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,
|
||||
er->ExceptionInformation[0]);
|
||||
}
|
||||
st->print(" " INTPTR_FORMAT, er->ExceptionInformation[1]);
|
||||
} else if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR &&
|
||||
er->NumberParameters >= 2 && UseSharedSpaces) {
|
||||
FileMapInfo* mapinfo = FileMapInfo::current_info();
|
||||
if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
|
||||
st->print("\n\nError accessing class data sharing archive." \
|
||||
" Mapped file inaccessible during execution, " \
|
||||
" possible disk/network problem.");
|
||||
|
||||
if (er->ExceptionCode == EXCEPTION_IN_PAGE_ERROR && UseSharedSpaces) {
|
||||
FileMapInfo* mapinfo = FileMapInfo::current_info();
|
||||
if (mapinfo->is_in_shared_space((void*)er->ExceptionInformation[1])) {
|
||||
st->print("\n\nError accessing class data sharing archive." \
|
||||
" Mapped file inaccessible during execution, " \
|
||||
" possible disk/network problem.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int num = er->NumberParameters;
|
||||
@ -2146,7 +2156,7 @@ int os::signal_wait() {
|
||||
|
||||
LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
|
||||
address handler) {
|
||||
JavaThread* thread = JavaThread::current();
|
||||
JavaThread* thread = (JavaThread*) Thread::current_or_null();
|
||||
// Save pc in thread
|
||||
#ifdef _M_IA64
|
||||
// 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;
|
||||
#endif
|
||||
#endif
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
// Handle SafeFetch32 and SafeFetchN exceptions.
|
||||
if (StubRoutines::is_safefetch_fault(pc)) {
|
||||
@ -4011,27 +4021,6 @@ bool os::message_box(const char* title, const char* message) {
|
||||
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 _WIN64
|
||||
// Helpers to check whether NX protection is enabled
|
||||
@ -4079,6 +4068,9 @@ void os::init(void) {
|
||||
fatal("DuplicateHandle failed\n");
|
||||
}
|
||||
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
|
||||
@ -5177,9 +5169,7 @@ void Parker::park(bool isAbsolute, jlong time) {
|
||||
}
|
||||
}
|
||||
|
||||
JavaThread* thread = (JavaThread*)(Thread::current());
|
||||
assert(thread->is_Java_thread(), "Must be JavaThread");
|
||||
JavaThread *jt = (JavaThread *)thread;
|
||||
JavaThread* thread = JavaThread::current();
|
||||
|
||||
// Don't wait if interrupted or already triggered
|
||||
if (Thread::is_interrupted(thread, false) ||
|
||||
@ -5187,16 +5177,16 @@ void Parker::park(bool isAbsolute, jlong time) {
|
||||
ResetEvent(_ParkEvent);
|
||||
return;
|
||||
} else {
|
||||
ThreadBlockInVM tbivm(jt);
|
||||
ThreadBlockInVM tbivm(thread);
|
||||
OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
|
||||
jt->set_suspend_equivalent();
|
||||
thread->set_suspend_equivalent();
|
||||
|
||||
WaitForSingleObject(_ParkEvent, time);
|
||||
ResetEvent(_ParkEvent);
|
||||
|
||||
// If externally suspended while waiting, re-suspend
|
||||
if (jt->handle_special_suspend_equivalent_condition()) {
|
||||
jt->java_suspend_self();
|
||||
if (thread->handle_special_suspend_equivalent_condition()) {
|
||||
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;
|
||||
|
||||
if (exception_code == EXCEPTION_ACCESS_VIOLATION) {
|
||||
JavaThread* thread = (JavaThread*)ThreadLocalStorage::get_thread_slow();
|
||||
JavaThread* thread = JavaThread::current();
|
||||
PEXCEPTION_RECORD exceptionRecord = e->ExceptionRecord;
|
||||
address addr = (address) exceptionRecord->ExceptionInformation[1];
|
||||
|
||||
@ -6033,3 +6023,48 @@ void TestReserveMemorySpecial_test() {
|
||||
UseNUMAInterleaving = old_use_numa_interleaving;
|
||||
}
|
||||
#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
|
||||
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/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.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;
|
||||
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
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.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -35,8 +35,7 @@
|
||||
/******************************/ \
|
||||
/* Threads (NOTE: incomplete) */ \
|
||||
/******************************/ \
|
||||
nonstatic_field(OSThread, _thread_id, pid_t) \
|
||||
nonstatic_field(OSThread, _pthread_id, pthread_t)
|
||||
nonstatic_field(OSThread, _thread_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) \
|
||||
@ -45,7 +44,6 @@
|
||||
/* Posix Thread IDs */ \
|
||||
/**********************/ \
|
||||
\
|
||||
declare_integer_type(pid_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)
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,62 +26,7 @@
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
|
||||
#ifndef _LP64
|
||||
void MacroAssembler::int3() {
|
||||
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/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
@ -405,7 +406,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
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
|
||||
// (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.
|
||||
* 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
|
||||
|
@ -134,7 +134,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
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.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -23,32 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
// nothing required here
|
||||
|
||||
|
||||
// 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/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
@ -249,7 +250,7 @@ JVM_handle_linux_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
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
|
||||
// (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.
|
||||
* 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);
|
||||
public:
|
||||
|
||||
static Thread *aarch64_get_thread_helper();
|
||||
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
static bool register_stack_overflow() { return false; }
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
@ -182,7 +183,7 @@ JVM_handle_linux_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
SignalHandlerMark shm(t);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.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) {
|
||||
sigcontext_t* ctx = (sigcontext_t*) uc;
|
||||
SIG_PC(ctx) = (intptr_t)addr;
|
||||
SIG_NPC(ctx) = (intptr_t)(addr+4);
|
||||
sigcontext* ctx = (sigcontext*) uc;
|
||||
SIG_PC(ctx) = (intptr_t)pc;
|
||||
SIG_NPC(ctx) = (intptr_t)(pc+4);
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
// (no destructors can be run)
|
||||
@ -695,6 +696,7 @@ JVM_handle_linux_signal(int sig,
|
||||
VMError::report_and_die(t, sig, pc, info, ucVoid);
|
||||
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,85 +26,7 @@
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
|
||||
#ifndef _LP64
|
||||
void MacroAssembler::int3() {
|
||||
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/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
@ -221,7 +222,7 @@ JVM_handle_linux_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
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
|
||||
// (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.
|
||||
* 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
|
||||
|
@ -125,7 +125,7 @@ JVM_handle_linux_signal(int sig,
|
||||
int abort_if_unrecognized) {
|
||||
ucontext_t* uc = (ucontext_t*) ucVoid;
|
||||
|
||||
Thread* t = ThreadLocalStorage::get_thread_slow();
|
||||
Thread* t = Thread::current_or_null_safe();
|
||||
|
||||
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) {
|
||||
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
|
||||
// (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);
|
||||
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
|
||||
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 "asm/macroAssembler.inline.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
|
||||
void MacroAssembler::int3() {
|
||||
push(rax);
|
||||
@ -37,33 +35,3 @@ void MacroAssembler::int3() {
|
||||
pop(rdx);
|
||||
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/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
@ -346,7 +347,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
}
|
||||
#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
|
||||
// (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