This commit is contained in:
Joseph Provino 2016-01-07 20:06:28 +00:00
commit 46c02f0d3b
1148 changed files with 41132 additions and 22378 deletions

View File

@ -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

View File

@ -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

View File

@ -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}"

View File

@ -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

View File

@ -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

View File

@ -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...");
}
}
}

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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");
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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());
}

View File

@ -1651,6 +1651,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
#endif // !_LP64
Unimplemented();
return 0;
}
#ifndef PRODUCT

View File

@ -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.");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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

View 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

View 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

View File

@ -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

View File

@ -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() {

View File

@ -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) {
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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);

View File

@ -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), "")

View File

@ -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;

View File

@ -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

View File

@ -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> {

View File

@ -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.

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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);

View 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");
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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; }
};
/*

View 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());
}

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View 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

View File

@ -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; }

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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) {

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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