# HG changeset patch # User lana # Date 1448918793 28800 # Node ID eac0c7fc469e42f90314412b3cf0aa5d8b9c859c # Parent 1a8be137cfee45f4e17d62ca5145453a34c5d1f3# Parent 6efbc7ffd767bfa24a1154c983269e92b53d69d5 Merge diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -1169,12 +1169,12 @@ const Register tmp = rscratch1; 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() + - PtrQueue::byte_offset_of_index())); + SATBMarkQueue::byte_offset_of_index())); Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf())); + SATBMarkQueue::byte_offset_of_buf())); Label done; Label runtime; @@ -1219,9 +1219,9 @@ const Register thread = rthread; 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() + - PtrQueue::byte_offset_of_buf())); + DirtyCardQueue::byte_offset_of_buf())); const Register card_addr = rscratch2; ExternalAddress cardtable((address) ct->byte_map_base); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -3487,18 +3487,18 @@ assert_different_registers(obj, pre_val, tmp); 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() + - PtrQueue::byte_offset_of_index())); + SATBMarkQueue::byte_offset_of_index())); Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf())); + SATBMarkQueue::byte_offset_of_buf())); // 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); } 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); } cbzw(tmp, done); @@ -3566,9 +3566,9 @@ assert(thread == rthread, "must be"); 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() + - PtrQueue::byte_offset_of_buf())); + DirtyCardQueue::byte_offset_of_buf())); BarrierSet* bs = Universe::heap()->barrier_set(); CardTableModRefBS* ct = (CardTableModRefBS*)bs; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -2633,11 +2633,11 @@ Label runtime, filtered; // Is marking active? - if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { - lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); + if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { + lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread); } else { - guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); - lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); + guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); + lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread); } cmpdi(CCR0, Rtmp1, 0); beq(CCR0, filtered); @@ -2672,13 +2672,13 @@ // (The index field is typed as size_t.) 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); 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. - 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. stdx(Rpre_val, Rbuffer, Rindex); @@ -2757,13 +2757,13 @@ const Register Rqueue_index = Rtmp2, 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); 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 - 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 b(filtered); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -630,11 +630,11 @@ Label filtered; // Is marking active? - if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { - __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); + if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { + __ lwz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread); } else { - guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption"); - __ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()), R16_thread); + guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); + __ lbz(Rtmp1, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), R16_thread); } __ cmpdi(CCR0, Rtmp1, 0); __ beq(CCR0, filtered); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -857,13 +857,13 @@ bool with_frame = false; // I don't know if we can do with-frame. int satb_q_index_byte_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_index()); + SATBMarkQueue::byte_offset_of_index()); int satb_q_buf_byte_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf()); + SATBMarkQueue::byte_offset_of_buf()); __ 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 __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp); @@ -961,14 +961,14 @@ int dirty_card_q_index_byte_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 = in_bytes(JavaThread::dirty_card_queue_offset() + - PtrQueue::byte_offset_of_buf()); + DirtyCardQueue::byte_offset_of_buf()); __ 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. __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -3632,19 +3632,19 @@ int satb_q_index_byte_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_index()); + SATBMarkQueue::byte_offset_of_index()); int satb_q_buf_byte_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf()); - - assert(in_bytes(PtrQueue::byte_width_of_index()) == sizeof(intptr_t) && - in_bytes(PtrQueue::byte_width_of_buf()) == sizeof(intptr_t), + SATBMarkQueue::byte_offset_of_buf()); + + assert(in_bytes(SATBMarkQueue::byte_width_of_index()) == sizeof(intptr_t) && + in_bytes(SATBMarkQueue::byte_width_of_buf()) == sizeof(intptr_t), "check sizes in assembly below"); __ 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. __ ld_ptr(G2_thread, satb_q_index_byte_offset, L0); @@ -3736,17 +3736,17 @@ } // Is marking active? - if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { + if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { ld(G2, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_active()), + SATBMarkQueue::byte_offset_of_active()), tmp); } else { - guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, + guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); ldsb(G2, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_active()), + SATBMarkQueue::byte_offset_of_active()), tmp); } @@ -3847,13 +3847,13 @@ int dirty_card_q_index_byte_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 = in_bytes(JavaThread::dirty_card_queue_offset() + - PtrQueue::byte_offset_of_buf()); + DirtyCardQueue::byte_offset_of_buf()); __ 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. __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, L0); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -1622,9 +1622,9 @@ NOT_LP64(__ get_thread(thread);) 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() + - PtrQueue::byte_offset_of_buf())); + SATBMarkQueue::byte_offset_of_buf())); Label done; Label runtime; @@ -1698,9 +1698,9 @@ const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); 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() + - PtrQueue::byte_offset_of_buf())); + DirtyCardQueue::byte_offset_of_buf())); __ push(rax); __ push(rcx); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -4248,18 +4248,18 @@ } 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() + - PtrQueue::byte_offset_of_index())); + SATBMarkQueue::byte_offset_of_index())); Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_buf())); + SATBMarkQueue::byte_offset_of_buf())); // 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); } 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); } jcc(Assembler::equal, done); @@ -4346,9 +4346,9 @@ #endif // _LP64 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() + - PtrQueue::byte_offset_of_buf())); + DirtyCardQueue::byte_offset_of_buf())); CardTableModRefBS* ct = barrier_set_cast(Universe::heap()->barrier_set()); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Mon Nov 30 13:26:33 2015 -0800 @@ -1193,9 +1193,12 @@ @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; - @HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset; - @HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset; - @HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset; + @HotSpotVMConstant(name = "dirtyCardQueueBufferOffset") @Stable private int dirtyCardQueueBufferOffset; + @HotSpotVMConstant(name = "dirtyCardQueueIndexOffset") @Stable private int dirtyCardQueueIndexOffset; + + @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; @@ -1396,23 +1399,23 @@ // G1 Collector Related Values. public int g1CardQueueIndexOffset() { - return javaThreadDirtyCardQueueOffset + ptrQueueIndexOffset; + return javaThreadDirtyCardQueueOffset + dirtyCardQueueIndexOffset; } public int g1CardQueueBufferOffset() { - return javaThreadDirtyCardQueueOffset + ptrQueueBufferOffset; + return javaThreadDirtyCardQueueOffset + dirtyCardQueueBufferOffset; } public int g1SATBQueueMarkingOffset() { - return javaThreadSatbMarkQueueOffset + ptrQueueActiveOffset; + return javaThreadSatbMarkQueueOffset + satbMarkQueueActiveOffset; } public int g1SATBQueueIndexOffset() { - return javaThreadSatbMarkQueueOffset + ptrQueueIndexOffset; + return javaThreadSatbMarkQueueOffset + satbMarkQueueIndexOffset; } 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; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/aix/vm/jsig.c --- a/hotspot/src/os/aix/vm/jsig.c Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/aix/vm/jsig.c Mon Nov 30 13:26:33 2015 -0800 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012, 2013 SAP AG. All rights reserved. + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012, 2015 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,26 +36,23 @@ #include #include #include +#include #define bool int #define true 1 #define false 0 -// Highest so far on AIX 5.2 is SIGSAK (63) -#define MAXSIGNUM 63 -#define MASK(sig) ((unsigned int)1 << sig) +static struct sigaction sact[NSIG]; /* saved signal handlers */ +static sigset_t jvmsigs; /* Signals used by jvm. */ -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int 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_cond_t cond = PTHREAD_COND_INITIALIZER; static pthread_t tid = 0; typedef void (*sa_handler_t)(int); 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 int (*sigaction_t)(int, const struct sigaction *, struct sigaction *); @@ -68,7 +65,7 @@ static void signal_lock() { pthread_mutex_lock(&mutex); /* 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 (tid != pthread_self()) { pthread_cond_wait(&cond, &mutex); @@ -84,10 +81,10 @@ bool is_sigset) { if (os_signal == NULL) { if (!is_sigset) { - // Aix: call functions directly instead of dlsym'ing them + // Aix: call functions directly instead of dlsym'ing them. os_signal = signal; } else { - // Aix: call functions directly instead of dlsym'ing them + // Aix: call functions directly instead of dlsym'ing them. os_signal = sigset; } if (os_signal == NULL) { @@ -112,7 +109,7 @@ signal_lock(); - sigused = (MASK(sig) & jvmsigs) != 0; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -129,7 +126,7 @@ save_signal_handler(sig, oldhandler); /* Record the signals used by jvm */ - jvmsigs |= MASK(sig); + sigaddset(&jvmsigs, sig); signal_unlock(); return oldhandler; @@ -149,12 +146,12 @@ sa_handler_t sigset(int sig, sa_handler_t disp) { return set_signal(sig, disp, true); - } +} static int call_os_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { 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; if (os_sigaction == NULL) { printf("%s\n", dlerror()); @@ -171,7 +168,7 @@ signal_lock(); - sigused = (MASK(sig) & jvmsigs) != 0; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -193,8 +190,8 @@ *oact = oldAct; } - /* Record the signals used by jvm */ - jvmsigs |= MASK(sig); + /* Record the signals used by jvm. */ + sigaddset(&jvmsigs, sig); signal_unlock(); return res; @@ -208,9 +205,10 @@ } } -/* The three functions for the jvm to call into */ +/* The three functions for the jvm to call into. */ void JVM_begin_signal_setting() { signal_lock(); + sigemptyset(&jvmsigs); jvm_signal_installing = true; tid = pthread_self(); signal_unlock(); @@ -226,7 +224,7 @@ struct sigaction *JVM_get_signal_action(int sig) { /* Does race condition make sense here? */ - if ((MASK(sig) & jvmsigs) != 0) { + if (sigismember(&jvmsigs, sig)) { return &sact[sig]; } return NULL; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -2769,8 +2769,12 @@ // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { 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; + } 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 @@ bool os::Aix::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Aix::sigact[MAXSIGNUM]; -unsigned int os::Aix::sigs = 0; +struct sigaction sigact[NSIG]; +sigset_t sigs; bool os::Aix::libjsig_is_loaded = false; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Aix::get_signal_action = NULL; @@ -3045,29 +3049,31 @@ } struct sigaction* os::Aix::get_preinstalled_handler(int sig) { - if ((((unsigned int)1 << sig) & sigs) != 0) { + if (sigismember(&sigs, sig)) { return &sigact[sig]; } return NULL; } 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; - sigs |= (unsigned int)1 << sig; + sigaddset(&sigs, sig); } // for diagnostic -int os::Aix::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; 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]; } void os::Aix::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - sigflags[sig] = flags; + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { + sigflags[sig] = flags; + } } void os::Aix::set_signal_handler(int sig, bool set_installed) { @@ -3107,7 +3113,7 @@ sigAct.sa_flags = SA_SIGINFO|SA_RESTART; } // 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; int ret = sigaction(sig, &sigAct, &oldAct); @@ -3140,10 +3146,11 @@ assert(UseSignalChaining, "should enable signal-chaining"); } if (libjsig_is_loaded) { - // Tell libjsig jvm is setting signal handlers + // Tell libjsig jvm is setting signal handlers. (*begin_signal_setting)(); } + ::sigemptyset(&sigs); set_signal_handler(SIGSEGV, true); set_signal_handler(SIGPIPE, true); set_signal_handler(SIGBUS, true); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/aix/vm/os_aix.hpp --- a/hotspot/src/os/aix/vm/os_aix.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/aix/vm/os_aix.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -34,15 +34,9 @@ class Aix { 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. #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(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -51,9 +45,6 @@ static void check_signal_handler(int sig); - // For signal flags diagnostics - static int sigflags[MAXSIGNUM]; - protected: static julong _physical_memory; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/bsd/vm/jsig.c --- a/hotspot/src/os/bsd/vm/jsig.c Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/bsd/vm/jsig.c Mon Nov 30 13:26:33 2015 -0800 @@ -36,12 +36,14 @@ #include #include #include +#include -#define MAXSIGNUM 32 -#define MASK(sig) ((unsigned int)1 << sig) - -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int jvmsigs = 0; /* signals used by jvm */ +#define MASK(sig) ((uint32_t)1 << (sig-1)) // 0 is not a signal. +#if (32 < NSIG-1) +#error "Not all signals can be encoded in jvmsigs. Adapt its type!" +#endif +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) */ /* used to synchronize the installation of signal handlers */ diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -2831,8 +2831,12 @@ // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { 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; + } 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 @@ bool os::Bsd::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Bsd::sigact[MAXSIGNUM]; -unsigned int os::Bsd::sigs = 0; +struct sigaction sigact[NSIG]; +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; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Bsd::get_signal_action = NULL; @@ -3064,29 +3071,31 @@ } 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 NULL; } 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; - sigs |= (unsigned int)1 << sig; + sigs |= (uint32_t)1 << (sig-1); } // for diagnostic -int os::Bsd::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; 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]; } void os::Bsd::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - sigflags[sig] = flags; + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { + sigflags[sig] = flags; + } } void os::Bsd::set_signal_handler(int sig, bool set_installed) { @@ -3137,7 +3146,7 @@ #endif // 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; int ret = sigaction(sig, &sigAct, &oldAct); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/bsd/vm/os_bsd.hpp --- a/hotspot/src/os/bsd/vm/os_bsd.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -40,10 +40,6 @@ friend class os; // 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(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -52,9 +48,6 @@ static void check_signal_handler(int sig); - // For signal flags diagnostics - static int sigflags[MAXSIGNUM]; - #ifdef __APPLE__ // mach_absolute_time static mach_timebase_info_data_t _timebase_info; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/linux/vm/jsig.c --- a/hotspot/src/os/linux/vm/jsig.c Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/linux/vm/jsig.c Mon Nov 30 13:26:33 2015 -0800 @@ -35,16 +35,19 @@ #include #include #include +#include #define bool int #define true 1 #define false 0 -#define MAXSIGNUM 32 -#define MASK(sig) ((unsigned int)1 << sig) - -static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ -static unsigned int jvmsigs = 0; /* signals used by jvm */ +#define MASK(sig) ((uint64_t)1 << (sig-1)) // 0 is not a signal. +// Check whether all signals fit into jvmsigs. -1 as MASK shifts by -1. +#if (64 < NSIG-1) +#error "Not all signals can be encoded in jvmsigs. Adapt its type!" +#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 */ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -107,7 +110,7 @@ signal_lock(); - sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); + sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -116,7 +119,7 @@ signal_unlock(); 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 * handlers and save the old ones. jvm uses sigaction(). * Leave the piece here just in case. */ @@ -165,7 +168,7 @@ signal_lock(); - sigused = (sig < MAXSIGNUM) && ((MASK(sig) & jvmsigs) != 0); + sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0); if (jvm_signal_installed && sigused) { /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ @@ -178,7 +181,7 @@ signal_unlock(); 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 * handlers and save the old ones. */ res = call_os_sigaction(sig, act, &oldAct); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -3989,15 +3989,19 @@ errno = old_errno; } - static int SR_initialize() { struct sigaction act; char *s; + // Get signal number to use for suspend/resume if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { 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; + } 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 @@ bool os::Linux::signal_handlers_are_installed = false; // For signal-chaining -struct sigaction os::Linux::sigact[MAXSIGNUM]; -unsigned int os::Linux::sigs = 0; +struct sigaction sigact[NSIG]; +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; typedef struct sigaction *(*get_signal_t)(int); get_signal_t os::Linux::get_signal_action = NULL; @@ -4230,29 +4237,29 @@ } 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 NULL; } 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; - sigs |= (unsigned int)1 << sig; + sigs |= (uint64_t)1 << (sig-1); } // for diagnostic -int os::Linux::sigflags[MAXSIGNUM]; +int sigflags[NSIG]; 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]; } void os::Linux::set_our_sigflags(int sig, int flags) { - assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); - if (sig > 0 && sig < MAXSIGNUM) { + assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); + if (sig > 0 && sig < NSIG) { sigflags[sig] = flags; } } @@ -4292,7 +4299,7 @@ sigAct.sa_flags = SA_SIGINFO|SA_RESTART; } // 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; int ret = sigaction(sig, &sigAct, &oldAct); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/linux/vm/os_linux.hpp --- a/hotspot/src/os/linux/vm/os_linux.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/linux/vm/os_linux.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -34,11 +34,6 @@ friend class os; 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(), // __sigaction(), signal() is loaded static struct sigaction *(*get_signal_action)(int); @@ -47,9 +42,6 @@ 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 (*_pthread_getcpuclockid)(pthread_t, clockid_t *); static int (*_pthread_setname_np)(pthread_t, const char*); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/solaris/vm/jvm_solaris.h --- a/hotspot/src/os/solaris/vm/jvm_solaris.h Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/solaris/vm/jvm_solaris.h Mon Nov 30 13:26:33 2015 -0800 @@ -91,10 +91,6 @@ #define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ #define SHUTDOWN2_SIGNAL SIGINT #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 */ #define JSIG_VERSION_1_4_1 0x30140100 diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -997,9 +997,8 @@ } // defined for >= Solaris 10. This allows builds on earlier versions -// of Solaris to take advantage of the newly reserved Solaris JVM signals -// With SIGJVM1, SIGJVM2, ASYNC_SIGNAL is SIGJVM2 and -XX:+UseAltSigs does -// nothing since these should have no conflict. Previously INTERRUPT_SIGNAL +// of Solaris to take advantage of the newly reserved Solaris JVM signals. +// With SIGJVM1, SIGJVM2, ASYNC_SIGNAL is SIGJVM2. Previously INTERRUPT_SIGNAL // was SIGJVM1. // #if !defined(SIGJVM1) @@ -1053,13 +1052,9 @@ sigaddset(&unblocked_sigs, SIGBUS); sigaddset(&unblocked_sigs, SIGFPE); - if (isJVM1available) { - os::Solaris::set_SIGasync(SIGJVM2); - } else if (UseAltSigs) { - os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL); - } else { - os::Solaris::set_SIGasync(ASYNC_SIGNAL); - } + // Always true on Solaris 10+ + guarantee(isJVM1available(), "SIGJVM1/2 missing!"); + os::Solaris::set_SIGasync(SIGJVM2); sigaddset(&unblocked_sigs, os::Solaris::SIGasync()); @@ -3922,7 +3917,7 @@ // save the old handler in jvm save_preinstalled_handler(sig, oldAct); } 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 // old sigaction on it own. @@ -3991,7 +3986,7 @@ 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()); } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/os/solaris/vm/os_solaris.hpp --- a/hotspot/src/os/solaris/vm/os_solaris.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -113,9 +113,6 @@ 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_preinstalled_handler(int); static int (*get_libjsig_version)(); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -1464,10 +1464,10 @@ bool do_load, bool patch, CodeEmitInfo* info) { // First we test whether marking is in progress. 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; } else { - guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, + guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); // 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. @@ -1477,7 +1477,7 @@ LIR_Address* mark_active_flag_addr = new LIR_Address(thrd, in_bytes(JavaThread::satb_mark_queue_offset() + - PtrQueue::byte_offset_of_active()), + SATBMarkQueue::byte_offset_of_active()), flag_type); // Read the marking-in-progress flag. LIR_Opr flag_val = new_register(T_INT); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/cms/promotionInfo.cpp --- a/hotspot/src/share/vm/gc/cms/promotionInfo.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/cms/promotionInfo.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -233,41 +233,11 @@ _tracking = true; } -#define CMSPrintPromoBlockInfo 1 - void PromotionInfo::stopTrackingPromotions(uint worker_id) { assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex, "spooling inconsistency?"); _firstIndex = _nextIndex = 1; _tracking = false; - if (CMSPrintPromoBlockInfo > 1) { - print_statistics(worker_id); - } -} - -void PromotionInfo::print_statistics(uint worker_id) const { - assert(_spoolHead == _spoolTail && _firstIndex == _nextIndex, - "Else will undercount"); - assert(CMSPrintPromoBlockInfo > 0, "Else unnecessary call"); - // Count the number of blocks and slots in the free pool - size_t slots = 0; - size_t blocks = 0; - for (SpoolBlock* cur_spool = _spareSpool; - cur_spool != NULL; - cur_spool = cur_spool->nextSpoolBlock) { - // the first entry is just a self-pointer; indices 1 through - // bufferSize - 1 are occupied (thus, bufferSize - 1 slots). - assert((void*)cur_spool->displacedHdr == (void*)&cur_spool->displacedHdr, - "first entry of displacedHdr should be self-referential"); - slots += cur_spool->bufferSize - 1; - blocks++; - } - if (_spoolHead != NULL) { - slots += _spoolHead->bufferSize - 1; - blocks++; - } - gclog_or_tty->print_cr(" [worker %d] promo_blocks = " SIZE_FORMAT ", promo_slots = " SIZE_FORMAT, - worker_id, blocks, slots); } // When _spoolTail is not NULL, then the slot <_spoolTail, _nextIndex> diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/cms/promotionInfo.hpp --- a/hotspot/src/share/vm/gc/cms/promotionInfo.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/cms/promotionInfo.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -207,7 +207,6 @@ } void print_on(outputStream* st) const; - void print_statistics(uint worker_id) const; }; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp --- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -119,20 +119,6 @@ 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) { // Used to determine if we had already claimed a par_id diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp --- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -72,6 +72,18 @@ void **get_buf() { return _buf;} size_t get_index() { return _index;} void reinitialize() { _buf = 0; _sz = 0; _index = 0;} + + // Compiler support. + static ByteSize byte_offset_of_index() { + return PtrQueue::byte_offset_of_index(); + } + using PtrQueue::byte_width_of_index; + + static ByteSize byte_offset_of_buf() { + return PtrQueue::byte_offset_of_buf(); + } + using PtrQueue::byte_width_of_buf; + }; @@ -112,14 +124,6 @@ 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 // specified closure to all its elements, nulling out those elements // processed. If all elements are processed, returns "true". If no diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1Allocator.cpp --- a/hotspot/src/share/vm/gc/g1/g1Allocator.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1Allocator.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -33,6 +33,8 @@ G1DefaultAllocator::G1DefaultAllocator(G1CollectedHeap* heap) : G1Allocator(heap), + _survivor_is_full(false), + _old_is_full(false), _retained_old_gc_alloc_region(NULL), _survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)), _old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)) { @@ -87,7 +89,8 @@ void G1DefaultAllocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { 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(); _old_gc_alloc_region.init(); @@ -118,6 +121,22 @@ _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) : PLAB(gclab_word_size), _retired(true) { } @@ -165,22 +184,6 @@ } } -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, size_t desired_word_size, size_t* actual_word_size, @@ -232,11 +235,6 @@ return result; } -void G1Allocator::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { - _survivor_is_full = false; - _old_is_full = false; -} - G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : _g1h(G1CollectedHeap::heap()), _allocator(allocator), diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1Allocator.hpp --- a/hotspot/src/share/vm/gc/g1/g1Allocator.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1Allocator.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -38,19 +38,16 @@ // Also keeps track of retained regions across GCs. class G1Allocator : public CHeapObj { friend class VMStructs; -private: - bool _survivor_is_full; - bool _old_is_full; protected: G1CollectedHeap* _g1h; virtual MutatorAllocRegion* mutator_alloc_region(AllocationContext_t context) = 0; - virtual bool survivor_is_full(AllocationContext_t context) const; - virtual bool old_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 = 0; - virtual void set_survivor_full(AllocationContext_t context); - virtual void set_old_full(AllocationContext_t context); + virtual void set_survivor_full(AllocationContext_t context) = 0; + virtual void set_old_full(AllocationContext_t context) = 0; // Accessors to the allocation regions. virtual SurvivorGCAllocRegion* survivor_gc_alloc_region(AllocationContext_t context) = 0; @@ -67,7 +64,7 @@ size_t* actual_word_size, AllocationContext_t context); public: - G1Allocator(G1CollectedHeap* heap) : _g1h(heap), _survivor_is_full(false), _old_is_full(false) { } + G1Allocator(G1CollectedHeap* heap) : _g1h(heap) { } virtual ~G1Allocator() { } static G1Allocator* create_allocator(G1CollectedHeap* g1h); @@ -79,7 +76,7 @@ virtual void init_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 abandon_gc_alloc_regions() = 0; @@ -119,6 +116,9 @@ // and old generation allocation region. // Can retain the (single) old generation allocation region across GCs. class G1DefaultAllocator : public G1Allocator { +private: + bool _survivor_is_full; + bool _old_is_full; protected: // Alloc region used to satisfy mutator allocation requests. MutatorAllocRegion _mutator_alloc_region; @@ -135,6 +135,12 @@ public: 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 release_mutator_alloc_region(); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -2278,6 +2278,10 @@ // And as a result the region we'll allocate will be humongous. 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) { // Let's use the existing mechanism for the allocation HeapWord* dummy_obj = humongous_obj_allocate(word_size, @@ -3561,6 +3565,9 @@ } } } + 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(); } assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty."); @@ -3848,6 +3855,13 @@ 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(); assert(check_cset_fast_test(), "Inconsistency in the InCSetState table."); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -467,8 +467,19 @@ } 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; } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp --- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -272,7 +272,7 @@ size_t _pending_cards; public: - G1Predictions& predictor() { return _predictor; } + const G1Predictions& predictor() const { return _predictor; } // Accessors diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp --- a/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1ParScanThreadState.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -84,7 +84,7 @@ public: G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, size_t young_cset_length); - ~G1ParScanThreadState(); + virtual ~G1ParScanThreadState(); void set_ref_processor(ReferenceProcessor* rp) { _scanner.set_ref_processor(rp); } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -307,7 +307,6 @@ } void G1RemSet::prepare_for_oops_into_collection_set_do() { - cleanupHRRS(); _g1->set_refine_cte_cl_concurrency(false); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); dcqs.concatenate_logs(); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/ptrQueue.hpp --- a/hotspot/src/share/vm/gc/g1/ptrQueue.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/ptrQueue.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -140,19 +140,27 @@ } // To support compiler. + +protected: + template 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)); } + template 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*)); } + template 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)); } }; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/satbMarkQueue.hpp --- a/hotspot/src/share/vm/gc/g1/satbMarkQueue.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/satbMarkQueue.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -68,6 +68,23 @@ void print(const char* name); static void print(const char* name, void** buf, size_t index, size_t sz); #endif // PRODUCT + + // Compiler support. + static ByteSize byte_offset_of_index() { + return PtrQueue::byte_offset_of_index(); + } + using PtrQueue::byte_width_of_index; + + static ByteSize byte_offset_of_buf() { + return PtrQueue::byte_offset_of_buf(); + } + using PtrQueue::byte_width_of_buf; + + static ByteSize byte_offset_of_active() { + return PtrQueue::byte_offset_of_active(); + } + using PtrQueue::byte_width_of_active; + }; class SATBMarkQueueSet: public PtrQueueSet { diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/g1/vmStructs_g1.hpp --- a/hotspot/src/share/vm/gc/g1/vmStructs_g1.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/vmStructs_g1.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -28,6 +28,7 @@ #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegionManager.hpp" +#include "utilities/macros.hpp" #define VM_STRUCTS_G1(nonstatic_field, static_field) \ \ @@ -62,6 +63,34 @@ \ nonstatic_field(HeapRegionSetCount, _length, uint) \ 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) \ @@ -76,10 +105,10 @@ declare_toplevel_type(HeapRegionSetBase) \ declare_toplevel_type(HeapRegionSetCount) \ declare_toplevel_type(G1MonitoringSupport) \ + declare_toplevel_type(PtrQueue) \ \ declare_toplevel_type(G1CollectedHeap*) \ declare_toplevel_type(HeapRegion*) \ declare_toplevel_type(G1MonitoringSupport*) \ - #endif // SHARE_VM_GC_G1_VMSTRUCTS_G1_HPP diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/parallel/pcTasks.cpp --- a/hotspot/src/share/vm/gc/parallel/pcTasks.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/parallel/pcTasks.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -52,8 +52,6 @@ ResourceMark rm; - NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); @@ -81,8 +79,6 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm); @@ -152,8 +148,6 @@ { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - NOT_PRODUCT(GCTraceTime tm("RefProcTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm); @@ -208,9 +202,6 @@ void StealMarkingTask::do_it(GCTaskManager* manager, uint which) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - NOT_PRODUCT(GCTraceTime tm("StealMarkingTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); ParCompactionManager::MarkAndPushClosure mark_and_push_closure(cm); @@ -240,9 +231,6 @@ void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); @@ -307,9 +295,6 @@ void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) { - NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); @@ -322,9 +307,6 @@ void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask", - PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -1319,3 +1319,11 @@ } return retVal; } + +void GenCollectedHeap::stop() { +#if INCLUDE_ALL_GCS + if (UseConcMarkSweepGC) { + ConcurrentMarkSweepThread::stop(); + } +#endif +} diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp --- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -499,6 +499,9 @@ protected: void gc_prologue(bool full); void gc_epilogue(bool full); + +public: + void stop(); }; #endif // SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/logging/logPrefix.hpp --- a/hotspot/src/share/vm/logging/logPrefix.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/logging/logPrefix.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -27,12 +27,17 @@ #include "gc/shared/gcId.hpp" #include "logging/logTag.hpp" -// Prefixes prepend each log message for a specified tagset with the given prefix. -// A prefix consists of a format string and a value or callback. Prefixes are added -// after the decorations but before the log message. +// Prefixes prepend each log message for a specified tagset with a given prefix. +// These prefixes are written before the log message but after the log decorations. +// +// 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. -// Syntax: LOG_PREFIX(, , LOG_TAGS()) +// Syntax: LOG_PREFIX(, LOG_TAGS()) +// Where the prefixer function matches the following signature: size_t (*)(char*, size_t) #define LOG_PREFIX_LIST // Currently unused/empty // The empty prefix, used when there's no prefix defined. @@ -44,12 +49,12 @@ } }; -#define LOG_PREFIX(fmt, fn, ...) \ +#define LOG_PREFIX(fn, ...) \ template <> struct LogPrefix<__VA_ARGS__> { \ static size_t prefix(char* buf, size_t len) { \ - int ret = jio_snprintf(buf, len, fmt, fn); \ - assert(ret >= 0, \ - "Failed to prefix log message using prefix ('%s', '%s'), log buffer too small?", fmt, #fn); \ + DEBUG_ONLY(buf[0] = '\0';) \ + size_t ret = fn(buf, len); \ + assert(ret == strlen(buf), "Length mismatch ret (" SIZE_FORMAT ") != buf length (" SIZE_FORMAT ")", ret, strlen(buf)); \ return ret; \ } \ }; diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/opto/compile.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -3549,7 +3549,7 @@ void Compile::verify_barriers() { if (UseG1GC) { // 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(); Unique_Node_List visited(area); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/opto/escape.cpp --- a/hotspot/src/share/vm/opto/escape.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/opto/escape.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -539,11 +539,11 @@ if (tls->Opcode() == Op_ThreadLocal) { int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot); 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. } 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. } } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -3986,16 +3986,16 @@ float likely = PROB_LIKELY(0.999); float unlikely = PROB_UNLIKELY(0.999); - BasicType active_type = in_bytes(PtrQueue::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"); + BasicType active_type = in_bytes(SATBMarkQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE; + assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 4 || in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "flag width"); // Offsets into the thread 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 - PtrQueue::byte_offset_of_index()); + SATBMarkQueue::byte_offset_of_index()); 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 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset)); @@ -4008,7 +4008,7 @@ // if (!marking) __ if_then(marking, BoolTest::ne, zero, unlikely); { 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); if (do_load) { @@ -4196,9 +4196,9 @@ // Offsets into the thread 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() + - PtrQueue::byte_offset_of_buf()); + DirtyCardQueue::byte_offset_of_buf()); // Pointers into the thread diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/opto/macro.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -290,7 +290,7 @@ cmpx->in(1)->is_Load()) { Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address); 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() && adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && adr->in(AddPNode::Offset) == MakeConX(marking_offset)) { diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -74,6 +74,7 @@ } \ } while(0) +char* Arguments::_jvm_flags_file = NULL; char** Arguments::_jvm_flags_array = NULL; int Arguments::_num_jvm_flags = 0; char** Arguments::_jvm_args_array = NULL; @@ -365,6 +366,7 @@ { "StarvationMonitorInterval", 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) }, + { "UseAltSigs", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) }, #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS { "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() }, @@ -2948,11 +2950,12 @@ round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) { return JNI_EINVAL; } - // -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads + // -Xoss, -Xsqnopause, -Xoptimize, -Xboundthreads, -Xusealtsigs } else if (match_option(option, "-Xoss", &tail) || match_option(option, "-Xsqnopause") || 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 char version[256]; JDK_Version::jdk(9).to_string(version, sizeof(version)); @@ -3035,11 +3038,6 @@ if (FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true) != Flag::SUCCESS) { 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 } else if (match_option(option, "-Xprof")) { #if INCLUDE_FPROF @@ -3932,7 +3930,6 @@ #endif // PRODUCT jint Arguments::insert_vm_options_file(const JavaVMInitArgs* args, - char** flags_file, char** vm_options_file, const int vm_options_file_pos, ScopedVMInitArgs *vm_options_file_args, @@ -3951,13 +3948,12 @@ } jint Arguments::match_special_option_and_act(const JavaVMInitArgs* args, - char ** flags_file, char ** vm_options_file, - ScopedVMInitArgs* vm_options_file_args, ScopedVMInitArgs* args_out) { // Remaining part of option string const char* tail; int vm_options_file_pos = -1; + ScopedVMInitArgs vm_options_file_args; for (int index = 0; index < args->nOptions; index++) { const JavaVMOption* option = args->options + index; @@ -3965,12 +3961,7 @@ continue; } if (match_option(option, "-XX:Flags=", &tail)) { - *flags_file = (char *) tail; - if (*flags_file == NULL) { - jio_fprintf(defaultStream::error_stream(), - "Cannot copy flags_file name.\n"); - return JNI_ENOMEM; - } + Arguments::set_jvm_flags_file(tail); continue; } if (match_option(option, "-XX:VMOptionsFile=", &tail)) { @@ -3986,9 +3977,9 @@ *vm_options_file = (char *) tail; vm_options_file_pos = index; // save position of -XX:VMOptionsFile // If there's a VMOptionsFile, parse that (also can set flags_file) - jint code = insert_vm_options_file(args, flags_file, vm_options_file, + jint code = insert_vm_options_file(args, vm_options_file, vm_options_file_pos, - vm_options_file_args, args_out); + &vm_options_file_args, args_out); if (code != JNI_OK) { return code; } @@ -4084,16 +4075,12 @@ // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed. const char* hotspotrc = ".hotspotrc"; - char* flags_file = NULL; char* vm_options_file = NULL; bool settings_file_specified = false; bool needs_hotspotrc_warning = false; ScopedVMInitArgs java_tool_options_args; ScopedVMInitArgs java_options_args; ScopedVMInitArgs modified_cmd_line_args; - // Pass in vm_options_file_args to keep memory for flags_file from being - // deallocated if found in the vm options file. - ScopedVMInitArgs vm_options_file_args; jint code = parse_java_tool_options_environment_variable(&java_tool_options_args); @@ -4107,13 +4094,12 @@ } code = match_special_option_and_act(java_tool_options_args.get(), - &flags_file, NULL, NULL, NULL); + NULL, NULL); if (code != JNI_OK) { return code; } - code = match_special_option_and_act(args, &flags_file, &vm_options_file, - &vm_options_file_args, + code = match_special_option_and_act(args, &vm_options_file, &modified_cmd_line_args); if (code != JNI_OK) { return code; @@ -4125,12 +4111,13 @@ args = modified_cmd_line_args.get(); } - code = match_special_option_and_act(java_options_args.get(), &flags_file, - NULL, NULL, NULL); + code = match_special_option_and_act(java_options_args.get(), + NULL, NULL); if (code != JNI_OK) { return code; } + const char * flags_file = Arguments::get_jvm_flags_file(); settings_file_specified = (flags_file != NULL); if (IgnoreUnrecognizedVMOptions) { diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -244,6 +244,8 @@ private: + // a pointer to the flags file name if it is specified + static char* _jvm_flags_file; // an array containing all flags specified in the .hotspotrc file static char** _jvm_flags_array; static int _num_jvm_flags; @@ -378,15 +380,12 @@ static jint parse_vm_options_file(const char* file_name, ScopedVMInitArgs* vm_args); static jint parse_options_buffer(const char* name, char* buffer, const size_t buf_len, ScopedVMInitArgs* vm_args); static jint insert_vm_options_file(const JavaVMInitArgs* args, - char** flags_file, char** vm_options_file, const int vm_options_file_pos, ScopedVMInitArgs* vm_options_file_args, ScopedVMInitArgs* args_out); static jint match_special_option_and_act(const JavaVMInitArgs* args, - char** flags_file, char** vm_options_file, - ScopedVMInitArgs* vm_options_file_args, ScopedVMInitArgs* args_out); static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, @@ -514,6 +513,14 @@ static void print_on(outputStream* st); static void print_summary_on(outputStream* st); + // convenient methods to get and set jvm_flags_file + static const char* get_jvm_flags_file() { return _jvm_flags_file; } + static void set_jvm_flags_file(const char *value) { + if (_jvm_flags_file != NULL) { + os::free(_jvm_flags_file); + } + _jvm_flags_file = os::strdup_check_oom(value); + } // convenient methods to obtain / print jvm_flags and jvm_args static const char* jvm_flags() { return build_resource_string(_jvm_flags_array, _num_jvm_flags); } static const char* jvm_args() { return build_resource_string(_jvm_args_array, _num_jvm_args); } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -1334,10 +1334,6 @@ "Use signal-chaining to invoke signal handlers installed " \ "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, \ "Allow JNIEnv proxies for jdbx") \ \ @@ -2523,9 +2519,6 @@ develop(bool, TraceWorkGang, false, \ "Trace activities of work gangs") \ \ - product(bool, TraceParallelOldGCTasks, false, \ - "Trace multithreaded GC activity") \ - \ develop(bool, TraceBlockOffsetTable, false, \ "Print BlockOffsetTable maps") \ \ diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -1378,10 +1378,6 @@ nonstatic_field(vframeArrayElement, _bci, int) \ 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(elapsedTimer, _counter, jlong) \ nonstatic_field(elapsedTimer, _active, bool) \ @@ -2273,8 +2269,6 @@ /* Miscellaneous types */ \ /***************/ \ \ - declare_toplevel_type(PtrQueue) \ - \ /* freelist */ \ declare_toplevel_type(FreeChunk*) \ declare_toplevel_type(AdaptiveFreeList*) \ @@ -3066,6 +3060,9 @@ #define GENERATE_VM_INT_CONSTANT_ENTRY(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) \ { name, (int32_t) value }, @@ -3296,6 +3293,9 @@ VM_INT_CONSTANTS_CMS(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 #if INCLUDE_TRACE diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -56,6 +56,7 @@ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); @@ -323,6 +324,10 @@ } } +void VMInfoDCmd::execute(DCmdSource source, TRAPS) { + VMError::print_vm_info(_output); +} + void SystemGCDCmd::execute(DCmdSource source, TRAPS) { if (!DisableExplicitGC) { Universe::heap()->collect(GCCause::_dcmd_gc_run); diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/services/diagnosticCommand.hpp --- a/hotspot/src/share/vm/services/diagnosticCommand.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -213,6 +213,23 @@ 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 { public: SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/utilities/debug.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -331,7 +331,9 @@ volatile int x = 0; volatile int y = 1/x; #ifndef _WIN32 - raise(SIGFPE); + // OSX implements raise(sig) incorrectly so we need to + // explicitly target the current thread + pthread_kill(pthread_self(), SIGFPE); #endif } // end: crash_with_sigfpe diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Mon Nov 30 13:26:33 2015 -0800 @@ -201,7 +201,7 @@ #endif // ZERO } -void VMError::print_oom_reasons(outputStream* st) { +static void print_oom_reasons(outputStream* st) { st->print_cr("# Possible reasons:"); 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"); @@ -217,7 +217,7 @@ 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 (UseParallelGC) return "parallel gc"; if (UseConcMarkSweepGC) return "concurrent mark sweep gc"; @@ -225,6 +225,33 @@ 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 // 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 @@ -401,30 +428,7 @@ STEP(90, "(printing Java version string)") - // VM version - 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() - ); + report_vm_version(st, buf, sizeof(buf)); STEP(100, "(printing problematic frame)") @@ -715,7 +719,6 @@ if (_verbose && 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(); } @@ -826,6 +829,147 @@ # 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; // An error could happen before tty is initialized or after it has been diff -r 1a8be137cfee -r eac0c7fc469e hotspot/src/share/vm/utilities/vmError.hpp --- a/hotspot/src/share/vm/utilities/vmError.hpp Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/src/share/vm/utilities/vmError.hpp Mon Nov 30 13:26:33 2015 -0800 @@ -88,9 +88,6 @@ static void print_stack_trace(outputStream* st, JavaThread* jt, 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) { return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR); } @@ -110,6 +107,9 @@ // Record status of core/minidump 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 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, diff -r 1a8be137cfee -r eac0c7fc469e hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestNoEagerReclaimOfHumongousRegions.java Mon Nov 30 13:26:33 2015 -0800 @@ -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 garbageAndRefList = new LinkedList(); + // 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(); + } +} diff -r 1a8be137cfee -r eac0c7fc469e hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java --- a/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/test/runtime/ErrorHandling/SecondaryErrorTest.java Mon Nov 30 13:26:33 2015 -0800 @@ -28,7 +28,6 @@ * @summary Synchronous signals during error reporting may terminate or hang VM process * @library /testlibrary * @author Thomas Stuefe (SAP) - * @requires os.family != "mac" * @modules java.base/sun.misc * java.management */ diff -r 1a8be137cfee -r eac0c7fc469e hotspot/test/runtime/logging/SafepointTest.java --- a/hotspot/test/runtime/logging/SafepointTest.java Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/test/runtime/logging/SafepointTest.java Mon Nov 30 13:26:33 2015 -0800 @@ -41,11 +41,9 @@ "-Xlog:safepoint=trace", "SafepointTestMain"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Safepoint synchronization initiated. ("); - output.shouldContain(" thread(s) to block"); output.shouldContain("Entering safepoint region: "); output.shouldContain("Leaving safepoint region"); output.shouldContain("_at_poll_safepoint"); - output.shouldContain("... found polling page "); output.shouldHaveExitValue(0); } } diff -r 1a8be137cfee -r eac0c7fc469e hotspot/test/runtime/logging/SafepointTestMain.java --- a/hotspot/test/runtime/logging/SafepointTestMain.java Sun Nov 29 11:00:00 2015 -0800 +++ b/hotspot/test/runtime/logging/SafepointTestMain.java Mon Nov 30 13:26:33 2015 -0800 @@ -24,21 +24,6 @@ import java.lang.ref.WeakReference; public class SafepointTestMain { - public static class B { - static int count = 0; - public static volatile boolean stop = false; - static void localSleep(int time) { - try{ - Thread.currentThread().sleep(time); - } catch(InterruptedException ie) { - } - } - - public static void infinite() { - while (!stop) { count++; } - } - } - public static byte[] garbage; public static volatile WeakReference weakref; @@ -48,16 +33,7 @@ } public static void main(String[] args) throws Exception { - // Run function in separate thread to force compilation and pint safepoint - // message for compiled method - new Thread() { - public void run() { - B.infinite(); - } - }.start(); - B.localSleep(1000); - // Cause several safepoints to run GC while the compiled method is running, - // to see safepoint messages + // Cause several safepoints to run GC to see safepoint messages for (int i = 0; i < 2; i++) { createweakref(); while(weakref.get() != null) { @@ -65,6 +41,5 @@ System.gc(); } } - B.stop = true; } }