annotate src/share/vm/runtime/safepoint.cpp @ 3917:eca1193ca245

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