annotate src/share/vm/runtime/safepoint.cpp @ 6862:8a5ea0a9ccc4

7127708: G1: change task num types from int to uint in concurrent mark Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich. Reviewed-by: johnc Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author johnc
date Sat, 06 Oct 2012 01:17:44 -0700
parents d2a62e0f25eb
children 957c266d8bc5 f34d701e952e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1538
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1538
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1538
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
25 #include "precompiled.hpp"
6162
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
26 #include "classfile/symbolTable.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
28 #include "code/codeCache.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
29 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
30 #include "code/nmethod.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
31 #include "code/pcDesc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
32 #include "code/scopeDesc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
33 #include "gc_interface/collectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
34 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
35 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
36 #include "memory/universe.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
37 #include "oops/oop.inline.hpp"
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 1972
diff changeset
38 #include "oops/symbol.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
39 #include "runtime/compilationPolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
40 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
41 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
42 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
43 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
44 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
45 #include "runtime/safepoint.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
46 #include "runtime/signature.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
47 #include "runtime/stubCodeGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
48 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
49 #include "runtime/sweeper.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
50 #include "runtime/synchronizer.hpp"
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
51 #include "services/memTracker.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
52 #include "services/runtimeService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
53 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
54 #ifdef TARGET_ARCH_x86
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
55 # include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
56 # include "vmreg_x86.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
57 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
58 #ifdef TARGET_ARCH_sparc
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
59 # include "nativeInst_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
60 # include "vmreg_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
61 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
62 #ifdef TARGET_ARCH_zero
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
63 # include "nativeInst_zero.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
64 # include "vmreg_zero.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
65 #endif
2192
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
66 #ifdef TARGET_ARCH_arm
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
67 # include "nativeInst_arm.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
68 # include "vmreg_arm.inline.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
69 #endif
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
70 #ifdef TARGET_ARCH_ppc
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
71 # include "nativeInst_ppc.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
72 # include "vmreg_ppc.inline.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2177
diff changeset
73 #endif
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
74 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
75 # include "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
76 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
77 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
78 # include "thread_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
79 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
80 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
81 # include "thread_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
82 #endif
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3767
diff changeset
83 #ifdef TARGET_OS_FAMILY_bsd
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3767
diff changeset
84 # include "thread_bsd.inline.hpp"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3767
diff changeset
85 #endif
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
86 #ifndef SERIALGC
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
87 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
88 #include "gc_implementation/shared/concurrentGCThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
89 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
90 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
91 #include "c1/c1_globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1905
diff changeset
92 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // --------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // Implementation of Safepoint begin/end
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 volatile int SafepointSynchronize::_waiting_to_block = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 volatile int SafepointSynchronize::_safepoint_counter = 0;
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
100 int SafepointSynchronize::_current_jni_active_count = 0;
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
101 long SafepointSynchronize::_end_of_last_safepoint = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static bool timeout_error_printed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Roll all threads forward to a safepoint and suspend them all
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void SafepointSynchronize::begin() {
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 Thread* myThread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
110 assert(myThread->is_VM_thread(), "Only VM thread may execute a safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
111
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
112 if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
113 _safepoint_begin_time = os::javaTimeNanos();
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
114 _ts_of_current_safepoint = tty->time_stamp().seconds();
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
115 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
118 if (UseConcMarkSweepGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // In the future we should investigate whether CMS can use the
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // more-general mechanism below. DLD (01/05).
a61af66fc99e Initial load
duke
parents:
diff changeset
121 ConcurrentMarkSweepThread::synchronize(false);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 628
diff changeset
122 } else if (UseG1GC) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
123 ConcurrentGCThread::safepoint_synchronize();
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // By getting the Threads_lock, we assure that no threads are about to start or
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // exit. It is released again in SafepointSynchronize::end().
a61af66fc99e Initial load
duke
parents:
diff changeset
129 Threads_lock->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert( _state == _not_synchronized, "trying to safepoint synchronize with wrong state");
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 int nof_threads = Threads::number_of_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 if (TraceSafepoint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 tty->print_cr("Safepoint synchronization initiated. (%d)", nof_threads);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 RuntimeService::record_safepoint_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 MutexLocker mu(Safepoint_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
142
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
143 // Reset the count of active JNI critical threads
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
144 _current_jni_active_count = 0;
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
145
0
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Set number of threads to wait for, before we initiate the callbacks
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _waiting_to_block = nof_threads;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 TryingToBlock = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 int still_running = nof_threads;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Save the starting time, so that it can be compared to see if this has taken
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // too long to complete.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 jlong safepoint_limit_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 timeout_error_printed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
155
1003
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
156 // PrintSafepointStatisticsTimeout can be specified separately. When
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
157 // specified, PrintSafepointStatistics will be set to true in
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
158 // deferred_initialize_stat method. The initialization has to be done
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
159 // early enough to avoid any races. See bug 6880029 for details.
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
160 if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
161 deferred_initialize_stat();
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
162 }
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
163
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Begin the process of bringing the system to a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Java threads can be in several different states and are
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // stopped by different mechanisms:
a61af66fc99e Initial load
duke
parents:
diff changeset
167 //
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // 1. Running interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // The interpeter dispatch table is changed to force it to
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // check for a safepoint condition between bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // 2. Running in native code
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // When returning from the native code, a Java thread must check
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // the safepoint _state to see if we must block. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // VM thread sees a Java thread in native, it does
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // not wait for this thread to block. The order of the memory
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // writes and reads of both the safepoint state and the Java
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // threads state is critical. In order to guarantee that the
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // memory writes are serialized with respect to each other,
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // the VM thread issues a memory barrier instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // (on MP systems). In order to avoid the overhead of issuing
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // a memory barrier for each Java thread making native calls, each Java
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // thread performs a write to a single memory page after changing
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // the thread state. The VM thread performs a sequence of
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // mprotect OS calls which forces all previous writes from all
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Java threads to be serialized. This is done in the
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // os::serialize_thread_states() call. This has proven to be
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // much more efficient than executing a membar instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // on every call to native code.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // 3. Running compiled Code
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Compiled code reads a global (Safepoint Polling) page that
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // is set to fault if we are trying to get to a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // 4. Blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // A thread which is blocked will not be allowed to return from the
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // block condition until the safepoint operation is complete.
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // 5. In VM or Transitioning between states
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // If a Java thread is currently running in the VM or transitioning
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // between states, the safepointing code will wait for the thread to
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // block itself when it attempts transitions to a new state.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 //
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _state = _synchronizing;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // Flush all thread states to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (!UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 os::serialize_thread_states();
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // Make interpreter safepoint aware
a61af66fc99e Initial load
duke
parents:
diff changeset
209 Interpreter::notice_safepoints();
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (UseCompilerSafepoints && DeferPollingPageLoopCount < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // Make polling safepoint aware
a61af66fc99e Initial load
duke
parents:
diff changeset
213 guarantee (PageArmed == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 PageArmed = 1 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 os::make_polling_page_unreadable();
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Consider using active_processor_count() ... but that call is expensive.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 int ncpus = os::processor_count() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
222 for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 assert(cur->safepoint_state()->is_running(), "Illegal initial state");
5928
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
224 // Clear the visited flag to ensure that the critical counts are collected properly.
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
225 cur->set_visited_for_critical_count(false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (SafepointTimeout)
a61af66fc99e Initial load
duke
parents:
diff changeset
230 safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // Iterate through all threads until it have been determined how to stop them all at a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
233 unsigned int iterations = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 int steps = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 while(still_running > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
238 ThreadSafepointState *cur_state = cur->safepoint_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (cur_state->is_running()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 cur_state->examine_state_of_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (!cur_state->is_running()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 still_running--;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // consider adjusting steps downward:
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // steps = 0
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // steps -= NNN
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // steps >>= 1
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // steps = MIN(steps, 2000-100)
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // if (iterations != 0) steps -= NNN
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if (TraceSafepoint && Verbose) cur_state->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253
1003
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
254 if (PrintSafepointStatistics && iterations == 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
255 begin_statistics(nof_threads, still_running);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if (still_running > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // Check for if it takes to long
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 print_safepoint_timeout(_spinning_timeout);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Spin to avoid context switching.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // There's a tension between allowing the mutators to run (and rendezvous)
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // vs spinning. As the VM thread spins, wasting cycles, it consumes CPU that
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // a mutator might otherwise use profitably to reach a safepoint. Excessive
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // spinning by the VM thread on a saturated system can increase rendezvous latency.
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Blocking or yielding incur their own penalties in the form of context switching
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // and the resultant loss of $ residency.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 //
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // Further complicating matters is that yield() does not work as naively expected
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // on many platforms -- yield() does not guarantee that any other ready threads
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // will run. As such we revert yield_all() after some number of iterations.
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Yield_all() is implemented as a short unconditional sleep on some platforms.
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Typical operating systems round a "short" sleep period up to 10 msecs, so sleeping
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // can actually increase the time it takes the VM thread to detect that a system-wide
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // stop-the-world safepoint has been reached. In a pathological scenario such as that
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // described in CR6415670 the VMthread may sleep just before the mutator(s) become safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // In that case the mutators will be stalled waiting for the safepoint to complete and the
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // the VMthread will be sleeping, waiting for the mutators to rendezvous. The VMthread
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // will eventually wake up and detect that all mutators are safe, at which point
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // we'll again make progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 //
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Beware too that that the VMThread typically runs at elevated priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // Its default priority is higher than the default mutator priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Obviously, this complicates spinning.
a61af66fc99e Initial load
duke
parents:
diff changeset
288 //
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Note too that on Windows XP SwitchThreadTo() has quite different behavior than Sleep(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Sleep(0) will _not yield to lower priority threads, while SwitchThreadTo() will.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 //
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // See the comments in synchronizer.cpp for additional remarks on spinning.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 //
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // In the future we might:
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // 1. Modify the safepoint scheme to avoid potentally unbounded spinning.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // This is tricky as the path used by a thread exiting the JVM (say on
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // on JNI call-out) simply stores into its state field. The burden
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // is placed on the VM thread, which must poll (spin).
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // 2. Find something useful to do while spinning. If the safepoint is GC-related
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // we might aggressively scan the stacks of threads that are already safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // 3. Use Solaris schedctl to examine the state of the still-running mutators.
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // If all the mutators are ONPROC there's no reason to sleep or yield.
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // 4. YieldTo() any still-running mutators that are ready but OFFPROC.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // 5. Check system saturation. If the system is not fully saturated then
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // simply spin and avoid sleep/yield.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // 6. As still-running mutators rendezvous they could unpark the sleeping
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // VMthread. This works well for still-running mutators that become
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // safe. The VMthread must still poll for mutators that call-out.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // 7. Drive the policy on time-since-begin instead of iterations.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // 8. Consider making the spin duration a function of the # of CPUs:
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Spin = (((ncpus-1) * M) + K) + F(still_running)
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Alternately, instead of counting iterations of the outer loop
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // we could count the # of threads visited in the inner loop, above.
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // 9. On windows consider using the return value from SwitchThreadTo()
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 if (UseCompilerSafepoints && int(iterations) == DeferPollingPageLoopCount) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 guarantee (PageArmed == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 PageArmed = 1 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 os::make_polling_page_unreadable();
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus)
a61af66fc99e Initial load
duke
parents:
diff changeset
325 ++steps ;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if (ncpus > 1 && steps < SafepointSpinBeforeYield) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 SpinPause() ; // MP-Polite spin
a61af66fc99e Initial load
duke
parents:
diff changeset
328 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (steps < DeferThrSuspendLoopCount) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 os::NakedYield() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 os::yield_all(steps) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Alternately, the VM thread could transiently depress its scheduling priority or
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // transiently increase the priority of the tardy mutator(s).
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 iterations ++ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 assert(iterations < (uint)max_jint, "We have been iterating in the safepoint loop too long");
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 assert(still_running == 0, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (PrintSafepointStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 update_statistics_on_spin_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // wait until all threads are stopped
a61af66fc99e Initial load
duke
parents:
diff changeset
348 while (_waiting_to_block > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if (TraceSafepoint) tty->print_cr("Waiting for %d thread(s) to block", _waiting_to_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (!SafepointTimeout || timeout_error_printed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 Safepoint_lock->wait(true); // true, means with no safepoint checks
a61af66fc99e Initial load
duke
parents:
diff changeset
352 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Compute remaining time
a61af66fc99e Initial load
duke
parents:
diff changeset
354 jlong remaining_time = safepoint_limit_time - os::javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // If there is no remaining time, then there is an error
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time / MICROUNITS)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 print_safepoint_timeout(_blocking_timeout);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 assert(_waiting_to_block == 0, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if (SafepointTimeout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 jlong current_time = os::javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 if (safepoint_limit_time < current_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 tty->print_cr("# SafepointSynchronize: Finished after "
a61af66fc99e Initial load
duke
parents:
diff changeset
369 INT64_FORMAT_W(6) " ms",
a61af66fc99e Initial load
duke
parents:
diff changeset
370 ((current_time - safepoint_limit_time) / MICROUNITS +
a61af66fc99e Initial load
duke
parents:
diff changeset
371 SafepointTimeoutDelay));
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 assert((_safepoint_counter & 0x1) == 0, "must be even");
a61af66fc99e Initial load
duke
parents:
diff changeset
377 assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
378 _safepoint_counter ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Record state
a61af66fc99e Initial load
duke
parents:
diff changeset
381 _state = _synchronized;
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
384
5928
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
385 #ifdef ASSERT
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
386 for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
387 // make sure all the threads were visited
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
388 assert(cur->was_visited_for_critical_count(), "missed a thread");
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
389 }
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
390 #endif // ASSERT
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
391
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
392 // Update the count of active JNI critical regions
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
393 GC_locker::set_jni_lock_count(_current_jni_active_count);
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
394
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if (TraceSafepoint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
396 VM_Operation *op = VMThread::vm_operation();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 tty->print_cr("Entering safepoint region: %s", (op != NULL) ? op->name() : "no vm operation");
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 RuntimeService::record_safepoint_synchronized();
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (PrintSafepointStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 update_statistics_on_sync_end(os::javaTimeNanos());
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Call stuff that needs to be run when a safepoint is just about to be completed
a61af66fc99e Initial load
duke
parents:
diff changeset
406 do_cleanup_tasks();
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
407
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
408 if (PrintSafepointStatistics) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
409 // Record how much time spend on the above cleanup tasks
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
410 update_statistics_on_cleanup_end(os::javaTimeNanos());
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
411 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Wake up all threads, so they are ready to resume execution after the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // operation has been carried out
a61af66fc99e Initial load
duke
parents:
diff changeset
416 void SafepointSynchronize::end() {
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert((_safepoint_counter & 0x1) == 1, "must be odd");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 _safepoint_counter ++;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // memory fence isn't required here since an odd _safepoint_counter
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // value can do no harm and a fence is issued below anyway.
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 DEBUG_ONLY(Thread* myThread = Thread::current();)
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert(myThread->is_VM_thread(), "Only VM thread can execute a safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (PrintSafepointStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 end_statistics(os::javaTimeNanos());
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // A pending_exception cannot be installed during a safepoint. The threads
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // may install an async exception after they come back from a safepoint into
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // pending_exception after they unblock. But that should happen later.
a61af66fc99e Initial load
duke
parents:
diff changeset
435 for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 assert (!(cur->has_pending_exception() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
437 cur->safepoint_state()->is_at_poll_safepoint()),
a61af66fc99e Initial load
duke
parents:
diff changeset
438 "safepoint installed a pending exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (PageArmed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Make polling safepoint aware
a61af66fc99e Initial load
duke
parents:
diff changeset
444 os::make_polling_page_readable();
a61af66fc99e Initial load
duke
parents:
diff changeset
445 PageArmed = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Remove safepoint check from interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
449 Interpreter::ignore_safepoints();
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 MutexLocker mu(Safepoint_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Set to not synchronized, so the threads will not go into the signal_thread_blocked method
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // when they get restarted.
a61af66fc99e Initial load
duke
parents:
diff changeset
458 _state = _not_synchronized;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (TraceSafepoint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 tty->print_cr("Leaving safepoint region");
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Start suspended threads
a61af66fc99e Initial load
duke
parents:
diff changeset
466 for(JavaThread *current = Threads::first(); current; current = current->next()) {
605
98cb887364d3 6810672: Comment typos
twisti
parents: 513
diff changeset
467 // A problem occurring on Solaris is when attempting to restart threads
0
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // the first #cpus - 1 go well, but then the VMThread is preempted when we get
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // to the next one (since it has been running the longest). We then have
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // to wait for a cpu to become available before we can continue restarting
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // FIXME: This causes the performance of the VM to degrade when active and with
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // large numbers of threads. Apparently this is due to the synchronous nature
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // of suspending threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 //
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // TODO-FIXME: the comments above are vestigial and no longer apply.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // Furthermore, using solaris' schedctl in this particular context confers no benefit
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (VMThreadHintNoPreempt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 os::hint_no_preempt();
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 ThreadSafepointState* cur_state = current->safepoint_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
482 assert(cur_state->type() != ThreadSafepointState::_running, "Thread not suspended at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
483 cur_state->restart();
a61af66fc99e Initial load
duke
parents:
diff changeset
484 assert(cur_state->is_running(), "safepoint state has not been reset");
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 RuntimeService::record_safepoint_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // Release threads lock, so threads can be created/destroyed again. It will also starts all threads
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // blocked in signal_thread_blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
491 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // If there are any concurrent GC threads resume them.
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (UseConcMarkSweepGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 ConcurrentMarkSweepThread::desynchronize(false);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 628
diff changeset
498 } else if (UseG1GC) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
499 ConcurrentGCThread::safepoint_desynchronize();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 #endif // SERIALGC
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
502 // record this time so VMThread can keep track how much time has elasped
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
503 // since last safepoint.
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
504 _end_of_last_safepoint = os::javaTimeMillis();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 bool SafepointSynchronize::is_cleanup_needed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // Need a safepoint if some inline cache buffers is non-empty
a61af66fc99e Initial load
duke
parents:
diff changeset
509 if (!InlineCacheBuffer::is_empty()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Various cleaning tasks that should be done periodically at safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
516 void SafepointSynchronize::do_cleanup_tasks() {
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
517 {
1321
0f6600cee529 6934758: Expose the break down of clean up task time during safepoint.
xlu
parents: 1291
diff changeset
518 TraceTime t1("deflating idle monitors", TraceSafepointCleanupTime);
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
519 ObjectSynchronizer::deflate_idle_monitors();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
522 {
1321
0f6600cee529 6934758: Expose the break down of clean up task time during safepoint.
xlu
parents: 1291
diff changeset
523 TraceTime t2("updating inline caches", TraceSafepointCleanupTime);
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
524 InlineCacheBuffer::update_inline_caches();
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
525 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1727
diff changeset
526 {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1727
diff changeset
527 TraceTime t3("compilation policy safepoint handler", TraceSafepointCleanupTime);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1727
diff changeset
528 CompilationPolicy::policy()->do_safepoint_work();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
530
6162
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
531 {
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
532 TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime);
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
533 NMethodSweeper::scan_stacks();
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
534 }
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
535
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
536 if (SymbolTable::needs_rehashing()) {
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
537 TraceTime t5("rehashing symbol table", TraceSafepointCleanupTime);
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
538 SymbolTable::rehash_table();
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
539 }
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
540
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
541 if (StringTable::needs_rehashing()) {
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
542 TraceTime t6("rehashing string table", TraceSafepointCleanupTime);
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
543 StringTable::rehash_table();
e9140bf80b4a 7158800: Improve storage of symbol tables
coleenp
parents: 5928
diff changeset
544 }
3767
2a241e764894 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 2426
diff changeset
545
2a241e764894 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 2426
diff changeset
546 // rotate log files?
2a241e764894 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 2426
diff changeset
547 if (UseGCLogFileRotation) {
2a241e764894 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 2426
diff changeset
548 gclog_or_tty->rotate_log();
2a241e764894 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 2426
diff changeset
549 }
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
550
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
551 if (MemTracker::is_on()) {
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
552 MemTracker::sync();
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
553 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 bool SafepointSynchronize::safepoint_safe(JavaThread *thread, JavaThreadState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 switch(state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 case _thread_in_native:
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // native threads are safe if they have no java stack or have walkable stack
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return !thread->has_last_Java_frame() || thread->frame_anchor()->walkable();
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // blocked threads should have already have walkable stack
a61af66fc99e Initial load
duke
parents:
diff changeset
564 case _thread_blocked:
a61af66fc99e Initial load
duke
parents:
diff changeset
565 assert(!thread->has_last_Java_frame() || thread->frame_anchor()->walkable(), "blocked and not walkable");
a61af66fc99e Initial load
duke
parents:
diff changeset
566 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
569 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
574 // See if the thread is running inside a lazy critical native and
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
575 // update the thread critical count if so. Also set a suspend flag to
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
576 // cause the native wrapper to return into the JVM to do the unlock
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
577 // once the native finishes.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
578 void SafepointSynchronize::check_for_lazy_critical_native(JavaThread *thread, JavaThreadState state) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
579 if (state == _thread_in_native &&
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
580 thread->has_last_Java_frame() &&
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
581 thread->frame_anchor()->walkable()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
582 // This thread might be in a critical native nmethod so look at
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
583 // the top of the stack and increment the critical count if it
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
584 // is.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
585 frame wrapper_frame = thread->last_frame();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
586 CodeBlob* stub_cb = wrapper_frame.cb();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
587 if (stub_cb != NULL &&
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
588 stub_cb->is_nmethod() &&
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
589 stub_cb->as_nmethod_or_null()->is_lazy_critical_native()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
590 // A thread could potentially be in a critical native across
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
591 // more than one safepoint, so only update the critical state on
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
592 // the first one. When it returns it will perform the unlock.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
593 if (!thread->do_critical_native_unlock()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
594 #ifdef ASSERT
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
595 if (!thread->in_critical()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
596 GC_locker::increment_debug_jni_lock_count();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
597 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
598 #endif
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
599 thread->enter_critical();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
600 // Make sure the native wrapper calls back on return to
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
601 // perform the needed critical unlock.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
602 thread->set_critical_native_unlock();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
603 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
604 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
605 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
606 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
607
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
608
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4867
diff changeset
609
0
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // -------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // Implementation of Safepoint callback point
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 void SafepointSynchronize::block(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 assert(thread != NULL, "thread must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
615 assert(thread->is_Java_thread(), "not a Java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // Threads shouldn't block if they are in the middle of printing, but...
a61af66fc99e Initial load
duke
parents:
diff changeset
618 ttyLocker::break_tty_lock_for_safepoint(os::current_thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Only bail from the block() call if the thread is gone from the
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // thread list; starting to exit should still block.
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (thread->is_terminated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // block current thread if we come here from native code when VM is gone
a61af66fc99e Initial load
duke
parents:
diff changeset
624 thread->block_if_vm_exited();
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // otherwise do nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
627 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 JavaThreadState state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
631 thread->frame_anchor()->make_walkable(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // Check that we have a valid thread_state at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
634 switch(state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 case _thread_in_vm_trans:
a61af66fc99e Initial load
duke
parents:
diff changeset
636 case _thread_in_Java: // From compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // We are highly likely to block on the Safepoint_lock. In order to avoid blocking in this case,
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // we pretend we are still in the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 thread->set_thread_state(_thread_in_vm);
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 if (is_synchronizing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
643 Atomic::inc (&TryingToBlock) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // We will always be holding the Safepoint_lock when we are examine the state
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // of a thread. Hence, the instructions between the Safepoint_lock->lock() and
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // Safepoint_lock->unlock() are happening atomic with regards to the safepoint code
a61af66fc99e Initial load
duke
parents:
diff changeset
649 Safepoint_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
650 if (is_synchronizing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Decrement the number of threads to wait for and signal vm thread
a61af66fc99e Initial load
duke
parents:
diff changeset
652 assert(_waiting_to_block > 0, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
653 _waiting_to_block--;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 thread->safepoint_state()->set_has_called_back(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
655
5928
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
656 DEBUG_ONLY(thread->set_visited_for_critical_count(true));
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
657 if (thread->in_critical()) {
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
658 // Notice that this thread is in a critical section
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
659 increment_jni_active_count();
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
660 }
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
661
0
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // Consider (_waiting_to_block < 2) to pipeline the wakeup of the VM thread
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if (_waiting_to_block == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 Safepoint_lock->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // We transition the thread to state _thread_blocked here, but
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // we can't do our usual check for external suspension and then
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // self-suspend after the lock_without_safepoint_check() call
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // below because we are often called during transitions while
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // we hold different locks. That would leave us suspended while
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // holding a resource which results in deadlocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 thread->set_thread_state(_thread_blocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 Safepoint_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // We now try to acquire the threads lock. Since this lock is hold by the VM thread during
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // the entire safepoint, the threads will all line up here during the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
679 Threads_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // restore original state. This is important if the thread comes from compiled code, so it
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // will continue to execute with the _thread_in_Java state.
a61af66fc99e Initial load
duke
parents:
diff changeset
682 thread->set_thread_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
683 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
684 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 case _thread_in_native_trans:
a61af66fc99e Initial load
duke
parents:
diff changeset
687 case _thread_blocked_trans:
a61af66fc99e Initial load
duke
parents:
diff changeset
688 case _thread_new_trans:
a61af66fc99e Initial load
duke
parents:
diff changeset
689 if (thread->safepoint_state()->type() == ThreadSafepointState::_call_back) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 thread->print_thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 fatal("Deadlock in safepoint code. "
a61af66fc99e Initial load
duke
parents:
diff changeset
692 "Should have called back to the VM before blocking.");
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // We transition the thread to state _thread_blocked here, but
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // we can't do our usual check for external suspension and then
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // self-suspend after the lock_without_safepoint_check() call
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // below because we are often called during transitions while
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // we hold different locks. That would leave us suspended while
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // holding a resource which results in deadlocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
701 thread->set_thread_state(_thread_blocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // It is not safe to suspend a thread if we discover it is in _thread_in_native_trans. Hence,
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // the safepoint code might still be waiting for it to block. We need to change the state here,
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // so it can see that it is at a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // Block until the safepoint operation is completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
708 Threads_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // Restore state
a61af66fc99e Initial load
duke
parents:
diff changeset
711 thread->set_thread_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
714 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 default:
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1321
diff changeset
717 fatal(err_msg("Illegal threadstate encountered: %d", state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // Check for pending. async. exceptions or suspends - except if the
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // thread was blocked inside the VM. has_special_runtime_exit_condition()
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // is called last since it grabs a lock and we only want to do that when
a61af66fc99e Initial load
duke
parents:
diff changeset
723 // we must.
a61af66fc99e Initial load
duke
parents:
diff changeset
724 //
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Note: we never deliver an async exception at a polling point as the
a61af66fc99e Initial load
duke
parents:
diff changeset
726 // compiler may not have an exception handler for it. The polling
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // code will notice the async and deoptimize and the exception will
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // be delivered. (Polling at a return point is ok though). Sure is
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // a lot of bother for a deprecated feature...
a61af66fc99e Initial load
duke
parents:
diff changeset
730 //
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // We don't deliver an async exception if the thread state is
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // _thread_in_native_trans so JNI functions won't be called with
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // a surprising pending exception. If the thread state is going back to java,
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // async exception is checked in check_special_condition_for_native_trans().
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (state != _thread_blocked_trans &&
a61af66fc99e Initial load
duke
parents:
diff changeset
737 state != _thread_in_vm_trans &&
a61af66fc99e Initial load
duke
parents:
diff changeset
738 thread->has_special_runtime_exit_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 thread->handle_special_runtime_exit_condition(
a61af66fc99e Initial load
duke
parents:
diff changeset
740 !thread->is_at_poll_safepoint() && (state != _thread_in_native_trans));
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // ------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
748 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
749 #define PTR_PAD ""
a61af66fc99e Initial load
duke
parents:
diff changeset
750 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
751 #define PTR_PAD " "
a61af66fc99e Initial load
duke
parents:
diff changeset
752 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
753
a61af66fc99e Initial load
duke
parents:
diff changeset
754 static void print_ptrs(intptr_t oldptr, intptr_t newptr, bool wasoop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 bool is_oop = newptr ? ((oop)newptr)->is_oop() : false;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 tty->print_cr(PTR_FORMAT PTR_PAD " %s %c " PTR_FORMAT PTR_PAD " %s %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
757 oldptr, wasoop?"oop":" ", oldptr == newptr ? ' ' : '!',
a61af66fc99e Initial load
duke
parents:
diff changeset
758 newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" "));
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 static void print_longs(jlong oldptr, jlong newptr, bool wasoop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 bool is_oop = newptr ? ((oop)(intptr_t)newptr)->is_oop() : false;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 tty->print_cr(PTR64_FORMAT " %s %c " PTR64_FORMAT " %s %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
764 oldptr, wasoop?"oop":" ", oldptr == newptr ? ' ' : '!',
a61af66fc99e Initial load
duke
parents:
diff changeset
765 newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" "));
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
769 static void print_me(intptr_t *new_sp, intptr_t *old_sp, bool *was_oops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
771 tty->print_cr("--------+------address-----+------before-----------+-------after----------+");
a61af66fc99e Initial load
duke
parents:
diff changeset
772 const int incr = 1; // Increment to skip a long, in units of intptr_t
a61af66fc99e Initial load
duke
parents:
diff changeset
773 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
774 tty->print_cr("--------+--address-+------before-----------+-------after----------+");
a61af66fc99e Initial load
duke
parents:
diff changeset
775 const int incr = 2; // Increment to skip a long, in units of intptr_t
a61af66fc99e Initial load
duke
parents:
diff changeset
776 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
777 tty->print_cr("---SP---|");
a61af66fc99e Initial load
duke
parents:
diff changeset
778 for( int i=0; i<16; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
779 tty->print("blob %c%d |"PTR_FORMAT" ","LO"[i>>3],i&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 tty->print_cr("--------|");
a61af66fc99e Initial load
duke
parents:
diff changeset
781 for( int i1=0; i1<frame::memory_parameter_word_sp_offset-16; i1++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 tty->print("argv pad|"PTR_FORMAT" ",new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
783 tty->print(" pad|"PTR_FORMAT" ",new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 tty->print_cr("--------|");
a61af66fc99e Initial load
duke
parents:
diff changeset
785 tty->print(" G1 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 tty->print(" G3 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
a61af66fc99e Initial load
duke
parents:
diff changeset
787 tty->print(" G4 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 tty->print(" G5 |"PTR_FORMAT" ",new_sp); print_longs(*(jlong*)old_sp,*(jlong*)new_sp,was_oops[incr-1]); old_sp += incr; new_sp += incr; was_oops += incr;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 tty->print_cr(" FSR |"PTR_FORMAT" "PTR64_FORMAT" "PTR64_FORMAT,new_sp,*(jlong*)old_sp,*(jlong*)new_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
790 old_sp += incr; new_sp += incr; was_oops += incr;
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // Skip the floats
a61af66fc99e Initial load
duke
parents:
diff changeset
792 tty->print_cr("--Float-|"PTR_FORMAT,new_sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 tty->print_cr("---FP---|");
a61af66fc99e Initial load
duke
parents:
diff changeset
794 old_sp += incr*32; new_sp += incr*32; was_oops += incr*32;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 for( int i2=0; i2<16; i2++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
796 tty->print("call %c%d |"PTR_FORMAT" ","LI"[i2>>3],i2&7,new_sp); print_ptrs(*old_sp++,*new_sp++,*was_oops++); }
a61af66fc99e Initial load
duke
parents:
diff changeset
797 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
799 #endif // SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
800 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
801
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
805 assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
a61af66fc99e Initial load
duke
parents:
diff changeset
806 assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Uncomment this to get some serious before/after printing of the
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // Sparc safepoint-blob frame structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
810 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
811 intptr_t* sp = thread->last_Java_sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
812 intptr_t stack_copy[150];
a61af66fc99e Initial load
duke
parents:
diff changeset
813 for( int i=0; i<150; i++ ) stack_copy[i] = sp[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
814 bool was_oops[150];
a61af66fc99e Initial load
duke
parents:
diff changeset
815 for( int i=0; i<150; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
816 was_oops[i] = stack_copy[i] ? ((oop)stack_copy[i])->is_oop() : false;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 */
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 if (ShowSafepointMsgs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 tty->print("handle_polling_page_exception: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 if (PrintSafepointStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
824 inc_page_trap_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 ThreadSafepointState* state = thread->safepoint_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 state->handle_polling_page_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // print_me(sp,stack_copy,was_oops);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 if (!timeout_error_printed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 timeout_error_printed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Print out the thread infor which didn't reach the safepoint for debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // purposes (useful when there are lots of threads in the debugger).
a61af66fc99e Initial load
duke
parents:
diff changeset
839 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
840 tty->print_cr("# SafepointSynchronize::begin: Timeout detected:");
a61af66fc99e Initial load
duke
parents:
diff changeset
841 if (reason == _spinning_timeout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 tty->print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint.");
a61af66fc99e Initial load
duke
parents:
diff changeset
843 } else if (reason == _blocking_timeout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 tty->print_cr("# SafepointSynchronize::begin: Timed out while waiting for threads to stop.");
a61af66fc99e Initial load
duke
parents:
diff changeset
845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
a61af66fc99e Initial load
duke
parents:
diff changeset
848 ThreadSafepointState *cur_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
849 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 for(JavaThread *cur_thread = Threads::first(); cur_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
851 cur_thread = cur_thread->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 cur_state = cur_thread->safepoint_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 if (cur_thread->thread_state() != _thread_blocked &&
a61af66fc99e Initial load
duke
parents:
diff changeset
855 ((reason == _spinning_timeout && cur_state->is_running()) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
856 (reason == _blocking_timeout && !cur_state->has_called_back()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 tty->print("# ");
a61af66fc99e Initial load
duke
parents:
diff changeset
858 cur_thread->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
859 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 tty->print_cr("# SafepointSynchronize::begin: (End of list)");
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // To debug the long safepoint, specify both DieOnSafepointTimeout &
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // ShowMessageBoxOnError.
a61af66fc99e Initial load
duke
parents:
diff changeset
867 if (DieOnSafepointTimeout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
868 char msg[1024];
a61af66fc99e Initial load
duke
parents:
diff changeset
869 VM_Operation *op = VMThread::vm_operation();
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 0
diff changeset
870 sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
871 SafepointTimeoutDelay,
a61af66fc99e Initial load
duke
parents:
diff changeset
872 op != NULL ? op->name() : "no vm operation");
a61af66fc99e Initial load
duke
parents:
diff changeset
873 fatal(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // -------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // Implementation of ThreadSafepointState
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 ThreadSafepointState::ThreadSafepointState(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
882 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 _type = _running;
a61af66fc99e Initial load
duke
parents:
diff changeset
884 _has_called_back = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
885 _at_poll_safepoint = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 void ThreadSafepointState::create(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 ThreadSafepointState *state = new ThreadSafepointState(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
890 thread->set_safepoint_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 void ThreadSafepointState::destroy(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (thread->safepoint_state()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 delete(thread->safepoint_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
896 thread->set_safepoint_state(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 void ThreadSafepointState::examine_state_of_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
901 assert(is_running(), "better be running or just have hit safepoint poll");
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 JavaThreadState state = _thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
904
1727
da877bdc9000 6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents: 1552
diff changeset
905 // Save the state at the start of safepoint processing.
da877bdc9000 6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents: 1552
diff changeset
906 _orig_thread_state = state;
da877bdc9000 6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents: 1552
diff changeset
907
0
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // Check for a thread that is suspended. Note that thread resume tries
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // to grab the Threads_lock which we own here, so a thread cannot be
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // resumed during safepoint synchronization.
a61af66fc99e Initial load
duke
parents:
diff changeset
911
979
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
912 // We check to see if this thread is suspended without locking to
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
913 // avoid deadlocking with a third thread that is waiting for this
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
914 // thread to be suspended. The third thread can notice the safepoint
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
915 // that we're trying to start at the beginning of its SR_lock->wait()
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
916 // call. If that happens, then the third thread will block on the
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
917 // safepoint while still holding the underlying SR_lock. We won't be
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
918 // able to get the SR_lock and we'll deadlock.
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
919 //
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
920 // We don't need to grab the SR_lock here for two reasons:
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
921 // 1) The suspend flags are both volatile and are set with an
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
922 // Atomic::cmpxchg() call so we should see the suspended
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
923 // state right away.
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
924 // 2) We're being called from the safepoint polling loop; if
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
925 // we don't see the suspended state on this iteration, then
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
926 // we'll come around again.
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
927 //
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 845
diff changeset
928 bool is_suspended = _thread->is_ext_suspended();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
929 if (is_suspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
930 roll_forward(_at_safepoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
931 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // Some JavaThread states have an initial safepoint state of
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // running, but are actually at a safepoint. We will happily
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // agree and update the safepoint state here.
a61af66fc99e Initial load
duke
parents:
diff changeset
937 if (SafepointSynchronize::safepoint_safe(_thread, state)) {
5928
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
938 SafepointSynchronize::check_for_lazy_critical_native(_thread, state);
4867
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
939 roll_forward(_at_safepoint);
1a2723f7ad8e 7129164: JNI Get/ReleasePrimitiveArrayCritical doesn't scale
never
parents: 3960
diff changeset
940 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if (state == _thread_in_vm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 roll_forward(_call_back);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // All other thread states will continue to run until they
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // transition and self-block in state _blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Safepoint polling in compiled code causes the Java threads to do the same.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Note: new threads may require a malloc so they must be allowed to finish
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 assert(is_running(), "examine_state_of_thread on non-running thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
954 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Returns true is thread could not be rolled forward at present position.
a61af66fc99e Initial load
duke
parents:
diff changeset
958 void ThreadSafepointState::roll_forward(suspend_type type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
959 _type = type;
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 switch(_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 case _at_safepoint:
a61af66fc99e Initial load
duke
parents:
diff changeset
963 SafepointSynchronize::signal_thread_at_safepoint();
5928
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
964 DEBUG_ONLY(_thread->set_visited_for_critical_count(true));
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
965 if (_thread->in_critical()) {
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
966 // Notice that this thread is in a critical section
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
967 SafepointSynchronize::increment_jni_active_count();
541c4a5e7b88 7150390: JFR test crashed on assert(_jni_lock_count == count) failed: must be equal
never
parents: 4873
diff changeset
968 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
969 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 case _call_back:
a61af66fc99e Initial load
duke
parents:
diff changeset
972 set_has_called_back(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 case _running:
a61af66fc99e Initial load
duke
parents:
diff changeset
976 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
977 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 void ThreadSafepointState::restart() {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 switch(type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 case _at_safepoint:
a61af66fc99e Initial load
duke
parents:
diff changeset
984 case _call_back:
a61af66fc99e Initial load
duke
parents:
diff changeset
985 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 case _running:
a61af66fc99e Initial load
duke
parents:
diff changeset
988 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
989 tty->print_cr("restart thread "INTPTR_FORMAT" with state %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
990 _thread, _type);
a61af66fc99e Initial load
duke
parents:
diff changeset
991 _thread->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
992 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
994 _type = _running;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 set_has_called_back(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998
a61af66fc99e Initial load
duke
parents:
diff changeset
999 void ThreadSafepointState::print_on(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 const char *s;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 switch(_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 case _running : s = "_running"; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 case _at_safepoint : s = "_at_safepoint"; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 case _call_back : s = "_call_back"; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 st->print_cr("Thread: " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 " [0x%2x] State: %s _has_called_back %d _at_poll_safepoint %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 _thread, _thread->osthread()->thread_id(), s, _has_called_back,
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 _at_poll_safepoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 _thread->print_thread_state_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // ---------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // Block the thread at the safepoint poll or poll return.
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 void ThreadSafepointState::handle_polling_page_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // Check state. block() will set thread state to thread_in_vm which will
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // cause the safepoint state _type to become _call_back.
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 assert(type() == ThreadSafepointState::_running,
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 "polling page exception on thread not running state");
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // Step 1: Find the nmethod from the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 if (ShowSafepointMsgs && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 tty->print_cr("Polling page exception at " INTPTR_FORMAT, thread()->saved_exception_pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 address real_return_addr = thread()->saved_exception_pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 CodeBlob *cb = CodeCache::find_blob(real_return_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 assert(cb != NULL && cb->is_nmethod(), "return address should be in nmethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 nmethod* nm = (nmethod*)cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // Find frame of caller
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 frame stub_fr = thread()->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 CodeBlob* stub_cb = stub_fr.cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 assert(stub_cb->is_safepoint_stub(), "must be a safepoint stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 RegisterMap map(thread(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 frame caller_fr = stub_fr.sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // Should only be poll_return or poll
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 assert( nm->is_at_poll_or_poll_return(real_return_addr), "should not be at call" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // This is a poll immediately before a return. The exception handling code
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // has already had the effect of causing the return to occur, so the execution
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // will continue immediately after the call. In addition, the oopmap at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // return point does not mark the return value as an oop (if it is), so
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // it needs a handle here to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if( nm->is_at_poll_return(real_return_addr) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // See if return type is an oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 bool return_oop = nm->method()->is_returning_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 Handle return_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 if (return_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // The oop result has been saved on the stack together with all
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // the other registers. In order to preserve it over GCs we need
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // to keep it in a handle.
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 oop result = caller_fr.saved_oop_result(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 assert(result == NULL || result->is_oop(), "must be oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 return_value = Handle(thread(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // Block the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 SafepointSynchronize::block(thread());
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 // restore oop result, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 if (return_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 caller_fr.set_saved_oop_result(&map, return_value());
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // This is a safepoint poll. Verify the return address and block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 set_at_poll_safepoint(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // verify the blob built the "return address" correctly
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 assert(real_return_addr == caller_fr.pc(), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // Block the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 SafepointSynchronize::block(thread());
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 set_at_poll_safepoint(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // If we have a pending async exception deoptimize the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // as otherwise we may never deliver it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 if (thread()->has_async_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 ThreadInVMfromJavaNoAsyncException __tiv(thread());
1905
ce6848d0666d 6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents: 1783
diff changeset
1092 Deoptimization::deoptimize_frame(thread(), caller_fr.id());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1094
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // If an exception has been installed we must check for a pending deoptimization
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 // Deoptimize frame if exception has been thrown.
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (thread()->has_pending_exception() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 RegisterMap map(thread(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 frame caller_fr = stub_fr.sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 if (caller_fr.is_deoptimized_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // The exception patch will destroy registers that are still
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // live and will be needed during deoptimization. Defer the
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // Async exception should have defered the exception until the
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // next safepoint which will be detected when we get into
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // the interpreter so if we have an exception now things
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // are messed up.
a61af66fc99e Initial load
duke
parents:
diff changeset
1108
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 fatal("Exception installed and deoptimization is pending");
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // Statistics & Instrumentations
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 SafepointSynchronize::SafepointStats* SafepointSynchronize::_safepoint_stats = NULL;
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1120 jlong SafepointSynchronize::_safepoint_begin_time = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 int SafepointSynchronize::_cur_stat_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 julong SafepointSynchronize::_safepoint_reasons[VM_Operation::VMOp_Terminating];
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 julong SafepointSynchronize::_coalesced_vmop_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 jlong SafepointSynchronize::_max_sync_time = 0;
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1125 jlong SafepointSynchronize::_max_vmop_time = 0;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1126 float SafepointSynchronize::_ts_of_current_safepoint = 0.0f;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1128 static jlong cleanup_end_time = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 static bool need_to_track_page_armed_status = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 static bool init_done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1131
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1132 // Helper method to print the header.
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1133 static void print_header() {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1134 tty->print(" vmop "
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1135 "[threads: total initially_running wait_to_block] ");
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1136 tty->print("[time: spin block sync cleanup vmop] ");
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1137
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1138 // no page armed status printed out if it is always armed.
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1139 if (need_to_track_page_armed_status) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1140 tty->print("page_armed ");
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1141 }
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1142
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1143 tty->print_cr("page_trap_count");
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1144 }
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1145
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 void SafepointSynchronize::deferred_initialize_stat() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 if (init_done) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 if (PrintSafepointStatisticsCount <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 fatal("Wrong PrintSafepointStatisticsCount");
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // If PrintSafepointStatisticsTimeout is specified, the statistics data will
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // be printed right away, in which case, _safepoint_stats will regress to
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // a single element array. Otherwise, it is a circular ring buffer with default
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // size of PrintSafepointStatisticsCount.
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 int stats_array_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 if (PrintSafepointStatisticsTimeout > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 stats_array_size = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 PrintSafepointStatistics = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 stats_array_size = PrintSafepointStatisticsCount;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6162
diff changeset
1165 * sizeof(SafepointStats), mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 guarantee(_safepoint_stats != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 "not enough memory for safepoint instrumentation data");
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 if (UseCompilerSafepoints && DeferPollingPageLoopCount >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 need_to_track_page_armed_status = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 init_done = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
1003
528d98fe1037 6880029: JDK 1.6.0_u14p Application crashed very early
xlu
parents: 979
diff changeset
1176 assert(init_done, "safepoint statistics array hasn't been initialized");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1179 spstat->_time_stamp = _ts_of_current_safepoint;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1180
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 VM_Operation *op = VMThread::vm_operation();
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 spstat->_vmop_type = (op != NULL ? op->type() : -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 if (op != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 _safepoint_reasons[spstat->_vmop_type]++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 spstat->_nof_total_threads = nof_threads;
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 spstat->_nof_initial_running_threads = nof_running;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 spstat->_nof_threads_hit_page_trap = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // Records the start time of spinning. The real time spent on spinning
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // will be adjusted when spin is done. Same trick is applied for time
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // spent on waiting for threads to block.
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 if (nof_running != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 spstat->_time_to_spin = os::javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 spstat->_time_to_spin = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 void SafepointSynchronize::update_statistics_on_spin_end() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
1203
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 jlong cur_time = os::javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 spstat->_nof_threads_wait_to_block = _waiting_to_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 if (spstat->_nof_initial_running_threads != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 spstat->_time_to_spin = cur_time - spstat->_time_to_spin;
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if (need_to_track_page_armed_status) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 spstat->_page_armed = (PageArmed == 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // Records the start time of waiting for to block. Updated when block is done.
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 if (_waiting_to_block != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 spstat->_time_to_wait_to_block = cur_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 spstat->_time_to_wait_to_block = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 void SafepointSynchronize::update_statistics_on_sync_end(jlong end_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 if (spstat->_nof_threads_wait_to_block != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 spstat->_time_to_wait_to_block = end_time -
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 spstat->_time_to_wait_to_block;
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1230
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // Records the end time of sync which will be used to calculate the total
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // vm operation time. Again, the real time spending in syncing will be deducted
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // from the start of the sync time later when end_statistics is called.
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1234 spstat->_time_to_sync = end_time - _safepoint_begin_time;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 if (spstat->_time_to_sync > _max_sync_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 _max_sync_time = spstat->_time_to_sync;
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 }
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1238
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1239 spstat->_time_to_do_cleanups = end_time;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1240 }
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1241
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1242 void SafepointSynchronize::update_statistics_on_cleanup_end(jlong end_time) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1243 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1244
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1245 // Record how long spent in cleanup tasks.
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1246 spstat->_time_to_do_cleanups = end_time - spstat->_time_to_do_cleanups;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1247
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1248 cleanup_end_time = end_time;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 void SafepointSynchronize::end_statistics(jlong vmop_end_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // Update the vm operation time.
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1255 spstat->_time_to_exec_vmop = vmop_end_time - cleanup_end_time;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1256 if (spstat->_time_to_exec_vmop > _max_vmop_time) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1257 _max_vmop_time = spstat->_time_to_exec_vmop;
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1258 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // Only the sync time longer than the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // PrintSafepointStatisticsTimeout will be printed out right away.
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 // By default, it is -1 meaning all samples will be put into the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 if ( PrintSafepointStatisticsTimeout > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 if (spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // The safepoint statistics will be printed out when the _safepoin_stats
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 // array fills up.
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1269 if (_cur_stat_index == PrintSafepointStatisticsCount - 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 _cur_stat_index = 0;
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1272 } else {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1273 _cur_stat_index++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1277
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 void SafepointSynchronize::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 SafepointStats* sstats = _safepoint_stats;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1281 for (int index = 0; index <= _cur_stat_index; index++) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1282 if (index % 30 == 0) {
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1283 print_header();
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1284 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 sstats = &_safepoint_stats[index];
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1286 tty->print("%.3f: ", sstats->_time_stamp);
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1287 tty->print("%-26s ["
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 INT32_FORMAT_W(8)INT32_FORMAT_W(11)INT32_FORMAT_W(15)
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1289 " ] ",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 sstats->_vmop_type == -1 ? "no vm operation" :
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 VM_Operation::name(sstats->_vmop_type),
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 sstats->_nof_total_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 sstats->_nof_initial_running_threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 sstats->_nof_threads_wait_to_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // "/ MICROUNITS " is to convert the unit from nanos to millis.
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1296 tty->print(" ["
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1297 INT64_FORMAT_W(6)INT64_FORMAT_W(6)
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1298 INT64_FORMAT_W(6)INT64_FORMAT_W(6)
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1299 INT64_FORMAT_W(6)" ] ",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 sstats->_time_to_spin / MICROUNITS,
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 sstats->_time_to_wait_to_block / MICROUNITS,
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 sstats->_time_to_sync / MICROUNITS,
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1303 sstats->_time_to_do_cleanups / MICROUNITS,
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1304 sstats->_time_to_exec_vmop / MICROUNITS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1305
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 if (need_to_track_page_armed_status) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 tty->print(INT32_FORMAT" ", sstats->_page_armed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 tty->print_cr(INT32_FORMAT" ", sstats->_nof_threads_hit_page_trap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // This method will be called when VM exits. It will first call
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // print_statistics to print out the rest of the sampling. Then
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // it tries to summarize the sampling.
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 void SafepointSynchronize::print_stat_on_exit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 if (_safepoint_stats == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // During VM exit, end_statistics may not get called and in that
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // case, if the sync time is less than PrintSafepointStatisticsTimeout,
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // don't print it out.
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // Approximate the vm op time.
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 _safepoint_stats[_cur_stat_index]._time_to_exec_vmop =
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1326 os::javaTimeNanos() - cleanup_end_time;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1327
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 if ( PrintSafepointStatisticsTimeout < 0 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 spstat->_time_to_sync > PrintSafepointStatisticsTimeout * MICROUNITS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
1333
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // Print out polling page sampling status.
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 if (!need_to_track_page_armed_status) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 if (UseCompilerSafepoints) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 tty->print_cr("Polling page always armed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 tty->print_cr("Defer polling page loop count = %d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 DeferPollingPageLoopCount);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 for (int index = 0; index < VM_Operation::VMOp_Terminating; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 if (_safepoint_reasons[index] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 tty->print_cr("%-26s"UINT64_FORMAT_W(10), VM_Operation::name(index),
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 _safepoint_reasons[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 tty->print_cr(UINT64_FORMAT_W(5)" VM operations coalesced during safepoint",
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 _coalesced_vmop_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 tty->print_cr("Maximum sync time "INT64_FORMAT_W(5)" ms",
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 _max_sync_time / MICROUNITS);
1291
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1355 tty->print_cr("Maximum vm operation time (except for Exit VM operation) "
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1356 INT64_FORMAT_W(5)" ms",
4b0f2f4918ed 6933402: RFE: Improve PrintSafepointStatistics output to track cleanup time
xlu
parents: 1003
diff changeset
1357 _max_vmop_time / MICROUNITS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // ------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // Non-product code
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 void SafepointSynchronize::print_state() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 if (_state == _not_synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 tty->print_cr("not synchronized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 } else if (_state == _synchronizing || _state == _synchronized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 tty->print_cr("State: %s", (_state == _synchronizing) ? "synchronizing" :
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 "synchronized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 cur->safepoint_state()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1377
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 void SafepointSynchronize::safepoint_msg(const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 if (ShowSafepointMsgs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 tty->vprint_cr(format, ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 #endif // !PRODUCT