Merge
This commit is contained in:
commit
4bea0af9ab
@ -494,3 +494,4 @@ bc48b669bc6610fac97e16593050c0f559cf6945 jdk9-b88
|
|||||||
20dff0211deda8d5877fda0e80b6d165ab93c6c2 jdk9-b89
|
20dff0211deda8d5877fda0e80b6d165ab93c6c2 jdk9-b89
|
||||||
7fe46dc64bb3a8df554b24cde0153ffb24f39c5e jdk9-b90
|
7fe46dc64bb3a8df554b24cde0153ffb24f39c5e jdk9-b90
|
||||||
3fd5c2ca4c20c183628b6dbeb8df821a961419e3 jdk9-b91
|
3fd5c2ca4c20c183628b6dbeb8df821a961419e3 jdk9-b91
|
||||||
|
53cb98d68a1aeb08d29c89d6da748de60c448e37 jdk9-b92
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
# Copyright 2007, 2008 Red Hat, Inc.
|
# Copyright 2007, 2008 Red Hat, Inc.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
@ -25,8 +25,16 @@
|
|||||||
|
|
||||||
# Setup common to Zero (non-Shark) and Shark versions of VM
|
# Setup common to Zero (non-Shark) and Shark versions of VM
|
||||||
|
|
||||||
# override this from the main file because some version of llvm do not like -Wundef
|
# Some versions of llvm do not like -Wundef
|
||||||
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wunused-function -Wunused-value
|
ifeq ($(USE_CLANG), true)
|
||||||
|
WARNING_FLAGS += -Wno-undef
|
||||||
|
endif
|
||||||
|
# Suppress some warning flags that are normally turned on for hotspot,
|
||||||
|
# because some of the zero code has not been updated accordingly.
|
||||||
|
WARNING_FLAGS += -Wno-return-type \
|
||||||
|
-Wno-format-nonliteral -Wno-format-security \
|
||||||
|
-Wno-maybe-uninitialized
|
||||||
|
|
||||||
|
|
||||||
# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
|
# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
|
||||||
OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
|
OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
|
||||||
@ -42,5 +50,3 @@ endif
|
|||||||
ifeq ($(ARCH_DATA_MODEL), 64)
|
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||||
CFLAGS += -D_LP64=1
|
CFLAGS += -D_LP64=1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OPT_CFLAGS/compactingPermGenGen.o = -O1
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
JVM_CurrentTimeMillis;
|
JVM_CurrentTimeMillis;
|
||||||
JVM_DefineClass;
|
JVM_DefineClass;
|
||||||
JVM_DefineClassWithSource;
|
JVM_DefineClassWithSource;
|
||||||
JVM_DefineClassWithSourceCond;
|
|
||||||
JVM_DesiredAssertionStatus;
|
JVM_DesiredAssertionStatus;
|
||||||
JVM_DoPrivileged;
|
JVM_DoPrivileged;
|
||||||
JVM_DumpAllStacks;
|
JVM_DumpAllStacks;
|
||||||
|
@ -48,6 +48,16 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
|
|||||||
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
|
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Add conditional directories here when needed.
|
||||||
|
ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc)
|
||||||
|
BUILD_HOTSPOT_JTREG_NATIVE_SRC += \
|
||||||
|
$(HOTSPOT_TOPDIR)/test/runtime/libadimalloc.solaris.sparc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TOOLCHAIN_TYPE), solstudio)
|
||||||
|
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_liboverflow := -lc
|
||||||
|
endif
|
||||||
|
|
||||||
BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
|
BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
|
||||||
|
|
||||||
BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg
|
BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg
|
||||||
|
@ -1169,12 +1169,12 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
const Register tmp = rscratch1;
|
const Register tmp = rscratch1;
|
||||||
|
|
||||||
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()));
|
SATBMarkQueue::byte_offset_of_active()));
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
SATBMarkQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
SATBMarkQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
Label done;
|
Label done;
|
||||||
Label runtime;
|
Label runtime;
|
||||||
@ -1219,9 +1219,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
const Register thread = rthread;
|
const Register thread = rthread;
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
DirtyCardQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
DirtyCardQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
const Register card_addr = rscratch2;
|
const Register card_addr = rscratch2;
|
||||||
ExternalAddress cardtable((address) ct->byte_map_base);
|
ExternalAddress cardtable((address) ct->byte_map_base);
|
||||||
|
@ -3487,18 +3487,18 @@ void MacroAssembler::g1_write_barrier_pre(Register obj,
|
|||||||
assert_different_registers(obj, pre_val, tmp);
|
assert_different_registers(obj, pre_val, tmp);
|
||||||
|
|
||||||
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()));
|
SATBMarkQueue::byte_offset_of_active()));
|
||||||
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
SATBMarkQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
SATBMarkQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
|
|
||||||
// Is marking active?
|
// Is marking active?
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
ldrw(tmp, in_progress);
|
ldrw(tmp, in_progress);
|
||||||
} else {
|
} else {
|
||||||
assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
|
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
||||||
ldrb(tmp, in_progress);
|
ldrb(tmp, in_progress);
|
||||||
}
|
}
|
||||||
cbzw(tmp, done);
|
cbzw(tmp, done);
|
||||||
@ -3566,9 +3566,9 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
|||||||
assert(thread == rthread, "must be");
|
assert(thread == rthread, "must be");
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
DirtyCardQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
DirtyCardQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
BarrierSet* bs = Universe::heap()->barrier_set();
|
BarrierSet* bs = Universe::heap()->barrier_set();
|
||||||
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
|
||||||
|
@ -2633,11 +2633,11 @@ void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offs
|
|||||||
Label runtime, filtered;
|
Label runtime, filtered;
|
||||||
|
|
||||||
// Is marking active?
|
// Is marking active?
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread);
|
lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
|
||||||
} else {
|
} else {
|
||||||
guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
|
guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
||||||
lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread);
|
lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
|
||||||
}
|
}
|
||||||
cmpdi(CCR0, Rtmp1, 0);
|
cmpdi(CCR0, Rtmp1, 0);
|
||||||
beq(CCR0, filtered);
|
beq(CCR0, filtered);
|
||||||
@ -2672,13 +2672,13 @@ void MacroAssembler::g1_write_barrier_pre(Register Robj, RegisterOrConstant offs
|
|||||||
// (The index field is typed as size_t.)
|
// (The index field is typed as size_t.)
|
||||||
const Register Rbuffer = Rtmp1, Rindex = Rtmp2;
|
const Register Rbuffer = Rtmp1, Rindex = Rtmp2;
|
||||||
|
|
||||||
ld(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_index()), R16_thread);
|
ld(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
|
||||||
cmpdi(CCR0, Rindex, 0);
|
cmpdi(CCR0, Rindex, 0);
|
||||||
beq(CCR0, runtime); // If index == 0, goto runtime.
|
beq(CCR0, runtime); // If index == 0, goto runtime.
|
||||||
ld(Rbuffer, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_buf()), R16_thread);
|
ld(Rbuffer, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_buf()), R16_thread);
|
||||||
|
|
||||||
addi(Rindex, Rindex, -wordSize); // Decrement index.
|
addi(Rindex, Rindex, -wordSize); // Decrement index.
|
||||||
std(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_index()), R16_thread);
|
std(Rindex, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_index()), R16_thread);
|
||||||
|
|
||||||
// Record the previous value.
|
// Record the previous value.
|
||||||
stdx(Rpre_val, Rbuffer, Rindex);
|
stdx(Rpre_val, Rbuffer, Rindex);
|
||||||
@ -2757,13 +2757,13 @@ void MacroAssembler::g1_write_barrier_post(Register Rstore_addr, Register Rnew_v
|
|||||||
|
|
||||||
const Register Rqueue_index = Rtmp2,
|
const Register Rqueue_index = Rtmp2,
|
||||||
Rqueue_buf = Rtmp3;
|
Rqueue_buf = Rtmp3;
|
||||||
ld(Rqueue_index, in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index()), R16_thread);
|
ld(Rqueue_index, in_bytes(JavaThread::dirty_card_queue_offset() + DirtyCardQueue::byte_offset_of_index()), R16_thread);
|
||||||
cmpdi(CCR0, Rqueue_index, 0);
|
cmpdi(CCR0, Rqueue_index, 0);
|
||||||
beq(CCR0, runtime); // index == 0 then jump to runtime
|
beq(CCR0, runtime); // index == 0 then jump to runtime
|
||||||
ld(Rqueue_buf, in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_buf()), R16_thread);
|
ld(Rqueue_buf, in_bytes(JavaThread::dirty_card_queue_offset() + DirtyCardQueue::byte_offset_of_buf()), R16_thread);
|
||||||
|
|
||||||
addi(Rqueue_index, Rqueue_index, -wordSize); // decrement index
|
addi(Rqueue_index, Rqueue_index, -wordSize); // decrement index
|
||||||
std(Rqueue_index, in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index()), R16_thread);
|
std(Rqueue_index, in_bytes(JavaThread::dirty_card_queue_offset() + DirtyCardQueue::byte_offset_of_index()), R16_thread);
|
||||||
|
|
||||||
stdx(Rcard_addr, Rqueue_buf, Rqueue_index); // store card
|
stdx(Rcard_addr, Rqueue_buf, Rqueue_index); // store card
|
||||||
b(filtered);
|
b(filtered);
|
||||||
|
@ -630,11 +630,11 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
Label filtered;
|
Label filtered;
|
||||||
|
|
||||||
// Is marking active?
|
// Is marking active?
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
__ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread);
|
__ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
|
||||||
} else {
|
} else {
|
||||||
guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
|
guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
||||||
__ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread);
|
__ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread);
|
||||||
}
|
}
|
||||||
__ cmpdi(CCR0, Rtmp1, 0);
|
__ cmpdi(CCR0, Rtmp1, 0);
|
||||||
__ beq(CCR0, filtered);
|
__ beq(CCR0, filtered);
|
||||||
|
@ -857,13 +857,13 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
bool with_frame = false; // I don't know if we can do with-frame.
|
bool with_frame = false; // I don't know if we can do with-frame.
|
||||||
int satb_q_index_byte_offset =
|
int satb_q_index_byte_offset =
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index());
|
SATBMarkQueue::byte_offset_of_index());
|
||||||
int satb_q_buf_byte_offset =
|
int satb_q_buf_byte_offset =
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf());
|
SATBMarkQueue::byte_offset_of_buf());
|
||||||
|
|
||||||
__ bind(restart);
|
__ bind(restart);
|
||||||
// Load the index into the SATB buffer. PtrQueue::_index is a
|
// Load the index into the SATB buffer. SATBMarkQueue::_index is a
|
||||||
// size_t so ld_ptr is appropriate
|
// size_t so ld_ptr is appropriate
|
||||||
__ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
|
__ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
|
||||||
|
|
||||||
@ -961,14 +961,14 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
|
|
||||||
int dirty_card_q_index_byte_offset =
|
int dirty_card_q_index_byte_offset =
|
||||||
in_bytes(JavaThread::dirty_card_queue_offset() +
|
in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index());
|
DirtyCardQueue::byte_offset_of_index());
|
||||||
int dirty_card_q_buf_byte_offset =
|
int dirty_card_q_buf_byte_offset =
|
||||||
in_bytes(JavaThread::dirty_card_queue_offset() +
|
in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf());
|
DirtyCardQueue::byte_offset_of_buf());
|
||||||
|
|
||||||
__ bind(restart);
|
__ bind(restart);
|
||||||
|
|
||||||
// Get the index into the update buffer. PtrQueue::_index is
|
// Get the index into the update buffer. DirtyCardQueue::_index is
|
||||||
// a size_t so ld_ptr is appropriate here.
|
// a size_t so ld_ptr is appropriate here.
|
||||||
__ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
|
__ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
|
||||||
|
|
||||||
|
@ -3632,19 +3632,19 @@ static void generate_satb_log_enqueue(bool with_frame) {
|
|||||||
|
|
||||||
int satb_q_index_byte_offset =
|
int satb_q_index_byte_offset =
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index());
|
SATBMarkQueue::byte_offset_of_index());
|
||||||
|
|
||||||
int satb_q_buf_byte_offset =
|
int satb_q_buf_byte_offset =
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf());
|
SATBMarkQueue::byte_offset_of_buf());
|
||||||
|
|
||||||
assert(in_bytes(PtrQueue::byte_width_of_index()) == sizeof(intptr_t) &&
|
assert(in_bytes(SATBMarkQueue::byte_width_of_index()) == sizeof(intptr_t) &&
|
||||||
in_bytes(PtrQueue::byte_width_of_buf()) == sizeof(intptr_t),
|
in_bytes(SATBMarkQueue::byte_width_of_buf()) == sizeof(intptr_t),
|
||||||
"check sizes in assembly below");
|
"check sizes in assembly below");
|
||||||
|
|
||||||
__ bind(restart);
|
__ bind(restart);
|
||||||
|
|
||||||
// Load the index into the SATB buffer. PtrQueue::_index is a size_t
|
// Load the index into the SATB buffer. SATBMarkQueue::_index is a size_t
|
||||||
// so ld_ptr is appropriate.
|
// so ld_ptr is appropriate.
|
||||||
__ ld_ptr(G2_thread, satb_q_index_byte_offset, L0);
|
__ ld_ptr(G2_thread, satb_q_index_byte_offset, L0);
|
||||||
|
|
||||||
@ -3736,17 +3736,17 @@ void MacroAssembler::g1_write_barrier_pre(Register obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is marking active?
|
// Is marking active?
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
ld(G2,
|
ld(G2,
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()),
|
SATBMarkQueue::byte_offset_of_active()),
|
||||||
tmp);
|
tmp);
|
||||||
} else {
|
} else {
|
||||||
guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1,
|
guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
|
||||||
"Assumption");
|
"Assumption");
|
||||||
ldsb(G2,
|
ldsb(G2,
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()),
|
SATBMarkQueue::byte_offset_of_active()),
|
||||||
tmp);
|
tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3847,13 +3847,13 @@ static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
|
|||||||
|
|
||||||
int dirty_card_q_index_byte_offset =
|
int dirty_card_q_index_byte_offset =
|
||||||
in_bytes(JavaThread::dirty_card_queue_offset() +
|
in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index());
|
DirtyCardQueue::byte_offset_of_index());
|
||||||
int dirty_card_q_buf_byte_offset =
|
int dirty_card_q_buf_byte_offset =
|
||||||
in_bytes(JavaThread::dirty_card_queue_offset() +
|
in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf());
|
DirtyCardQueue::byte_offset_of_buf());
|
||||||
__ bind(restart);
|
__ bind(restart);
|
||||||
|
|
||||||
// Load the index into the update buffer. PtrQueue::_index is
|
// Load the index into the update buffer. DirtyCardQueue::_index is
|
||||||
// a size_t so ld_ptr is appropriate here.
|
// a size_t so ld_ptr is appropriate here.
|
||||||
__ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, L0);
|
__ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, L0);
|
||||||
|
|
||||||
|
@ -1622,9 +1622,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
NOT_LP64(__ get_thread(thread);)
|
NOT_LP64(__ get_thread(thread);)
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
SATBMarkQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
SATBMarkQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
Label done;
|
Label done;
|
||||||
Label runtime;
|
Label runtime;
|
||||||
@ -1698,9 +1698,9 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
|||||||
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
DirtyCardQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
DirtyCardQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
__ push(rax);
|
__ push(rax);
|
||||||
__ push(rcx);
|
__ push(rcx);
|
||||||
|
@ -4248,18 +4248,18 @@ void MacroAssembler::g1_write_barrier_pre(Register obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()));
|
SATBMarkQueue::byte_offset_of_active()));
|
||||||
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
SATBMarkQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
SATBMarkQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
|
|
||||||
// Is marking active?
|
// Is marking active?
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
cmpl(in_progress, 0);
|
cmpl(in_progress, 0);
|
||||||
} else {
|
} else {
|
||||||
assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
|
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
||||||
cmpb(in_progress, 0);
|
cmpb(in_progress, 0);
|
||||||
}
|
}
|
||||||
jcc(Assembler::equal, done);
|
jcc(Assembler::equal, done);
|
||||||
@ -4346,9 +4346,9 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
|
|||||||
#endif // _LP64
|
#endif // _LP64
|
||||||
|
|
||||||
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index()));
|
DirtyCardQueue::byte_offset_of_index()));
|
||||||
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf()));
|
DirtyCardQueue::byte_offset_of_buf()));
|
||||||
|
|
||||||
CardTableModRefBS* ct =
|
CardTableModRefBS* ct =
|
||||||
barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
|
barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
|
||||||
|
@ -1193,9 +1193,12 @@ public class HotSpotVMConfig {
|
|||||||
@HotSpotVMConstant(name = "frame::interpreter_frame_sender_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameSenderSpOffset;
|
@HotSpotVMConstant(name = "frame::interpreter_frame_sender_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameSenderSpOffset;
|
||||||
@HotSpotVMConstant(name = "frame::interpreter_frame_last_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameLastSpOffset;
|
@HotSpotVMConstant(name = "frame::interpreter_frame_last_sp_offset", archs = {"amd64"}) @Stable public int frameInterpreterFrameLastSpOffset;
|
||||||
|
|
||||||
@HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset;
|
@HotSpotVMConstant(name = "dirtyCardQueueBufferOffset") @Stable private int dirtyCardQueueBufferOffset;
|
||||||
@HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset;
|
@HotSpotVMConstant(name = "dirtyCardQueueIndexOffset") @Stable private int dirtyCardQueueIndexOffset;
|
||||||
@HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset;
|
|
||||||
|
@HotSpotVMConstant(name = "satbMarkQueueBufferOffset") @Stable private int satbMarkQueueBufferOffset;
|
||||||
|
@HotSpotVMConstant(name = "satbMarkQueueIndexOffset") @Stable private int satbMarkQueueIndexOffset;
|
||||||
|
@HotSpotVMConstant(name = "satbMarkQueueActiveOffset") @Stable private int satbMarkQueueActiveOffset;
|
||||||
|
|
||||||
@HotSpotVMField(name = "OSThread::_interrupted", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadInterruptedOffset;
|
@HotSpotVMField(name = "OSThread::_interrupted", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int osThreadInterruptedOffset;
|
||||||
|
|
||||||
@ -1396,23 +1399,23 @@ public class HotSpotVMConfig {
|
|||||||
// G1 Collector Related Values.
|
// G1 Collector Related Values.
|
||||||
|
|
||||||
public int g1CardQueueIndexOffset() {
|
public int g1CardQueueIndexOffset() {
|
||||||
return javaThreadDirtyCardQueueOffset + ptrQueueIndexOffset;
|
return javaThreadDirtyCardQueueOffset + dirtyCardQueueIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int g1CardQueueBufferOffset() {
|
public int g1CardQueueBufferOffset() {
|
||||||
return javaThreadDirtyCardQueueOffset + ptrQueueBufferOffset;
|
return javaThreadDirtyCardQueueOffset + dirtyCardQueueBufferOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int g1SATBQueueMarkingOffset() {
|
public int g1SATBQueueMarkingOffset() {
|
||||||
return javaThreadSatbMarkQueueOffset + ptrQueueActiveOffset;
|
return javaThreadSatbMarkQueueOffset + satbMarkQueueActiveOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int g1SATBQueueIndexOffset() {
|
public int g1SATBQueueIndexOffset() {
|
||||||
return javaThreadSatbMarkQueueOffset + ptrQueueIndexOffset;
|
return javaThreadSatbMarkQueueOffset + satbMarkQueueIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int g1SATBQueueBufferOffset() {
|
public int g1SATBQueueBufferOffset() {
|
||||||
return javaThreadSatbMarkQueueOffset + ptrQueueBufferOffset;
|
return javaThreadSatbMarkQueueOffset + satbMarkQueueBufferOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
|
@HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
* Copyright 2012, 2015 SAP AG. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -36,26 +36,23 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define bool int
|
#define bool int
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
// Highest so far on AIX 5.2 is SIGSAK (63)
|
static struct sigaction sact[NSIG]; /* saved signal handlers */
|
||||||
#define MAXSIGNUM 63
|
static sigset_t jvmsigs; /* Signals used by jvm. */
|
||||||
#define MASK(sig) ((unsigned int)1 << sig)
|
|
||||||
|
|
||||||
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
|
/* Used to synchronize the installation of signal handlers. */
|
||||||
static unsigned int jvmsigs = 0; /* signals used by jvm */
|
|
||||||
|
|
||||||
/* used to synchronize the installation of signal handlers */
|
|
||||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||||
static pthread_t tid = 0;
|
static pthread_t tid = 0;
|
||||||
|
|
||||||
typedef void (*sa_handler_t)(int);
|
typedef void (*sa_handler_t)(int);
|
||||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||||
// signal_t is already defined on AIX
|
// signal_t is already defined on AIX.
|
||||||
typedef sa_handler_t (*signal_like_function_t)(int, sa_handler_t);
|
typedef sa_handler_t (*signal_like_function_t)(int, sa_handler_t);
|
||||||
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
|
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
|
||||||
|
|
||||||
@ -68,7 +65,7 @@ static bool jvm_signal_installed = false;
|
|||||||
static void signal_lock() {
|
static void signal_lock() {
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
/* When the jvm is installing its set of signal handlers, threads
|
/* When the jvm is installing its set of signal handlers, threads
|
||||||
* other than the jvm thread should wait */
|
* other than the jvm thread should wait. */
|
||||||
if (jvm_signal_installing) {
|
if (jvm_signal_installing) {
|
||||||
if (tid != pthread_self()) {
|
if (tid != pthread_self()) {
|
||||||
pthread_cond_wait(&cond, &mutex);
|
pthread_cond_wait(&cond, &mutex);
|
||||||
@ -84,10 +81,10 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
|
|||||||
bool is_sigset) {
|
bool is_sigset) {
|
||||||
if (os_signal == NULL) {
|
if (os_signal == NULL) {
|
||||||
if (!is_sigset) {
|
if (!is_sigset) {
|
||||||
// Aix: call functions directly instead of dlsym'ing them
|
// Aix: call functions directly instead of dlsym'ing them.
|
||||||
os_signal = signal;
|
os_signal = signal;
|
||||||
} else {
|
} else {
|
||||||
// Aix: call functions directly instead of dlsym'ing them
|
// Aix: call functions directly instead of dlsym'ing them.
|
||||||
os_signal = sigset;
|
os_signal = sigset;
|
||||||
}
|
}
|
||||||
if (os_signal == NULL) {
|
if (os_signal == NULL) {
|
||||||
@ -112,7 +109,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
|||||||
|
|
||||||
signal_lock();
|
signal_lock();
|
||||||
|
|
||||||
sigused = (MASK(sig) & jvmsigs) != 0;
|
sigused = sigismember(&jvmsigs, sig);
|
||||||
if (jvm_signal_installed && sigused) {
|
if (jvm_signal_installed && sigused) {
|
||||||
/* jvm has installed its signal handler for this signal. */
|
/* jvm has installed its signal handler for this signal. */
|
||||||
/* Save the handler. Don't really install it. */
|
/* Save the handler. Don't really install it. */
|
||||||
@ -129,7 +126,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
|||||||
save_signal_handler(sig, oldhandler);
|
save_signal_handler(sig, oldhandler);
|
||||||
|
|
||||||
/* Record the signals used by jvm */
|
/* Record the signals used by jvm */
|
||||||
jvmsigs |= MASK(sig);
|
sigaddset(&jvmsigs, sig);
|
||||||
|
|
||||||
signal_unlock();
|
signal_unlock();
|
||||||
return oldhandler;
|
return oldhandler;
|
||||||
@ -154,7 +151,7 @@ sa_handler_t sigset(int sig, sa_handler_t disp) {
|
|||||||
static int call_os_sigaction(int sig, const struct sigaction *act,
|
static int call_os_sigaction(int sig, const struct sigaction *act,
|
||||||
struct sigaction *oact) {
|
struct sigaction *oact) {
|
||||||
if (os_sigaction == NULL) {
|
if (os_sigaction == NULL) {
|
||||||
// Aix: call functions directly instead of dlsym'ing them
|
// Aix: call functions directly instead of dlsym'ing them.
|
||||||
os_sigaction = sigaction;
|
os_sigaction = sigaction;
|
||||||
if (os_sigaction == NULL) {
|
if (os_sigaction == NULL) {
|
||||||
printf("%s\n", dlerror());
|
printf("%s\n", dlerror());
|
||||||
@ -171,7 +168,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
|||||||
|
|
||||||
signal_lock();
|
signal_lock();
|
||||||
|
|
||||||
sigused = (MASK(sig) & jvmsigs) != 0;
|
sigused = sigismember(&jvmsigs, sig);
|
||||||
if (jvm_signal_installed && sigused) {
|
if (jvm_signal_installed && sigused) {
|
||||||
/* jvm has installed its signal handler for this signal. */
|
/* jvm has installed its signal handler for this signal. */
|
||||||
/* Save the handler. Don't really install it. */
|
/* Save the handler. Don't really install it. */
|
||||||
@ -193,8 +190,8 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
|||||||
*oact = oldAct;
|
*oact = oldAct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record the signals used by jvm */
|
/* Record the signals used by jvm. */
|
||||||
jvmsigs |= MASK(sig);
|
sigaddset(&jvmsigs, sig);
|
||||||
|
|
||||||
signal_unlock();
|
signal_unlock();
|
||||||
return res;
|
return res;
|
||||||
@ -208,9 +205,10 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The three functions for the jvm to call into */
|
/* The three functions for the jvm to call into. */
|
||||||
void JVM_begin_signal_setting() {
|
void JVM_begin_signal_setting() {
|
||||||
signal_lock();
|
signal_lock();
|
||||||
|
sigemptyset(&jvmsigs);
|
||||||
jvm_signal_installing = true;
|
jvm_signal_installing = true;
|
||||||
tid = pthread_self();
|
tid = pthread_self();
|
||||||
signal_unlock();
|
signal_unlock();
|
||||||
@ -226,7 +224,7 @@ void JVM_end_signal_setting() {
|
|||||||
|
|
||||||
struct sigaction *JVM_get_signal_action(int sig) {
|
struct sigaction *JVM_get_signal_action(int sig) {
|
||||||
/* Does race condition make sense here? */
|
/* Does race condition make sense here? */
|
||||||
if ((MASK(sig) & jvmsigs) != 0) {
|
if (sigismember(&jvmsigs, sig)) {
|
||||||
return &sact[sig];
|
return &sact[sig];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2769,8 +2769,12 @@ static int SR_initialize() {
|
|||||||
// Get signal number to use for suspend/resume
|
// Get signal number to use for suspend/resume
|
||||||
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
||||||
int sig = ::strtol(s, 0, 10);
|
int sig = ::strtol(s, 0, 10);
|
||||||
if (sig > 0 || sig < NSIG) {
|
if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769.
|
||||||
|
sig < NSIG) { // Must be legal signal and fit into sigflags[].
|
||||||
SR_signum = sig;
|
SR_signum = sig;
|
||||||
|
} else {
|
||||||
|
warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",
|
||||||
|
sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2966,8 +2970,8 @@ void javaSignalHandler(int sig, siginfo_t* info, void* uc) {
|
|||||||
bool os::Aix::signal_handlers_are_installed = false;
|
bool os::Aix::signal_handlers_are_installed = false;
|
||||||
|
|
||||||
// For signal-chaining
|
// For signal-chaining
|
||||||
struct sigaction os::Aix::sigact[MAXSIGNUM];
|
struct sigaction sigact[NSIG];
|
||||||
unsigned int os::Aix::sigs = 0;
|
sigset_t sigs;
|
||||||
bool os::Aix::libjsig_is_loaded = false;
|
bool os::Aix::libjsig_is_loaded = false;
|
||||||
typedef struct sigaction *(*get_signal_t)(int);
|
typedef struct sigaction *(*get_signal_t)(int);
|
||||||
get_signal_t os::Aix::get_signal_action = NULL;
|
get_signal_t os::Aix::get_signal_action = NULL;
|
||||||
@ -3045,30 +3049,32 @@ bool os::Aix::chained_handler(int sig, siginfo_t* siginfo, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sigaction* os::Aix::get_preinstalled_handler(int sig) {
|
struct sigaction* os::Aix::get_preinstalled_handler(int sig) {
|
||||||
if ((((unsigned int)1 << sig) & sigs) != 0) {
|
if (sigismember(&sigs, sig)) {
|
||||||
return &sigact[sig];
|
return &sigact[sig];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Aix::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
void os::Aix::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigact[sig] = oldAct;
|
sigact[sig] = oldAct;
|
||||||
sigs |= (unsigned int)1 << sig;
|
sigaddset(&sigs, sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for diagnostic
|
// for diagnostic
|
||||||
int os::Aix::sigflags[MAXSIGNUM];
|
int sigflags[NSIG];
|
||||||
|
|
||||||
int os::Aix::get_our_sigflags(int sig) {
|
int os::Aix::get_our_sigflags(int sig) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
return sigflags[sig];
|
return sigflags[sig];
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Aix::set_our_sigflags(int sig, int flags) {
|
void os::Aix::set_our_sigflags(int sig, int flags) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
|
if (sig > 0 && sig < NSIG) {
|
||||||
sigflags[sig] = flags;
|
sigflags[sig] = flags;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void os::Aix::set_signal_handler(int sig, bool set_installed) {
|
void os::Aix::set_signal_handler(int sig, bool set_installed) {
|
||||||
// Check for overwrite.
|
// Check for overwrite.
|
||||||
@ -3107,7 +3113,7 @@ void os::Aix::set_signal_handler(int sig, bool set_installed) {
|
|||||||
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
|
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
|
||||||
}
|
}
|
||||||
// Save flags, which are set by ours
|
// Save flags, which are set by ours
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigflags[sig] = sigAct.sa_flags;
|
sigflags[sig] = sigAct.sa_flags;
|
||||||
|
|
||||||
int ret = sigaction(sig, &sigAct, &oldAct);
|
int ret = sigaction(sig, &sigAct, &oldAct);
|
||||||
@ -3140,10 +3146,11 @@ void os::Aix::install_signal_handlers() {
|
|||||||
assert(UseSignalChaining, "should enable signal-chaining");
|
assert(UseSignalChaining, "should enable signal-chaining");
|
||||||
}
|
}
|
||||||
if (libjsig_is_loaded) {
|
if (libjsig_is_loaded) {
|
||||||
// Tell libjsig jvm is setting signal handlers
|
// Tell libjsig jvm is setting signal handlers.
|
||||||
(*begin_signal_setting)();
|
(*begin_signal_setting)();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::sigemptyset(&sigs);
|
||||||
set_signal_handler(SIGSEGV, true);
|
set_signal_handler(SIGSEGV, true);
|
||||||
set_signal_handler(SIGPIPE, true);
|
set_signal_handler(SIGPIPE, true);
|
||||||
set_signal_handler(SIGBUS, true);
|
set_signal_handler(SIGBUS, true);
|
||||||
|
@ -34,15 +34,9 @@ static bool zero_page_read_protected() { return false; }
|
|||||||
class Aix {
|
class Aix {
|
||||||
friend class os;
|
friend class os;
|
||||||
|
|
||||||
// For signal-chaining
|
|
||||||
// highest so far (AIX 5.2 - 6.1) is SIGSAK (63)
|
|
||||||
#define MAXSIGNUM 63
|
|
||||||
// Length of strings included in the libperfstat structures.
|
// Length of strings included in the libperfstat structures.
|
||||||
#define IDENTIFIER_LENGTH 64
|
#define IDENTIFIER_LENGTH 64
|
||||||
|
|
||||||
static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
|
|
||||||
static unsigned int sigs; // mask of signals that have
|
|
||||||
// preinstalled signal handlers
|
|
||||||
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
||||||
// __sigaction(), signal() is loaded
|
// __sigaction(), signal() is loaded
|
||||||
static struct sigaction *(*get_signal_action)(int);
|
static struct sigaction *(*get_signal_action)(int);
|
||||||
@ -51,9 +45,6 @@ class Aix {
|
|||||||
|
|
||||||
static void check_signal_handler(int sig);
|
static void check_signal_handler(int sig);
|
||||||
|
|
||||||
// For signal flags diagnostics
|
|
||||||
static int sigflags[MAXSIGNUM];
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static julong _physical_memory;
|
static julong _physical_memory;
|
||||||
|
@ -36,12 +36,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define MAXSIGNUM 32
|
#define MASK(sig) ((uint32_t)1 << (sig-1)) // 0 is not a signal.
|
||||||
#define MASK(sig) ((unsigned int)1 << sig)
|
#if (32 < NSIG-1)
|
||||||
|
#error "Not all signals can be encoded in jvmsigs. Adapt its type!"
|
||||||
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
|
#endif
|
||||||
static unsigned int jvmsigs = 0; /* signals used by jvm */
|
static struct sigaction sact[NSIG]; /* saved signal handlers */
|
||||||
|
static uint32_t jvmsigs = 0; /* signals used by jvm */
|
||||||
static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
|
static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
|
||||||
|
|
||||||
/* used to synchronize the installation of signal handlers */
|
/* used to synchronize the installation of signal handlers */
|
||||||
|
@ -2831,8 +2831,12 @@ static int SR_initialize() {
|
|||||||
// Get signal number to use for suspend/resume
|
// Get signal number to use for suspend/resume
|
||||||
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
||||||
int sig = ::strtol(s, 0, 10);
|
int sig = ::strtol(s, 0, 10);
|
||||||
if (sig > 0 || sig < NSIG) {
|
if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769.
|
||||||
|
sig < NSIG) { // Must be legal signal and fit into sigflags[].
|
||||||
SR_signum = sig;
|
SR_signum = sig;
|
||||||
|
} else {
|
||||||
|
warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",
|
||||||
|
sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2985,8 +2989,11 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
|
|||||||
bool os::Bsd::signal_handlers_are_installed = false;
|
bool os::Bsd::signal_handlers_are_installed = false;
|
||||||
|
|
||||||
// For signal-chaining
|
// For signal-chaining
|
||||||
struct sigaction os::Bsd::sigact[MAXSIGNUM];
|
struct sigaction sigact[NSIG];
|
||||||
unsigned int os::Bsd::sigs = 0;
|
uint32_t sigs = 0;
|
||||||
|
#if (32 < NSIG-1)
|
||||||
|
#error "Not all signals can be encoded in sigs. Adapt its type!"
|
||||||
|
#endif
|
||||||
bool os::Bsd::libjsig_is_loaded = false;
|
bool os::Bsd::libjsig_is_loaded = false;
|
||||||
typedef struct sigaction *(*get_signal_t)(int);
|
typedef struct sigaction *(*get_signal_t)(int);
|
||||||
get_signal_t os::Bsd::get_signal_action = NULL;
|
get_signal_t os::Bsd::get_signal_action = NULL;
|
||||||
@ -3064,30 +3071,32 @@ bool os::Bsd::chained_handler(int sig, siginfo_t* siginfo, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sigaction* os::Bsd::get_preinstalled_handler(int sig) {
|
struct sigaction* os::Bsd::get_preinstalled_handler(int sig) {
|
||||||
if ((((unsigned int)1 << sig) & sigs) != 0) {
|
if ((((uint32_t)1 << (sig-1)) & sigs) != 0) {
|
||||||
return &sigact[sig];
|
return &sigact[sig];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigact[sig] = oldAct;
|
sigact[sig] = oldAct;
|
||||||
sigs |= (unsigned int)1 << sig;
|
sigs |= (uint32_t)1 << (sig-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for diagnostic
|
// for diagnostic
|
||||||
int os::Bsd::sigflags[MAXSIGNUM];
|
int sigflags[NSIG];
|
||||||
|
|
||||||
int os::Bsd::get_our_sigflags(int sig) {
|
int os::Bsd::get_our_sigflags(int sig) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
return sigflags[sig];
|
return sigflags[sig];
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Bsd::set_our_sigflags(int sig, int flags) {
|
void os::Bsd::set_our_sigflags(int sig, int flags) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
|
if (sig > 0 && sig < NSIG) {
|
||||||
sigflags[sig] = flags;
|
sigflags[sig] = flags;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void os::Bsd::set_signal_handler(int sig, bool set_installed) {
|
void os::Bsd::set_signal_handler(int sig, bool set_installed) {
|
||||||
// Check for overwrite.
|
// Check for overwrite.
|
||||||
@ -3137,7 +3146,7 @@ void os::Bsd::set_signal_handler(int sig, bool set_installed) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Save flags, which are set by ours
|
// Save flags, which are set by ours
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigflags[sig] = sigAct.sa_flags;
|
sigflags[sig] = sigAct.sa_flags;
|
||||||
|
|
||||||
int ret = sigaction(sig, &sigAct, &oldAct);
|
int ret = sigaction(sig, &sigAct, &oldAct);
|
||||||
|
@ -40,10 +40,6 @@ class Bsd {
|
|||||||
friend class os;
|
friend class os;
|
||||||
|
|
||||||
// For signal-chaining
|
// For signal-chaining
|
||||||
#define MAXSIGNUM 32
|
|
||||||
static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
|
|
||||||
static unsigned int sigs; // mask of signals that have
|
|
||||||
// preinstalled signal handlers
|
|
||||||
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
||||||
// __sigaction(), signal() is loaded
|
// __sigaction(), signal() is loaded
|
||||||
static struct sigaction *(*get_signal_action)(int);
|
static struct sigaction *(*get_signal_action)(int);
|
||||||
@ -52,9 +48,6 @@ class Bsd {
|
|||||||
|
|
||||||
static void check_signal_handler(int sig);
|
static void check_signal_handler(int sig);
|
||||||
|
|
||||||
// For signal flags diagnostics
|
|
||||||
static int sigflags[MAXSIGNUM];
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// mach_absolute_time
|
// mach_absolute_time
|
||||||
static mach_timebase_info_data_t _timebase_info;
|
static mach_timebase_info_data_t _timebase_info;
|
||||||
|
@ -35,16 +35,19 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define bool int
|
#define bool int
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
#define MAXSIGNUM 32
|
#define MASK(sig) ((uint64_t)1 << (sig-1)) // 0 is not a signal.
|
||||||
#define MASK(sig) ((unsigned int)1 << sig)
|
// Check whether all signals fit into jvmsigs. -1 as MASK shifts by -1.
|
||||||
|
#if (64 < NSIG-1)
|
||||||
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
|
#error "Not all signals can be encoded in jvmsigs. Adapt its type!"
|
||||||
static unsigned int jvmsigs = 0; /* signals used by jvm */
|
#endif
|
||||||
|
static struct sigaction sact[NSIG]; /* saved signal handlers */
|
||||||
|
static uint64_t jvmsigs = 0; /* signals used by jvm */
|
||||||
|
|
||||||
/* used to synchronize the installation of signal handlers */
|
/* used to synchronize the installation of signal handlers */
|
||||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
@ -107,7 +110,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
|||||||
|
|
||||||
signal_lock();
|
signal_lock();
|
||||||
|
|
||||||
sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
|
sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
|
||||||
if (jvm_signal_installed && sigused) {
|
if (jvm_signal_installed && sigused) {
|
||||||
/* jvm has installed its signal handler for this signal. */
|
/* jvm has installed its signal handler for this signal. */
|
||||||
/* Save the handler. Don't really install it. */
|
/* Save the handler. Don't really install it. */
|
||||||
@ -116,7 +119,7 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
|||||||
|
|
||||||
signal_unlock();
|
signal_unlock();
|
||||||
return oldhandler;
|
return oldhandler;
|
||||||
} else if (sig < MAXSIGNUM && jvm_signal_installing) {
|
} else if (sig < NSIG && jvm_signal_installing) {
|
||||||
/* jvm is installing its signal handlers. Install the new
|
/* jvm is installing its signal handlers. Install the new
|
||||||
* handlers and save the old ones. jvm uses sigaction().
|
* handlers and save the old ones. jvm uses sigaction().
|
||||||
* Leave the piece here just in case. */
|
* Leave the piece here just in case. */
|
||||||
@ -165,7 +168,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
|||||||
|
|
||||||
signal_lock();
|
signal_lock();
|
||||||
|
|
||||||
sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0);
|
sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
|
||||||
if (jvm_signal_installed && sigused) {
|
if (jvm_signal_installed && sigused) {
|
||||||
/* jvm has installed its signal handler for this signal. */
|
/* jvm has installed its signal handler for this signal. */
|
||||||
/* Save the handler. Don't really install it. */
|
/* Save the handler. Don't really install it. */
|
||||||
@ -178,7 +181,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
|||||||
|
|
||||||
signal_unlock();
|
signal_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
} else if (sig < MAXSIGNUM && jvm_signal_installing) {
|
} else if (sig < NSIG && jvm_signal_installing) {
|
||||||
/* jvm is installing its signal handlers. Install the new
|
/* jvm is installing its signal handlers. Install the new
|
||||||
* handlers and save the old ones. */
|
* handlers and save the old ones. */
|
||||||
res = call_os_sigaction(sig, act, &oldAct);
|
res = call_os_sigaction(sig, act, &oldAct);
|
||||||
|
@ -3989,15 +3989,19 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
|||||||
errno = old_errno;
|
errno = old_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int SR_initialize() {
|
static int SR_initialize() {
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
// Get signal number to use for suspend/resume
|
// Get signal number to use for suspend/resume
|
||||||
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
|
||||||
int sig = ::strtol(s, 0, 10);
|
int sig = ::strtol(s, 0, 10);
|
||||||
if (sig > 0 || sig < _NSIG) {
|
if (sig > MAX2(SIGSEGV, SIGBUS) && // See 4355769.
|
||||||
|
sig < NSIG) { // Must be legal signal and fit into sigflags[].
|
||||||
SR_signum = sig;
|
SR_signum = sig;
|
||||||
|
} else {
|
||||||
|
warning("You set _JAVA_SR_SIGNUM=%d. It must be in range [%d, %d]. Using %d instead.",
|
||||||
|
sig, MAX2(SIGSEGV, SIGBUS)+1, NSIG-1, SR_signum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4151,8 +4155,11 @@ void signalHandler(int sig, siginfo_t* info, void* uc) {
|
|||||||
bool os::Linux::signal_handlers_are_installed = false;
|
bool os::Linux::signal_handlers_are_installed = false;
|
||||||
|
|
||||||
// For signal-chaining
|
// For signal-chaining
|
||||||
struct sigaction os::Linux::sigact[MAXSIGNUM];
|
struct sigaction sigact[NSIG];
|
||||||
unsigned int os::Linux::sigs = 0;
|
uint64_t sigs = 0;
|
||||||
|
#if (64 < NSIG-1)
|
||||||
|
#error "Not all signals can be encoded in sigs. Adapt its type!"
|
||||||
|
#endif
|
||||||
bool os::Linux::libjsig_is_loaded = false;
|
bool os::Linux::libjsig_is_loaded = false;
|
||||||
typedef struct sigaction *(*get_signal_t)(int);
|
typedef struct sigaction *(*get_signal_t)(int);
|
||||||
get_signal_t os::Linux::get_signal_action = NULL;
|
get_signal_t os::Linux::get_signal_action = NULL;
|
||||||
@ -4230,29 +4237,29 @@ bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
|
struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
|
||||||
if ((((unsigned int)1 << sig) & sigs) != 0) {
|
if ((((uint64_t)1 << (sig-1)) & sigs) != 0) {
|
||||||
return &sigact[sig];
|
return &sigact[sig];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigact[sig] = oldAct;
|
sigact[sig] = oldAct;
|
||||||
sigs |= (unsigned int)1 << sig;
|
sigs |= (uint64_t)1 << (sig-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for diagnostic
|
// for diagnostic
|
||||||
int os::Linux::sigflags[MAXSIGNUM];
|
int sigflags[NSIG];
|
||||||
|
|
||||||
int os::Linux::get_our_sigflags(int sig) {
|
int os::Linux::get_our_sigflags(int sig) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
return sigflags[sig];
|
return sigflags[sig];
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::Linux::set_our_sigflags(int sig, int flags) {
|
void os::Linux::set_our_sigflags(int sig, int flags) {
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
if (sig > 0 && sig < MAXSIGNUM) {
|
if (sig > 0 && sig < NSIG) {
|
||||||
sigflags[sig] = flags;
|
sigflags[sig] = flags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4292,7 +4299,7 @@ void os::Linux::set_signal_handler(int sig, bool set_installed) {
|
|||||||
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
|
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
|
||||||
}
|
}
|
||||||
// Save flags, which are set by ours
|
// Save flags, which are set by ours
|
||||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
assert(sig > 0 && sig < NSIG, "vm signal out of expected range");
|
||||||
sigflags[sig] = sigAct.sa_flags;
|
sigflags[sig] = sigAct.sa_flags;
|
||||||
|
|
||||||
int ret = sigaction(sig, &sigAct, &oldAct);
|
int ret = sigaction(sig, &sigAct, &oldAct);
|
||||||
|
@ -34,11 +34,6 @@ class Linux {
|
|||||||
friend class os;
|
friend class os;
|
||||||
friend class TestReserveMemorySpecial;
|
friend class TestReserveMemorySpecial;
|
||||||
|
|
||||||
// For signal-chaining
|
|
||||||
#define MAXSIGNUM 32
|
|
||||||
static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
|
|
||||||
static unsigned int sigs; // mask of signals that have
|
|
||||||
// preinstalled signal handlers
|
|
||||||
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
static bool libjsig_is_loaded; // libjsig that interposes sigaction(),
|
||||||
// __sigaction(), signal() is loaded
|
// __sigaction(), signal() is loaded
|
||||||
static struct sigaction *(*get_signal_action)(int);
|
static struct sigaction *(*get_signal_action)(int);
|
||||||
@ -47,9 +42,6 @@ class Linux {
|
|||||||
|
|
||||||
static void check_signal_handler(int sig);
|
static void check_signal_handler(int sig);
|
||||||
|
|
||||||
// For signal flags diagnostics
|
|
||||||
static int sigflags[MAXSIGNUM];
|
|
||||||
|
|
||||||
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
||||||
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
||||||
static int (*_pthread_setname_np)(pthread_t, const char*);
|
static int (*_pthread_setname_np)(pthread_t, const char*);
|
||||||
|
@ -837,6 +837,21 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
|||||||
#if defined(IA64) && !defined(AIX)
|
#if defined(IA64) && !defined(AIX)
|
||||||
{ SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },
|
{ SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__sparc) && defined(SOLARIS)
|
||||||
|
// define Solaris Sparc M7 ADI SEGV signals
|
||||||
|
#if !defined(SEGV_ACCADI)
|
||||||
|
#define SEGV_ACCADI 3
|
||||||
|
#endif
|
||||||
|
{ SIGSEGV, SEGV_ACCADI, "SEGV_ACCADI", "ADI not enabled for mapped object." },
|
||||||
|
#if !defined(SEGV_ACCDERR)
|
||||||
|
#define SEGV_ACCDERR 4
|
||||||
|
#endif
|
||||||
|
{ SIGSEGV, SEGV_ACCDERR, "SEGV_ACCDERR", "ADI disrupting exception." },
|
||||||
|
#if !defined(SEGV_ACCPERR)
|
||||||
|
#define SEGV_ACCPERR 5
|
||||||
|
#endif
|
||||||
|
{ SIGSEGV, SEGV_ACCPERR, "SEGV_ACCPERR", "ADI precise exception." },
|
||||||
|
#endif // defined(__sparc) && defined(SOLARIS)
|
||||||
{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },
|
{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },
|
||||||
{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },
|
{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },
|
||||||
{ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },
|
{ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },
|
||||||
|
@ -91,10 +91,6 @@
|
|||||||
#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */
|
#define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */
|
||||||
#define SHUTDOWN2_SIGNAL SIGINT
|
#define SHUTDOWN2_SIGNAL SIGINT
|
||||||
#define SHUTDOWN3_SIGNAL SIGTERM
|
#define SHUTDOWN3_SIGNAL SIGTERM
|
||||||
/* alternative signals used with -XX:+UseAltSigs (or for backward
|
|
||||||
compatibility with 1.2, -Xusealtsigs) flag. Chosen to be
|
|
||||||
unlikely to conflict with applications embedding the vm */
|
|
||||||
#define ALT_ASYNC_SIGNAL (SIGRTMIN + SIGRTMAX)/2 /* alternate async signal */
|
|
||||||
|
|
||||||
/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */
|
/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */
|
||||||
#define JSIG_VERSION_1_4_1 0x30140100
|
#define JSIG_VERSION_1_4_1 0x30140100
|
||||||
|
@ -997,9 +997,8 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// defined for >= Solaris 10. This allows builds on earlier versions
|
// defined for >= Solaris 10. This allows builds on earlier versions
|
||||||
// of Solaris to take advantage of the newly reserved Solaris JVM signals
|
// of Solaris to take advantage of the newly reserved Solaris JVM signals.
|
||||||
// With SIGJVM1, SIGJVM2, ASYNC_SIGNAL is SIGJVM2 and -XX:+UseAltSigs does
|
// With SIGJVM1, SIGJVM2, ASYNC_SIGNAL is SIGJVM2. Previously INTERRUPT_SIGNAL
|
||||||
// nothing since these should have no conflict. Previously INTERRUPT_SIGNAL
|
|
||||||
// was SIGJVM1.
|
// was SIGJVM1.
|
||||||
//
|
//
|
||||||
#if !defined(SIGJVM1)
|
#if !defined(SIGJVM1)
|
||||||
@ -1053,13 +1052,9 @@ void os::Solaris::signal_sets_init() {
|
|||||||
sigaddset(&unblocked_sigs, SIGBUS);
|
sigaddset(&unblocked_sigs, SIGBUS);
|
||||||
sigaddset(&unblocked_sigs, SIGFPE);
|
sigaddset(&unblocked_sigs, SIGFPE);
|
||||||
|
|
||||||
if (isJVM1available) {
|
// Always true on Solaris 10+
|
||||||
|
guarantee(isJVM1available(), "SIGJVM1/2 missing!");
|
||||||
os::Solaris::set_SIGasync(SIGJVM2);
|
os::Solaris::set_SIGasync(SIGJVM2);
|
||||||
} else if (UseAltSigs) {
|
|
||||||
os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL);
|
|
||||||
} else {
|
|
||||||
os::Solaris::set_SIGasync(ASYNC_SIGNAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
|
sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
|
||||||
|
|
||||||
@ -3922,7 +3917,7 @@ void os::Solaris::set_signal_handler(int sig, bool set_installed,
|
|||||||
// save the old handler in jvm
|
// save the old handler in jvm
|
||||||
save_preinstalled_handler(sig, oldAct);
|
save_preinstalled_handler(sig, oldAct);
|
||||||
} else {
|
} else {
|
||||||
vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal, try -XX:+UseAltSigs.");
|
vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal.");
|
||||||
}
|
}
|
||||||
// libjsig also interposes the sigaction() call below and saves the
|
// libjsig also interposes the sigaction() call below and saves the
|
||||||
// old sigaction on it own.
|
// old sigaction on it own.
|
||||||
@ -3991,7 +3986,7 @@ void os::run_periodic_checks() {
|
|||||||
DO_SIGNAL_CHECK(BREAK_SIGNAL);
|
DO_SIGNAL_CHECK(BREAK_SIGNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See comments above for using JVM1/JVM2 and UseAltSigs
|
// See comments above for using JVM1/JVM2
|
||||||
DO_SIGNAL_CHECK(os::Solaris::SIGasync());
|
DO_SIGNAL_CHECK(os::Solaris::SIGasync());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,6 @@ class Solaris {
|
|||||||
|
|
||||||
static void try_enable_extended_io();
|
static void try_enable_extended_io();
|
||||||
|
|
||||||
// For signal-chaining
|
|
||||||
static unsigned long sigs; // mask of signals that have
|
|
||||||
// preinstalled signal handlers
|
|
||||||
static struct sigaction *(*get_signal_action)(int);
|
static struct sigaction *(*get_signal_action)(int);
|
||||||
static struct sigaction *get_preinstalled_handler(int);
|
static struct sigaction *get_preinstalled_handler(int);
|
||||||
static int (*get_libjsig_version)();
|
static int (*get_libjsig_version)();
|
||||||
|
@ -1464,10 +1464,10 @@ void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr p
|
|||||||
bool do_load, bool patch, CodeEmitInfo* info) {
|
bool do_load, bool patch, CodeEmitInfo* info) {
|
||||||
// First we test whether marking is in progress.
|
// First we test whether marking is in progress.
|
||||||
BasicType flag_type;
|
BasicType flag_type;
|
||||||
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
flag_type = T_INT;
|
flag_type = T_INT;
|
||||||
} else {
|
} else {
|
||||||
guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1,
|
guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
|
||||||
"Assumption");
|
"Assumption");
|
||||||
// Use unsigned type T_BOOLEAN here rather than signed T_BYTE since some platforms, eg. ARM,
|
// Use unsigned type T_BOOLEAN here rather than signed T_BYTE since some platforms, eg. ARM,
|
||||||
// need to use unsigned instructions to use the large offset to load the satb_mark_queue.
|
// need to use unsigned instructions to use the large offset to load the satb_mark_queue.
|
||||||
@ -1477,7 +1477,7 @@ void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr p
|
|||||||
LIR_Address* mark_active_flag_addr =
|
LIR_Address* mark_active_flag_addr =
|
||||||
new LIR_Address(thrd,
|
new LIR_Address(thrd,
|
||||||
in_bytes(JavaThread::satb_mark_queue_offset() +
|
in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active()),
|
SATBMarkQueue::byte_offset_of_active()),
|
||||||
flag_type);
|
flag_type);
|
||||||
// Read the marking-in-progress flag.
|
// Read the marking-in-progress flag.
|
||||||
LIR_Opr flag_val = new_register(T_INT);
|
LIR_Opr flag_val = new_register(T_INT);
|
||||||
|
@ -97,7 +97,7 @@ int SymbolTable::_symbols_removed = 0;
|
|||||||
int SymbolTable::_symbols_counted = 0;
|
int SymbolTable::_symbols_counted = 0;
|
||||||
volatile int SymbolTable::_parallel_claimed_idx = 0;
|
volatile int SymbolTable::_parallel_claimed_idx = 0;
|
||||||
|
|
||||||
void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total) {
|
void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int* removed) {
|
||||||
for (int i = start_idx; i < end_idx; ++i) {
|
for (int i = start_idx; i < end_idx; ++i) {
|
||||||
HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
|
HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||||
HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
|
HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
|
||||||
@ -110,7 +110,6 @@ void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Symbol* s = entry->literal();
|
Symbol* s = entry->literal();
|
||||||
(*memory_total) += s->size();
|
|
||||||
(*processed)++;
|
(*processed)++;
|
||||||
assert(s != NULL, "just checking");
|
assert(s != NULL, "just checking");
|
||||||
// If reference count is zero, remove.
|
// If reference count is zero, remove.
|
||||||
@ -133,15 +132,9 @@ void SymbolTable::buckets_unlink(int start_idx, int end_idx, int* processed, int
|
|||||||
// This is done late during GC.
|
// This is done late during GC.
|
||||||
void SymbolTable::unlink(int* processed, int* removed) {
|
void SymbolTable::unlink(int* processed, int* removed) {
|
||||||
size_t memory_total = 0;
|
size_t memory_total = 0;
|
||||||
buckets_unlink(0, the_table()->table_size(), processed, removed, &memory_total);
|
buckets_unlink(0, the_table()->table_size(), processed, removed);
|
||||||
_symbols_removed += *removed;
|
_symbols_removed += *removed;
|
||||||
_symbols_counted += *processed;
|
_symbols_counted += *processed;
|
||||||
// Exclude printing for normal PrintGCDetails because people parse
|
|
||||||
// this output.
|
|
||||||
if (PrintGCDetails && Verbose && WizardMode) {
|
|
||||||
gclog_or_tty->print(" [Symbols=%d size=" SIZE_FORMAT "K] ", *processed,
|
|
||||||
(memory_total*HeapWordSize)/1024);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
|
void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
|
||||||
@ -158,16 +151,10 @@ void SymbolTable::possibly_parallel_unlink(int* processed, int* removed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||||
buckets_unlink(start_idx, end_idx, processed, removed, &memory_total);
|
buckets_unlink(start_idx, end_idx, processed, removed);
|
||||||
}
|
}
|
||||||
Atomic::add(*processed, &_symbols_counted);
|
Atomic::add(*processed, &_symbols_counted);
|
||||||
Atomic::add(*removed, &_symbols_removed);
|
Atomic::add(*removed, &_symbols_removed);
|
||||||
// Exclude printing for normal PrintGCDetails because people parse
|
|
||||||
// this output.
|
|
||||||
if (PrintGCDetails && Verbose && WizardMode) {
|
|
||||||
gclog_or_tty->print(" [Symbols: scanned=%d removed=%d size=" SIZE_FORMAT "K] ", *processed, *removed,
|
|
||||||
(memory_total*HeapWordSize)/1024);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new table and using alternate hash code, populate the new table
|
// Create a new table and using alternate hash code, populate the new table
|
||||||
|
@ -132,7 +132,7 @@ private:
|
|||||||
static volatile int _parallel_claimed_idx;
|
static volatile int _parallel_claimed_idx;
|
||||||
|
|
||||||
// Release any dead symbols
|
// Release any dead symbols
|
||||||
static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total);
|
static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed);
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
symbol_alloc_batch_size = 8,
|
symbol_alloc_batch_size = 8,
|
||||||
|
@ -119,20 +119,6 @@ void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
|
|||||||
t->dirty_card_queue().handle_zero_index();
|
t->dirty_card_queue().handle_zero_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
|
|
||||||
bool consume,
|
|
||||||
uint worker_i) {
|
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
|
|
||||||
for (JavaThread* t = Threads::first(); t; t = t->next()) {
|
|
||||||
bool b = t->dirty_card_queue().apply_closure(cl, consume);
|
|
||||||
guarantee(b, "Should not be interrupted.");
|
|
||||||
}
|
|
||||||
bool b = shared_dirty_card_queue()->apply_closure(cl,
|
|
||||||
consume,
|
|
||||||
worker_i);
|
|
||||||
guarantee(b, "Should not be interrupted.");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
|
bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
|
||||||
|
|
||||||
// Used to determine if we had already claimed a par_id
|
// Used to determine if we had already claimed a par_id
|
||||||
|
@ -72,6 +72,18 @@ public:
|
|||||||
void **get_buf() { return _buf;}
|
void **get_buf() { return _buf;}
|
||||||
size_t get_index() { return _index;}
|
size_t get_index() { return _index;}
|
||||||
void reinitialize() { _buf = 0; _sz = 0; _index = 0;}
|
void reinitialize() { _buf = 0; _sz = 0; _index = 0;}
|
||||||
|
|
||||||
|
// Compiler support.
|
||||||
|
static ByteSize byte_offset_of_index() {
|
||||||
|
return PtrQueue::byte_offset_of_index<DirtyCardQueue>();
|
||||||
|
}
|
||||||
|
using PtrQueue::byte_width_of_index;
|
||||||
|
|
||||||
|
static ByteSize byte_offset_of_buf() {
|
||||||
|
return PtrQueue::byte_offset_of_buf<DirtyCardQueue>();
|
||||||
|
}
|
||||||
|
using PtrQueue::byte_width_of_buf;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -112,14 +124,6 @@ public:
|
|||||||
|
|
||||||
static void handle_zero_index_for_thread(JavaThread* t);
|
static void handle_zero_index_for_thread(JavaThread* t);
|
||||||
|
|
||||||
// Apply the given closure to all entries in all currently-active buffers.
|
|
||||||
// This should only be applied at a safepoint. (Currently must not be called
|
|
||||||
// in parallel; this should change in the future.) If "consume" is true,
|
|
||||||
// processed entries are discarded.
|
|
||||||
void iterate_closure_all_threads(CardTableEntryClosure* cl,
|
|
||||||
bool consume = true,
|
|
||||||
uint worker_i = 0);
|
|
||||||
|
|
||||||
// If there exists some completed buffer, pop it, then apply the
|
// If there exists some completed buffer, pop it, then apply the
|
||||||
// specified closure to all its elements, nulling out those elements
|
// specified closure to all its elements, nulling out those elements
|
||||||
// processed. If all elements are processed, returns "true". If no
|
// processed. If all elements are processed, returns "true". If no
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "gc/g1/g1AllocRegion.inline.hpp"
|
#include "gc/g1/g1AllocRegion.inline.hpp"
|
||||||
|
#include "gc/g1/g1EvacStats.inline.hpp"
|
||||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||||
#include "runtime/orderAccess.inline.hpp"
|
#include "runtime/orderAccess.inline.hpp"
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "gc/g1/g1Allocator.inline.hpp"
|
#include "gc/g1/g1Allocator.inline.hpp"
|
||||||
#include "gc/g1/g1AllocRegion.inline.hpp"
|
#include "gc/g1/g1AllocRegion.inline.hpp"
|
||||||
|
#include "gc/g1/g1EvacStats.inline.hpp"
|
||||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||||
#include "gc/g1/g1CollectorPolicy.hpp"
|
#include "gc/g1/g1CollectorPolicy.hpp"
|
||||||
#include "gc/g1/g1MarkSweep.hpp"
|
#include "gc/g1/g1MarkSweep.hpp"
|
||||||
@ -33,6 +34,8 @@
|
|||||||
|
|
||||||
G1DefaultAllocator::G1DefaultAllocator(G1CollectedHeap* heap) :
|
G1DefaultAllocator::G1DefaultAllocator(G1CollectedHeap* heap) :
|
||||||
G1Allocator(heap),
|
G1Allocator(heap),
|
||||||
|
_survivor_is_full(false),
|
||||||
|
_old_is_full(false),
|
||||||
_retained_old_gc_alloc_region(NULL),
|
_retained_old_gc_alloc_region(NULL),
|
||||||
_survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)),
|
_survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)),
|
||||||
_old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)) {
|
_old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)) {
|
||||||
@ -87,7 +90,8 @@ void G1Allocator::reuse_retained_old_region(EvacuationInfo& evacuation_info,
|
|||||||
void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
|
void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
|
||||||
assert_at_safepoint(true /* should_be_vm_thread */);
|
assert_at_safepoint(true /* should_be_vm_thread */);
|
||||||
|
|
||||||
G1Allocator::init_gc_alloc_regions(evacuation_info);
|
_survivor_is_full = false;
|
||||||
|
_old_is_full = false;
|
||||||
|
|
||||||
_survivor_gc_alloc_region.init();
|
_survivor_gc_alloc_region.init();
|
||||||
_old_gc_alloc_region.init();
|
_old_gc_alloc_region.init();
|
||||||
@ -118,6 +122,22 @@ void G1DefaultAllocator::abandon_gc_alloc_regions() {
|
|||||||
_retained_old_gc_alloc_region = NULL;
|
_retained_old_gc_alloc_region = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool G1DefaultAllocator::survivor_is_full(AllocationContext_t context) const {
|
||||||
|
return _survivor_is_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool G1DefaultAllocator::old_is_full(AllocationContext_t context) const {
|
||||||
|
return _old_is_full;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G1DefaultAllocator::set_survivor_full(AllocationContext_t context) {
|
||||||
|
_survivor_is_full = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G1DefaultAllocator::set_old_full(AllocationContext_t context) {
|
||||||
|
_old_is_full = true;
|
||||||
|
}
|
||||||
|
|
||||||
G1PLAB::G1PLAB(size_t gclab_word_size) :
|
G1PLAB::G1PLAB(size_t gclab_word_size) :
|
||||||
PLAB(gclab_word_size), _retired(true) { }
|
PLAB(gclab_word_size), _retired(true) { }
|
||||||
|
|
||||||
@ -165,22 +185,6 @@ HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool G1Allocator::survivor_is_full(AllocationContext_t context) const {
|
|
||||||
return _survivor_is_full;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool G1Allocator::old_is_full(AllocationContext_t context) const {
|
|
||||||
return _old_is_full;
|
|
||||||
}
|
|
||||||
|
|
||||||
void G1Allocator::set_survivor_full(AllocationContext_t context) {
|
|
||||||
_survivor_is_full = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void G1Allocator::set_old_full(AllocationContext_t context) {
|
|
||||||
_old_is_full = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapWord* G1Allocator::survivor_attempt_allocation(size_t min_word_size,
|
HeapWord* G1Allocator::survivor_attempt_allocation(size_t min_word_size,
|
||||||
size_t desired_word_size,
|
size_t desired_word_size,
|
||||||
size_t* actual_word_size,
|
size_t* actual_word_size,
|
||||||
@ -232,11 +236,6 @@ HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1Allocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
|
|
||||||
_survivor_is_full = false;
|
|
||||||
_old_is_full = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
|
G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
|
||||||
_g1h(G1CollectedHeap::heap()),
|
_g1h(G1CollectedHeap::heap()),
|
||||||
_allocator(allocator),
|
_allocator(allocator),
|
||||||
|
@ -38,19 +38,16 @@ class EvacuationInfo;
|
|||||||
// Also keeps track of retained regions across GCs.
|
// Also keeps track of retained regions across GCs.
|
||||||
class G1Allocator : public CHeapObj<mtGC> {
|
class G1Allocator : public CHeapObj<mtGC> {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
private:
|
|
||||||
bool _survivor_is_full;
|
|
||||||
bool _old_is_full;
|
|
||||||
protected:
|
protected:
|
||||||
G1CollectedHeap* _g1h;
|
G1CollectedHeap* _g1h;
|
||||||
|
|
||||||
virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
|
virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0;
|
||||||
|
|
||||||
virtual bool survivor_is_full(AllocationContext_t context) const;
|
virtual bool survivor_is_full(AllocationContext_t context) const = 0;
|
||||||
virtual bool old_is_full(AllocationContext_t context) const;
|
virtual bool old_is_full(AllocationContext_t context) const = 0;
|
||||||
|
|
||||||
virtual void set_survivor_full(AllocationContext_t context);
|
virtual void set_survivor_full(AllocationContext_t context) = 0;
|
||||||
virtual void set_old_full(AllocationContext_t context);
|
virtual void set_old_full(AllocationContext_t context) = 0;
|
||||||
|
|
||||||
// Accessors to the allocation regions.
|
// Accessors to the allocation regions.
|
||||||
virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
|
virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0;
|
||||||
@ -67,7 +64,7 @@ protected:
|
|||||||
size_t* actual_word_size,
|
size_t* actual_word_size,
|
||||||
AllocationContext_t context);
|
AllocationContext_t context);
|
||||||
public:
|
public:
|
||||||
G1Allocator(G1CollectedHeap* heap) : _g1h(heap), _survivor_is_full(false), _old_is_full(false) { }
|
G1Allocator(G1CollectedHeap* heap) : _g1h(heap) { }
|
||||||
virtual ~G1Allocator() { }
|
virtual ~G1Allocator() { }
|
||||||
|
|
||||||
static G1Allocator* create_allocator(G1CollectedHeap* g1h);
|
static G1Allocator* create_allocator(G1CollectedHeap* g1h);
|
||||||
@ -79,7 +76,7 @@ public:
|
|||||||
virtual void init_mutator_alloc_region() = 0;
|
virtual void init_mutator_alloc_region() = 0;
|
||||||
virtual void release_mutator_alloc_region() = 0;
|
virtual void release_mutator_alloc_region() = 0;
|
||||||
|
|
||||||
virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
|
virtual void init_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
|
||||||
virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
|
virtual void release_gc_alloc_regions(EvacuationInfo& evacuation_info) = 0;
|
||||||
virtual void abandon_gc_alloc_regions() = 0;
|
virtual void abandon_gc_alloc_regions() = 0;
|
||||||
|
|
||||||
@ -119,6 +116,9 @@ public:
|
|||||||
// and old generation allocation region.
|
// and old generation allocation region.
|
||||||
// Can retain the (single) old generation allocation region across GCs.
|
// Can retain the (single) old generation allocation region across GCs.
|
||||||
class G1DefaultAllocator : public G1Allocator {
|
class G1DefaultAllocator : public G1Allocator {
|
||||||
|
private:
|
||||||
|
bool _survivor_is_full;
|
||||||
|
bool _old_is_full;
|
||||||
protected:
|
protected:
|
||||||
// Alloc region used to satisfy mutator allocation requests.
|
// Alloc region used to satisfy mutator allocation requests.
|
||||||
MutatorAllocRegion _mutator_alloc_region;
|
MutatorAllocRegion _mutator_alloc_region;
|
||||||
@ -135,6 +135,12 @@ protected:
|
|||||||
public:
|
public:
|
||||||
G1DefaultAllocator(G1CollectedHeap* heap);
|
G1DefaultAllocator(G1CollectedHeap* heap);
|
||||||
|
|
||||||
|
virtual bool survivor_is_full(AllocationContext_t context) const;
|
||||||
|
virtual bool old_is_full(AllocationContext_t context) const ;
|
||||||
|
|
||||||
|
virtual void set_survivor_full(AllocationContext_t context);
|
||||||
|
virtual void set_old_full(AllocationContext_t context);
|
||||||
|
|
||||||
virtual void init_mutator_alloc_region();
|
virtual void init_mutator_alloc_region();
|
||||||
virtual void release_mutator_alloc_region();
|
virtual void release_mutator_alloc_region();
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "gc/g1/g1CollectorState.hpp"
|
#include "gc/g1/g1CollectorState.hpp"
|
||||||
#include "gc/g1/g1ErgoVerbose.hpp"
|
#include "gc/g1/g1ErgoVerbose.hpp"
|
||||||
#include "gc/g1/g1EvacFailure.hpp"
|
#include "gc/g1/g1EvacFailure.hpp"
|
||||||
|
#include "gc/g1/g1EvacStats.inline.hpp"
|
||||||
#include "gc/g1/g1GCPhaseTimes.hpp"
|
#include "gc/g1/g1GCPhaseTimes.hpp"
|
||||||
#include "gc/g1/g1Log.hpp"
|
#include "gc/g1/g1Log.hpp"
|
||||||
#include "gc/g1/g1MarkSweep.hpp"
|
#include "gc/g1/g1MarkSweep.hpp"
|
||||||
@ -2278,6 +2279,10 @@ void G1CollectedHeap::allocate_dummy_regions() {
|
|||||||
// And as a result the region we'll allocate will be humongous.
|
// And as a result the region we'll allocate will be humongous.
|
||||||
guarantee(is_humongous(word_size), "sanity");
|
guarantee(is_humongous(word_size), "sanity");
|
||||||
|
|
||||||
|
// _filler_array_max_size is set to humongous object threshold
|
||||||
|
// but temporarily change it to use CollectedHeap::fill_with_object().
|
||||||
|
SizeTFlagSetting fs(_filler_array_max_size, word_size);
|
||||||
|
|
||||||
for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) {
|
for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) {
|
||||||
// Let's use the existing mechanism for the allocation
|
// Let's use the existing mechanism for the allocation
|
||||||
HeapWord* dummy_obj = humongous_obj_allocate(word_size,
|
HeapWord* dummy_obj = humongous_obj_allocate(word_size,
|
||||||
@ -3561,6 +3566,9 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(hrrs.n_yielded() == r->rem_set()->occupied(),
|
||||||
|
"Remembered set hash maps out of sync, cur: " SIZE_FORMAT " entries, next: " SIZE_FORMAT " entries",
|
||||||
|
hrrs.n_yielded(), r->rem_set()->occupied());
|
||||||
r->rem_set()->clear_locked();
|
r->rem_set()->clear_locked();
|
||||||
}
|
}
|
||||||
assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
|
assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
|
||||||
@ -3848,6 +3856,13 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
|||||||
|
|
||||||
evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
|
evacuation_info.set_collectionset_regions(g1_policy()->cset_region_length());
|
||||||
|
|
||||||
|
// Make sure the remembered sets are up to date. This needs to be
|
||||||
|
// done before register_humongous_regions_with_cset(), because the
|
||||||
|
// remembered sets are used there to choose eager reclaim candidates.
|
||||||
|
// If the remembered sets are not up to date we might miss some
|
||||||
|
// entries that need to be handled.
|
||||||
|
g1_rem_set()->cleanupHRRS();
|
||||||
|
|
||||||
register_humongous_regions_with_cset();
|
register_humongous_regions_with_cset();
|
||||||
|
|
||||||
assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
|
assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
|
||||||
|
@ -467,8 +467,19 @@ bool G1CollectorPolicy::predict_will_fit(uint young_length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t free_bytes = (base_free_regions - young_length) * HeapRegion::GrainBytes;
|
size_t free_bytes = (base_free_regions - young_length) * HeapRegion::GrainBytes;
|
||||||
if ((2.0 /* magic */ * _predictor.sigma()) * bytes_to_copy > free_bytes) {
|
|
||||||
// end condition 3: out-of-space (conservatively!)
|
// When copying, we will likely need more bytes free than is live in the region.
|
||||||
|
// Add some safety margin to factor in the confidence of our guess, and the
|
||||||
|
// natural expected waste.
|
||||||
|
// (100.0 / G1ConfidencePercent) is a scale factor that expresses the uncertainty
|
||||||
|
// of the calculation: the lower the confidence, the more headroom.
|
||||||
|
// (100 + TargetPLABWastePct) represents the increase in expected bytes during
|
||||||
|
// copying due to anticipated waste in the PLABs.
|
||||||
|
double safety_factor = (100.0 / G1ConfidencePercent) * (100 + TargetPLABWastePct) / 100.0;
|
||||||
|
size_t expected_bytes_to_copy = safety_factor * bytes_to_copy;
|
||||||
|
|
||||||
|
if (expected_bytes_to_copy > free_bytes) {
|
||||||
|
// end condition 3: out-of-space
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "memory/allocation.inline.hpp"
|
||||||
#include "gc/g1/g1EvacStats.hpp"
|
#include "gc/g1/g1EvacStats.hpp"
|
||||||
#include "gc/shared/gcId.hpp"
|
#include "gc/shared/gcId.hpp"
|
||||||
#include "trace/tracing.hpp"
|
#include "trace/tracing.hpp"
|
||||||
@ -114,3 +115,4 @@ void G1EvacStats::adjust_desired_plab_sz() {
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G1EvacStats::~G1EvacStats() { }
|
||||||
|
@ -22,11 +22,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SHARE_VM_gc_G1_G1EVACSTATS_HPP
|
#ifndef SHARE_VM_GC_G1_G1EVACSTATS_HPP
|
||||||
#define SHARE_VM_gc_G1_G1EVACSTATS_HPP
|
#define SHARE_VM_GC_G1_G1EVACSTATS_HPP
|
||||||
|
|
||||||
#include "gc/shared/plab.hpp"
|
#include "gc/shared/plab.hpp"
|
||||||
#include "runtime/atomic.hpp"
|
|
||||||
|
|
||||||
// Records various memory allocation statistics gathered during evacuation.
|
// Records various memory allocation statistics gathered during evacuation.
|
||||||
class G1EvacStats : public PLABStats {
|
class G1EvacStats : public PLABStats {
|
||||||
@ -75,19 +74,11 @@ class G1EvacStats : public PLABStats {
|
|||||||
// Amount of space in heapwords wasted (unused) in the failing regions when an evacuation failure happens.
|
// Amount of space in heapwords wasted (unused) in the failing regions when an evacuation failure happens.
|
||||||
size_t failure_waste() const { return _failure_waste; }
|
size_t failure_waste() const { return _failure_waste; }
|
||||||
|
|
||||||
void add_direct_allocated(size_t value) {
|
inline void add_direct_allocated(size_t value);
|
||||||
Atomic::add_ptr(value, &_direct_allocated);
|
inline void add_region_end_waste(size_t value);
|
||||||
}
|
inline void add_failure_used_and_waste(size_t used, size_t waste);
|
||||||
|
|
||||||
void add_region_end_waste(size_t value) {
|
~G1EvacStats();
|
||||||
Atomic::add_ptr(value, &_region_end_waste);
|
|
||||||
Atomic::add_ptr(1, &_regions_filled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_failure_used_and_waste(size_t used, size_t waste) {
|
|
||||||
Atomic::add_ptr(used, &_failure_used);
|
|
||||||
Atomic::add_ptr(waste, &_failure_waste);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_gc_G1_G1EVACSTATS_HPP
|
#endif // SHARE_VM_GC_G1_G1EVACSTATS_HPP
|
||||||
|
45
hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp
Normal file
45
hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_GC_G1_G1EVACSTATS_INLINE_HPP
|
||||||
|
#define SHARE_VM_GC_G1_G1EVACSTATS_INLINE_HPP
|
||||||
|
|
||||||
|
#include "gc/g1/g1EvacStats.hpp"
|
||||||
|
#include "runtime/atomic.inline.hpp"
|
||||||
|
|
||||||
|
inline void G1EvacStats::add_direct_allocated(size_t value) {
|
||||||
|
Atomic::add_ptr(value, &_direct_allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void G1EvacStats::add_region_end_waste(size_t value) {
|
||||||
|
Atomic::add_ptr(value, &_region_end_waste);
|
||||||
|
Atomic::add_ptr(1, &_regions_filled);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void G1EvacStats::add_failure_used_and_waste(size_t used, size_t waste) {
|
||||||
|
Atomic::add_ptr(used, &_failure_used);
|
||||||
|
Atomic::add_ptr(waste, &_failure_waste);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SHARE_VM_GC_G1_G1EVACSTATS_INLINE_HPP
|
@ -307,7 +307,6 @@ size_t G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void G1RemSet::prepare_for_oops_into_collection_set_do() {
|
void G1RemSet::prepare_for_oops_into_collection_set_do() {
|
||||||
cleanupHRRS();
|
|
||||||
_g1->set_refine_cte_cl_concurrency(false);
|
_g1->set_refine_cte_cl_concurrency(false);
|
||||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
dcqs.concatenate_logs();
|
dcqs.concatenate_logs();
|
||||||
|
@ -140,19 +140,27 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// To support compiler.
|
// To support compiler.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename Derived>
|
||||||
static ByteSize byte_offset_of_index() {
|
static ByteSize byte_offset_of_index() {
|
||||||
return byte_offset_of(PtrQueue, _index);
|
return byte_offset_of(Derived, _index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteSize byte_width_of_index() { return in_ByteSize(sizeof(size_t)); }
|
static ByteSize byte_width_of_index() { return in_ByteSize(sizeof(size_t)); }
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
static ByteSize byte_offset_of_buf() {
|
static ByteSize byte_offset_of_buf() {
|
||||||
return byte_offset_of(PtrQueue, _buf);
|
return byte_offset_of(Derived, _buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteSize byte_width_of_buf() { return in_ByteSize(sizeof(void*)); }
|
static ByteSize byte_width_of_buf() { return in_ByteSize(sizeof(void*)); }
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
static ByteSize byte_offset_of_active() {
|
static ByteSize byte_offset_of_active() {
|
||||||
return byte_offset_of(PtrQueue, _active);
|
return byte_offset_of(Derived, _active);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteSize byte_width_of_active() { return in_ByteSize(sizeof(bool)); }
|
static ByteSize byte_width_of_active() { return in_ByteSize(sizeof(bool)); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -68,6 +68,23 @@ public:
|
|||||||
void print(const char* name);
|
void print(const char* name);
|
||||||
static void print(const char* name, void** buf, size_t index, size_t sz);
|
static void print(const char* name, void** buf, size_t index, size_t sz);
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
||||||
|
// Compiler support.
|
||||||
|
static ByteSize byte_offset_of_index() {
|
||||||
|
return PtrQueue::byte_offset_of_index<SATBMarkQueue>();
|
||||||
|
}
|
||||||
|
using PtrQueue::byte_width_of_index;
|
||||||
|
|
||||||
|
static ByteSize byte_offset_of_buf() {
|
||||||
|
return PtrQueue::byte_offset_of_buf<SATBMarkQueue>();
|
||||||
|
}
|
||||||
|
using PtrQueue::byte_width_of_buf;
|
||||||
|
|
||||||
|
static ByteSize byte_offset_of_active() {
|
||||||
|
return PtrQueue::byte_offset_of_active<SATBMarkQueue>();
|
||||||
|
}
|
||||||
|
using PtrQueue::byte_width_of_active;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SATBMarkQueueSet: public PtrQueueSet {
|
class SATBMarkQueueSet: public PtrQueueSet {
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "gc/g1/g1CollectedHeap.hpp"
|
#include "gc/g1/g1CollectedHeap.hpp"
|
||||||
#include "gc/g1/heapRegion.hpp"
|
#include "gc/g1/heapRegion.hpp"
|
||||||
#include "gc/g1/heapRegionManager.hpp"
|
#include "gc/g1/heapRegionManager.hpp"
|
||||||
|
#include "utilities/macros.hpp"
|
||||||
|
|
||||||
#define VM_STRUCTS_G1(nonstatic_field, static_field) \
|
#define VM_STRUCTS_G1(nonstatic_field, static_field) \
|
||||||
\
|
\
|
||||||
@ -62,6 +63,34 @@
|
|||||||
\
|
\
|
||||||
nonstatic_field(HeapRegionSetCount, _length, uint) \
|
nonstatic_field(HeapRegionSetCount, _length, uint) \
|
||||||
nonstatic_field(HeapRegionSetCount, _capacity, size_t) \
|
nonstatic_field(HeapRegionSetCount, _capacity, size_t) \
|
||||||
|
\
|
||||||
|
nonstatic_field(PtrQueue, _active, bool) \
|
||||||
|
nonstatic_field(PtrQueue, _buf, void**) \
|
||||||
|
nonstatic_field(PtrQueue, _index, size_t) \
|
||||||
|
|
||||||
|
|
||||||
|
#define VM_INT_CONSTANTS_G1(declare_constant, declare_constant_with_value) \
|
||||||
|
\
|
||||||
|
JVMCI_ONLY( \
|
||||||
|
declare_constant_with_value( \
|
||||||
|
"dirtyCardQueueBufferOffset", \
|
||||||
|
in_bytes(DirtyCardQueue::byte_offset_of_buf())) \
|
||||||
|
declare_constant_with_value( \
|
||||||
|
"dirtyCardQueueIndexOffset", \
|
||||||
|
in_bytes(DirtyCardQueue::byte_offset_of_index())) \
|
||||||
|
) /* JVMCI_ONLY */ \
|
||||||
|
\
|
||||||
|
JVMCI_ONLY( \
|
||||||
|
declare_constant_with_value( \
|
||||||
|
"satbMarkQueueBufferOffset", \
|
||||||
|
in_bytes(SATBMarkQueue::byte_offset_of_buf())) \
|
||||||
|
declare_constant_with_value( \
|
||||||
|
"satbMarkQueueIndexOffset", \
|
||||||
|
in_bytes(SATBMarkQueue::byte_offset_of_index())) \
|
||||||
|
declare_constant_with_value( \
|
||||||
|
"satbMarkQueueActiveOffset", \
|
||||||
|
in_bytes(SATBMarkQueue::byte_offset_of_active())) \
|
||||||
|
) /* JVMCI_ONLY */ \
|
||||||
|
|
||||||
|
|
||||||
#define VM_TYPES_G1(declare_type, declare_toplevel_type) \
|
#define VM_TYPES_G1(declare_type, declare_toplevel_type) \
|
||||||
@ -76,10 +105,10 @@
|
|||||||
declare_toplevel_type(HeapRegionSetBase) \
|
declare_toplevel_type(HeapRegionSetBase) \
|
||||||
declare_toplevel_type(HeapRegionSetCount) \
|
declare_toplevel_type(HeapRegionSetCount) \
|
||||||
declare_toplevel_type(G1MonitoringSupport) \
|
declare_toplevel_type(G1MonitoringSupport) \
|
||||||
|
declare_toplevel_type(PtrQueue) \
|
||||||
\
|
\
|
||||||
declare_toplevel_type(G1CollectedHeap*) \
|
declare_toplevel_type(G1CollectedHeap*) \
|
||||||
declare_toplevel_type(HeapRegion*) \
|
declare_toplevel_type(HeapRegion*) \
|
||||||
declare_toplevel_type(G1MonitoringSupport*) \
|
declare_toplevel_type(G1MonitoringSupport*) \
|
||||||
|
|
||||||
|
|
||||||
#endif // SHARE_VM_GC_G1_VMSTRUCTS_G1_HPP
|
#endif // SHARE_VM_GC_G1_VMSTRUCTS_G1_HPP
|
||||||
|
@ -1319,3 +1319,11 @@ jlong GenCollectedHeap::millis_since_last_gc() {
|
|||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenCollectedHeap::stop() {
|
||||||
|
#if INCLUDE_ALL_GCS
|
||||||
|
if (UseConcMarkSweepGC) {
|
||||||
|
ConcurrentMarkSweepThread::stop();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -499,6 +499,9 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
void gc_prologue(bool full);
|
void gc_prologue(bool full);
|
||||||
void gc_epilogue(bool full);
|
void gc_epilogue(bool full);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
|
#endif // SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
|
||||||
|
@ -27,12 +27,17 @@
|
|||||||
#include "gc/shared/gcId.hpp"
|
#include "gc/shared/gcId.hpp"
|
||||||
#include "logging/logTag.hpp"
|
#include "logging/logTag.hpp"
|
||||||
|
|
||||||
// Prefixes prepend each log message for a specified tagset with the given prefix.
|
// Prefixes prepend each log message for a specified tagset with a given prefix.
|
||||||
// A prefix consists of a format string and a value or callback. Prefixes are added
|
// These prefixes are written before the log message but after the log decorations.
|
||||||
// after the decorations but before the log message.
|
//
|
||||||
|
// A prefix is defined as a function that takes a buffer (with some size) as argument.
|
||||||
|
// This function will be called for each log message, and should write the prefix
|
||||||
|
// to the given buffer. The function should return how many characters it wrote,
|
||||||
|
// which should never exceed the given size.
|
||||||
//
|
//
|
||||||
// List of prefixes for specific tags and/or tagsets.
|
// List of prefixes for specific tags and/or tagsets.
|
||||||
// Syntax: LOG_PREFIX(<printf format>, <value/callback for value>, LOG_TAGS(<chosen log tags>))
|
// Syntax: LOG_PREFIX(<name of prefixer function>, LOG_TAGS(<chosen log tags>))
|
||||||
|
// Where the prefixer function matches the following signature: size_t (*)(char*, size_t)
|
||||||
#define LOG_PREFIX_LIST // Currently unused/empty
|
#define LOG_PREFIX_LIST // Currently unused/empty
|
||||||
|
|
||||||
// The empty prefix, used when there's no prefix defined.
|
// The empty prefix, used when there's no prefix defined.
|
||||||
@ -44,12 +49,12 @@ struct LogPrefix : public AllStatic {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LOG_PREFIX(fmt, fn, ...) \
|
#define LOG_PREFIX(fn, ...) \
|
||||||
template <> struct LogPrefix<__VA_ARGS__> { \
|
template <> struct LogPrefix<__VA_ARGS__> { \
|
||||||
static size_t prefix(char* buf, size_t len) { \
|
static size_t prefix(char* buf, size_t len) { \
|
||||||
int ret = jio_snprintf(buf, len, fmt, fn); \
|
DEBUG_ONLY(buf[0] = '\0';) \
|
||||||
assert(ret >= 0, \
|
size_t ret = fn(buf, len); \
|
||||||
"Failed to prefix log message using prefix ('%s', '%s'), log buffer too small?", fmt, #fn); \
|
assert(ret == strlen(buf), "Length mismatch ret (" SIZE_FORMAT ") != buf length (" SIZE_FORMAT ")", ret, strlen(buf)); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
};
|
};
|
||||||
|
@ -3549,7 +3549,7 @@ void Compile::verify_graph_edges(bool no_dead_code) {
|
|||||||
void Compile::verify_barriers() {
|
void Compile::verify_barriers() {
|
||||||
if (UseG1GC) {
|
if (UseG1GC) {
|
||||||
// Verify G1 pre-barriers
|
// Verify G1 pre-barriers
|
||||||
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active());
|
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active());
|
||||||
|
|
||||||
ResourceArea *area = Thread::current()->resource_area();
|
ResourceArea *area = Thread::current()->resource_area();
|
||||||
Unique_Node_List visited(area);
|
Unique_Node_List visited(area);
|
||||||
|
@ -539,11 +539,11 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
|
|||||||
if (tls->Opcode() == Op_ThreadLocal) {
|
if (tls->Opcode() == Op_ThreadLocal) {
|
||||||
int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
|
int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
|
||||||
if (offs == in_bytes(JavaThread::satb_mark_queue_offset() +
|
if (offs == in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf())) {
|
SATBMarkQueue::byte_offset_of_buf())) {
|
||||||
break; // G1 pre barrier previous oop value store.
|
break; // G1 pre barrier previous oop value store.
|
||||||
}
|
}
|
||||||
if (offs == in_bytes(JavaThread::dirty_card_queue_offset() +
|
if (offs == in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf())) {
|
DirtyCardQueue::byte_offset_of_buf())) {
|
||||||
break; // G1 post barrier card address store.
|
break; // G1 post barrier card address store.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3986,16 +3986,16 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
|
|||||||
float likely = PROB_LIKELY(0.999);
|
float likely = PROB_LIKELY(0.999);
|
||||||
float unlikely = PROB_UNLIKELY(0.999);
|
float unlikely = PROB_UNLIKELY(0.999);
|
||||||
|
|
||||||
BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
|
BasicType active_type = in_bytes(SATBMarkQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
|
||||||
assert(in_bytes(PtrQueue::byte_width_of_active()) == 4 || in_bytes(PtrQueue::byte_width_of_active()) == 1, "flag width");
|
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 4 || in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "flag width");
|
||||||
|
|
||||||
// Offsets into the thread
|
// Offsets into the thread
|
||||||
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 648
|
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 648
|
||||||
PtrQueue::byte_offset_of_active());
|
SATBMarkQueue::byte_offset_of_active());
|
||||||
const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656
|
const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656
|
||||||
PtrQueue::byte_offset_of_index());
|
SATBMarkQueue::byte_offset_of_index());
|
||||||
const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652
|
const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652
|
||||||
PtrQueue::byte_offset_of_buf());
|
SATBMarkQueue::byte_offset_of_buf());
|
||||||
|
|
||||||
// Now the actual pointers into the thread
|
// Now the actual pointers into the thread
|
||||||
Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
|
Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
|
||||||
@ -4008,7 +4008,7 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
|
|||||||
// if (!marking)
|
// if (!marking)
|
||||||
__ if_then(marking, BoolTest::ne, zero, unlikely); {
|
__ if_then(marking, BoolTest::ne, zero, unlikely); {
|
||||||
BasicType index_bt = TypeX_X->basic_type();
|
BasicType index_bt = TypeX_X->basic_type();
|
||||||
assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
|
assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 SATBMarkQueue::_index with wrong size.");
|
||||||
Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
|
Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
|
||||||
|
|
||||||
if (do_load) {
|
if (do_load) {
|
||||||
@ -4196,9 +4196,9 @@ void GraphKit::g1_write_barrier_post(Node* oop_store,
|
|||||||
|
|
||||||
// Offsets into the thread
|
// Offsets into the thread
|
||||||
const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
|
const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_index());
|
DirtyCardQueue::byte_offset_of_index());
|
||||||
const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
|
const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_buf());
|
DirtyCardQueue::byte_offset_of_buf());
|
||||||
|
|
||||||
// Pointers into the thread
|
// Pointers into the thread
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
|
|||||||
cmpx->in(1)->is_Load()) {
|
cmpx->in(1)->is_Load()) {
|
||||||
Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
|
Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
|
||||||
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
|
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||||
PtrQueue::byte_offset_of_active());
|
SATBMarkQueue::byte_offset_of_active());
|
||||||
if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
|
if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
|
||||||
adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
|
adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
|
||||||
adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
|
adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
|
||||||
|
@ -861,11 +861,10 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
||||||
// and JVM_DefineClassWithSourceCond()
|
|
||||||
static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
||||||
jobject loader, const jbyte *buf,
|
jobject loader, const jbyte *buf,
|
||||||
jsize len, jobject pd, const char *source,
|
jsize len, jobject pd, const char *source,
|
||||||
jboolean verify, TRAPS) {
|
TRAPS) {
|
||||||
if (source == NULL) source = "__JVM_DefineClass__";
|
if (source == NULL) source = "__JVM_DefineClass__";
|
||||||
|
|
||||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||||
@ -906,8 +905,7 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
|||||||
Handle protection_domain (THREAD, JNIHandles::resolve(pd));
|
Handle protection_domain (THREAD, JNIHandles::resolve(pd));
|
||||||
Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,
|
Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,
|
||||||
protection_domain, &st,
|
protection_domain, &st,
|
||||||
verify != 0,
|
true, CHECK_NULL);
|
||||||
CHECK_NULL);
|
|
||||||
|
|
||||||
if (TraceClassResolution && k != NULL) {
|
if (TraceClassResolution && k != NULL) {
|
||||||
trace_class_resolution(k);
|
trace_class_resolution(k);
|
||||||
@ -920,23 +918,14 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
|||||||
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
|
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
|
||||||
JVMWrapper2("JVM_DefineClass %s", name);
|
JVMWrapper2("JVM_DefineClass %s", name);
|
||||||
|
|
||||||
return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, true, THREAD);
|
return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
|
JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
|
||||||
JVMWrapper2("JVM_DefineClassWithSource %s", name);
|
JVMWrapper2("JVM_DefineClassWithSource %s", name);
|
||||||
|
|
||||||
return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD);
|
return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD);
|
||||||
JVM_END
|
|
||||||
|
|
||||||
JVM_ENTRY(jclass, JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,
|
|
||||||
jobject loader, const jbyte *buf,
|
|
||||||
jsize len, jobject pd,
|
|
||||||
const char *source, jboolean verify))
|
|
||||||
JVMWrapper2("JVM_DefineClassWithSourceCond %s", name);
|
|
||||||
|
|
||||||
return jvm_define_class_common(env, name, loader, buf, len, pd, source, verify, THREAD);
|
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
|
JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
|
||||||
|
@ -378,17 +378,6 @@ JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
|
|||||||
const jbyte *buf, jsize len, jobject pd,
|
const jbyte *buf, jsize len, jobject pd,
|
||||||
const char *source);
|
const char *source);
|
||||||
|
|
||||||
/* Define a class with a source with conditional verification (added HSX 14)
|
|
||||||
* -Xverify:all will verify anyway, -Xverify:none will not verify,
|
|
||||||
* -Xverify:remote (default) will obey this conditional
|
|
||||||
* i.e. true = should_verify_class
|
|
||||||
*/
|
|
||||||
JNIEXPORT jclass JNICALL
|
|
||||||
JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name,
|
|
||||||
jobject loader, const jbyte *buf,
|
|
||||||
jsize len, jobject pd, const char *source,
|
|
||||||
jboolean verify);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reflection support functions
|
* Reflection support functions
|
||||||
*/
|
*/
|
||||||
|
@ -366,6 +366,7 @@ static SpecialFlag const special_jvm_flags[] = {
|
|||||||
{ "StarvationMonitorInterval", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
{ "StarvationMonitorInterval", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||||
{ "PreInflateSpin", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
{ "PreInflateSpin", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||||
{ "JNIDetachReleasesMonitors", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
{ "JNIDetachReleasesMonitors", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||||
|
{ "UseAltSigs", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||||
|
|
||||||
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
|
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
|
||||||
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
|
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
|
||||||
@ -2949,11 +2950,12 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) {
|
round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) {
|
||||||
return JNI_EINVAL;
|
return JNI_EINVAL;
|
||||||
}
|
}
|
||||||
// -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads
|
// -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads, -Xusealtsigs
|
||||||
} else if (match_option(option, "-Xoss", &tail) ||
|
} else if (match_option(option, "-Xoss", &tail) ||
|
||||||
match_option(option, "-Xsqnopause") ||
|
match_option(option, "-Xsqnopause") ||
|
||||||
match_option(option, "-Xoptimize") ||
|
match_option(option, "-Xoptimize") ||
|
||||||
match_option(option, "-Xboundthreads")) {
|
match_option(option, "-Xboundthreads") ||
|
||||||
|
match_option(option, "-Xusealtsigs")) {
|
||||||
// All these options are deprecated in JDK 9 and will be removed in a future release
|
// All these options are deprecated in JDK 9 and will be removed in a future release
|
||||||
char version[256];
|
char version[256];
|
||||||
JDK_Version::jdk(9).to_string(version, sizeof(version));
|
JDK_Version::jdk(9).to_string(version, sizeof(version));
|
||||||
@ -3036,11 +3038,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
|
|||||||
if (FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true) != Flag::SUCCESS) {
|
if (FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true) != Flag::SUCCESS) {
|
||||||
return JNI_EINVAL;
|
return JNI_EINVAL;
|
||||||
}
|
}
|
||||||
} else if (match_option(option, "-Xusealtsigs")) {
|
|
||||||
// change default internal VM signals used - lower case for back compat
|
|
||||||
if (FLAG_SET_CMDLINE(bool, UseAltSigs, true) != Flag::SUCCESS) {
|
|
||||||
return JNI_EINVAL;
|
|
||||||
}
|
|
||||||
// -Xprof
|
// -Xprof
|
||||||
} else if (match_option(option, "-Xprof")) {
|
} else if (match_option(option, "-Xprof")) {
|
||||||
#if INCLUDE_FPROF
|
#if INCLUDE_FPROF
|
||||||
|
@ -279,7 +279,7 @@ void emit_range_double(const char* name, double min, double max) {
|
|||||||
// Generate func argument to pass into emit_range_xxx functions
|
// Generate func argument to pass into emit_range_xxx functions
|
||||||
#define EMIT_RANGE_CHECK(a, b) , a, b
|
#define EMIT_RANGE_CHECK(a, b) , a, b
|
||||||
|
|
||||||
#define INITIAL_RANGES_SIZE 204
|
#define INITIAL_RANGES_SIZE 205
|
||||||
GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
|
GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
|
||||||
|
|
||||||
// Check the ranges of all flags that have them
|
// Check the ranges of all flags that have them
|
||||||
|
@ -1031,9 +1031,10 @@ public:
|
|||||||
product(bool, CreateCoredumpOnCrash, true, \
|
product(bool, CreateCoredumpOnCrash, true, \
|
||||||
"Create core/mini dump on VM fatal error") \
|
"Create core/mini dump on VM fatal error") \
|
||||||
\
|
\
|
||||||
product(uintx, ErrorLogTimeout, 2 * 60, \
|
product(uint64_t, ErrorLogTimeout, 2 * 60, \
|
||||||
"Timeout, in seconds, to limit the time spent on writing an " \
|
"Timeout, in seconds, to limit the time spent on writing an " \
|
||||||
"error log in case of a crash.") \
|
"error log in case of a crash.") \
|
||||||
|
range(0, (uint64_t)max_jlong/1000) \
|
||||||
\
|
\
|
||||||
product_pd(bool, UseOSErrorReporting, \
|
product_pd(bool, UseOSErrorReporting, \
|
||||||
"Let VM fatal error propagate to the OS (ie. WER on Windows)") \
|
"Let VM fatal error propagate to the OS (ie. WER on Windows)") \
|
||||||
@ -1334,10 +1335,6 @@ public:
|
|||||||
"Use signal-chaining to invoke signal handlers installed " \
|
"Use signal-chaining to invoke signal handlers installed " \
|
||||||
"by the application (Solaris & Linux only)") \
|
"by the application (Solaris & Linux only)") \
|
||||||
\
|
\
|
||||||
product(bool, UseAltSigs, false, \
|
|
||||||
"Use alternate signals instead of SIGUSR1 & SIGUSR2 for VM " \
|
|
||||||
"internal signals (Solaris only)") \
|
|
||||||
\
|
|
||||||
product(bool, AllowJNIEnvProxy, false, \
|
product(bool, AllowJNIEnvProxy, false, \
|
||||||
"Allow JNIEnv proxies for jdbx") \
|
"Allow JNIEnv proxies for jdbx") \
|
||||||
\
|
\
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "runtime/arguments.hpp"
|
#include "runtime/arguments.hpp"
|
||||||
#include "runtime/biasedLocking.hpp"
|
#include "runtime/biasedLocking.hpp"
|
||||||
#include "runtime/compilationPolicy.hpp"
|
#include "runtime/compilationPolicy.hpp"
|
||||||
|
#include "runtime/deoptimization.hpp"
|
||||||
#include "runtime/fprofiler.hpp"
|
#include "runtime/fprofiler.hpp"
|
||||||
#include "runtime/init.hpp"
|
#include "runtime/init.hpp"
|
||||||
#include "runtime/interfaceSupport.hpp"
|
#include "runtime/interfaceSupport.hpp"
|
||||||
|
@ -1299,7 +1299,7 @@ void WatcherThread::run() {
|
|||||||
if (!ShowMessageBoxOnError
|
if (!ShowMessageBoxOnError
|
||||||
&& (OnError == NULL || OnError[0] == '\0')
|
&& (OnError == NULL || OnError[0] == '\0')
|
||||||
&& Arguments::abort_hook() == NULL) {
|
&& Arguments::abort_hook() == NULL) {
|
||||||
os::sleep(this, ErrorLogTimeout * 60 * 1000, false);
|
os::sleep(this, (jlong)ErrorLogTimeout * 1000, false); // in seconds
|
||||||
fdStream err(defaultStream::output_fd());
|
fdStream err(defaultStream::output_fd());
|
||||||
err.print_raw_cr("# [ timer expired, abort... ]");
|
err.print_raw_cr("# [ timer expired, abort... ]");
|
||||||
// skip atexit/vm_exit/vm_abort hooks
|
// skip atexit/vm_exit/vm_abort hooks
|
||||||
|
@ -1378,10 +1378,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
|||||||
nonstatic_field(vframeArrayElement, _bci, int) \
|
nonstatic_field(vframeArrayElement, _bci, int) \
|
||||||
nonstatic_field(vframeArrayElement, _method, Method*) \
|
nonstatic_field(vframeArrayElement, _method, Method*) \
|
||||||
\
|
\
|
||||||
nonstatic_field(PtrQueue, _active, bool) \
|
|
||||||
nonstatic_field(PtrQueue, _buf, void**) \
|
|
||||||
nonstatic_field(PtrQueue, _index, size_t) \
|
|
||||||
\
|
|
||||||
nonstatic_field(AccessFlags, _flags, jint) \
|
nonstatic_field(AccessFlags, _flags, jint) \
|
||||||
nonstatic_field(elapsedTimer, _counter, jlong) \
|
nonstatic_field(elapsedTimer, _counter, jlong) \
|
||||||
nonstatic_field(elapsedTimer, _active, bool) \
|
nonstatic_field(elapsedTimer, _active, bool) \
|
||||||
@ -2273,8 +2269,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
|||||||
/* Miscellaneous types */ \
|
/* Miscellaneous types */ \
|
||||||
/***************/ \
|
/***************/ \
|
||||||
\
|
\
|
||||||
declare_toplevel_type(PtrQueue) \
|
|
||||||
\
|
|
||||||
/* freelist */ \
|
/* freelist */ \
|
||||||
declare_toplevel_type(FreeChunk*) \
|
declare_toplevel_type(FreeChunk*) \
|
||||||
declare_toplevel_type(AdaptiveFreeList<FreeChunk>*) \
|
declare_toplevel_type(AdaptiveFreeList<FreeChunk>*) \
|
||||||
@ -3066,6 +3060,9 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
|||||||
#define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
|
#define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
|
||||||
{ QUOTE(name), (int32_t) name },
|
{ QUOTE(name), (int32_t) name },
|
||||||
|
|
||||||
|
#define GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY(name, value) \
|
||||||
|
{ (name), (int32_t)(value) },
|
||||||
|
|
||||||
#define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
|
#define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
|
||||||
{ name, (int32_t) value },
|
{ name, (int32_t) value },
|
||||||
|
|
||||||
@ -3296,6 +3293,9 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
|
|||||||
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
|
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
|
||||||
|
|
||||||
VM_INT_CONSTANTS_PARNEW(GENERATE_VM_INT_CONSTANT_ENTRY)
|
VM_INT_CONSTANTS_PARNEW(GENERATE_VM_INT_CONSTANT_ENTRY)
|
||||||
|
|
||||||
|
VM_INT_CONSTANTS_G1(GENERATE_VM_INT_CONSTANT_ENTRY,
|
||||||
|
GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY)
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
|
|
||||||
#if INCLUDE_TRACE
|
#if INCLUDE_TRACE
|
||||||
|
@ -56,6 +56,7 @@ void DCmdRegistrant::register_dcmds(){
|
|||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SetVMFlagDCmd>(full_export, true, false));
|
||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMDynamicLibrariesDCmd>(full_export, true, false));
|
||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(full_export, true, false));
|
||||||
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMInfoDCmd>(full_export, true, false));
|
||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(full_export, true, false));
|
||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
|
||||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
|
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
|
||||||
@ -323,6 +324,10 @@ int VMUptimeDCmd::num_arguments() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMInfoDCmd::execute(DCmdSource source, TRAPS) {
|
||||||
|
VMError::print_vm_info(_output);
|
||||||
|
}
|
||||||
|
|
||||||
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
|
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
|
||||||
if (!DisableExplicitGC) {
|
if (!DisableExplicitGC) {
|
||||||
Universe::heap()->collect(GCCause::_dcmd_gc_run);
|
Universe::heap()->collect(GCCause::_dcmd_gc_run);
|
||||||
|
@ -213,6 +213,23 @@ public:
|
|||||||
virtual void execute(DCmdSource source, TRAPS);
|
virtual void execute(DCmdSource source, TRAPS);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VMInfoDCmd : public DCmd {
|
||||||
|
public:
|
||||||
|
VMInfoDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
|
||||||
|
static const char* name() { return "VM.info"; }
|
||||||
|
static const char* description() {
|
||||||
|
return "Print information about JVM environment and status.";
|
||||||
|
}
|
||||||
|
static const char* impact() { return "Low"; }
|
||||||
|
static const JavaPermission permission() {
|
||||||
|
JavaPermission p = {"java.lang.management.ManagementPermission",
|
||||||
|
"monitor", NULL};
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
static int num_arguments() { return 0; }
|
||||||
|
virtual void execute(DCmdSource source, TRAPS);
|
||||||
|
};
|
||||||
|
|
||||||
class SystemGCDCmd : public DCmd {
|
class SystemGCDCmd : public DCmd {
|
||||||
public:
|
public:
|
||||||
SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
|
SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
|
||||||
|
@ -331,7 +331,9 @@ static void crash_with_sigfpe() {
|
|||||||
volatile int x = 0;
|
volatile int x = 0;
|
||||||
volatile int y = 1/x;
|
volatile int y = 1/x;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
raise(SIGFPE);
|
// OSX implements raise(sig) incorrectly so we need to
|
||||||
|
// explicitly target the current thread
|
||||||
|
pthread_kill(pthread_self(), SIGFPE);
|
||||||
#endif
|
#endif
|
||||||
} // end: crash_with_sigfpe
|
} // end: crash_with_sigfpe
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
|
|||||||
#endif // ZERO
|
#endif // ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMError::print_oom_reasons(outputStream* st) {
|
static void print_oom_reasons(outputStream* st) {
|
||||||
st->print_cr("# Possible reasons:");
|
st->print_cr("# Possible reasons:");
|
||||||
st->print_cr("# The system is out of physical RAM or swap space");
|
st->print_cr("# The system is out of physical RAM or swap space");
|
||||||
st->print_cr("# In 32 bit mode, the process size limit was hit");
|
st->print_cr("# In 32 bit mode, the process size limit was hit");
|
||||||
@ -217,7 +217,7 @@ void VMError::print_oom_reasons(outputStream* st) {
|
|||||||
st->print_cr("# This output file may be truncated or incomplete.");
|
st->print_cr("# This output file may be truncated or incomplete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* VMError::gc_mode() {
|
static const char* gc_mode() {
|
||||||
if (UseG1GC) return "g1 gc";
|
if (UseG1GC) return "g1 gc";
|
||||||
if (UseParallelGC) return "parallel gc";
|
if (UseParallelGC) return "parallel gc";
|
||||||
if (UseConcMarkSweepGC) return "concurrent mark sweep gc";
|
if (UseConcMarkSweepGC) return "concurrent mark sweep gc";
|
||||||
@ -225,6 +225,33 @@ const char* VMError::gc_mode() {
|
|||||||
return "ERROR in GC mode";
|
return "ERROR in GC mode";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void report_vm_version(outputStream* st, char* buf, int buflen) {
|
||||||
|
// VM version
|
||||||
|
st->print_cr("#");
|
||||||
|
JDK_Version::current().to_string(buf, buflen);
|
||||||
|
const char* runtime_name = JDK_Version::runtime_name() != NULL ?
|
||||||
|
JDK_Version::runtime_name() : "";
|
||||||
|
const char* runtime_version = JDK_Version::runtime_version() != NULL ?
|
||||||
|
JDK_Version::runtime_version() : "";
|
||||||
|
st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
|
||||||
|
// This is the long version with some default settings added
|
||||||
|
st->print_cr("# Java VM: %s (%s, %s%s%s%s%s, %s, %s)",
|
||||||
|
Abstract_VM_Version::vm_name(),
|
||||||
|
Abstract_VM_Version::vm_release(),
|
||||||
|
Abstract_VM_Version::vm_info_string(),
|
||||||
|
TieredCompilation ? ", tiered" : "",
|
||||||
|
#if INCLUDE_JVMCI
|
||||||
|
EnableJVMCI ? ", jvmci" : "",
|
||||||
|
UseJVMCICompiler ? ", jvmci compiler" : "",
|
||||||
|
#else
|
||||||
|
"", "",
|
||||||
|
#endif
|
||||||
|
UseCompressedOops ? ", compressed oops" : "",
|
||||||
|
gc_mode(),
|
||||||
|
Abstract_VM_Version::vm_platform_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// This is the main function to report a fatal error. Only one thread can
|
// This is the main function to report a fatal error. Only one thread can
|
||||||
// call this function, so we don't need to worry about MT-safety. But it's
|
// call this function, so we don't need to worry about MT-safety. But it's
|
||||||
// possible that the error handler itself may crash or die on an internal
|
// possible that the error handler itself may crash or die on an internal
|
||||||
@ -401,30 +428,7 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
|
|
||||||
STEP(90, "(printing Java version string)")
|
STEP(90, "(printing Java version string)")
|
||||||
|
|
||||||
// VM version
|
report_vm_version(st, buf, sizeof(buf));
|
||||||
st->print_cr("#");
|
|
||||||
JDK_Version::current().to_string(buf, sizeof(buf));
|
|
||||||
const char* runtime_name = JDK_Version::runtime_name() != NULL ?
|
|
||||||
JDK_Version::runtime_name() : "";
|
|
||||||
const char* runtime_version = JDK_Version::runtime_version() != NULL ?
|
|
||||||
JDK_Version::runtime_version() : "";
|
|
||||||
st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
|
|
||||||
// This is the long version with some default settings added
|
|
||||||
st->print_cr("# Java VM: %s (%s, %s%s%s%s%s, %s, %s)",
|
|
||||||
Abstract_VM_Version::vm_name(),
|
|
||||||
Abstract_VM_Version::vm_release(),
|
|
||||||
Abstract_VM_Version::vm_info_string(),
|
|
||||||
TieredCompilation ? ", tiered" : "",
|
|
||||||
#if INCLUDE_JVMCI
|
|
||||||
EnableJVMCI ? ", jvmci" : "",
|
|
||||||
UseJVMCICompiler ? ", jvmci compiler" : "",
|
|
||||||
#else
|
|
||||||
"", "",
|
|
||||||
#endif
|
|
||||||
UseCompressedOops ? ", compressed oops" : "",
|
|
||||||
gc_mode(),
|
|
||||||
Abstract_VM_Version::vm_platform_string()
|
|
||||||
);
|
|
||||||
|
|
||||||
STEP(100, "(printing problematic frame)")
|
STEP(100, "(printing problematic frame)")
|
||||||
|
|
||||||
@ -715,7 +719,6 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
if (_verbose && Universe::is_fully_initialized()) {
|
if (_verbose && Universe::is_fully_initialized()) {
|
||||||
Universe::heap()->print_on_error(st);
|
Universe::heap()->print_on_error(st);
|
||||||
st->cr();
|
st->cr();
|
||||||
|
|
||||||
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
|
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
|
||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
@ -826,6 +829,147 @@ void VMError::report(outputStream* st, bool _verbose) {
|
|||||||
# undef END
|
# undef END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report for the vm_info_cmd. This prints out the information above omitting
|
||||||
|
// crash and thread specific information. If output is added above, it should be added
|
||||||
|
// here also, if it is safe to call during a running process.
|
||||||
|
void VMError::print_vm_info(outputStream* st) {
|
||||||
|
|
||||||
|
char buf[O_BUFLEN];
|
||||||
|
report_vm_version(st, buf, sizeof(buf));
|
||||||
|
|
||||||
|
// STEP("(printing summary)")
|
||||||
|
|
||||||
|
st->cr();
|
||||||
|
st->print_cr("--------------- S U M M A R Y ------------");
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing VM option summary)")
|
||||||
|
|
||||||
|
// VM options
|
||||||
|
Arguments::print_summary_on(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing summary machine and OS info)")
|
||||||
|
|
||||||
|
os::print_summary_info(st, buf, sizeof(buf));
|
||||||
|
|
||||||
|
// STEP("(printing date and time)")
|
||||||
|
|
||||||
|
os::print_date_and_time(st, buf, sizeof(buf));
|
||||||
|
|
||||||
|
// Skip: STEP("(printing thread)")
|
||||||
|
|
||||||
|
// STEP("(printing process)")
|
||||||
|
|
||||||
|
st->cr();
|
||||||
|
st->print_cr("--------------- P R O C E S S ---------------");
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing number of OutOfMemoryError and StackOverflow exceptions)")
|
||||||
|
|
||||||
|
if (Exceptions::has_exception_counts()) {
|
||||||
|
st->print_cr("OutOfMemory and StackOverflow Exception counts:");
|
||||||
|
Exceptions::print_exception_counts_on_error(st);
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP("(printing compressed oops mode")
|
||||||
|
|
||||||
|
if (UseCompressedOops) {
|
||||||
|
Universe::print_compressed_oops_mode(st);
|
||||||
|
if (UseCompressedClassPointers) {
|
||||||
|
Metaspace::print_compressed_class_space(st);
|
||||||
|
}
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP("(printing heap information)")
|
||||||
|
|
||||||
|
if (Universe::is_fully_initialized()) {
|
||||||
|
Universe::heap()->print_on_error(st);
|
||||||
|
st->cr();
|
||||||
|
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP("(printing code cache information)")
|
||||||
|
|
||||||
|
if (Universe::is_fully_initialized()) {
|
||||||
|
// print code cache information before vm abort
|
||||||
|
CodeCache::print_summary(st);
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP("(printing ring buffers)")
|
||||||
|
|
||||||
|
Events::print_all(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing dynamic libraries)")
|
||||||
|
|
||||||
|
// dynamic libraries, or memory map
|
||||||
|
os::print_dll_info(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing VM options)")
|
||||||
|
|
||||||
|
// VM options
|
||||||
|
Arguments::print_on(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing warning if internal testing API used)")
|
||||||
|
|
||||||
|
if (WhiteBox::used()) {
|
||||||
|
st->print_cr("Unsupported internal testing APIs have been used.");
|
||||||
|
st->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP("(printing all environment variables)")
|
||||||
|
|
||||||
|
os::print_environment_variables(st, env_list);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing signal handlers)")
|
||||||
|
|
||||||
|
os::print_signal_handlers(st, buf, sizeof(buf));
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(Native Memory Tracking)")
|
||||||
|
|
||||||
|
MemTracker::error_report(st);
|
||||||
|
|
||||||
|
// STEP("(printing system)")
|
||||||
|
|
||||||
|
st->cr();
|
||||||
|
st->print_cr("--------------- S Y S T E M ---------------");
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing OS information)")
|
||||||
|
|
||||||
|
os::print_os_info(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing CPU info)")
|
||||||
|
|
||||||
|
os::print_cpu_info(st, buf, sizeof(buf));
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing memory info)")
|
||||||
|
|
||||||
|
os::print_memory_info(st);
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// STEP("(printing internal vm info)")
|
||||||
|
|
||||||
|
st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string());
|
||||||
|
st->cr();
|
||||||
|
|
||||||
|
// print a defined marker to show that error handling finished correctly.
|
||||||
|
// STEP("(printing end marker)")
|
||||||
|
|
||||||
|
st->print_cr("END.");
|
||||||
|
}
|
||||||
|
|
||||||
volatile intptr_t VMError::first_error_tid = -1;
|
volatile intptr_t VMError::first_error_tid = -1;
|
||||||
|
|
||||||
// An error could happen before tty is initialized or after it has been
|
// An error could happen before tty is initialized or after it has been
|
||||||
|
@ -88,9 +88,6 @@ class VMError : public AllStatic {
|
|||||||
static void print_stack_trace(outputStream* st, JavaThread* jt,
|
static void print_stack_trace(outputStream* st, JavaThread* jt,
|
||||||
char* buf, int buflen, bool verbose = false);
|
char* buf, int buflen, bool verbose = false);
|
||||||
|
|
||||||
static const char* gc_mode();
|
|
||||||
static void print_oom_reasons(outputStream* st);
|
|
||||||
|
|
||||||
static bool should_report_bug(unsigned int id) {
|
static bool should_report_bug(unsigned int id) {
|
||||||
return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
|
return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR);
|
||||||
}
|
}
|
||||||
@ -110,6 +107,9 @@ public:
|
|||||||
// Record status of core/minidump
|
// Record status of core/minidump
|
||||||
static void record_coredump_status(const char* message, bool status);
|
static void record_coredump_status(const char* message, bool status);
|
||||||
|
|
||||||
|
// support for VM.info diagnostic command
|
||||||
|
static void print_vm_info(outputStream* st);
|
||||||
|
|
||||||
// main error reporting function
|
// main error reporting function
|
||||||
static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
|
static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
|
||||||
Thread* thread, address pc, void* siginfo, void* context,
|
Thread* thread, address pc, void* siginfo, void* context,
|
||||||
|
91
hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java
Normal file
91
hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test TestNoEagerReclaimOfHumongousRegions
|
||||||
|
* @bug 8139424
|
||||||
|
* @summary Test to check that a live humongous object is not eagerly reclaimed. This is a regression test for
|
||||||
|
* 8139424 and the test will crash if an eager reclaim occur. The test is not 100% deterministic and
|
||||||
|
* might pass even if there are problems in the code, but it will never crash unless there is a problem.
|
||||||
|
* @requires vm.gc=="G1" | vm.gc=="null"
|
||||||
|
* @key gc
|
||||||
|
* @library /testlibrary /test/lib
|
||||||
|
* @modules java.base/sun.misc
|
||||||
|
* @build TestNoEagerReclaimOfHumongousRegions
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -XX:+PrintGC -XX:+UseG1GC -XX:MaxTenuringThreshold=0 -XX:G1RSetSparseRegionEntries=32 -XX:G1HeapRegionSize=1m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+G1TraceEagerReclaimHumongousObjects TestNoEagerReclaimOfHumongousRegions
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
public class TestNoEagerReclaimOfHumongousRegions {
|
||||||
|
// Helper class to keep reference to humongous byte[].
|
||||||
|
static class LargeRef {
|
||||||
|
private byte[] _ref;
|
||||||
|
|
||||||
|
LargeRef(byte[] ref) {
|
||||||
|
_ref = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] ref() { return _ref; }
|
||||||
|
}
|
||||||
|
|
||||||
|
static LargeRef humongous_reference_holder;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException{
|
||||||
|
WhiteBox wb = WhiteBox.getWhiteBox();
|
||||||
|
LinkedList<Object> garbageAndRefList = new LinkedList<Object>();
|
||||||
|
// Creating a 1M large byte array. Since the test specifies the heap
|
||||||
|
// region size to be 1m this will be a humongous object. We then
|
||||||
|
// store a pointer to the array in the static object to keep it live
|
||||||
|
// during the whole test.
|
||||||
|
humongous_reference_holder = new LargeRef(new byte[1 * 1024 * 1024]);
|
||||||
|
|
||||||
|
// Create some garbage and a reference to the humongous object each round.
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
garbageAndRefList.add(new byte[400*1000]);
|
||||||
|
garbageAndRefList.add(new LargeRef(humongous_reference_holder.ref()));
|
||||||
|
|
||||||
|
// Promote to old, goal is to get rem-set entries for the humongous
|
||||||
|
// object from different regions. The test specifies MaxTenuringThreshold=0,
|
||||||
|
// this will make sure we get objects promoted to old at once.
|
||||||
|
wb.youngGC();
|
||||||
|
}
|
||||||
|
// Clear the garbage and reference list.
|
||||||
|
garbageAndRefList.clear();
|
||||||
|
|
||||||
|
// Run a concurrent mark cycle to mark all references but the static one as dead.
|
||||||
|
wb.g1StartConcMarkCycle();
|
||||||
|
while (wb.g1InConcurrentMark()) {
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run a young collection to make sure humongous object still can't be eagerly reclaimed.
|
||||||
|
wb.youngGC();
|
||||||
|
// Will crash/assert if humongous object has been reclaimed.
|
||||||
|
wb.fullGC();
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,6 @@
|
|||||||
* @summary Synchronous signals during error reporting may terminate or hang VM process
|
* @summary Synchronous signals during error reporting may terminate or hang VM process
|
||||||
* @library /testlibrary
|
* @library /testlibrary
|
||||||
* @author Thomas Stuefe (SAP)
|
* @author Thomas Stuefe (SAP)
|
||||||
* @requires os.family != "mac"
|
|
||||||
* @modules java.base/sun.misc
|
* @modules java.base/sun.misc
|
||||||
* java.management
|
* java.management
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public class SEGVOverflow {
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
native static String nativesegv();
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String str = nativesegv();
|
||||||
|
if (str == null) {
|
||||||
|
System.out.println("FAILED: malloc returned null");
|
||||||
|
} else {
|
||||||
|
System.out.println(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test Testlibadimalloc.java
|
||||||
|
* @bug 8141445
|
||||||
|
* @summary make sure the Solaris Sparc M7 libadimalloc.so library generates SIGSEGV's on buffer overflow
|
||||||
|
* @requires (os.family == "solaris" & os.arch == "sparcv9")
|
||||||
|
* @library /testlibrary
|
||||||
|
* @build jdk.test.lib.*
|
||||||
|
* @compile SEGVOverflow.java
|
||||||
|
* @run driver Testlibadimalloc
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.*;
|
||||||
|
import java.util.*;
|
||||||
|
import jdk.test.lib.ProcessTools;
|
||||||
|
|
||||||
|
public class Testlibadimalloc {
|
||||||
|
|
||||||
|
// Expected return value when java program cores
|
||||||
|
static final int EXPECTED_RET_VAL = 6;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
|
||||||
|
// See if the libadimalloc.so library exists
|
||||||
|
Path path = Paths.get("/usr/lib/64/libadimalloc.so");
|
||||||
|
|
||||||
|
// If the libadimalloc.so file does not exist, pass the test
|
||||||
|
if (!(Files.isRegularFile(path) || Files.isSymbolicLink(path))) {
|
||||||
|
System.out.println("Test skipped; libadimalloc.so does not exist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the JDK, library and class path properties
|
||||||
|
String libpath = System.getProperty("java.library.path");
|
||||||
|
|
||||||
|
// Create a new java process for the SEGVOverflow Java/JNI test
|
||||||
|
ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Djava.library.path=" + libpath + ":.", "SEGVOverflow");
|
||||||
|
|
||||||
|
// Add the LD_PRELOAD_64 value to the environment
|
||||||
|
Map<String, String> env = builder.environment();
|
||||||
|
env.put("LD_PRELOAD_64", "libadimalloc.so");
|
||||||
|
|
||||||
|
// Start the process, get the pid and then wait for the test to finish
|
||||||
|
Process process = builder.start();
|
||||||
|
long pid = process.getPid();
|
||||||
|
int retval = process.waitFor();
|
||||||
|
|
||||||
|
// make sure the SEGVOverflow test crashed
|
||||||
|
boolean found = false;
|
||||||
|
if (retval == EXPECTED_RET_VAL) {
|
||||||
|
String filename = "hs_err_pid" + pid + ".log";
|
||||||
|
Path filepath = Paths.get(filename);
|
||||||
|
// check to see if hs_err_file exists
|
||||||
|
if (Files.isRegularFile(filepath)) {
|
||||||
|
// see if the crash was due to a SEGV_ACCPERR signal
|
||||||
|
File hs_err_file = new File(filename);
|
||||||
|
Scanner scanner = new Scanner(hs_err_file);
|
||||||
|
while (!found && scanner.hasNextLine()) {
|
||||||
|
String nextline = scanner.nextLine();
|
||||||
|
if (nextline.contains("SEGV_ACCPERR")) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Test failed; hs_err_file does not exist: "
|
||||||
|
+ filepath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Test failed; java test program did not " +
|
||||||
|
"return expected error: expected = " +
|
||||||
|
EXPECTED_RET_VAL + ", retval = " + retval);
|
||||||
|
}
|
||||||
|
// If SEGV_ACCPERR was not found in the hs_err file fail the test
|
||||||
|
if (!found) {
|
||||||
|
System.out.println("FAIL: SEGV_ACCPERR not found");
|
||||||
|
throw new RuntimeException("FAIL: SEGV_ACCPERR not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL Java_SEGVOverflow_nativesegv(JNIEnv *env, jobject obj) {
|
||||||
|
char *buffer1;
|
||||||
|
char *buffer2;
|
||||||
|
char *buffer3;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
jstring ret = NULL;
|
||||||
|
|
||||||
|
// sleep for a bit to let the libadimalloc library initialize
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
// allocate three buffers
|
||||||
|
buffer1 = (char *)malloc(64);
|
||||||
|
buffer2 = (char *)malloc(64);
|
||||||
|
buffer3 = (char *)malloc(64);
|
||||||
|
if ((buffer1 == NULL) || (buffer2 == NULL) || (buffer3 == NULL)) {
|
||||||
|
// this return will result in a test failure
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read past the end of each buffer multiple times to increase the probability
|
||||||
|
// that an ADI version mismatch occurs so an ADI fault is triggered.
|
||||||
|
ch = buffer1[70];
|
||||||
|
ch = buffer2[70];
|
||||||
|
ch = buffer3[70];
|
||||||
|
ch = buffer1[140];
|
||||||
|
ch = buffer2[140];
|
||||||
|
ch = buffer3[140];
|
||||||
|
|
||||||
|
// create a failed test return value because this test should have cored
|
||||||
|
buffer1 = "TEST FAILED, a read past the end of a buffer succeeded.";
|
||||||
|
ret = (*env)->NewStringUTF(env, buffer1);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user