annotate src/share/vm/runtime/thread.cpp @ 3979:4dfb2df418f2

6484982: G1: process references during evacuation pauses Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate. Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author johnc
date Thu, 22 Sep 2011 10:57:37 -0700
parents e6b1331a51d2
children fd65bc7c09b6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
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: 1320
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1320
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: 1320
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: 1922
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
26 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
27 #include "classfile/javaClasses.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
28 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
29 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
30 #include "code/scopeDesc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
31 #include "compiler/compileBroker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
32 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
33 #include "interpreter/linkResolver.hpp"
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
34 #include "interpreter/oopMapCache.hpp"
2126
db2b0f8c1cef 6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents: 2100
diff changeset
35 #include "jvmtifiles/jvmtiEnv.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
36 #include "memory/oopFactory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
37 #include "memory/universe.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
38 #include "oops/instanceKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
39 #include "oops/objArrayOop.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
40 #include "oops/oop.inline.hpp"
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
41 #include "oops/symbol.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
42 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
43 #include "prims/jvmtiExport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
44 #include "prims/jvmtiThreadState.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
45 #include "prims/privilegedStack.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
46 #include "runtime/aprofiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
47 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
48 #include "runtime/biasedLocking.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
49 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
50 #include "runtime/fprofiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
51 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
52 #include "runtime/init.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
53 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
54 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
55 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
56 #include "runtime/jniPeriodicChecker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
57 #include "runtime/memprofiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
58 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
59 #include "runtime/objectMonitor.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
60 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
61 #include "runtime/safepoint.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
62 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
63 #include "runtime/statSampler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
64 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
65 #include "runtime/task.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
66 #include "runtime/threadCritical.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
67 #include "runtime/threadLocalStorage.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
68 #include "runtime/vframe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
69 #include "runtime/vframeArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
70 #include "runtime/vframe_hp.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
71 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
72 #include "runtime/vm_operations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
73 #include "services/attachListener.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
74 #include "services/management.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
75 #include "services/threadService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
76 #include "utilities/defaultStream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
77 #include "utilities/dtrace.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
78 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
79 #include "utilities/preserveException.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
80 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
81 # include "os_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
82 # include "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
83 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
84 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
85 # include "os_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
86 # include "thread_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
87 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
88 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
89 # include "os_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
90 # include "thread_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
91 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
92 #ifndef SERIALGC
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
93 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
94 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
95 #include "gc_implementation/parallelScavenge/pcTasks.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
96 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
97 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
98 #include "c1/c1_Compiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
99 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
100 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
101 #include "opto/c2compiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
102 #include "opto/idealGraphPrinter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1922
diff changeset
103 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 #ifdef DTRACE_ENABLED
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Only bother with this argument setup if dtrace is available
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 HS_DTRACE_PROBE_DECL(hotspot, vm__init__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 HS_DTRACE_PROBE_DECL(hotspot, vm__init__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 HS_DTRACE_PROBE_DECL5(hotspot, thread__start, char*, intptr_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 intptr_t, intptr_t, bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 HS_DTRACE_PROBE_DECL5(hotspot, thread__stop, char*, intptr_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
114 intptr_t, intptr_t, bool);
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 #define DTRACE_THREAD_PROBE(probe, javathread) \
a61af66fc99e Initial load
duke
parents:
diff changeset
117 { \
a61af66fc99e Initial load
duke
parents:
diff changeset
118 ResourceMark rm(this); \
a61af66fc99e Initial load
duke
parents:
diff changeset
119 int len = 0; \
a61af66fc99e Initial load
duke
parents:
diff changeset
120 const char* name = (javathread)->get_thread_name(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
121 len = strlen(name); \
a61af66fc99e Initial load
duke
parents:
diff changeset
122 HS_DTRACE_PROBE5(hotspot, thread__##probe, \
a61af66fc99e Initial load
duke
parents:
diff changeset
123 name, len, \
a61af66fc99e Initial load
duke
parents:
diff changeset
124 java_lang_Thread::thread_id((javathread)->threadObj()), \
a61af66fc99e Initial load
duke
parents:
diff changeset
125 (javathread)->osthread()->thread_id(), \
a61af66fc99e Initial load
duke
parents:
diff changeset
126 java_lang_Thread::is_daemon((javathread)->threadObj())); \
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 #else // ndef DTRACE_ENABLED
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 #define DTRACE_THREAD_PROBE(probe, javathread)
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 #endif // ndef DTRACE_ENABLED
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Class hierarchy
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // - Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // - VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // - WatcherThread
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // - ConcurrentMarkSweepThread
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // - JavaThread
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // - CompilerThread
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // ======= Thread ========
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Support for forcing alignment of thread objects for biased locking
a61af66fc99e Initial load
duke
parents:
diff changeset
146 void* Thread::operator new(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 const int alignment = markOopDesc::biased_lock_alignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 size_t aligned_size = size + (alignment - sizeof(intptr_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
150 void* real_malloc_addr = CHeapObj::operator new(aligned_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 void* aligned_addr = (void*) align_size_up((intptr_t) real_malloc_addr, alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 assert(((uintptr_t) aligned_addr + (uintptr_t) size) <=
a61af66fc99e Initial load
duke
parents:
diff changeset
153 ((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size),
a61af66fc99e Initial load
duke
parents:
diff changeset
154 "JavaThread alignment code overflowed allocated storage");
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (TraceBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if (aligned_addr != real_malloc_addr)
a61af66fc99e Initial load
duke
parents:
diff changeset
157 tty->print_cr("Aligned thread " INTPTR_FORMAT " to " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
158 real_malloc_addr, aligned_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 ((Thread*) aligned_addr)->_real_malloc_address = real_malloc_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 return aligned_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return CHeapObj::operator new(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 void Thread::operator delete(void* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 void* real_malloc_addr = ((Thread*) p)->_real_malloc_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 CHeapObj::operator delete(real_malloc_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 CHeapObj::operator delete(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread,
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // JavaThread
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 Thread::Thread() {
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
182 // stack and get_thread
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
183 set_stack_base(NULL);
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
184 set_stack_size(0);
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
185 set_self_raw_id(0);
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
186 set_lgrp_id(-1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // allocated data structures
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
189 set_osthread(NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 set_resource_area(new ResourceArea());
a61af66fc99e Initial load
duke
parents:
diff changeset
191 set_handle_area(new HandleArea(NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
192 set_active_handles(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 set_free_handle_block(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 set_last_handle_mark(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // This initial value ==> never claimed.
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _oops_do_parity = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // the handle mark links itself to last_handle_mark
a61af66fc99e Initial load
duke
parents:
diff changeset
200 new HandleMark(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // plain initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
203 debug_only(_owned_locks = NULL;)
a61af66fc99e Initial load
duke
parents:
diff changeset
204 debug_only(_allow_allocation_count = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
205 NOT_PRODUCT(_allow_safepoint_count = 0;)
806
821269eca479 6820167: GCALotAtAllSafepoints + FullGCALot(ScavengeALot) options crash JVM
ysr
parents: 702
diff changeset
206 NOT_PRODUCT(_skip_gcalot = false;)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
207 CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
208 _jvmti_env_iteration_count = 0;
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2014
diff changeset
209 set_allocated_bytes(0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
210 _vm_operation_started_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 _vm_operation_completed_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
212 _current_pending_monitor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 _current_pending_monitor_is_from_java = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 _current_waiting_monitor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 _num_nested_signal = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 omFreeList = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 omFreeCount = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 omFreeProvision = 32 ;
1587
b96a3e44582f 6852873: Reduce safepoint cleanup time
acorn
parents: 1320
diff changeset
219 omInUseList = NULL ;
b96a3e44582f 6852873: Reduce safepoint cleanup time
acorn
parents: 1320
diff changeset
220 omInUseCount = 0 ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 _suspend_flags = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // thread-specific hashCode stream generator state - Marsaglia shift-xor form
a61af66fc99e Initial load
duke
parents:
diff changeset
226 _hashStateX = os::random() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
227 _hashStateY = 842502087 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 _hashStateZ = 0x8767 ; // (int)(3579807591LL & 0xffff) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 _hashStateW = 273326509 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 _OnTrap = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 _schedctl = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _Stalled = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 _TypeTag = 0x2BAD ;
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // Many of the following fields are effectively final - immutable
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Note that nascent threads can't use the Native Monitor-Mutex
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // construct until the _MutexEvent is initialized ...
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // we might instead use a stack of ParkEvents that we could provision on-demand.
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // The stack would act as a cache to avoid calls to ParkEvent::Allocate()
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // and ::Release()
a61af66fc99e Initial load
duke
parents:
diff changeset
243 _ParkEvent = ParkEvent::Allocate (this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 _SleepEvent = ParkEvent::Allocate (this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _MutexEvent = ParkEvent::Allocate (this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 _MuxEvent = ParkEvent::Allocate (this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 #ifdef CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
249 if (CheckUnhandledOops) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _unhandled_oops = new UnhandledOops(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 #endif // CHECK_UNHANDLED_OOPS
a61af66fc99e Initial load
duke
parents:
diff changeset
253 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 assert((((uintptr_t) this) & (markOopDesc::biased_lock_alignment - 1)) == 0, "forced alignment of thread object failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
256 assert(this == _real_malloc_address ||
a61af66fc99e Initial load
duke
parents:
diff changeset
257 this == (void*) align_size_up((intptr_t) _real_malloc_address, markOopDesc::biased_lock_alignment),
a61af66fc99e Initial load
duke
parents:
diff changeset
258 "bug in forced alignment of thread objects");
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 void Thread::initialize_thread_local_storage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Note: Make sure this method only calls
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // non-blocking operations. Otherwise, it might not work
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // with the thread-startup/safepoint interaction.
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // During Java thread startup, safepoint code should allow this
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // method to complete because it may need to allocate memory to
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // store information for the new thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // initialize structure dependent on thread local storage
a61af66fc99e Initial load
duke
parents:
diff changeset
273 ThreadLocalStorage::set_thread(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // set up any platform-specific state.
a61af66fc99e Initial load
duke
parents:
diff changeset
276 os::initialize_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void Thread::record_stack_base_and_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 set_stack_base(os::current_stack_base());
a61af66fc99e Initial load
duke
parents:
diff changeset
282 set_stack_size(os::current_stack_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 Thread::~Thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Reclaim the objectmonitors from the omFreeList of the moribund thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
288 ObjectSynchronizer::omFlush (this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // deallocate data structures
a61af66fc99e Initial load
duke
parents:
diff changeset
291 delete resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // since the handle marks are using the handle area, we have to deallocated the root
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // handle mark before deallocating the thread's handle area,
a61af66fc99e Initial load
duke
parents:
diff changeset
294 assert(last_handle_mark() != NULL, "check we have an element");
a61af66fc99e Initial load
duke
parents:
diff changeset
295 delete last_handle_mark();
a61af66fc99e Initial load
duke
parents:
diff changeset
296 assert(last_handle_mark() == NULL, "check we have reached the end");
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // It's possible we can encounter a null _ParkEvent, etc., in stillborn threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // We NULL out the fields for good hygiene.
a61af66fc99e Initial load
duke
parents:
diff changeset
300 ParkEvent::Release (_ParkEvent) ; _ParkEvent = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 ParkEvent::Release (_SleepEvent) ; _SleepEvent = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 ParkEvent::Release (_MutexEvent) ; _MutexEvent = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 ParkEvent::Release (_MuxEvent) ; _MuxEvent = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 delete handle_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // osthread() can be NULL, if creation of thread failed.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (osthread() != NULL) os::free_thread(osthread());
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 delete _SR_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // clear thread local storage if the Thread is deleting itself
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (this == Thread::current()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 ThreadLocalStorage::set_thread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // In the case where we're not the current thread, invalidate all the
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // caches in case some code tries to get the current thread or the
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // thread that was destroyed, and gets stale information.
a61af66fc99e Initial load
duke
parents:
diff changeset
319 ThreadLocalStorage::invalidate_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 CHECK_UNHANDLED_OOPS_ONLY(if (CheckUnhandledOops) delete unhandled_oops();)
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // NOTE: dummy function for assertion purpose.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 void Thread::run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Private method to check for dangling thread pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
331 void check_for_dangling_thread_pointer(Thread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
333 "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // Tracing method for basic thread operations
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void Thread::trace(const char* msg, const Thread* const thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 if (!TraceThreadEvents) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 ThreadCritical tc;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 const char *name = "non-Java thread";
a61af66fc99e Initial load
duke
parents:
diff changeset
345 int prio = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (thread->is_Java_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
347 && !thread->is_Compiler_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // The Threads_lock must be held to get information about
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // this thread but may not be in some situations when
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // tracing thread events.
a61af66fc99e Initial load
duke
parents:
diff changeset
351 bool release_Threads_lock = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (!Threads_lock->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 Threads_lock->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
354 release_Threads_lock = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
356 JavaThread* jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 name = (char *)jt->get_thread_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
358 oop thread_oop = jt->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (thread_oop != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 prio = java_lang_Thread::priority(thread_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (release_Threads_lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 tty->print_cr("Thread::%s " INTPTR_FORMAT " [%lx] %s (prio: %d)", msg, thread, thread->osthread()->thread_id(), name, prio);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 ThreadPriority Thread::get_priority(const Thread* const thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 trace("get priority", thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 ThreadPriority priority;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // Can return an error!
a61af66fc99e Initial load
duke
parents:
diff changeset
375 (void)os::get_priority(thread, priority);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 assert(MinPriority <= priority && priority <= MaxPriority, "non-Java priority found");
a61af66fc99e Initial load
duke
parents:
diff changeset
377 return priority;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 void Thread::set_priority(Thread* thread, ThreadPriority priority) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 trace("set priority", thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 debug_only(check_for_dangling_thread_pointer(thread);)
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // Can return an error!
a61af66fc99e Initial load
duke
parents:
diff changeset
384 (void)os::set_priority(thread, priority);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 void Thread::start(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 trace("start", thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // Start is different from resume in that its safety is guaranteed by context or
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // being called from a Java method synchronized on the Thread object.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 if (!DisableStartThread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Initialize the thread state to RUNNABLE before starting this thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // Can not set it after the thread started because we do not know the
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // exact thread state at that time. It could be in MONITOR_WAIT or
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // in SLEEPING or some other state.
a61af66fc99e Initial load
duke
parents:
diff changeset
398 java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
a61af66fc99e Initial load
duke
parents:
diff changeset
399 java_lang_Thread::RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 os::start_thread(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Enqueue a VM_Operation to do the job for us - sometime later
a61af66fc99e Initial load
duke
parents:
diff changeset
406 void Thread::send_async_exception(oop java_thread, oop java_throwable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 VM_ThreadStop* vm_stop = new VM_ThreadStop(java_thread, java_throwable);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 VMThread::execute(vm_stop);
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 //
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Check if an external suspend request has completed (or has been
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // cancelled). Returns true if the thread is externally suspended and
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // false otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 //
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // The bits parameter returns information about the code path through
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // the routine. Useful for debugging:
a61af66fc99e Initial load
duke
parents:
diff changeset
419 //
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // set in is_ext_suspend_completed():
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // 0x00000001 - routine was entered
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // 0x00000010 - routine return false at end
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // 0x00000100 - thread exited (return false)
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // 0x00000200 - suspend request cancelled (return false)
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // 0x00000400 - thread suspended (return true)
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // 0x00001000 - thread is in a suspend equivalent state (return true)
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // 0x00002000 - thread is native and walkable (return true)
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // 0x00004000 - thread is native_trans and walkable (needed retry)
a61af66fc99e Initial load
duke
parents:
diff changeset
429 //
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // set in wait_for_ext_suspend_completion():
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // 0x00010000 - routine was entered
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // 0x00020000 - suspend request cancelled before loop (return false)
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // 0x00040000 - thread suspended before loop (return true)
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // 0x00080000 - suspend request cancelled in loop (return false)
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // 0x00100000 - thread suspended in loop (return true)
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // 0x00200000 - suspend not completed during retry loop (return false)
a61af66fc99e Initial load
duke
parents:
diff changeset
437 //
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Helper class for tracing suspend wait debug bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 //
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // 0x00000100 indicates that the target thread exited before it could
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // self-suspend which is not a wait failure. 0x00000200, 0x00020000 and
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // 0x00080000 each indicate a cancelled suspend request so they don't
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // count as wait failures either.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 #define DEBUG_FALSE_BITS (0x00000010 | 0x00200000)
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 class TraceSuspendDebugBits : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
449 JavaThread * jt;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 bool is_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
451 bool called_by_wait; // meaningful when !is_wait
a61af66fc99e Initial load
duke
parents:
diff changeset
452 uint32_t * bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
455 TraceSuspendDebugBits(JavaThread *_jt, bool _is_wait, bool _called_by_wait,
a61af66fc99e Initial load
duke
parents:
diff changeset
456 uint32_t *_bits) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 jt = _jt;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 is_wait = _is_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 called_by_wait = _called_by_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 bits = _bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 ~TraceSuspendDebugBits() {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 if (!is_wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 #if 1
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // By default, don't trace bits for is_ext_suspend_completed() calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // That trace is very chatty.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if (!called_by_wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // If tracing for is_ext_suspend_completed() is enabled, then only
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // trace calls to it from wait_for_ext_suspend_completion()
a61af66fc99e Initial load
duke
parents:
diff changeset
473 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (AssertOnSuspendWaitFailure || TraceSuspendWaitFailures) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (bits != NULL && (*bits & DEBUG_FALSE_BITS) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 MutexLocker ml(Threads_lock); // needed for get_thread_name()
a61af66fc99e Initial load
duke
parents:
diff changeset
481 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
484 "Failed wait_for_ext_suspend_completion(thread=%s, debug_bits=%x)",
a61af66fc99e Initial load
duke
parents:
diff changeset
485 jt->get_thread_name(), *bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 guarantee(!AssertOnSuspendWaitFailure, "external suspend wait failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 };
a61af66fc99e Initial load
duke
parents:
diff changeset
492 #undef DEBUG_FALSE_BITS
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 bool JavaThread::is_ext_suspend_completed(bool called_by_wait, int delay, uint32_t *bits) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 TraceSuspendDebugBits tsdb(this, false /* !is_wait */, called_by_wait, bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 bool did_trans_retry = false; // only do thread_in_native_trans retry once
a61af66fc99e Initial load
duke
parents:
diff changeset
499 bool do_trans_retry; // flag to force the retry
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 *bits |= 0x00000001;
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 do_trans_retry = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (is_exiting()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Thread is in the process of exiting. This is always checked
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // first to reduce the risk of dereferencing a freed JavaThread.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 *bits |= 0x00000100;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (!is_external_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Suspend request is cancelled. This is always checked before
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // is_ext_suspended() to reduce the risk of a rogue resume
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // confusing the thread that made the suspend request.
a61af66fc99e Initial load
duke
parents:
diff changeset
517 *bits |= 0x00000200;
a61af66fc99e Initial load
duke
parents:
diff changeset
518 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 if (is_ext_suspended()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // thread is suspended
a61af66fc99e Initial load
duke
parents:
diff changeset
523 *bits |= 0x00000400;
a61af66fc99e Initial load
duke
parents:
diff changeset
524 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // Now that we no longer do hard suspends of threads running
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // native code, the target thread can be changing thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // while we are in this routine:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 //
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // _thread_in_native -> _thread_in_native_trans -> _thread_blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
532 //
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // We save a copy of the thread state as observed at this moment
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // and make our decision about suspend completeness based on the
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // copy. This closes the race where the thread state is seen as
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // _thread_in_native_trans in the if-thread_blocked check, but is
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // seen as _thread_blocked in if-thread_in_native_trans check.
a61af66fc99e Initial load
duke
parents:
diff changeset
538 JavaThreadState save_state = thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 if (save_state == _thread_blocked && is_suspend_equivalent()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // If the thread's state is _thread_blocked and this blocking
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // condition is known to be equivalent to a suspend, then we can
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // consider the thread to be externally suspended. This means that
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // the code that sets _thread_blocked has been modified to do
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // self-suspension if the blocking condition releases. We also
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // used to check for CONDVAR_WAIT here, but that is now covered by
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // the _thread_blocked with self-suspension check.
a61af66fc99e Initial load
duke
parents:
diff changeset
548 //
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Return true since we wouldn't be here unless there was still an
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // external suspend request.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 *bits |= 0x00001000;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
553 } else if (save_state == _thread_in_native && frame_anchor()->walkable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // Threads running native code will self-suspend on native==>VM/Java
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // transitions. If its stack is walkable (should always be the case
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // unless this function is called before the actual java_suspend()
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // call), then the wait is done.
a61af66fc99e Initial load
duke
parents:
diff changeset
558 *bits |= 0x00002000;
a61af66fc99e Initial load
duke
parents:
diff changeset
559 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 } else if (!called_by_wait && !did_trans_retry &&
a61af66fc99e Initial load
duke
parents:
diff changeset
561 save_state == _thread_in_native_trans &&
a61af66fc99e Initial load
duke
parents:
diff changeset
562 frame_anchor()->walkable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // The thread is transitioning from thread_in_native to another
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // thread state. check_safepoint_and_suspend_for_native_trans()
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // will force the thread to self-suspend. If it hasn't gotten
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // there yet we may have caught the thread in-between the native
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // code check above and the self-suspend. Lucky us. If we were
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // called by wait_for_ext_suspend_completion(), then it
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // will be doing the retries so we don't have to.
a61af66fc99e Initial load
duke
parents:
diff changeset
570 //
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Since we use the saved thread state in the if-statement above,
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // there is a chance that the thread has already transitioned to
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // _thread_blocked by the time we get here. In that case, we will
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // make a single unnecessary pass through the logic below. This
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // doesn't hurt anything since we still do the trans retry.
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 *bits |= 0x00004000;
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Once the thread leaves thread_in_native_trans for another
a61af66fc99e Initial load
duke
parents:
diff changeset
580 // thread state, we break out of this retry loop. We shouldn't
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // need this flag to prevent us from getting back here, but
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // sometimes paranoia is good.
a61af66fc99e Initial load
duke
parents:
diff changeset
583 did_trans_retry = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // We wait for the thread to transition to a more usable state.
a61af66fc99e Initial load
duke
parents:
diff changeset
586 for (int i = 1; i <= SuspendRetryCount; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // We used to do an "os::yield_all(i)" call here with the intention
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // that yielding would increase on each retry. However, the parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // is ignored on Linux which means the yield didn't scale up. Waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // on the SR_lock below provides a much more predictable scale up for
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // the delay. It also provides a simple/direct point to check for any
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // safepoint requests from the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // temporarily drops SR_lock while doing wait with safepoint check
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // (if we're a JavaThread - the WatcherThread can also call this)
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // and increase delay with each retry
a61af66fc99e Initial load
duke
parents:
diff changeset
597 SR_lock()->wait(!Thread::current()->is_Java_thread(), i * delay);
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // check the actual thread state instead of what we saved above
a61af66fc99e Initial load
duke
parents:
diff changeset
600 if (thread_state() != _thread_in_native_trans) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // the thread has transitioned to another thread state so
a61af66fc99e Initial load
duke
parents:
diff changeset
602 // try all the checks (except this one) one more time.
a61af66fc99e Initial load
duke
parents:
diff changeset
603 do_trans_retry = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606 } // end retry loop
a61af66fc99e Initial load
duke
parents:
diff changeset
607
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610 } while (do_trans_retry);
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 *bits |= 0x00000010;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 //
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // Wait for an external suspend request to complete (or be cancelled).
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Returns true if the thread is externally suspended and false otherwise.
a61af66fc99e Initial load
duke
parents:
diff changeset
619 //
a61af66fc99e Initial load
duke
parents:
diff changeset
620 bool JavaThread::wait_for_ext_suspend_completion(int retries, int delay,
a61af66fc99e Initial load
duke
parents:
diff changeset
621 uint32_t *bits) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 TraceSuspendDebugBits tsdb(this, true /* is_wait */,
a61af66fc99e Initial load
duke
parents:
diff changeset
623 false /* !called_by_wait */, bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // local flag copies to minimize SR_lock hold time
a61af66fc99e Initial load
duke
parents:
diff changeset
626 bool is_suspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
627 bool pending;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 uint32_t reset_bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // set a marker so is_ext_suspend_completed() knows we are the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
631 *bits |= 0x00010000;
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // We use reset_bits to reinitialize the bits value at the top of
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // each retry loop. This allows the caller to make use of any
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // unused bits for their own marking purposes.
a61af66fc99e Initial load
duke
parents:
diff changeset
636 reset_bits = *bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 is_suspended = is_ext_suspend_completed(true /* called_by_wait */,
a61af66fc99e Initial load
duke
parents:
diff changeset
641 delay, bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
642 pending = is_external_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // must release SR_lock to allow suspension to complete
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 if (!pending) {
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // A cancelled suspend request is the only false return from
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // is_ext_suspend_completed() that keeps us from entering the
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // retry loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
650 *bits |= 0x00020000;
a61af66fc99e Initial load
duke
parents:
diff changeset
651 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if (is_suspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 *bits |= 0x00040000;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 for (int i = 1; i <= retries; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 *bits = reset_bits; // reinit to only track last retry
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // We used to do an "os::yield_all(i)" call here with the intention
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // that yielding would increase on each retry. However, the parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // is ignored on Linux which means the yield didn't scale up. Waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // on the SR_lock below provides a much more predictable scale up for
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // the delay. It also provides a simple/direct point to check for any
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // safepoint requests from the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 MutexLocker ml(SR_lock());
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // wait with safepoint check (if we're a JavaThread - the WatcherThread
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // can also call this) and increase delay with each retry
a61af66fc99e Initial load
duke
parents:
diff changeset
673 SR_lock()->wait(!Thread::current()->is_Java_thread(), i * delay);
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 is_suspended = is_ext_suspend_completed(true /* called_by_wait */,
a61af66fc99e Initial load
duke
parents:
diff changeset
676 delay, bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // It is possible for the external suspend request to be cancelled
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // (by a resume) before the actual suspend operation is completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // Refresh our local copy to see if we still need to wait.
a61af66fc99e Initial load
duke
parents:
diff changeset
681 pending = is_external_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 if (!pending) {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // A cancelled suspend request is the only false return from
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // is_ext_suspend_completed() that keeps us from staying in the
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // retry loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
688 *bits |= 0x00080000;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692 if (is_suspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 *bits |= 0x00100000;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 } // end retry loop
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // thread did not suspend after all our retries
a61af66fc99e Initial load
duke
parents:
diff changeset
699 *bits |= 0x00200000;
a61af66fc99e Initial load
duke
parents:
diff changeset
700 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
704 void JavaThread::record_jump(address target, address instr, const char* file, int line) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // This should not need to be atomic as the only way for simultaneous
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // updates is via interrupts. Even then this should be rare or non-existant
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // and we don't care that much anyway.
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 int index = _jmp_ring_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
711 _jmp_ring_index = (index + 1 ) & (jump_ring_buffer_size - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 _jmp_ring[index]._target = (intptr_t) target;
a61af66fc99e Initial load
duke
parents:
diff changeset
713 _jmp_ring[index]._instruction = (intptr_t) instr;
a61af66fc99e Initial load
duke
parents:
diff changeset
714 _jmp_ring[index]._file = file;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 _jmp_ring[index]._line = line;
a61af66fc99e Initial load
duke
parents:
diff changeset
716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
717 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // Called by flat profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // Callers have already called wait_for_ext_suspend_completion
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // The assertion for that is currently too complex to put here:
a61af66fc99e Initial load
duke
parents:
diff changeset
722 bool JavaThread::profile_last_Java_frame(frame* _fr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 bool gotframe = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
724 // self suspension saves needed state.
a61af66fc99e Initial load
duke
parents:
diff changeset
725 if (has_last_Java_frame() && _anchor.walkable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
726 *_fr = pd_last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
727 gotframe = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
729 return gotframe;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 void Thread::interrupt(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 trace("interrupt", thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 debug_only(check_for_dangling_thread_pointer(thread);)
a61af66fc99e Initial load
duke
parents:
diff changeset
735 os::interrupt(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 bool Thread::is_interrupted(Thread* thread, bool clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 trace("is_interrupted", thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
740 debug_only(check_for_dangling_thread_pointer(thread);)
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // Note: If clear_interrupted==false, this simply fetches and
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // returns the value of the field osthread()->interrupted().
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return os::is_interrupted(thread, clear_interrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // GC Support
a61af66fc99e Initial load
duke
parents:
diff changeset
748 bool Thread::claim_oops_do_par_case(int strong_roots_parity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 jint thread_parity = _oops_do_parity;
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if (thread_parity != strong_roots_parity) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 jint res = Atomic::cmpxchg(strong_roots_parity, &_oops_do_parity, thread_parity);
3979
4dfb2df418f2 6484982: G1: process references during evacuation pauses
johnc
parents: 3938
diff changeset
752 if (res == thread_parity) {
4dfb2df418f2 6484982: G1: process references during evacuation pauses
johnc
parents: 3938
diff changeset
753 return true;
4dfb2df418f2 6484982: G1: process references during evacuation pauses
johnc
parents: 3938
diff changeset
754 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
755 guarantee(res == strong_roots_parity, "Or else what?");
a61af66fc99e Initial load
duke
parents:
diff changeset
756 assert(SharedHeap::heap()->n_par_threads() > 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
757 "Should only fail when parallel.");
a61af66fc99e Initial load
duke
parents:
diff changeset
758 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 assert(SharedHeap::heap()->n_par_threads() > 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
762 "Should only fail when parallel.");
a61af66fc99e Initial load
duke
parents:
diff changeset
763 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
766 void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
767 active_handles()->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // Do oop for ThreadShadow
a61af66fc99e Initial load
duke
parents:
diff changeset
769 f->do_oop((oop*)&_pending_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 handle_area()->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
773 void Thread::nmethods_do(CodeBlobClosure* cf) {
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
774 // no nmethods in a generic thread...
0
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 void Thread::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // get_priority assumes osthread initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
779 if (osthread() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 st->print("prio=%d tid=" INTPTR_FORMAT " ", get_priority(this), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 osthread()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783 debug_only(if (WizardMode) print_owned_locks_on(st);)
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Thread::print_on_error() is called by fatal error handler. Don't use
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // any lock or allocate memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
788 void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
789 if (is_VM_thread()) st->print("VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
790 else if (is_Compiler_thread()) st->print("CompilerThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
791 else if (is_Java_thread()) st->print("JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
792 else if (is_GC_task_thread()) st->print("GCTaskThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
793 else if (is_Watcher_thread()) st->print("WatcherThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
794 else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
795 else st->print("Thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
a61af66fc99e Initial load
duke
parents:
diff changeset
798 _stack_base - _stack_size, _stack_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 if (osthread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
801 st->print(" [id=%d]", osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
806 void Thread::print_owned_locks_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 Monitor *cur = _owned_locks;
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (cur == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 st->print(" (no locks) ");
a61af66fc99e Initial load
duke
parents:
diff changeset
810 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 st->print_cr(" Locks owned:");
a61af66fc99e Initial load
duke
parents:
diff changeset
812 while(cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 cur->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 cur = cur->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 static int ref_use_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 bool Thread::owns_locks_but_compiled_lock() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 if (cur != Compile_lock) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // The flag: potential_vm_operation notifies if this particular safepoint state could potential
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // invoke the vm-thread (i.e., and oop allocation). In that case, we also have to make sure that
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // no threads which allow_vm_block's are held
a61af66fc99e Initial load
duke
parents:
diff changeset
836 void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Check if current thread is allowed to block at a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
838 if (!(_allow_safepoint_count == 0))
a61af66fc99e Initial load
duke
parents:
diff changeset
839 fatal("Possible safepoint reached by thread that does not allow it");
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (is_Java_thread() && ((JavaThread*)this)->thread_state() != _thread_in_vm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 fatal("LEAF method calling lock?");
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (potential_vm_operation && is_Java_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
846 && !Universe::is_bootstrapping()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // Make sure we do not hold any locks that the VM thread also uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // This could potentially lead to deadlocks
a61af66fc99e Initial load
duke
parents:
diff changeset
849 for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Threads_lock is special, since the safepoint synchronization will not start before this is
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // since it is used to transfer control between JavaThreads and the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // Do not *exclude* any locks unless you are absolutly sure it is correct. Ask someone else first!
a61af66fc99e Initial load
duke
parents:
diff changeset
854 if ( (cur->allow_vm_block() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
855 cur != Threads_lock &&
a61af66fc99e Initial load
duke
parents:
diff changeset
856 cur != Compile_lock && // Temporary: should not be necessary when we get spearate compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
857 cur != VMOperationRequest_lock &&
a61af66fc99e Initial load
duke
parents:
diff changeset
858 cur != VMOperationQueue_lock) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
859 cur->rank() == Mutex::special) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 warning("Thread holding lock at safepoint that vm can block on: %s", cur->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
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 (GCALotAtAllSafepoints) {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // We could enter a safepoint here and thus have a gc
a61af66fc99e Initial load
duke
parents:
diff changeset
867 InterfaceSupport::check_gc_alot();
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 bool Thread::is_in_stack(address adr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
874 assert(Thread::current() == this, "is_in_stack can only be called from current thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
875 address end = os::current_stack_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
876 if (stack_base() >= adr && adr >= end) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // used for compilation in the future. If that change is made, the need for these methods
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // should be revisited, and they should be removed if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
886
a61af66fc99e Initial load
duke
parents:
diff changeset
887 bool Thread::is_lock_owned(address adr) const {
1688
2dfd013a7465 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 1608
diff changeset
888 return on_local_stack(adr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 bool Thread::set_as_starting_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // NOTE: this must be called inside the main thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 return os::create_main_thread((JavaThread*)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
896 static void initialize_class(Symbol* class_name, TRAPS) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
897 klassOop klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 instanceKlass::cast(klass)->initialize(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // Creates the initial ThreadGroup
a61af66fc99e Initial load
duke
parents:
diff changeset
903 static Handle create_initial_thread_group(TRAPS) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
904 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ThreadGroup(), true, CHECK_NH);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 instanceKlassHandle klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 Handle system_instance = klass->allocate_instance_handle(CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 JavaCalls::call_special(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
911 system_instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
912 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
913 vmSymbols::object_initializer_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
914 vmSymbols::void_method_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917 Universe::set_system_thread_group(system_instance());
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 Handle main_instance = klass->allocate_instance_handle(CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
920 {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Handle string = java_lang_String::create_from_str("main", CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
923 JavaCalls::call_special(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
924 main_instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
925 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
926 vmSymbols::object_initializer_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
927 vmSymbols::threadgroup_string_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
928 system_instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
929 string,
a61af66fc99e Initial load
duke
parents:
diff changeset
930 CHECK_NH);
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 return main_instance;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // Creates the initial Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
936 static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
937 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
938 instanceKlassHandle klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 java_lang_Thread::set_thread(thread_oop(), thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 java_lang_Thread::set_priority(thread_oop(), NormPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
943 thread->set_threadObj(thread_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 Handle string = java_lang_String::create_from_str("main", CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 JavaCalls::call_special(&result, thread_oop,
a61af66fc99e Initial load
duke
parents:
diff changeset
949 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
950 vmSymbols::object_initializer_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
951 vmSymbols::threadgroup_string_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
952 thread_group,
a61af66fc99e Initial load
duke
parents:
diff changeset
953 string,
a61af66fc99e Initial load
duke
parents:
diff changeset
954 CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
955 return thread_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 static void call_initializeSystemClass(TRAPS) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
959 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
960 instanceKlassHandle klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 JavaValue result(T_VOID);
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
963 JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
964 vmSymbols::void_method_signature(), CHECK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966
2129
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
967 // General purpose hook into Java code, run once when the VM is initialized.
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
968 // The Java library method itself may be changed independently from the VM.
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
969 static void call_postVMInitHook(TRAPS) {
3938
e6b1331a51d2 7086585: make Java field injection more flexible
never
parents: 3908
diff changeset
970 klassOop k = SystemDictionary::PostVMInitHook_klass();
2129
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
971 instanceKlassHandle klass (THREAD, k);
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
972 if (klass.not_null()) {
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
973 JavaValue result(T_VOID);
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
974 JavaCalls::call_static(&result, klass, vmSymbols::run_method_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
975 vmSymbols::void_method_signature(),
2129
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
976 CHECK);
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
977 }
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
978 }
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
979
0
a61af66fc99e Initial load
duke
parents:
diff changeset
980 static void reset_vm_info_property(TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // the vm info string
a61af66fc99e Initial load
duke
parents:
diff changeset
982 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 const char *vm_info = VM_Version::vm_info_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // java.lang.System class
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
986 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
987 instanceKlassHandle klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // setProperty arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
990 Handle key_str = java_lang_String::create_from_str("java.vm.info", CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
991 Handle value_str = java_lang_String::create_from_str(vm_info, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // return value
a61af66fc99e Initial load
duke
parents:
diff changeset
994 JavaValue r(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
995
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // public static String setProperty(String key, String value);
a61af66fc99e Initial load
duke
parents:
diff changeset
997 JavaCalls::call_static(&r,
a61af66fc99e Initial load
duke
parents:
diff changeset
998 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
999 vmSymbols::setProperty_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1000 vmSymbols::string_string_string_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 key_str,
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 value_str,
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 void JavaThread::allocate_threadObj(Handle thread_group, char* thread_name, bool daemon, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 assert(thread_group.not_null(), "thread group should be specified");
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 assert(threadObj() == NULL, "should only create Java thread object once");
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1011 klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 instanceKlassHandle klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 java_lang_Thread::set_thread(thread_oop(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 java_lang_Thread::set_priority(thread_oop(), NormPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 set_threadObj(thread_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 if (thread_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 Handle name = java_lang_String::create_from_str(thread_name, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // Thread gets assigned specified name and null target
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 JavaCalls::call_special(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 thread_oop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1026 vmSymbols::object_initializer_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1027 vmSymbols::threadgroup_string_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 thread_group, // Argument 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 name, // Argument 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // Thread gets assigned name "Thread-nnn" and null target
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // (java.lang.Thread doesn't have a constructor taking only a ThreadGroup argument)
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 JavaCalls::call_special(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 thread_oop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1037 vmSymbols::object_initializer_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1038 vmSymbols::threadgroup_runnable_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 thread_group, // Argument 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 Handle(), // Argument 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 if (daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 java_lang_Thread::set_daemon(thread_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1053 KlassHandle group(this, SystemDictionary::ThreadGroup_klass());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 Handle threadObj(this, this->threadObj());
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 JavaCalls::call_special(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 thread_group,
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 group,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1059 vmSymbols::add_method_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1060 vmSymbols::thread_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 threadObj, // Arg 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // NamedThread -- non-JavaThread subclasses with multiple
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // uniquely named instances should derive from this.
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 NamedThread::NamedThread() : Thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 _name = NULL;
1119
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
1071 _processed_thread = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 NamedThread::~NamedThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 if (_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 FREE_C_HEAP_ARRAY(char, _name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 _name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 void NamedThread::set_name(const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 guarantee(_name == NULL, "Only get to set name once.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 _name = NEW_C_HEAP_ARRAY(char, max_name_len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 guarantee(_name != NULL, "alloc failure");
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 jio_vsnprintf(_name, max_name_len, format, ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // ======= WatcherThread ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // The watcher thread exists to simulate timer interrupts. It should
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // be replaced by an abstraction over whatever native support for
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // timer interrupts exists on the platform.
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 WatcherThread* WatcherThread::_watcher_thread = NULL;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1098 volatile bool WatcherThread::_should_terminate = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 WatcherThread::WatcherThread() : Thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 if (os::create_thread(this, os::watcher_thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 _watcher_thread = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // Set the watcher thread to the highest OS priority which should not be
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // used, unless a Java thread with priority java.lang.Thread.MAX_PRIORITY
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // is created. The only normal thread using this priority is the reference
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // handler thread, which runs for very short intervals only.
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // If the VMThread's priority is not lower than the WatcherThread profiling
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // will be inaccurate.
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 os::set_priority(this, MaxPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 if (!DisableStartThread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 os::start_thread(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 void WatcherThread::run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 assert(this == watcher_thread(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 this->record_stack_base_and_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 this->initialize_thread_local_storage();
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 this->set_active_handles(JNIHandleBlock::allocate_block());
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 while(!_should_terminate) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 assert(watcher_thread() == Thread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 assert(watcher_thread() == this, "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1127
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // Calculate how long it'll be until the next PeriodicTask work
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // should be done, and sleep that amount of time.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1130 size_t time_to_wait = PeriodicTask::time_to_wait();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1131
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1132 // we expect this to timeout - we only ever get unparked when
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1133 // we should terminate
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1134 {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1135 OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1136
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1137 jlong prev_time = os::javaTimeNanos();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1138 for (;;) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1139 int res= _SleepEvent->park(time_to_wait);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1140 if (res == OS_TIMEOUT || _should_terminate)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1141 break;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1142 // spurious wakeup of some kind
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1143 jlong now = os::javaTimeNanos();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1144 time_to_wait -= (now - prev_time) / 1000000;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1145 if (time_to_wait <= 0)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1146 break;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1147 prev_time = now;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1148 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1149 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 if (is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // A fatal error has happened, the error handler(VMError::report_and_die)
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // should abort JVM after creating an error log file. However in some
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // rare cases, the error handler itself might deadlock. Here we try to
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // kill JVM if the fatal error handler fails to abort in 2 minutes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // This code is in WatcherThread because WatcherThread wakes up
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // periodically so the fatal error handler doesn't need to do anything;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // also because the WatcherThread is less likely to crash than other
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (!ShowMessageBoxOnError
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 && (OnError == NULL || OnError[0] == '\0')
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 && Arguments::abort_hook() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 os::sleep(this, 2 * 60 * 1000, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 fdStream err(defaultStream::output_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 err.print_raw_cr("# [ timer expired, abort... ]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // skip atexit/vm_exit/vm_abort hooks
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 os::die();
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Wake up 5 seconds later, the fatal handler may reset OnError or
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // ShowMessageBoxOnError when it is ready to abort.
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 os::sleep(this, 5 * 1000, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 PeriodicTask::real_time_tick(time_to_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // If we have no more tasks left due to dynamic disenrollment,
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // shut down the thread since we don't currently support dynamic enrollment
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 if (PeriodicTask::num_tasks() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 _should_terminate = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // Signal that it is terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 _watcher_thread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 Terminator_lock->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // Thread destructor usually does this..
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 ThreadLocalStorage::set_thread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 void WatcherThread::start() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 if (watcher_thread() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 _should_terminate = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // Create the single instance of WatcherThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 new WatcherThread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 void WatcherThread::stop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // it is ok to take late safepoints here, if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 MutexLocker mu(Terminator_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 _should_terminate = true;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1211 OrderAccess::fence(); // ensure WatcherThread sees update in main loop
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1212
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1213 Thread* watcher = watcher_thread();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1214 if (watcher != NULL)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1215 watcher->_SleepEvent->unpark();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1216
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 while(watcher_thread() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // This wait should make safepoint checks, wait without a timeout,
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // and wait as a suspend-equivalent condition.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // Note: If the FlatProfiler is running, then this thread is waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // for the WatcherThread to terminate and the WatcherThread, via the
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // FlatProfiler task, is waiting for the external suspend request on
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // this thread to complete. wait_for_ext_suspend_completion() will
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // eventually timeout, but that takes time. Making this wait a
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // suspend-equivalent condition solves that timeout problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 Terminator_lock->wait(!Mutex::_no_safepoint_check_flag, 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 Mutex::_as_suspend_equivalent_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 void WatcherThread::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 st->print("\"%s\" ", name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 Thread::print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // ======= JavaThread ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1240
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 // A JavaThread is a normal Java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 void JavaThread::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 // Initialize fields
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1245
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1246 // Set the claimed par_id to -1 (ie not claiming any par_ids)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1247 set_claimed_par_id(-1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1248
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 set_saved_exception_pc(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 set_threadObj(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 _anchor.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 set_entry_point(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 set_jni_functions(jni_functions());
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 set_callee_target(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 set_vm_result(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 set_vm_result_2(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 set_vframe_array_head(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 set_vframe_array_last(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 set_deferred_locals(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 set_deopt_mark(NULL);
1814
fd5d4527cdf5 6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents: 1731
diff changeset
1261 set_deopt_nmethod(NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 clear_must_deopt_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 set_monitor_chunks(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 set_next(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 set_thread_state(_thread_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 _terminated = _not_terminated;
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 _privileged_stack_top = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 _array_for_gc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 _suspend_equivalent = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 _in_deopt_handler = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 _doing_unsafe_access = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 _stack_guard_state = stack_guard_unused;
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 _exception_oop = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 _exception_pc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 _exception_handler_pc = 0;
1903
87d6a4d1ecbc 6990192: VM crashes in ciTypeFlow::get_block_for()
twisti
parents: 1843
diff changeset
1276 _is_method_handle_return = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 _jvmti_thread_state= NULL;
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
1278 _should_post_on_exceptions_flag = JNI_FALSE;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 _jvmti_get_loaded_classes_closure = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 _interp_only_mode = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 _special_runtime_exit_condition = _no_async_condition;
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 _pending_async_exception = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 _is_compiling = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 _thread_stat = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 _thread_stat = new ThreadStatistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 _blocked_on_compilation = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 _jni_active_critical = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 _do_not_unlock_if_synchronized = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 _cached_monitor_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 _parker = Parker::Allocate(this) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 _jmp_ring_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 for (int ji = 0 ; ji < jump_ring_buffer_size ; ji++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 record_jump(NULL, NULL, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 set_thread_profiler(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 if (FlatProfiler::is_active()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // This is where we would decide to either give each thread it's own profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // or use one global one from FlatProfiler,
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // or up to some count of the number of profiled threads, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 ThreadProfiler* pp = new ThreadProfiler();
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 pp->engage();
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 set_thread_profiler(pp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // Setup safepoint state info for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 ThreadSafepointState::create(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 debug_only(_java_call_counter = 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // JVMTI PopFrame support
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 _popframe_condition = popframe_inactive;
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 _popframe_preserved_args = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 _popframe_preserved_args_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 pd_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1322 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1323 SATBMarkQueueSet JavaThread::_satb_mark_queue_set;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1324 DirtyCardQueueSet JavaThread::_dirty_card_queue_set;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1325 #endif // !SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1326
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1327 JavaThread::JavaThread(bool is_attaching) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1328 Thread()
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1329 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1330 , _satb_mark_queue(&_satb_mark_queue_set),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1331 _dirty_card_queue(&_dirty_card_queue_set)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1332 #endif // !SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1333 {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 _is_attaching = is_attaching;
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 997
diff changeset
1336 assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 bool JavaThread::reguard_stack(address cur_sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 if (_stack_guard_state != stack_guard_yellow_disabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 return true; // Stack already guarded or guard pages not needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 if (register_stack_overflow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // For those architectures which have separate register and
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 // memory stacks, we must check the register stack to see if
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // it has overflowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // Java code never executes within the yellow zone: the latter is only
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // there to provoke an exception during stack banging. If java code
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // is executing there, either StackShadowPages should be larger, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // some exception code in c1, c2 or the interpreter isn't unwinding
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // when it should.
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 guarantee(cur_sp > stack_yellow_zone_base(), "not enough space to reguard - increase StackShadowPages");
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 enable_stack_yellow_zone();
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1361
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 bool JavaThread::reguard_stack(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 return reguard_stack(os::current_stack_pointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 void JavaThread::block_if_vm_exited() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 if (_terminated == _vm_exited) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // _vm_exited is set at safepoint, and Threads_lock is never released
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // we will block here forever
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 Threads_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // Remove this ifdef when C1 is ported to the compiler interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 static void compiler_thread_entry(JavaThread* thread, TRAPS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1380 JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1381 Thread()
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1382 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1383 , _satb_mark_queue(&_satb_mark_queue_set),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1384 _dirty_card_queue(&_dirty_card_queue_set)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1385 #endif // !SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
1386 {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 if (TraceThreadEvents) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 tty->print_cr("creating thread %p", this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 _is_attaching = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 set_entry_point(entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // Create the native thread itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // %note runtime_23
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 os::ThreadType thr_type = os::java_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 os::java_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 os::create_thread(this, thr_type, stack_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // The _osthread may be NULL here because we ran out of memory (too many threads active).
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // We need to throw and OutOfMemoryError - however we cannot do this here because the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // may hold a lock and all locks must be unlocked before throwing the exception (throwing
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // the exception consists of creating the exception object & initializing it, initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // will leave the VM via a JavaCall and then all locks must be unlocked).
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 // The thread is still suspended when we reach here. Thread must be explicit started
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // by creator! Furthermore, the thread must also explicitly be added to the Threads list
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // by calling Threads:add. The reason why this is not done here, is because the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // object must be fully initialized (take a look at JVM_Start)
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 JavaThread::~JavaThread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 if (TraceThreadEvents) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 tty->print_cr("terminate thread %p", this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1416
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // JSR166 -- return the parker to the free list
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 Parker::Release(_parker);
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 _parker = NULL ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // Free any remaining previous UnrollBlock
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 vframeArray* old_array = vframe_array_last();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 if (old_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 Deoptimization::UnrollBlock* old_info = old_array->unroll_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 old_array->set_unroll_block(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 delete old_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 delete old_array;
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1430
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = deferred_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (deferred != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 // This can only happen if thread is destroyed before deoptimization occurs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 assert(deferred->length() != 0, "empty array!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 jvmtiDeferredLocalVariableSet* dlv = deferred->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 deferred->remove_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // individual jvmtiDeferredLocalVariableSet are CHeapObj's
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 delete dlv;
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 } while (deferred->length() != 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 delete deferred;
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // All Java related clean up happens in exit
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 ThreadSafepointState::destroy(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 if (_thread_profiler != NULL) delete _thread_profiler;
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 if (_thread_stat != NULL) delete _thread_stat;
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1449
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // The first routine called by a new Java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 void JavaThread::run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // initialize thread-local alloc buffer related fields
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 this->initialize_tlab();
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // used to test validitity of stack trace backs
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 this->record_base_of_stack_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // Record real stack base and size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 this->record_stack_base_and_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1461
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // Initialize thread local storage; set before calling MutexLocker
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 this->initialize_thread_local_storage();
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 this->create_stack_guard_pages();
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1467 this->cache_global_variables();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
1468
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // Thread is now sufficient initialized to be handled by the safepoint code as being
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // in the VM. Change thread state from _thread_new to _thread_in_vm
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 assert(JavaThread::current() == this, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 assert(!Thread::current()->owns_locks(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 DTRACE_THREAD_PROBE(start, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // This operation might block. We call that after all safepoint checks for a new thread has
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // been completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 this->set_active_handles(JNIHandleBlock::allocate_block());
a61af66fc99e Initial load
duke
parents:
diff changeset
1481
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 if (JvmtiExport::should_post_thread_life()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 JvmtiExport::post_thread_start(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 // We call another function to do the rest so we are sure that the stack addresses used
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 // from there will be lower than the stack base just computed
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 thread_main_inner();
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // Note, thread is no longer valid at this point!
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 void JavaThread::thread_main_inner() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 assert(JavaThread::current() == this, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 assert(this->threadObj() != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
2162
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1498 // Execute thread entry point unless this thread has a pending exception
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1499 // or has been stopped before starting.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 // Note: Due to JVM_StopThread we can have pending exceptions already!
2162
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1501 if (!this->has_pending_exception() &&
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1502 !java_lang_Thread::is_stillborn(this->threadObj())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 HandleMark hm(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 this->entry_point()(this, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1506
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 DTRACE_THREAD_PROBE(stop, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1508
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 this->exit(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 delete this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 static void ensure_join(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // We do not need to grap the Threads_lock, since we are operating on ourself.
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 Handle threadObj(thread, thread->threadObj());
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 assert(threadObj.not_null(), "java thread object must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 ObjectLocker lock(threadObj, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 // Ignore pending exception (ThreadDeath), since we are exiting anyway
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 thread->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED.
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
2162
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1523 // Clear the native thread instance - this makes isAlive return false and allows the join()
ccfcb502af3f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 2129
diff changeset
1524 // to complete once we've done the notify_all below
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 java_lang_Thread::set_thread(threadObj(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 lock.notify_all(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // Ignore pending exception (ThreadDeath), since we are exiting anyway
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 thread->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1531
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // For any new cleanup additions, please check to see if they need to be applied to
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // cleanup_failed_attach_current_thread as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 assert(this == JavaThread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 if (!InitializeJavaLangSystem) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 HandleMark hm(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 Handle uncaught_exception(this, this->pending_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 this->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 Handle threadObj(this, this->threadObj());
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 assert(threadObj.not_null(), "Java thread object should be created");
a61af66fc99e Initial load
duke
parents:
diff changeset
1543
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 if (get_thread_profiler() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 get_thread_profiler()->disengage();
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 get_thread_profiler()->print(get_thread_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1549
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // FIXIT: This code should be moved into else part, when reliable 1.2/1.3 check is in place
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1554
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // FIXIT: The is_null check is only so it works better on JDK1.2 VM's. This
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // has to be fixed by a runtime query method
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 if (!destroy_vm || JDK_Version::is_jdk12x_version()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // JSR-166: change call from from ThreadGroup.uncaughtException to
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // java.lang.Thread.dispatchUncaughtException
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if (uncaught_exception.not_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 Handle group(this, java_lang_Thread::threadGroup(threadObj()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 Events::log("uncaught exception INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT",
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 (address)uncaught_exception(), (address)threadObj(), (address)group());
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 // Check if the method Thread.dispatchUncaughtException() exists. If so
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // call it. Otherwise we have an older library without the JSR-166 changes,
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // so call ThreadGroup.uncaughtException()
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 KlassHandle recvrKlass(THREAD, threadObj->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 CallInfo callinfo;
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1573 KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 LinkResolver::resolve_virtual_call(callinfo, threadObj, recvrKlass, thread_klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1575 vmSymbols::dispatchUncaughtException_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1576 vmSymbols::throwable_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 KlassHandle(), false, false, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 methodHandle method = callinfo.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 if (method.not_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 JavaCalls::call_virtual(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 threadObj, thread_klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1584 vmSymbols::dispatchUncaughtException_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1585 vmSymbols::throwable_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 uncaught_exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 } else {
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1589 KlassHandle thread_group(THREAD, SystemDictionary::ThreadGroup_klass());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 JavaCalls::call_virtual(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 group, thread_group,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1593 vmSymbols::uncaughtException_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1594 vmSymbols::thread_throwable_void_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 threadObj, // Arg 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 uncaught_exception, // Arg 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 }
2200
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1599 if (HAS_PENDING_EXCEPTION) {
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1600 ResourceMark rm(this);
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1601 jio_fprintf(defaultStream::error_stream(),
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1602 "\nException: %s thrown from the UncaughtExceptionHandler"
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1603 " in thread \"%s\"\n",
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1604 Klass::cast(pending_exception()->klass())->external_name(),
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1605 get_thread_name());
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1606 CLEAR_PENDING_EXCEPTION;
fb539912d338 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 2177
diff changeset
1607 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // the execution of the method. If that is not enough, then we don't really care. Thread.stop
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // is deprecated anyhow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 { int count = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 JavaValue result(T_VOID);
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1618 KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 JavaCalls::call_virtual(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 threadObj, thread_klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1621 vmSymbols::exit_method_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
1622 vmSymbols::void_method_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1627
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // notify JVMTI
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 if (JvmtiExport::should_post_thread_life()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 JvmtiExport::post_thread_end(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // We have notified the agents that we are exiting, before we go on,
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // we must check for a pending external suspend request and honor it
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // in order to not surprise the thread that made the suspend request.
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 if (!is_external_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 set_terminated(_thread_exiting);
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 ThreadService::current_thread_exiting(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // Implied else:
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // Things get a little tricky here. We have a pending external
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // suspend request, but we are holding the SR_lock so we
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // can't just self-suspend. So we temporarily drop the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // and then self-suspend.
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1650
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 ThreadBlockInVM tbivm(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
1653
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // We're done with this suspend request, but we have to loop around
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // and check again. Eventually we will get SR_lock without a pending
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // external suspend request and will be able to mark ourselves as
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // exiting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 // no more external suspends are allowed at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 // before_exit() has already posted JVMTI THREAD_END events
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1663
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // Notify waiters on thread object. This has to be done after exit() is called
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // on the thread (if the thread is the last thread in a daemon ThreadGroup the
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // group should have the destroyed bit set before waiters are notified).
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 ensure_join(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 assert(!this->has_pending_exception(), "ensure_join should have cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
1669
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // 6282335 JNI DetachCurrentThread spec states that all Java monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // held by this thread must be released. A detach operation must only
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // get here if there are no Java frames on the stack. Therefore, any
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 // owned monitors at this point MUST be JNI-acquired monitors which are
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 // pre-inflated and in the monitor cache.
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 // ensure_join() ignores IllegalThreadStateExceptions, and so does this.
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 if (exit_type == jni_detach && JNIDetachReleasesMonitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 assert(!this->has_last_Java_frame(), "detaching with Java frames?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 ObjectSynchronizer::release_monitors_owned_by_thread(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 assert(!this->has_pending_exception(), "release_monitors should have cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // These things needs to be done while we are still a Java Thread. Make sure that thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 // is in a consistent state, in case GC happens
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 assert(_privileged_stack_top == NULL, "must be NULL when we get here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 if (active_handles() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 JNIHandleBlock* block = active_handles();
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 set_active_handles(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 JNIHandleBlock::release_block(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 if (free_handle_block() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 JNIHandleBlock* block = free_handle_block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 set_free_handle_block(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 JNIHandleBlock::release_block(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // These have to be removed while this is still a valid thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 remove_stack_guard_pages();
a61af66fc99e Initial load
duke
parents:
diff changeset
1701
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 if (UseTLAB) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 tlab().make_parsable(true); // retire TLAB
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
2126
db2b0f8c1cef 6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents: 2100
diff changeset
1706 if (JvmtiEnv::environments_might_exist()) {
49
31000d79ec71 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 0
diff changeset
1707 JvmtiExport::cleanup_thread(this);
31000d79ec71 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 0
diff changeset
1708 }
31000d79ec71 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 0
diff changeset
1709
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1710 #ifndef SERIALGC
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1711 // We must flush G1-related buffers before removing a thread from
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1712 // the list of active threads.
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1713 if (UseG1GC) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1714 flush_barrier_queues();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1715 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1716 #endif
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1717
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 Threads::remove(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1721
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1722 #ifndef SERIALGC
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1723 // Flush G1-related queues.
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1724 void JavaThread::flush_barrier_queues() {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1725 satb_mark_queue().flush();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1726 dirty_card_queue().flush();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1727 }
1842
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1728
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1729 void JavaThread::initialize_queues() {
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1730 assert(!SafepointSynchronize::is_at_safepoint(),
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1731 "we should not be at a safepoint");
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1732
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1733 ObjPtrQueue& satb_queue = satb_mark_queue();
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1734 SATBMarkQueueSet& satb_queue_set = satb_mark_queue_set();
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1735 // The SATB queue should have been constructed with its active
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1736 // field set to false.
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1737 assert(!satb_queue.is_active(), "SATB queue should not be active");
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1738 assert(satb_queue.is_empty(), "SATB queue should be empty");
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1739 // If we are creating the thread during a marking cycle, we should
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1740 // set the active field of the SATB queue to true.
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1741 if (satb_queue_set.is_active()) {
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1742 satb_queue.set_active(true);
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1743 }
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1744
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1745 DirtyCardQueue& dirty_queue = dirty_card_queue();
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1746 // The dirty card queue should have been constructed with its
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1747 // active field set to true.
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1748 assert(dirty_queue.is_active(), "dirty card queue should be active");
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1749 }
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
1750 #endif // !SERIALGC
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1751
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 void JavaThread::cleanup_failed_attach_current_thread() {
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1753 if (get_thread_profiler() != NULL) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1754 get_thread_profiler()->disengage();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1755 ResourceMark rm;
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1756 get_thread_profiler()->print(get_thread_name());
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1757 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1758
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1759 if (active_handles() != NULL) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1760 JNIHandleBlock* block = active_handles();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1761 set_active_handles(NULL);
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1762 JNIHandleBlock::release_block(block);
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1763 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1764
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1765 if (free_handle_block() != NULL) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1766 JNIHandleBlock* block = free_handle_block();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1767 set_free_handle_block(NULL);
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1768 JNIHandleBlock::release_block(block);
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1769 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1770
1290
c8a467bf56ad 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 1213
diff changeset
1771 // These have to be removed while this is still a valid thread.
c8a467bf56ad 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 1213
diff changeset
1772 remove_stack_guard_pages();
c8a467bf56ad 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 1213
diff changeset
1773
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1774 if (UseTLAB) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1775 tlab().make_parsable(true); // retire TLAB, if any
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1776 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1777
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1778 #ifndef SERIALGC
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1779 if (UseG1GC) {
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1780 flush_barrier_queues();
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1781 }
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1782 #endif
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1783
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1784 Threads::remove(this);
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1785 delete this;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1787
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
441
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1789
da9cb4e97a5f 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 383
diff changeset
1790
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 JavaThread* JavaThread::active() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 Thread* thread = ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 assert(thread != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 return (JavaThread*) thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 assert(thread->is_VM_thread(), "this must be a vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 VM_Operation* op = ((VMThread*) thread)->vm_operation();
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 JavaThread *ret=op == NULL ? NULL : (JavaThread *)op->calling_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 assert(ret->is_Java_thread(), "must be a Java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1804
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 bool JavaThread::is_lock_owned(address adr) const {
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 669
diff changeset
1806 if (Thread::is_lock_owned(adr)) return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1807
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 if (chunk->contains(adr)) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1811
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1814
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 void JavaThread::add_monitor_chunk(MonitorChunk* chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 chunk->set_next(monitor_chunks());
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 set_monitor_chunks(chunk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 void JavaThread::remove_monitor_chunk(MonitorChunk* chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 guarantee(monitor_chunks() != NULL, "must be non empty");
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 if (monitor_chunks() == chunk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 set_monitor_chunks(chunk->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 MonitorChunk* prev = monitor_chunks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 while (prev->next() != chunk) prev = prev->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 prev->set_next(chunk->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // JVM support.
a61af66fc99e Initial load
duke
parents:
diff changeset
1833
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 // Note: this function shouldn't block if it's called in
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // _thread_in_native_trans state (such as from
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 // check_special_condition_for_native_trans()).
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 void JavaThread::check_and_handle_async_exceptions(bool check_unsafe_error) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 if (has_last_Java_frame() && has_async_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // If we are at a polling page safepoint (not a poll return)
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // then we must defer async exception because live registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // will be clobbered by the exception path. Poll return is
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 // ok because the call we a returning from already collides
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // with exception handling registers and so there is no issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 // (The exception handling path kills call result registers but
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 // this is ok since the exception kills the result anyway).
a61af66fc99e Initial load
duke
parents:
diff changeset
1847
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 if (is_at_poll_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 // if the code we are returning to has deoptimized we must defer
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // the exception otherwise live registers get clobbered on the
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // exception path before deoptimization is able to retrieve them.
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 RegisterMap map(this, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 frame caller_fr = last_frame().sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 assert(caller_fr.is_compiled_frame(), "what?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 if (caller_fr.is_deoptimized_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 if (TraceExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 tty->print_cr("deferred async exception at compiled safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 JavaThread::AsyncRequests condition = clear_special_runtime_exit_condition();
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 if (condition == _no_async_condition) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 // Conditions have changed since has_special_runtime_exit_condition()
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 // was called:
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // - if we were here only because of an external suspend request,
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 // then that was taken care of above (or cancelled) so we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // - if we were here because of another async request, then it has
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 // been cleared between the has_special_runtime_exit_condition()
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // and now so again we are done
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 // Check for pending async. exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 if (_pending_async_exception != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Only overwrite an already pending exception, if it is not a threadDeath.
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1881 if (!has_pending_exception() || !pending_exception()->is_a(SystemDictionary::ThreadDeath_klass())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1882
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // We cannot call Exceptions::_throw(...) here because we cannot block
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 set_pending_exception(_pending_async_exception, __FILE__, __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 if (TraceExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 tty->print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 if (has_last_Java_frame() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 frame f = last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", f.pc(), f.sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 tty->print_cr(" of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 _pending_async_exception = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 clear_has_async_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1899
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 if (check_unsafe_error &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 condition == _async_unsafe_access_error && !has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 condition = _no_async_condition; // done
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 switch (thread_state()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 case _thread_in_vm:
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 JavaThread* THREAD = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation");
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 case _thread_in_native:
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 ThreadInVMfromNative tiv(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 JavaThread* THREAD = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation");
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 case _thread_in_Java:
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 ThreadInVMfromJava tiv(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 JavaThread* THREAD = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in a recent unsafe memory access operation in compiled Java code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 assert(condition == _no_async_condition || has_pending_exception() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 (!check_unsafe_error && condition == _async_unsafe_access_error),
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 "must have handled the async condition, if no exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1930
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // Check for pending external suspend. Internal suspend requests do
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 // not use handle_special_runtime_exit_condition().
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // If JNIEnv proxies are allowed, don't self-suspend if the target
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 // thread is not the current thread. In older versions of jdbx, jdbx
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // threads could call into the VM with another thread's JNIEnv so we
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // can be here operating on behalf of a suspended thread (4432884).
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 bool do_self_suspend = is_external_suspend_with_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // Because thread is external suspended the safepoint code will count
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 // thread as at a safepoint. This can be odd because we can be here
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 // as _thread_in_Java which would normally transition to _thread_blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 // at a safepoint. We would like to mark the thread as _thread_blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // before calling java_suspend_self like all other callers of it but
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // we must then observe proper safepoint protocol. (We can't leave
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 // _thread_blocked with a safepoint in progress). However we can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // here as _thread_in_native_trans so we can't use a normal transition
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // constructor/destructor pair because they assert on that type of
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // transition. We could do something like:
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // JavaThreadState state = thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 // set_thread_state(_thread_in_vm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 // {
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // ThreadBlockInVM tbivm(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 // set_thread_state(_thread_in_vm_trans);
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 // if (safepoint) block;
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // set_thread_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 // but that is pretty messy. Instead we just go with the way the
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 // code has worked before and note that this is the only path to
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // java_suspend_self that doesn't put the thread in _thread_blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 // mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 frame_anchor()->make_walkable(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
1970
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // We might be here for reasons in addition to the self-suspend request
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // so check for other async requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1974
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 if (check_asyncs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 check_and_handle_async_exceptions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 void JavaThread::send_thread_stop(oop java_throwable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 assert(Thread::current()->is_VM_thread(), "should be in the vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 assert(Threads_lock->is_locked(), "Threads_lock should be locked by safepoint code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 // Do not throw asynchronous exceptions against the compiler thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 // (the compiler thread should not be a Java thread -- fix in 1.4.2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 if (is_Compiler_thread()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 // Actually throw the Throwable against the target Thread - however
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 // only if there is no thread death exception installed already.
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
1992 if (_pending_async_exception == NULL || !_pending_async_exception->is_a(SystemDictionary::ThreadDeath_klass())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // If the topmost frame is a runtime stub, then we are calling into
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // OptoRuntime from compiled code. Some runtime stubs (new, monitor_exit..)
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // must deoptimize the caller before continuing, as the compiled exception handler table
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // may not be valid
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 if (has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 frame f = last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 if (f.is_runtime_frame() || f.is_safepoint_blob_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 RegisterMap reg_map(this, UseBiasedLocking);
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 frame compiled_frame = f.sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 if (compiled_frame.can_be_deoptimized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 Deoptimization::deoptimize(this, compiled_frame, &reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // Set async. pending exception in thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 set_pending_async_exception(java_throwable);
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 if (TraceExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 tty->print_cr("Pending Async. exception installed of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 // for AbortVMOnException flag
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 NOT_PRODUCT(Exceptions::debug_check_abort(instanceKlass::cast(_pending_async_exception->klass())->external_name()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 // Interrupt thread so it will wake up from a potential wait()
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 Thread::interrupt(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2025
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 // External suspension mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 // Tell the VM to suspend a thread when ever it knows that it does not hold on
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 // to any VM_locks and it is at a transition
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // Self-suspension will happen on the transition out of the vm.
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // Catch "this" coming in from JNIEnv pointers when the thread has been freed
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 // Guarantees on return:
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 // + Target thread will not execute any new bytecode (that's why we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // force a safepoint)
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 // + Target thread will not enter any new monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 void JavaThread::java_suspend() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 { MutexLocker mu(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 if (!Threads::includes(this) || is_exiting() || this->threadObj() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 { MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 if (!is_external_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 // a racing resume has cancelled us; bail out now
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 // suspend is done
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // Warning: is_ext_suspend_completed() may temporarily drop the
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 // SR_lock to allow the thread to reach a stable thread state if
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // it is currently in a transient thread state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (is_ext_suspend_completed(false /* !called_by_wait */,
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 SuspendRetryDelay, &debug_bits) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2061
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 VM_ForceSafepoint vm_suspend;
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 VMThread::execute(&vm_suspend);
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2065
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // Part II of external suspension.
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 // A JavaThread self suspends when it detects a pending external suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 // request. This is usually on transitions. It is also done in places
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 // where continuing to the next transition would surprise the caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 // e.g., monitor entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // Returns the number of times that the thread self-suspended.
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // Note: DO NOT call java_suspend_self() when you just want to block current
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // thread. java_suspend_self() is the second stage of cooperative
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // suspension for external suspend requests and should only be used
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // to complete an external suspend request.
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 int JavaThread::java_suspend_self() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 int ret = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // we are in the process of exiting so don't suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 if (is_exiting()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 clear_external_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2087
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 assert(_anchor.walkable() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 (is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 "must have walkable stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
2091
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
979
87770dcf831b 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 844
diff changeset
2094 assert(!this->is_ext_suspended(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 "a thread trying to self-suspend should not already be suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 if (this->is_suspend_equivalent()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 // If we are self-suspending as a result of the lifting of a
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 // suspend equivalent condition, then the suspend_equivalent
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 // flag is not cleared until we set the ext_suspended flag so
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 // that wait_for_ext_suspend_completion() returns consistent
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // results.
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 this->clear_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2105
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 // A racing resume may have cancelled us before we grabbed SR_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 // above. Or another external suspend request could be waiting for us
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // by the time we return from SR_lock()->wait(). The thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 // that requested the suspension may already be trying to walk our
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // stack and if we return now, we can change the stack out from under
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 // it. This would be a "bad thing (TM)" and cause the stack walker
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // to crash. We stay self-suspended until there are no more pending
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 // external suspend requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 while (is_external_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 ret++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 this->set_ext_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 // _ext_suspended flag is cleared by java_resume()
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 while (is_ext_suspended()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 this->SR_lock()->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2123
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2126
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 // verify the JavaThread has not yet been published in the Threads::list, and
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 // hence doesn't need protection from concurrent access at this stage
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 void JavaThread::verify_not_published() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 if (!Threads_lock->owned_by_self()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 assert( !Threads::includes(this),
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 "java thread shouldn't have been published yet!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 assert( !Threads::includes(this),
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 "java thread shouldn't have been published yet!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2142
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // Slow path when the native==>VM/Java barriers detect a safepoint is in
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // progress or when _suspend_flags is non-zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // Current thread needs to self-suspend if there is a suspend request and/or
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // block if a safepoint is in progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 // Async exception ISN'T checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // Note only the ThreadInVMfromNative transition can call this function
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 // directly and when thread state is _thread_in_native_trans
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 assert(thread->thread_state() == _thread_in_native_trans, "wrong state");
a61af66fc99e Initial load
duke
parents:
diff changeset
2152
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 JavaThread *curJT = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 bool do_self_suspend = thread->is_external_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
2155
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 assert(!curJT->has_last_Java_frame() || curJT->frame_anchor()->walkable(), "Unwalkable stack in native->vm transition");
a61af66fc99e Initial load
duke
parents:
diff changeset
2157
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 // If JNIEnv proxies are allowed, don't self-suspend if the target
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // thread is not the current thread. In older versions of jdbx, jdbx
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // threads could call into the VM with another thread's JNIEnv so we
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 // can be here operating on behalf of a suspended thread (4432884).
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 if (do_self_suspend && (!AllowJNIEnvProxy || curJT == thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 JavaThreadState state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
2164
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // We mark this thread_blocked state as a suspend-equivalent so
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // that a caller to is_ext_suspend_completed() won't be confused.
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // The suspend-equivalent state is cleared by java_suspend_self().
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // If the safepoint code sees the _thread_in_native_trans state, it will
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // wait until the thread changes to other thread state. There is no
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // guarantee on how soon we can obtain the SR_lock and complete the
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // self-suspend request. It would be a bad idea to let safepoint wait for
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // too long. Temporarily change the state to _thread_blocked to
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 // let the VM thread know that this thread is ready for GC. The problem
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 // of changing thread state is that safepoint could happen just after
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 // java_suspend_self() returns after being resumed, and VM thread will
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 // see the _thread_blocked state. We must check for safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 // after restoring the state and make sure we won't leave while a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // is in progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 thread->set_thread_state(_thread_blocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 thread->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 thread->set_thread_state(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // Make sure new state is seen by VM thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 if (os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 if (UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // Force a fence between the write above and read below
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 // Must use this rather than serialization page in particular on Windows
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 InterfaceSupport::serialize_memory(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 if (SafepointSynchronize::do_call_back()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 // If we are safepointing, then block the caller which may not be
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 // the same as the target thread (see above).
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 SafepointSynchronize::block(curJT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2201
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 if (thread->is_deopt_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 thread->clear_deopt_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 frame f = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 while ( f.id() != thread->must_deopt_id() && ! f.is_first_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 f = f.sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 if (f.id() == thread->must_deopt_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 thread->clear_must_deopt_id();
1727
da877bdc9000 6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents: 1689
diff changeset
2211 f.deoptimize(thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 fatal("missed deoptimization!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2217
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // Slow path when the native==>VM/Java barriers detect a safepoint is in
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // progress or when _suspend_flags is non-zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // Current thread needs to self-suspend if there is a suspend request and/or
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // block if a safepoint is in progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // Also check for pending async exception (not including unsafe access error).
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 // Note only the native==>VM/Java barriers can call this function and when
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 // thread state is _thread_in_native_trans.
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 void JavaThread::check_special_condition_for_native_trans(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 check_safepoint_and_suspend_for_native_trans(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2227
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 if (thread->has_async_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 // We are in _thread_in_native_trans state, don't handle unsafe
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 // access error since that may block.
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 thread->check_and_handle_async_exceptions(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // We need to guarantee the Threads_lock here, since resumes are not
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // allowed during safepoint synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 // Can only resume from an external suspension
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 void JavaThread::java_resume() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 assert_locked_or_safepoint(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 // Sanity check: thread is gone, has started exiting or the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 // was not externally suspended.
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 if (!Threads::includes(this) || is_exiting() || !is_external_suspend()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2246
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 clear_external_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
2250
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 if (is_ext_suspended()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 clear_ext_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 SR_lock()->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2256
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 void JavaThread::create_stack_guard_pages() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 address low_addr = stack_base() - stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 int allocate = os::allocate_stack_guard_pages();
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
a61af66fc99e Initial load
duke
parents:
diff changeset
2264
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1290
diff changeset
2265 if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 warning("Attempt to allocate stack guard pages failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 if (os::guard_memory((char *) low_addr, len)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 _stack_guard_state = stack_guard_enabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 warning("Attempt to protect stack guard pages failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 if (os::uncommit_memory((char *) low_addr, len)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 warning("Attempt to deallocate stack guard pages failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2279
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 void JavaThread::remove_stack_guard_pages() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 if (_stack_guard_state == stack_guard_unused) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 address low_addr = stack_base() - stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2284
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 if (os::allocate_stack_guard_pages()) {
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1290
diff changeset
2286 if (os::remove_stack_guard_pages((char *) low_addr, len)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 _stack_guard_state = stack_guard_unused;
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 warning("Attempt to deallocate stack guard pages failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 if (_stack_guard_state == stack_guard_unused) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 if (os::unguard_memory((char *) low_addr, len)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 _stack_guard_state = stack_guard_unused;
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 warning("Attempt to unprotect stack guard pages failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2300
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 void JavaThread::enable_stack_yellow_zone() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 assert(_stack_guard_state != stack_guard_enabled, "already enabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2304
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 // The base notation is from the stacks point of view, growing downward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 // We need to adjust it to work correctly with guard_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 address base = stack_yellow_zone_base() - stack_yellow_zone_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2308
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 guarantee(base < stack_base(),"Error calculating stack yellow zone");
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 guarantee(base < os::current_stack_pointer(),"Error calculating stack yellow zone");
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 if (os::guard_memory((char *) base, stack_yellow_zone_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 _stack_guard_state = stack_guard_enabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 warning("Attempt to guard stack yellow zone failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 enable_register_stack_guard();
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2319
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 void JavaThread::disable_stack_yellow_zone() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 assert(_stack_guard_state != stack_guard_yellow_disabled, "already disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2323
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 // Simply return if called for a thread that does not use guard pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 if (_stack_guard_state == stack_guard_unused) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 // The base notation is from the stacks point of view, growing downward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // We need to adjust it to work correctly with guard_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 address base = stack_yellow_zone_base() - stack_yellow_zone_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2330
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 if (os::unguard_memory((char *)base, stack_yellow_zone_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 _stack_guard_state = stack_guard_yellow_disabled;
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 warning("Attempt to unguard stack yellow zone failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 disable_register_stack_guard();
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2338
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 void JavaThread::enable_stack_red_zone() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 // The base notation is from the stacks point of view, growing downward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // We need to adjust it to work correctly with guard_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 address base = stack_red_zone_base() - stack_red_zone_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2344
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 guarantee(base < stack_base(),"Error calculating stack red zone");
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 guarantee(base < os::current_stack_pointer(),"Error calculating stack red zone");
a61af66fc99e Initial load
duke
parents:
diff changeset
2347
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 if(!os::guard_memory((char *) base, stack_red_zone_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 warning("Attempt to guard stack red zone failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2352
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 void JavaThread::disable_stack_red_zone() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // The base notation is from the stacks point of view, growing downward.
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 // We need to adjust it to work correctly with guard_memory()
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 address base = stack_red_zone_base() - stack_red_zone_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 if (!os::unguard_memory((char *)base, stack_red_zone_size())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 warning("Attempt to unguard stack red zone failed.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 void JavaThread::frames_do(void f(frame*, const RegisterMap* map)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 // ignore is there is no stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 if (!has_last_Java_frame()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 // traverse the stack frames. Starts from top frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 frame* fr = fst.current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 f(fr, fst.register_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2372
a61af66fc99e Initial load
duke
parents:
diff changeset
2373
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 // Deoptimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // Function for testing deoptimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 void JavaThread::deoptimize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 StackFrameStream fst(this, UseBiasedLocking);
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 bool deopt = false; // Dump stack only if a deopt actually happens.
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 bool only_at = strlen(DeoptimizeOnlyAt) > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // Iterate over all frames in the thread and deoptimize
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 for(; !fst.is_done(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 if(fst.current()->can_be_deoptimized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2385
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 if (only_at) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // Deoptimize only at particular bcis. DeoptimizeOnlyAt
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // consists of comma or carriage return separated numbers so
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 // search for the current bci in that string.
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 address pc = fst.current()->pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 nmethod* nm = (nmethod*) fst.current()->cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 ScopeDesc* sd = nm->scope_desc_at( pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 char buffer[8];
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 jio_snprintf(buffer, sizeof(buffer), "%d", sd->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 size_t len = strlen(buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 const char * found = strstr(DeoptimizeOnlyAt, buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 while (found != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 if ((found[len] == ',' || found[len] == '\n' || found[len] == '\0') &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 (found == DeoptimizeOnlyAt || found[-1] == ',' || found[-1] == '\n')) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 // Check that the bci found is bracketed by terminators.
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 found = strstr(found + 1, buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 if (!found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2409
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 if (DebugDeoptimization && !deopt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 deopt = true; // One-time only print before deopt
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 tty->print_cr("[BEFORE Deoptimization]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 trace_frames();
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 trace_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2419
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 if (DebugDeoptimization && deopt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 tty->print_cr("[AFTER Deoptimization]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 trace_frames();
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2425
a61af66fc99e Initial load
duke
parents:
diff changeset
2426
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // Make zombies
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 void JavaThread::make_zombies() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 if (fst.current()->can_be_deoptimized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 // it is a Java nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 nmethod* nm = CodeCache::find_nmethod(fst.current()->pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 nm->make_not_entrant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2438
a61af66fc99e Initial load
duke
parents:
diff changeset
2439
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 void JavaThread::deoptimized_wrt_marked_nmethods() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 if (!has_last_Java_frame()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 StackFrameStream fst(this, UseBiasedLocking);
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 for(; !fst.is_done(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 if (fst.current()->should_be_deoptimized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2450
a61af66fc99e Initial load
duke
parents:
diff changeset
2451
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 // GC support
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 static void frame_gc_epilogue(frame* f, const RegisterMap* map) { f->gc_epilogue(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2454
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 void JavaThread::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 frames_do(frame_gc_epilogue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2458
a61af66fc99e Initial load
duke
parents:
diff changeset
2459
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 static void frame_gc_prologue(frame* f, const RegisterMap* map) { f->gc_prologue(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2461
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 void JavaThread::gc_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 frames_do(frame_gc_prologue);
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2465
1119
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2466 // If the caller is a NamedThread, then remember, in the current scope,
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2467 // the given JavaThread in its _processed_thread field.
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2468 class RememberProcessedThread: public StackObj {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2469 NamedThread* _cur_thr;
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2470 public:
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2471 RememberProcessedThread(JavaThread* jthr) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2472 Thread* thread = Thread::current();
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2473 if (thread->is_Named_thread()) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2474 _cur_thr = (NamedThread *)thread;
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2475 _cur_thr->set_processed_thread(jthr);
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2476 } else {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2477 _cur_thr = NULL;
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2478 }
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2479 }
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2480
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2481 ~RememberProcessedThread() {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2482 if (_cur_thr) {
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2483 _cur_thr->set_processed_thread(NULL);
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2484 }
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2485 }
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2486 };
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2487
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2488 void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
1166
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1144
diff changeset
2489 // Verify that the deferred card marks have been flushed.
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1144
diff changeset
2490 assert(deferred_card_mark().is_empty(), "Should be empty during GC");
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 997
diff changeset
2491
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 // The ThreadProfiler oops_do is done from FlatProfiler::oops_do
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 // since there may be more than one thread using each ThreadProfiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2494
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 // Traverse the GCHandles
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2496 Thread::oops_do(f, cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2497
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2500
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 if (has_last_Java_frame()) {
1119
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2502 // Record JavaThread to GC thread
547f81740344 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 1115
diff changeset
2503 RememberProcessedThread rpt(this);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2504
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 // Traverse the privileged stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 if (_privileged_stack_top != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 _privileged_stack_top->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2509
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 // traverse the registered growable array
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 if (_array_for_gc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 for (int index = 0; index < _array_for_gc->length(); index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 f->do_oop(_array_for_gc->adr_at(index));
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 // Traverse the monitor chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 chunk->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2521
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 // Traverse the execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2524 fst.current()->oops_do(f, cf, fst.register_map());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2527
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 // callee_target is never live across a gc point so NULL it here should
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 // it still contain a methdOop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 set_callee_target(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 assert(vframe_array_head() == NULL, "deopt in progress at a safepoint!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 // If we have deferred set_locals there might be oops waiting to be
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 // written
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = deferred_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 if (list != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 for (int i = 0; i < list->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 list->at(i)->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2542
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 // Traverse instance variables at the end since the GC may be moving things
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 // around using this function
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 f->do_oop((oop*) &_threadObj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 f->do_oop((oop*) &_vm_result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 f->do_oop((oop*) &_vm_result_2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 f->do_oop((oop*) &_exception_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 f->do_oop((oop*) &_pending_async_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 if (jvmti_thread_state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 jvmti_thread_state()->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2555
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2556 void JavaThread::nmethods_do(CodeBlobClosure* cf) {
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2557 Thread::nmethods_do(cf); // (super method is a no-op)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2558
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2561
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 if (has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 // Traverse the execution stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2565 fst.current()->nmethods_do(cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2569
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 const char* _get_thread_state_name(JavaThreadState _thread_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 switch (_thread_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 case _thread_uninitialized: return "_thread_uninitialized";
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 case _thread_new: return "_thread_new";
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 case _thread_new_trans: return "_thread_new_trans";
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 case _thread_in_native: return "_thread_in_native";
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 case _thread_in_native_trans: return "_thread_in_native_trans";
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 case _thread_in_vm: return "_thread_in_vm";
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 case _thread_in_vm_trans: return "_thread_in_vm_trans";
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 case _thread_in_Java: return "_thread_in_Java";
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 case _thread_in_Java_trans: return "_thread_in_Java_trans";
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 case _thread_blocked: return "_thread_blocked";
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 case _thread_blocked_trans: return "_thread_blocked_trans";
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 default: return "unknown thread state";
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2587
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 void JavaThread::print_thread_state_on(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 st->print_cr(" JavaThread state: %s", _get_thread_state_name(_thread_state));
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 void JavaThread::print_thread_state() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 print_thread_state_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2596
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 // Called by Threads::print() for VM_PrintThreads operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 void JavaThread::print_on(outputStream *st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 st->print("\"%s\" ", get_thread_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 oop thread_oop = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 if (thread_oop != NULL && java_lang_Thread::is_daemon(thread_oop)) st->print("daemon ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 Thread::print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 // print guess for valid stack memory region (assume 4K pages); helps lock debugging
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 669
diff changeset
2604 st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 st->print_cr(" java.lang.Thread.State: %s", java_lang_Thread::thread_status_name(thread_oop));
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 print_thread_state_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 _safepoint_state->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2613
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 // Called by fatal error handler. The difference between this and
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 // JavaThread::print() is that we can't grab lock or allocate memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 st->print("JavaThread \"%s\"", get_thread_name_string(buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 oop thread_obj = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 if (thread_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon");
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 st->print(" [");
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 st->print("%s", _get_thread_state_name(_thread_state));
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 if (osthread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 st->print(", id=%d", osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 _stack_base - _stack_size, _stack_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 st->print("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2632
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 // Verification
a61af66fc99e Initial load
duke
parents:
diff changeset
2634
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 static void frame_verify(frame* f, const RegisterMap *map) { f->verify(map); }
a61af66fc99e Initial load
duke
parents:
diff changeset
2636
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 void JavaThread::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 // Verify oops in the thread.
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
2639 oops_do(&VerifyOopClosure::verify_oop, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2640
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 // Verify the stack frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 frames_do(frame_verify);
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2644
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 // CR 6300358 (sub-CR 2137150)
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 // Most callers of this method assume that it can't return NULL but a
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 // thread may not have a name whilst it is in the process of attaching to
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 // the VM - see CR 6412693, and there are places where a JavaThread can be
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 // seen prior to having it's threadObj set (eg JNI attaching threads and
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 // if vm exit occurs during initialization). These cases can all be accounted
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 // for such that this method never returns NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 const char* JavaThread::get_thread_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 // early safepoints can hit while current thread does not yet have TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 if (!SafepointSynchronize::is_at_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 Thread *cur = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 if (!(cur->is_Java_thread() && cur == this)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 // Current JavaThreads are allowed to get their own name without
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 // the Threads_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 assert_locked_or_safepoint(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 return get_thread_name_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2666
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 // Returns a non-NULL representation of this thread's name, or a suitable
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 // descriptive string if there is no set name
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 const char* name_str;
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 oop thread_obj = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 if (thread_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 typeArrayOop name = java_lang_Thread::name(thread_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 if (name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 if (buf == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 name_str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 name_str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length(), buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 else if (is_attaching()) { // workaround for 6412693 - see 6404306
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 name_str = "<no-name - thread is attaching>";
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 name_str = Thread::name();
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 name_str = Thread::name();
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 assert(name_str != NULL, "unexpected NULL thread name");
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 return name_str;
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2695
a61af66fc99e Initial load
duke
parents:
diff changeset
2696
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 const char* JavaThread::get_threadgroup_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 debug_only(if (JavaThread::current() != this) assert_locked_or_safepoint(Threads_lock);)
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 oop thread_obj = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 if (thread_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 oop thread_group = java_lang_Thread::threadGroup(thread_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 if (thread_group != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 typeArrayOop name = java_lang_ThreadGroup::name(thread_group);
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // ThreadGroup.name can be null
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 if (name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 return str;
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 const char* JavaThread::get_parent_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 debug_only(if (JavaThread::current() != this) assert_locked_or_safepoint(Threads_lock);)
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 oop thread_obj = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 if (thread_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 oop thread_group = java_lang_Thread::threadGroup(thread_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 if (thread_group != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 oop parent = java_lang_ThreadGroup::parent(thread_group);
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 if (parent != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 typeArrayOop name = java_lang_ThreadGroup::name(parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 // ThreadGroup.name can be null
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 if (name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 return str;
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 ThreadPriority JavaThread::java_priority() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 oop thr_oop = threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 if (thr_oop == NULL) return NormPriority; // Bootstrapping
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 ThreadPriority priority = java_lang_Thread::priority(thr_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 return priority;
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2741
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // Link Java Thread object <-> C++ Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2746
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 // Get the C++ thread object (an oop) from the JNI handle (a jthread)
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 // and put it into a new Handle. The Handle "thread_oop" can then
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 // be used to pass the C++ thread object to other methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
2750
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 // Set the Java level thread object (jthread) field of the
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 // new thread (a JavaThread *) to C++ thread object using the
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 // "thread_oop" handle.
a61af66fc99e Initial load
duke
parents:
diff changeset
2754
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 // Set the thread field (a JavaThread *) of the
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 // oop representing the java_lang_Thread to the new thread (a JavaThread *).
a61af66fc99e Initial load
duke
parents:
diff changeset
2757
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 Handle thread_oop(Thread::current(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 JNIHandles::resolve_non_null(jni_thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 assert(instanceKlass::cast(thread_oop->klass())->is_linked(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 "must be initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 set_threadObj(thread_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 java_lang_Thread::set_thread(thread_oop(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2764
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 if (prio == NoPriority) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 prio = java_lang_Thread::priority(thread_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 assert(prio != NoPriority, "A valid priority should be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2769
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 // Push the Java priority down to the native thread; needs Threads_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 Thread::set_priority(this, prio);
a61af66fc99e Initial load
duke
parents:
diff changeset
2772
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // Add the new thread to the Threads list and set it in motion.
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 // We must have threads lock in order to call Threads::add.
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 // It is crucial that we do not block before the thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // added to the Threads list for if a GC happens, then the java_thread oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 // will not be visited by GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 Threads::add(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2780
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 oop JavaThread::current_park_blocker() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 // Support for JSR-166 locks
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 oop thread_oop = threadObj();
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
2784 if (thread_oop != NULL &&
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
2785 JDK_Version::current().supports_thread_park_blocker()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 return java_lang_Thread::park_blocker(thread_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2790
a61af66fc99e Initial load
duke
parents:
diff changeset
2791
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 void JavaThread::print_stack_on(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 if (!has_last_Java_frame()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2796
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 RegisterMap reg_map(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 vframe* start_vf = last_java_vframe(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 int count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 for (vframe* f = start_vf; f; f = f->sender() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 if (f->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 javaVFrame* jvf = javaVFrame::cast(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 java_lang_Throwable::print_stack_element(st, jvf->method(), jvf->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2804
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 // Print out lock information
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 if (JavaMonitorsInStackTrace) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 jvf->print_lock_info_on(st, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // Ignore non-Java frames
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2812
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // Bail-out case for too deep stacks
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 if (MaxJavaStackTraceDepth == count) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2818
a61af66fc99e Initial load
duke
parents:
diff changeset
2819
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // JVMTI PopFrame support
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 void JavaThread::popframe_preserve_args(ByteSize size_in_bytes, void* start) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 assert(_popframe_preserved_args == NULL, "should not wipe out old PopFrame preserved arguments");
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 if (in_bytes(size_in_bytes) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes));
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 _popframe_preserved_args_size = in_bytes(size_in_bytes);
1603
d93949c5bdcc 6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents: 1584
diff changeset
2826 Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2829
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 void* JavaThread::popframe_preserved_args() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 return _popframe_preserved_args;
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 ByteSize JavaThread::popframe_preserved_args_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 return in_ByteSize(_popframe_preserved_args_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2837
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 WordSize JavaThread::popframe_preserved_args_size_in_words() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 int sz = in_bytes(popframe_preserved_args_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 assert(sz % wordSize == 0, "argument size must be multiple of wordSize");
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 return in_WordSize(sz / wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2843
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 void JavaThread::popframe_free_preserved_args() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 assert(_popframe_preserved_args != NULL, "should not free PopFrame preserved arguments twice");
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args);
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 _popframe_preserved_args = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 _popframe_preserved_args_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2850
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2852
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 void JavaThread::trace_frames() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 tty->print_cr("[Describe stack]");
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 int frame_no = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 tty->print(" %d. ", frame_no++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 fst.current()->print_value_on(tty,this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2862
3908
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2863 class PrintAndVerifyOopClosure: public OopClosure {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2864 protected:
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2865 template <class T> inline void do_oop_work(T* p) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2866 oop obj = oopDesc::load_decode_heap_oop(p);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2867 if (obj == NULL) return;
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2868 tty->print(INTPTR_FORMAT ": ", p);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2869 if (obj->is_oop_or_null()) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2870 if (obj->is_objArray()) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2871 tty->print_cr("valid objArray: " INTPTR_FORMAT, (oopDesc*) obj);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2872 } else {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2873 obj->print();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2874 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2875 } else {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2876 tty->print_cr("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2877 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2878 tty->cr();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2879 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2880 public:
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2881 virtual void do_oop(oop* p) { do_oop_work(p); }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2882 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2883 };
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2884
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2885
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2886 static void oops_print(frame* f, const RegisterMap *map) {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2887 PrintAndVerifyOopClosure print;
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2888 f->print_value();
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2889 f->oops_do(&print, NULL, (RegisterMap*)map);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2890 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2891
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2892 // Print our all the locations that contain oops and whether they are
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2893 // valid or not. This useful when trying to find the oldest frame
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2894 // where an oop has gone bad since the frame walk is from youngest to
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2895 // oldest.
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2896 void JavaThread::trace_oops() {
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2897 tty->print_cr("[Trace oops]");
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2898 frames_do(oops_print);
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2899 }
7588156f5cf9 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 3899
diff changeset
2900
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2901
3388
a80577f854f9 7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents: 3384
diff changeset
2902 #ifdef ASSERT
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2903 // Print or validate the layout of stack frames
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2904 void JavaThread::print_frame_layout(int depth, bool validate_only) {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2905 ResourceMark rm;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2906 PRESERVE_EXCEPTION_MARK;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2907 FrameValues values;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2908 int frame_no = 0;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2909 for(StackFrameStream fst(this, false); !fst.is_done(); fst.next()) {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2910 fst.current()->describe(values, ++frame_no);
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2911 if (depth == frame_no) break;
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2912 }
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2913 if (validate_only) {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2914 values.validate();
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2915 } else {
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2916 tty->print_cr("[Describe stack layout]");
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2917 values.print();
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2918 }
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2919 }
3388
a80577f854f9 7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents: 3384
diff changeset
2920 #endif
3336
2e038ad0c1d0 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 2416
diff changeset
2921
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 void JavaThread::trace_stack_from(vframe* start_vf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 int vframe_no = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 for (vframe* f = start_vf; f; f = f->sender() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 if (f->is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 javaVFrame::cast(f)->print_activation(vframe_no++);
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 f->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 if (vframe_no > StackPrintLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 tty->print_cr("...<more frames>...");
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2937
a61af66fc99e Initial load
duke
parents:
diff changeset
2938
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 void JavaThread::trace_stack() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 if (!has_last_Java_frame()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 RegisterMap reg_map(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 trace_stack_from(last_java_vframe(&reg_map));
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2946
a61af66fc99e Initial load
duke
parents:
diff changeset
2947
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
a61af66fc99e Initial load
duke
parents:
diff changeset
2950
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 javaVFrame* JavaThread::last_java_vframe(RegisterMap *reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 assert(reg_map != NULL, "a map must be given");
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 frame f = last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 for (vframe* vf = vframe::new_vframe(&f, reg_map, this); vf; vf = vf->sender() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 if (vf->is_java_frame()) return javaVFrame::cast(vf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2959
a61af66fc99e Initial load
duke
parents:
diff changeset
2960
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 klassOop JavaThread::security_get_caller_class(int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 vframeStream vfst(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 vfst.security_get_caller_frame(depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 if (!vfst.at_end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 return vfst.method()->method_holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2969
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 static void compiler_thread_entry(JavaThread* thread, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 assert(thread->is_Compiler_thread(), "must be compiler thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 CompileBroker::compiler_thread_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2974
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 // Create a CompilerThread
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 : JavaThread(&compiler_thread_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 _env = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 _log = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 _task = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 _queue = queue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 _counters = counters;
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1552
diff changeset
2983 _buffer_blob = NULL;
3384
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2984 _scanned_nmethod = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2985
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 _ideal_graph_printer = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2990
3384
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2991 void CompilerThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2992 JavaThread::oops_do(f, cf);
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2993 if (_scanned_nmethod != NULL && cf != NULL) {
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2994 // Safepoints can occur when the sweeper is scanning an nmethod so
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2995 // process it here to make sure it isn't unloaded in the middle of
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2996 // a scan.
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2997 cf->do_code_blob(_scanned_nmethod);
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2998 }
f52ed367b66d 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 3336
diff changeset
2999 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3000
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 // ======= Threads ========
a61af66fc99e Initial load
duke
parents:
diff changeset
3002
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 // The Threads class links together all active threads, and provides
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 // operations over all threads. It is protected by its own Mutex
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // lock, which is also used in other contexts to protect thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 // operations from having the thread being operated on from exiting
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 // and going away unexpectedly (e.g., safepoint synchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
3008
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 JavaThread* Threads::_thread_list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 int Threads::_number_of_threads = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 int Threads::_number_of_non_daemon_threads = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 int Threads::_return_code = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 size_t JavaThread::_stack_size_at_create = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3014
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 // All JavaThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next())
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 void os_stream();
a61af66fc99e Initial load
duke
parents:
diff changeset
3019
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 // All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 void Threads::threads_do(ThreadClosure* tc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 assert_locked_or_safepoint(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 // ALL_JAVA_THREADS iterates through all JavaThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 tc->do_thread(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // Someday we could have a table or list of all non-JavaThreads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // For now, just manually iterate through them.
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 tc->do_thread(VMThread::vm_thread());
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 Universe::heap()->gc_threads_do(tc);
323
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3031 WatcherThread *wt = WatcherThread::watcher_thread();
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3032 // Strictly speaking, the following NULL check isn't sufficient to make sure
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3033 // the data for WatcherThread is still valid upon being examined. However,
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3034 // considering that WatchThread terminates when the VM is on the way to
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3035 // exit at safepoint, the chance of the above is extremely small. The right
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3036 // way to prevent termination of WatcherThread would be to acquire
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3037 // Terminator_lock, but we can't do that without violating the lock rank
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3038 // checking in some cases.
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3039 if (wt != NULL)
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3040 tc->do_thread(wt);
b33eef719520 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 286
diff changeset
3041
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 // If CompilerThreads ever become non-JavaThreads, add them here
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3044
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
3047 extern void JDK_Version_init();
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
3048
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 // Check version
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
a61af66fc99e Initial load
duke
parents:
diff changeset
3051
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 // Initialize the output stream module
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 ostream_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3054
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 // Process java launcher properties.
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 Arguments::process_sun_java_launcher_properties(args);
a61af66fc99e Initial load
duke
parents:
diff changeset
3057
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 // Initialize the os module before using TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 os::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3060
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // Initialize system properties.
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 Arguments::init_system_properties();
a61af66fc99e Initial load
duke
parents:
diff changeset
3063
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
3064 // So that JDK version can be used as a discrimintor when parsing arguments
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
3065 JDK_Version_init();
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 196
diff changeset
3066
1864
dfb38ea7da17 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 1731
diff changeset
3067 // Update/Initialize System properties after JDK version number is known
dfb38ea7da17 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 1731
diff changeset
3068 Arguments::init_version_specific_system_properties();
dfb38ea7da17 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 1731
diff changeset
3069
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // Parse arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 jint parse_result = Arguments::parse(args);
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 if (parse_result != JNI_OK) return parse_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3073
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 if (PauseAtStartup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 os::pause();
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3077
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 HS_DTRACE_PROBE(hotspot, vm__init__begin);
a61af66fc99e Initial load
duke
parents:
diff changeset
3079
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 // Record VM creation timing statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 TraceVmCreationTime create_vm_timer;
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 create_vm_timer.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3083
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // Timing (must come after argument parsing)
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 TraceTime timer("Create VM", TraceStartupTime);
a61af66fc99e Initial load
duke
parents:
diff changeset
3086
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 // Initialize the os module after parsing the args
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 jint os_init_2_result = os::init_2();
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 if (os_init_2_result != JNI_OK) return os_init_2_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3090
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // Initialize output stream logging
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 ostream_init_log();
a61af66fc99e Initial load
duke
parents:
diff changeset
3093
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // Convert -Xrun to -agentlib: if there is no JVM_OnLoad
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 // Must be before create_vm_init_agents()
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 if (Arguments::init_libraries_at_startup()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 convert_vm_init_libraries_to_agents();
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3099
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // Launch -agentlib/-agentpath and converted -Xrun agents
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 if (Arguments::init_agents_at_startup()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 create_vm_init_agents();
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3104
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // Initialize Threads state
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 _thread_list = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 _number_of_threads = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 _number_of_non_daemon_threads = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3109
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 // Initialize TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 ThreadLocalStorage::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3112
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 // Initialize global data structures and create system classes in heap
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 vm_init_globals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 // Attach the main thread to this os thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 JavaThread* main_thread = new JavaThread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 main_thread->set_thread_state(_thread_in_vm);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 // must do this before set_active_handles and initialize_thread_local_storage
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // Note: on solaris initialize_thread_local_storage() will (indirectly)
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 // change the stack size recorded here to one based on the java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 // stacksize. This adjusted size is what is used to figure the placement
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // of the guard pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 main_thread->record_stack_base_and_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 main_thread->initialize_thread_local_storage();
a61af66fc99e Initial load
duke
parents:
diff changeset
3126
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 main_thread->set_active_handles(JNIHandleBlock::allocate_block());
a61af66fc99e Initial load
duke
parents:
diff changeset
3128
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 if (!main_thread->set_as_starting_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 vm_shutdown_during_initialization(
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 "Failed necessary internal allocation. Out of swap space");
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 delete main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3136
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 // Enable guard page *after* os::create_main_thread(), otherwise it would
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 // crash Linux VM, see notes in os_linux.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 main_thread->create_stack_guard_pages();
a61af66fc99e Initial load
duke
parents:
diff changeset
3140
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
3141 // Initialize Java-Level synchronization subsystem
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
3142 ObjectMonitor::Initialize() ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3143
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 // Initialize global modules
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 jint status = init_globals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 if (status != JNI_OK) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 delete main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3151
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3152 // Should be done after the heap is fully created
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3153 main_thread->cache_global_variables();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3154
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3156
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 { MutexLocker mu(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 Threads::add(main_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3160
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 // Any JVMTI raw monitors entered in onload will transition into
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 // real raw monitor. VM is setup enough here for raw monitor enter.
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 JvmtiExport::transition_pending_onload_raw_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
3164
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 if (VerifyBeforeGC &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 Universe::heap()->total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 Universe::heap()->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 Universe::verify(); // make sure we're starting with a clean slate
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3170
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 // Create the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 { TraceTime timer("Start VMThread", TraceStartupTime);
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 VMThread::create();
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 Thread* vmthread = VMThread::vm_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3175
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 if (!os::create_thread(vmthread, os::vm_thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 vm_exit_during_initialization("Cannot create VM thread. Out of system resources.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3178
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 // Wait for the VM thread to become ready, and VMThread::run to initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 // Monitors can have spurious returns, must always check another state flag
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 MutexLocker ml(Notify_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 os::start_thread(vmthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 while (vmthread->active_handles() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 Notify_lock->wait();
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3189
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 assert (Universe::is_fully_initialized(), "not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3192
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 // At this point, the Universe is initialized, but we have not executed
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 // any byte code. Now is a good time (the only time) to dump out the
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 // internal state of the JVM for sharing.
a61af66fc99e Initial load
duke
parents:
diff changeset
3196
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 if (DumpSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 Universe::heap()->preload_and_dump(CHECK_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3201
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 // Always call even when there are not JVMTI environments yet, since environments
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // may be attached late and JVMTI must track phases of VM execution
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 JvmtiExport::enter_start_phase();
a61af66fc99e Initial load
duke
parents:
diff changeset
3205
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 JvmtiExport::post_vm_start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3208
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 TraceTime timer("Initialize java.lang classes", TraceStartupTime);
a61af66fc99e Initial load
duke
parents:
diff changeset
3211
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 create_vm_init_libraries();
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3215
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 if (InitializeJavaLangString) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3217 initialize_class(vmSymbols::java_lang_String(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 warning("java.lang.String not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3221
18
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3222 if (AggressiveOpts) {
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3223 {
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3224 // Forcibly initialize java/util/HashMap and mutate the private
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3225 // static final "frontCacheEnabled" field before we start creating instances
18
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3226 #ifdef ASSERT
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3227 klassOop tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3228 assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet");
18
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3229 #endif
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3230 klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3231 KlassHandle k = KlassHandle(THREAD, k_o);
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3232 guarantee(k.not_null(), "Must find java/util/HashMap");
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3233 instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3234 ik->initialize(CHECK_0);
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3235 fieldDescriptor fd;
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3236 // Possible we might not find this field; if so, don't break
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3237 if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2302
diff changeset
3238 k()->java_mirror()->bool_field_put(fd.offset(), true);
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3239 }
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3240 }
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3241
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3242 if (UseStringCache) {
669
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3243 // Forcibly initialize java/lang/StringValue and mutate the private
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3244 // static final "stringCacheEnabled" field before we start creating instances
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3245 klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0);
669
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3246 // Possible that StringValue isn't present: if so, silently don't break
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3247 if (k_o != NULL) {
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3248 KlassHandle k = KlassHandle(THREAD, k_o);
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3249 instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3250 ik->initialize(CHECK_0);
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3251 fieldDescriptor fd;
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3252 // Possible we might not find this field: if so, silently don't break
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3253 if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
2376
c7f3d0b4570f 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 2302
diff changeset
3254 k()->java_mirror()->bool_field_put(fd.offset(), true);
669
eca19a8425b5 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 441
diff changeset
3255 }
192
6d13fcb3663f 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 62
diff changeset
3256 }
18
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3257 }
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3258 }
c7d713375c94 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 0
diff changeset
3259
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 // Initialize java_lang.System (needed before creating the thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 if (InitializeJavaLangSystem) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3262 initialize_class(vmSymbols::java_lang_System(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3263 initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 Handle thread_group = create_initial_thread_group(CHECK_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 Universe::set_main_thread_group(thread_group());
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3266 initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 main_thread->set_threadObj(thread_object);
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // Set thread status to running since main thread has
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 // been started and running.
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 java_lang_Thread::set_thread_status(thread_object,
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 java_lang_Thread::RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3273
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 // The VM preresolve methods to these classes. Make sure that get initialized
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3275 initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3276 initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 // The VM creates & returns objects of this class. Make sure it's initialized.
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3278 initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 call_initializeSystemClass(CHECK_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 warning("java.lang.System not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3283
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // an instance of OutOfMemory exception has been allocated earlier
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 if (InitializeJavaLangExceptionsErrors) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3286 initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3287 initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3288 initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3289 initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3290 initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3291 initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3292 initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 warning("java.lang.OutOfMemoryError has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 warning("java.lang.NullPointerException has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 warning("java.lang.ClassCastException has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 warning("java.lang.ArrayStoreException has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 warning("java.lang.ArithmeticException has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 warning("java.lang.StackOverflowError has not been initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 }
2416
38fea01eb669 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 2376
diff changeset
3301 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3302
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 // See : bugid 4211085.
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 // Background : the static initializer of java.lang.Compiler tries to read
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 // property"java.compiler" and read & write property "java.vm.info".
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 // When a security manager is installed through the command line
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 // option "-Djava.security.manager", the above properties are not
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 // readable and the static initializer for java.lang.Compiler fails
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 // resulting in a NoClassDefFoundError. This can happen in any
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 // user code which calls methods in java.lang.Compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 // Hack : the hack is to pre-load and initialize this class, so that only
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 // system domains are on the stack when the properties are read.
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 // Currently even the AWT code has calls to methods in java.lang.Compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 // On the classic VM, java.lang.Compiler is loaded very early to load the JIT.
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 // Future Fix : the best fix is to grant everyone permissions to read "java.compiler" and
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 // read and write"java.vm.info" in the default policy file. See bugid 4211383
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 // Once that is done, we should remove this hack.
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3318 initialize_class(vmSymbols::java_lang_Compiler(), CHECK_0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3319
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 // More hackery - the static initializer of java.lang.Compiler adds the string "nojit" to
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 // the java.vm.info property if no jit gets loaded through java.lang.Compiler (the hotspot
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 // compiler does not get loaded through java.lang.Compiler). "java -version" with the
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 // hotspot vm says "nojit" all the time which is confusing. So, we reset it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 // This should also be taken out as soon as 4211383 gets fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 reset_vm_info_property(CHECK_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3326
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 quicken_jni_functions();
a61af66fc99e Initial load
duke
parents:
diff changeset
3328
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 // Set flag that basic initialization has completed. Used by exceptions and various
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 // debug stuff, that does not work until all basic classes have been initialized.
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 set_init_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
3332
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 HS_DTRACE_PROBE(hotspot, vm__init__end);
a61af66fc99e Initial load
duke
parents:
diff changeset
3334
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 // record VM initialization completion time
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 Management::record_vm_init_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
3337
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // Compute system loader. Note that this has to occur after set_init_completed, since
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 // valid exceptions may be thrown in the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 // set_init_completed has just been called, causing exceptions not to be shortcut
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 // anymore. We call vm_exit_during_initialization directly instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 SystemDictionary::compute_java_system_loader(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3347
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 // Support for ConcurrentMarkSweep. This should be cleaned up
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3350 // and better encapsulated. The ugly nested if test would go away
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3351 // once things are properly refactored. XXX YSR
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3352 if (UseConcMarkSweepGC || UseG1GC) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3353 if (UseConcMarkSweepGC) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3354 ConcurrentMarkSweepThread::makeSurrogateLockerThread(THREAD);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3355 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3356 ConcurrentMarkThread::makeSurrogateLockerThread(THREAD);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 62
diff changeset
3357 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
3363
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 // Always call even when there are not JVMTI environments yet, since environments
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 // may be attached late and JVMTI must track phases of VM execution
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 JvmtiExport::enter_live_phase();
a61af66fc99e Initial load
duke
parents:
diff changeset
3367
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 // Signal Dispatcher needs to be started before VMInit event is posted
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 os::signal_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3370
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 // Start Attach Listener if +StartAttachListener or it can't be started lazily
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 if (!DisableAttachMechanism) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 if (StartAttachListener || AttachListener::init_at_startup()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 AttachListener::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3377
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 // Launch -Xrun agents
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 // Must be done in the JVMTI live phase so that for backward compatibility the JDWP
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 // back-end can launch with -Xdebug -Xrunjdwp.
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 if (!EagerXrunInit && Arguments::init_libraries_at_startup()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 create_vm_init_libraries();
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3384
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 // Notify JVMTI agents that VM initialization is complete - nop if no agents.
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 JvmtiExport::post_vm_initialized();
a61af66fc99e Initial load
duke
parents:
diff changeset
3387
3799
48048b59a551 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 3769
diff changeset
3388 if (CleanChunkPoolAsync) {
48048b59a551 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 3769
diff changeset
3389 Chunk::start_chunk_pool_cleaner_task();
48048b59a551 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 3769
diff changeset
3390 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3391
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 // initialize compiler(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 CompileBroker::compilation_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3394
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 Management::initialize(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 // management agent fails to start possibly due to
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 // configuration problem and is responsible for printing
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // stack trace if appropriate. Simply exit VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 vm_exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3402
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 if (Arguments::has_profile()) FlatProfiler::engage(main_thread, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 if (Arguments::has_alloc_profile()) AllocationProfiler::engage();
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 if (MemProfiling) MemProfiler::engage();
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 StatSampler::engage();
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 if (CheckJNICalls) JniPeriodicChecker::engage();
a61af66fc99e Initial load
duke
parents:
diff changeset
3408
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 BiasedLocking::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
3410
2129
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3411 if (JDK_Version::current().post_vm_init_hook_enabled()) {
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3412 call_postVMInitHook(THREAD);
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3413 // The Java side of PostVMInitHook.run must deal with all
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3414 // exceptions and provide means of diagnosis.
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3415 if (HAS_PENDING_EXCEPTION) {
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3416 CLEAR_PENDING_EXCEPTION;
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3417 }
8f8dfba37802 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 2126
diff changeset
3418 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3419
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 // Start up the WatcherThread if there are any periodic tasks
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 // NOTE: All PeriodicTasks should be registered by now. If they
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 // aren't, late joiners might appear to start slowly (we might
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 // take a while to process their first tick).
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 if (PeriodicTask::num_tasks() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 WatcherThread::start();
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3427
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3428 // Give os specific code one last chance to start
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3429 os::init_3();
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1608
diff changeset
3430
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 create_vm_timer.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3434
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 // type for the Agent_OnLoad and JVM_OnLoad entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 typedef jint (JNICALL *OnLoadEntry_t)(JavaVM *, char *, void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 // Find a command line agent library and return its entry point for
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 // -agentlib: -agentpath: -Xrun
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 // num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_symbols[], size_t num_symbol_entries) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 OnLoadEntry_t on_load_entry = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 void *library = agent->os_lib(); // check if we have looked it up before
a61af66fc99e Initial load
duke
parents:
diff changeset
3445
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 if (library == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 char buffer[JVM_MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 char ebuf[1024];
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 const char *name = agent->name();
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3450 const char *msg = "Could not find agent library ";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3451
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 if (agent->is_absolute_path()) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3453 library = os::dll_load(name, ebuf, sizeof ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 if (library == NULL) {
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3455 const char *sub_msg = " in absolute path, with error: ";
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3456 size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3457 char *buf = NEW_C_HEAP_ARRAY(char, len);
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3458 jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 // If we can't find the agent, exit.
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3460 vm_exit_during_initialization(buf, NULL);
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3461 FREE_C_HEAP_ARRAY(char, buf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 // Try to load the agent from the standard dll directory
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3465 os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3466 library = os::dll_load(buffer, ebuf, sizeof ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 #ifdef KERNEL
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 // Download instrument dll
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 if (library == NULL && strcmp(name, "instrument") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 char *props = Arguments::get_kernel_properties();
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 char *home = Arguments::get_java_home();
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 const char *fmt = "%s/bin/java %s -Dkernel.background.download=false"
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 " sun.jkernel.DownloadManager -download client_jvm";
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3474 size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3475 char *cmd = NEW_C_HEAP_ARRAY(char, length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 jio_snprintf(cmd, length, fmt, home, props);
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 int status = os::fork_and_exec(cmd);
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 FreeHeap(props);
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 if (status == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 warning(cmd);
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 vm_exit_during_initialization("fork_and_exec failed: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 }
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3484 FREE_C_HEAP_ARRAY(char, cmd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 // when this comes back the instrument.dll should be where it belongs.
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3486 library = os::dll_load(buffer, ebuf, sizeof ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 #endif // KERNEL
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 if (library == NULL) { // Try the local directory
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 char ns[1] = {0};
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3491 os::dll_build_name(buffer, sizeof(buffer), ns, name);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3492 library = os::dll_load(buffer, ebuf, sizeof ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 if (library == NULL) {
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3494 const char *sub_msg = " on the library path, with error: ";
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3495 size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3496 char *buf = NEW_C_HEAP_ARRAY(char, len);
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3497 jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // If we can't find the agent, exit.
1694
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3499 vm_exit_during_initialization(buf, NULL);
ab3fd720516c 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 1681
diff changeset
3500 FREE_C_HEAP_ARRAY(char, buf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 agent->set_os_lib(library);
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3506
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 // Find the OnLoad function.
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 for (size_t symbol_index = 0; symbol_index < num_symbol_entries; symbol_index++) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3509 on_load_entry = CAST_TO_FN_PTR(OnLoadEntry_t, os::dll_lookup(library, on_load_symbols[symbol_index]));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 if (on_load_entry != NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 return on_load_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3514
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // Find the JVM_OnLoad entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 static OnLoadEntry_t lookup_jvm_on_load(AgentLibrary* agent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 const char *on_load_symbols[] = JVM_ONLOAD_SYMBOLS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 return lookup_on_load(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3520
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 // Find the Agent_OnLoad entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 static OnLoadEntry_t lookup_agent_on_load(AgentLibrary* agent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 const char *on_load_symbols[] = AGENT_ONLOAD_SYMBOLS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 return lookup_on_load(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3526
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 // For backwards compatibility with -Xrun
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 // Convert libraries with no JVM_OnLoad, but which have Agent_OnLoad to be
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // treated like -agentpath:
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 // Must be called before agent libraries are created
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 void Threads::convert_vm_init_libraries_to_agents() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 AgentLibrary* agent;
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 AgentLibrary* next;
a61af66fc99e Initial load
duke
parents:
diff changeset
3534
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 for (agent = Arguments::libraries(); agent != NULL; agent = next) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 next = agent->next(); // cache the next agent now as this agent may get moved off this list
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 OnLoadEntry_t on_load_entry = lookup_jvm_on_load(agent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3538
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 // If there is an JVM_OnLoad function it will get called later,
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 // otherwise see if there is an Agent_OnLoad
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 if (on_load_entry == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 on_load_entry = lookup_agent_on_load(agent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 if (on_load_entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // switch it to the agent list -- so that Agent_OnLoad will be called,
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 // JVM_OnLoad won't be attempted and Agent_OnUnload will
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 Arguments::convert_library_to_agent(agent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 vm_exit_during_initialization("Could not find JVM_OnLoad or Agent_OnLoad function in the library", agent->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3553
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 // Create agents for -agentlib: -agentpath: and converted -Xrun
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 // Invokes Agent_OnLoad
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 // Called very early -- before JavaThreads exist
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 void Threads::create_vm_init_agents() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 extern struct JavaVM_ main_vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 AgentLibrary* agent;
a61af66fc99e Initial load
duke
parents:
diff changeset
3560
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 JvmtiExport::enter_onload_phase();
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 OnLoadEntry_t on_load_entry = lookup_agent_on_load(agent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3564
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 if (on_load_entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 // Invoke the Agent_OnLoad function
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 jint err = (*on_load_entry)(&main_vm, agent->options(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 if (err != JNI_OK) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 vm_exit_during_initialization("agent library failed to init", agent->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 vm_exit_during_initialization("Could not find Agent_OnLoad function in the agent library", agent->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 JvmtiExport::enter_primordial_phase();
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3577
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3581
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 void Threads::shutdown_vm_agents() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 // Send any Agent_OnUnload notifications
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 extern struct JavaVM_ main_vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3587
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 // Find the Agent_OnUnload function.
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3591 os::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index]));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3592
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 // Invoke the Agent_OnUnload function
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 if (unload_entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 ThreadToNativeFromVM ttn(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 HandleMark hm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 (*unload_entry)(&main_vm);
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3604
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 // Called for after the VM is initialized for -Xrun libraries which have not been converted to agent libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // Invokes JVM_OnLoad
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 void Threads::create_vm_init_libraries() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 extern struct JavaVM_ main_vm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 AgentLibrary* agent;
a61af66fc99e Initial load
duke
parents:
diff changeset
3610
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 for (agent = Arguments::libraries(); agent != NULL; agent = agent->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 OnLoadEntry_t on_load_entry = lookup_jvm_on_load(agent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3613
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 if (on_load_entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 // Invoke the JVM_OnLoad function
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 ThreadToNativeFromVM ttn(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 HandleMark hm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 jint err = (*on_load_entry)(&main_vm, agent->options(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 if (err != JNI_OK) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 vm_exit_during_initialization("-Xrun library failed to init", agent->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 vm_exit_during_initialization("Could not find JVM_OnLoad function in -Xrun library", agent->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3628
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 // Last thread running calls java.lang.Shutdown.shutdown()
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 void JavaThread::invoke_shutdown_hooks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 HandleMark hm(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3632
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // We could get here with a pending exception, if so clear it now.
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 if (this->has_pending_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 this->clear_pending_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3637
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 klassOop k =
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3640 SystemDictionary::resolve_or_null(vmSymbols::java_lang_Shutdown(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 if (k != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 // SystemDictionary::resolve_or_null will return null if there was
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 // an exception. If we cannot load the Shutdown class, just don't
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 // call Shutdown.shutdown() at all. This will mean the shutdown hooks
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // and finalizers (if runFinalizersOnExit is set) won't be run.
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 // Note that if a shutdown hook was registered or runFinalizersOnExit
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // was called, the Shutdown class would have already been loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // (Runtime.addShutdownHook and runFinalizersOnExit will load it).
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 instanceKlassHandle shutdown_klass (THREAD, k);
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 JavaValue result(T_VOID);
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 JavaCalls::call_static(&result,
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 shutdown_klass,
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3654 vmSymbols::shutdown_method_name(),
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 2162
diff changeset
3655 vmSymbols::void_method_signature(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3660
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 // Threads::destroy_vm() is normally called from jni_DestroyJavaVM() when
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 // the program falls off the end of main(). Another VM exit path is through
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // vm_exit() when the program calls System.exit() to return a value or when
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // there is a serious error in VM. The two shutdown paths are not exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 // the same, but they share Shutdown.shutdown() at Java level and before_exit()
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 // and VM_Exit op at VM level.
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // Shutdown sequence:
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // + Wait until we are the last non-daemon thread to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // <-- every thing is still working at this moment -->
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 // + Call java.lang.Shutdown.shutdown(), which will invoke Java level
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 // shutdown hooks, run finalizers if finalization-on-exit
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 // + Call before_exit(), prepare for VM exit
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // > run VM level shutdown hooks (they are registered through JVM_OnExit(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // currently the only user of this mechanism is File.deleteOnExit())
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // > stop flat profiler, StatSampler, watcher thread, CMS threads,
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // post thread end and vm death events to JVMTI,
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // stop signal thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // + Call JavaThread::exit(), it will:
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // > release JNI handle blocks, remove stack guard pages
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 // > remove this thread from Threads list
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // <-- no more Java code from this thread after this point -->
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 // + Stop VM thread, it will bring the remaining VM to a safepoint and stop
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // the compiler threads at safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // <-- do not use anything that could get blocked by Safepoint -->
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 // + Disable tracing at JNI/JVM barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 // + Set _vm_exited flag for threads that are still running native code
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // + Delete this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 // + Call exit_globals()
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 // > deletes tty
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 // > deletes PerfMemory resources
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // + Return to caller
a61af66fc99e Initial load
duke
parents:
diff changeset
3693
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 bool Threads::destroy_vm() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3696
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 // Wait until we are the last non-daemon thread to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 { MutexLocker nu(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 while (Threads::number_of_non_daemon_threads() > 1 )
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // This wait should make safepoint checks, wait without a timeout,
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // and wait as a suspend-equivalent condition.
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 // Note: If the FlatProfiler is running and this thread is waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 // for another non-daemon thread to finish, then the FlatProfiler
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 // is waiting for the external suspend request on this thread to
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 // complete. wait_for_ext_suspend_completion() will eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // timeout, but that takes time. Making this wait a suspend-
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // equivalent condition solves that timeout problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 Threads_lock->wait(!Mutex::_no_safepoint_check_flag, 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 Mutex::_as_suspend_equivalent_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3713
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 // Hang forever on exit if we are reporting an error.
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 if (ShowMessageBoxOnError && is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 os::infinite_sleep();
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 }
2302
da091bb67459 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 2203
diff changeset
3718 os::wait_for_keypress_at_exit();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3719
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 if (JDK_Version::is_jdk12x_version()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 // We are the last thread running, so check if finalizers should be run.
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 // For 1.3 or later this is done in thread->invoke_shutdown_hooks()
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 HandleMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 Universe::run_finalizers_on_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 // run Java level shutdown hooks
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 thread->invoke_shutdown_hooks();
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3729
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 before_exit(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3731
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 thread->exit(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3733
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 // Stop VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 // 4945125 The vm thread comes to a safepoint during exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 // GC vm_operations can get caught at the safepoint, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 // heap is unparseable if they are caught. Grab the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 // to prevent this. The GC vm_operations will not be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 // queue until after the vm thread is dead.
3769
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3741 // After this point, we'll never emerge out of the safepoint before
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3742 // the VM exits, so concurrent GC threads do not need to be explicitly
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3743 // stopped; they remain inactive until the process exits.
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3744 // Note: some concurrent G1 threads may be running during a safepoint,
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3745 // but these will not be accessing the heap, just some G1-specific side
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3746 // data structures that are not accessed by any other threads but them
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3747 // after this point in a terminal safepoint.
ef2d1b8f2dd4 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 3388
diff changeset
3748
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3750
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 VMThread::wait_for_vm_thread_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 assert(SafepointSynchronize::is_at_safepoint(), "VM thread should exit at Safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 VMThread::destroy();
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3755
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 // clean up ideal graph printers
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 #if defined(COMPILER2) && !defined(PRODUCT)
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 IdealGraphPrinter::clean_up();
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3760
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 // Now, all Java threads are gone except daemon threads. Daemon threads
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 // running Java code or in VM are stopped by the Safepoint. However,
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 // daemon threads executing native code are still running. But they
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 // will be stopped at native=>Java/VM barriers. Note that we can't
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 // simply kill or suspend them, as it is inherently deadlock-prone.
a61af66fc99e Initial load
duke
parents:
diff changeset
3766
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 // disable function tracing at JNI/JVM barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 TraceJNICalls = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 TraceJVMCalls = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 TraceRuntimeCalls = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3773
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 VM_Exit::set_vm_exited();
a61af66fc99e Initial load
duke
parents:
diff changeset
3775
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 notify_vm_shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
3777
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 delete thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3779
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 // exit_globals() will delete tty
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 exit_globals();
a61af66fc99e Initial load
duke
parents:
diff changeset
3782
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3785
a61af66fc99e Initial load
duke
parents:
diff changeset
3786
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 jboolean Threads::is_supported_jni_version_including_1_1(jint version) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 if (version == JNI_VERSION_1_1) return JNI_TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 return is_supported_jni_version(version);
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3791
a61af66fc99e Initial load
duke
parents:
diff changeset
3792
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 jboolean Threads::is_supported_jni_version(jint version) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 if (version == JNI_VERSION_1_2) return JNI_TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 if (version == JNI_VERSION_1_4) return JNI_TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 if (version == JNI_VERSION_1_6) return JNI_TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 return JNI_FALSE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3799
a61af66fc99e Initial load
duke
parents:
diff changeset
3800
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 void Threads::add(JavaThread* p, bool force_daemon) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 // The threads lock must be owned at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 assert_locked_or_safepoint(Threads_lock);
1842
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
3804
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
3805 // See the comment for this method in thread.hpp for its purpose and
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
3806 // why it is called here.
6e0aac35bfa9 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 1838
diff changeset
3807 p->initialize_queues();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 p->set_next(_thread_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 _thread_list = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 _number_of_threads++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 oop threadObj = p->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 bool daemon = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 // Bootstrapping problem: threadObj can be null for initial
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 // JavaThread (or for threads attached via JNI)
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 if ((!force_daemon) && (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 _number_of_non_daemon_threads++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 daemon = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3819
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 ThreadService::add_thread(p, daemon);
a61af66fc99e Initial load
duke
parents:
diff changeset
3821
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 // Possible GC point.
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 Events::log("Thread added: " INTPTR_FORMAT, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3825
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 void Threads::remove(JavaThread* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 // Extra scope needed for Thread_lock, so we can check
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 // that we do not remove thread without safepoint code notice
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 { MutexLocker ml(Threads_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3830
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 assert(includes(p), "p must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
3832
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 JavaThread* current = _thread_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 JavaThread* prev = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3835
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 while (current != p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 prev = current;
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 current = current->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3840
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 if (prev) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 prev->set_next(current->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 _thread_list = p->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 _number_of_threads--;
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 oop threadObj = p->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 bool daemon = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 if (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 _number_of_non_daemon_threads--;
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 daemon = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3852
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 // Only one thread left, do a notify on the Threads_lock so a thread waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 // on destroy_vm will wake up.
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 if (number_of_non_daemon_threads() == 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 Threads_lock->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 ThreadService::remove_thread(p, daemon);
a61af66fc99e Initial load
duke
parents:
diff changeset
3859
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 // Make sure that safepoint code disregard this thread. This is needed since
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 // the thread might mess around with locks after this point. This can cause it
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 // to do callbacks into the safepoint code. However, the safepoint code is not aware
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 // of this thread since it is removed from the queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 p->set_terminated_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 } // unlock Threads_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3866
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 // Since Events::log uses a lock, we grab it outside the Threads_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 Events::log("Thread exited: " INTPTR_FORMAT, p);
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3870
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // Threads_lock must be held when this is called (or must be called during a safepoint)
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 bool Threads::includes(JavaThread* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 assert(Threads_lock->is_locked(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 ALL_JAVA_THREADS(q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 if (q == p ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3881
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 // Operations on the Threads list for GC. These are not explicitly locked,
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 // but the garbage collector must provide a safe context for them to run.
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 // In particular, these things should never be called when the Threads_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 // is held by some other thread. (Note: the Safepoint abstraction also
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 // uses the Threads_lock to gurantee this property. It also makes sure that
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 // all threads gets blocked when exiting or starting).
a61af66fc99e Initial load
duke
parents:
diff changeset
3888
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3889 void Threads::oops_do(OopClosure* f, CodeBlobClosure* cf) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 ALL_JAVA_THREADS(p) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3891 p->oops_do(f, cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 }
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3893 VMThread::vm_thread()->oops_do(f, cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3895
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3896 void Threads::possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 // Introduce a mechanism allowing parallel threads to claim threads as
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 // root groups. Overhead should be small enough to use all the time,
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 // even in sequential code.
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 SharedHeap* sh = SharedHeap::heap();
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 bool is_par = (sh->n_par_threads() > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 int cp = SharedHeap::heap()->strong_roots_parity();
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 if (p->claim_oops_do(is_par, cp)) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3905 p->oops_do(f, cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 VMThread* vmt = VMThread::vm_thread();
3979
4dfb2df418f2 6484982: G1: process references during evacuation pauses
johnc
parents: 3938
diff changeset
3909 if (vmt->claim_oops_do(is_par, cp)) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3910 vmt->oops_do(f, cf);
3979
4dfb2df418f2 6484982: G1: process references during evacuation pauses
johnc
parents: 3938
diff changeset
3911 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3913
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 // Used by ParallelScavenge
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 void Threads::create_thread_roots_tasks(GCTaskQueue* q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 q->enqueue(new ThreadRootsTask(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 q->enqueue(new ThreadRootsTask(VMThread::vm_thread()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3922
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 // Used by Parallel Old
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 void Threads::create_thread_roots_marking_tasks(GCTaskQueue* q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 q->enqueue(new ThreadRootsMarkingTask(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 q->enqueue(new ThreadRootsMarkingTask(VMThread::vm_thread()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
3931
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3932 void Threads::nmethods_do(CodeBlobClosure* cf) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 ALL_JAVA_THREADS(p) {
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3934 p->nmethods_do(cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 }
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 844
diff changeset
3936 VMThread::vm_thread()->nmethods_do(cf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3938
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 void Threads::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 p->gc_epilogue();
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3944
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 void Threads::gc_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 p->gc_prologue();
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3950
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 void Threads::deoptimized_wrt_marked_nmethods() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 p->deoptimized_wrt_marked_nmethods();
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3956
a61af66fc99e Initial load
duke
parents:
diff changeset
3957
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 // Get count Java threads that are waiting to enter the specified monitor.
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 GrowableArray<JavaThread*>* Threads::get_pending_threads(int count,
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 address monitor, bool doLock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 assert(doLock || SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 "must grab Threads_lock or be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 GrowableArray<JavaThread*>* result = new GrowableArray<JavaThread*>(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
3964
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 MutexLockerEx ml(doLock ? Threads_lock : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 if (p->is_Compiler_thread()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3970
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 address pending = (address)p->current_pending_monitor();
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 if (pending == monitor) { // found a match
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 if (i < count) result->append(p); // save the first count matches
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3980
a61af66fc99e Initial load
duke
parents:
diff changeset
3981
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 assert(doLock ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 Threads_lock->owned_by_self() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 SafepointSynchronize::is_at_safepoint(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 "must grab Threads_lock or be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
3987
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 // NULL owner means not locked so we can skip the search
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 if (owner == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3990
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 MutexLockerEx ml(doLock ? Threads_lock : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 // first, see if owner is the address of a Java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 if (owner == (address)p) return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 if (UseHeavyMonitors) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4000
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 // If we didn't find a matching Java thread and we didn't force use of
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 // heavyweight monitors, then the owner is the stack address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 // Lock Word in the owning Java thread's stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 JavaThread* the_owner = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 MutexLockerEx ml(doLock ? Threads_lock : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 ALL_JAVA_THREADS(q) {
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 669
diff changeset
4010 if (q->is_lock_owned(owner)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 the_owner = q;
702
b9fba36710f2 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 669
diff changeset
4012 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 assert(the_owner != NULL, "Did not find owning Java thread for lock word address");
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 return the_owner;
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4019
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 // Threads::print_on() is called at safepoint by VM_PrintThreads operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 char buf[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 st->print_cr(os::local_time_string(buf, sizeof(buf)));
a61af66fc99e Initial load
duke
parents:
diff changeset
4024
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 st->print_cr("Full thread dump %s (%s %s):",
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 Abstract_VM_Version::vm_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 Abstract_VM_Version::vm_release(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 Abstract_VM_Version::vm_info_string()
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 );
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4031
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 // Dump concurrent locks
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 ConcurrentLocksDump concurrent_locks;
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 if (print_concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 concurrent_locks.dump_at_safepoint();
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
4039
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 p->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 if (print_stacks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 if (internal_format) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 p->trace_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 p->print_stack_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 if (print_concurrent_locks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4053 concurrent_locks.print_locks_on(p, st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4057
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 VMThread::vm_thread()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 Universe::heap()->print_gc_threads_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 WatcherThread* wt = WatcherThread::watcher_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 if (wt != NULL) wt->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 CompileBroker::print_compiler_threads_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 st->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4067
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 // Threads::print_on_error() is called by fatal error handler. It's possible
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 // that VM is not at safepoint and/or current thread is inside signal handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 // Don't print stack trace, as the stack may not be walkable. Don't allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 // memory (even in resource area), it might deadlock the error handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 void Threads::print_on_error(outputStream* st, Thread* current, char* buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 bool found_current = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 st->print_cr("Java Threads: ( => current thread )");
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 ALL_JAVA_THREADS(thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 bool is_current = (current == thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4077 found_current = found_current || is_current;
a61af66fc99e Initial load
duke
parents:
diff changeset
4078
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 st->print("%s", is_current ? "=>" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4080
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 st->print(PTR_FORMAT, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 thread->print_on_error(st, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4087
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 st->print_cr("Other Threads:");
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 if (VMThread::vm_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 bool is_current = (current == VMThread::vm_thread());
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 found_current = found_current || is_current;
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 st->print("%s", current == VMThread::vm_thread() ? "=>" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4093
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 st->print(PTR_FORMAT, VMThread::vm_thread());
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 VMThread::vm_thread()->print_on_error(st, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 WatcherThread* wt = WatcherThread::watcher_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 if (wt != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 bool is_current = (current == wt);
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 found_current = found_current || is_current;
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 st->print("%s", is_current ? "=>" : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4104
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 st->print(PTR_FORMAT, wt);
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 wt->print_on_error(st, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 if (!found_current) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 st->print("=>" PTR_FORMAT " (exited) ", current);
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 current->print_on_error(st, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4117
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4118 // Internal SpinLock and Mutex
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4119 // Based on ParkEvent
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4120
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4121 // Ad-hoc mutual exclusion primitives: SpinLock and Mux
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 //
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4123 // We employ SpinLocks _only for low-contention, fixed-length
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4124 // short-duration critical sections where we're concerned
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4125 // about native mutex_t or HotSpot Mutex:: latency.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4126 // The mux construct provides a spin-then-block mutual exclusion
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4127 // mechanism.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4128 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4129 // Testing has shown that contention on the ListLock guarding gFreeList
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4130 // is common. If we implement ListLock as a simple SpinLock it's common
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4131 // for the JVM to devolve to yielding with little progress. This is true
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4132 // despite the fact that the critical sections protected by ListLock are
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4133 // extremely short.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 //
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4135 // TODO-FIXME: ListLock should be of type SpinLock.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4136 // We should make this a 1st-class type, integrated into the lock
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4137 // hierarchy as leaf-locks. Critically, the SpinLock structure
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4138 // should have sufficient padding to avoid false-sharing and excessive
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4139 // cache-coherency traffic.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4140
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4141
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4142 typedef volatile int SpinLockT ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4143
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4144 void Thread::SpinAcquire (volatile int * adr, const char * LockName) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4145 if (Atomic::cmpxchg (1, adr, 0) == 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4146 return ; // normal fast-path return
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4147 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4148
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4149 // Slow-path : We've encountered contention -- Spin/Yield/Block strategy.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4150 TEVENT (SpinAcquire - ctx) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4151 int ctr = 0 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4152 int Yields = 0 ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 for (;;) {
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4154 while (*adr != 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4155 ++ctr ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4156 if ((ctr & 0xFFF) == 0 || !os::is_MP()) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4157 if (Yields > 5) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4158 // Consider using a simple NakedSleep() instead.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4159 // Then SpinAcquire could be called by non-JVM threads
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4160 Thread::current()->_ParkEvent->park(1) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4161 } else {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4162 os::NakedYield() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4163 ++Yields ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4164 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4165 } else {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4166 SpinPause() ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4167 }
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4168 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4169 if (Atomic::cmpxchg (1, adr, 0) == 0) return ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4172
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4173 void Thread::SpinRelease (volatile int * adr) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4174 assert (*adr != 0, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4175 OrderAccess::fence() ; // guarantee at least release consistency.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4176 // Roach-motel semantics.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4177 // It's safe if subsequent LDs and STs float "up" into the critical section,
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4178 // but prior LDs and STs within the critical section can't be allowed
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4179 // to reorder or float past the ST that releases the lock.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4180 *adr = 0 ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4182
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4183 // muxAcquire and muxRelease:
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4184 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4185 // * muxAcquire and muxRelease support a single-word lock-word construct.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4186 // The LSB of the word is set IFF the lock is held.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4187 // The remainder of the word points to the head of a singly-linked list
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4188 // of threads blocked on the lock.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4189 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4190 // * The current implementation of muxAcquire-muxRelease uses its own
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4191 // dedicated Thread._MuxEvent instance. If we're interested in
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4192 // minimizing the peak number of extant ParkEvent instances then
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4193 // we could eliminate _MuxEvent and "borrow" _ParkEvent as long
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4194 // as certain invariants were satisfied. Specifically, care would need
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4195 // to be taken with regards to consuming unpark() "permits".
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4196 // A safe rule of thumb is that a thread would never call muxAcquire()
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4197 // if it's enqueued (cxq, EntryList, WaitList, etc) and will subsequently
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4198 // park(). Otherwise the _ParkEvent park() operation in muxAcquire() could
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4199 // consume an unpark() permit intended for monitorenter, for instance.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4200 // One way around this would be to widen the restricted-range semaphore
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4201 // implemented in park(). Another alternative would be to provide
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4202 // multiple instances of the PlatformEvent() for each thread. One
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4203 // instance would be dedicated to muxAcquire-muxRelease, for instance.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4204 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4205 // * Usage:
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4206 // -- Only as leaf locks
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4207 // -- for short-term locking only as muxAcquire does not perform
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4208 // thread state transitions.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4209 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4210 // Alternatives:
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4211 // * We could implement muxAcquire and muxRelease with MCS or CLH locks
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4212 // but with parking or spin-then-park instead of pure spinning.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4213 // * Use Taura-Oyama-Yonenzawa locks.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4214 // * It's possible to construct a 1-0 lock if we encode the lockword as
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4215 // (List,LockByte). Acquire will CAS the full lockword while Release
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4216 // will STB 0 into the LockByte. The 1-0 scheme admits stranding, so
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4217 // acquiring threads use timers (ParkTimed) to detect and recover from
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4218 // the stranding window. Thread/Node structures must be aligned on 256-byte
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4219 // boundaries by using placement-new.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4220 // * Augment MCS with advisory back-link fields maintained with CAS().
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4221 // Pictorially: LockWord -> T1 <-> T2 <-> T3 <-> ... <-> Tn <-> Owner.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4222 // The validity of the backlinks must be ratified before we trust the value.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4223 // If the backlinks are invalid the exiting thread must back-track through the
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4224 // the forward links, which are always trustworthy.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4225 // * Add a successor indication. The LockWord is currently encoded as
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4226 // (List, LOCKBIT:1). We could also add a SUCCBIT or an explicit _succ variable
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4227 // to provide the usual futile-wakeup optimization.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4228 // See RTStt for details.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4229 // * Consider schedctl.sc_nopreempt to cover the critical section.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4230 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4231
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4232
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4233 typedef volatile intptr_t MutexT ; // Mux Lock-word
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4234 enum MuxBits { LOCKBIT = 1 } ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4235
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4236 void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4237 intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4238 if (w == 0) return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4239 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4240 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4241 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4242
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4243 TEVENT (muxAcquire - Contention) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4244 ParkEvent * const Self = Thread::current()->_MuxEvent ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4245 assert ((intptr_t(Self) & LOCKBIT) == 0, "invariant") ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 for (;;) {
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4247 int its = (os::is_MP() ? 100 : 0) + 1 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4248
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4249 // Optional spin phase: spin-then-park strategy
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4250 while (--its >= 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4251 w = *Lock ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4252 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4253 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4254 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4255 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4256
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4257 Self->reset() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4258 Self->OnList = intptr_t(Lock) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4259 // The following fence() isn't _strictly necessary as the subsequent
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4260 // CAS() both serializes execution and ratifies the fetched *Lock value.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4261 OrderAccess::fence();
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4262 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4263 w = *Lock ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4264 if ((w & LOCKBIT) == 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4265 if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4266 Self->OnList = 0 ; // hygiene - allows stronger asserts
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4267 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4268 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4269 continue ; // Interference -- *Lock changed -- Just retry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 }
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4271 assert (w & LOCKBIT, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4272 Self->ListNext = (ParkEvent *) (w & ~LOCKBIT );
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4273 if (Atomic::cmpxchg_ptr (intptr_t(Self)|LOCKBIT, Lock, w) == w) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4274 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4275
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4276 while (Self->OnList != 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4277 Self->park() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4278 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4281
1878
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4282 void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4283 intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4284 if (w == 0) return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4285 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4286 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4287 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4288
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4289 TEVENT (muxAcquire - Contention) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4290 ParkEvent * ReleaseAfter = NULL ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4291 if (ev == NULL) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4292 ev = ReleaseAfter = ParkEvent::Allocate (NULL) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4293 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4294 assert ((intptr_t(ev) & LOCKBIT) == 0, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4295 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4296 guarantee (ev->OnList == 0, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4297 int its = (os::is_MP() ? 100 : 0) + 1 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4298
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4299 // Optional spin phase: spin-then-park strategy
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4300 while (--its >= 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4301 w = *Lock ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4302 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4303 if (ReleaseAfter != NULL) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4304 ParkEvent::Release (ReleaseAfter) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4305 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4306 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4307 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4308 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4309
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4310 ev->reset() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4311 ev->OnList = intptr_t(Lock) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4312 // The following fence() isn't _strictly necessary as the subsequent
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4313 // CAS() both serializes execution and ratifies the fetched *Lock value.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4314 OrderAccess::fence();
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4315 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4316 w = *Lock ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4317 if ((w & LOCKBIT) == 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4318 if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4319 ev->OnList = 0 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4320 // We call ::Release while holding the outer lock, thus
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4321 // artificially lengthening the critical section.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4322 // Consider deferring the ::Release() until the subsequent unlock(),
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4323 // after we've dropped the outer lock.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4324 if (ReleaseAfter != NULL) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4325 ParkEvent::Release (ReleaseAfter) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4326 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4327 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4328 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4329 continue ; // Interference -- *Lock changed -- Just retry
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4330 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4331 assert (w & LOCKBIT, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4332 ev->ListNext = (ParkEvent *) (w & ~LOCKBIT );
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4333 if (Atomic::cmpxchg_ptr (intptr_t(ev)|LOCKBIT, Lock, w) == w) break ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4334 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4335
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4336 while (ev->OnList != 0) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4337 ev->park() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4338 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4339 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4340 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4341
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4342 // Release() must extract a successor from the list and then wake that thread.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4343 // It can "pop" the front of the list or use a detach-modify-reattach (DMR) scheme
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4344 // similar to that used by ParkEvent::Allocate() and ::Release(). DMR-based
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4345 // Release() would :
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4346 // (A) CAS() or swap() null to *Lock, releasing the lock and detaching the list.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4347 // (B) Extract a successor from the private list "in-hand"
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4348 // (C) attempt to CAS() the residual back into *Lock over null.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4349 // If there were any newly arrived threads and the CAS() would fail.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4350 // In that case Release() would detach the RATs, re-merge the list in-hand
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4351 // with the RATs and repeat as needed. Alternately, Release() might
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4352 // detach and extract a successor, but then pass the residual list to the wakee.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4353 // The wakee would be responsible for reattaching and remerging before it
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4354 // competed for the lock.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4355 //
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4356 // Both "pop" and DMR are immune from ABA corruption -- there can be
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4357 // multiple concurrent pushers, but only one popper or detacher.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4358 // This implementation pops from the head of the list. This is unfair,
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4359 // but tends to provide excellent throughput as hot threads remain hot.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4360 // (We wake recently run threads first).
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4361
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4362 void Thread::muxRelease (volatile intptr_t * Lock) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4363 for (;;) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4364 const intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4365 assert (w & LOCKBIT, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4366 if (w == LOCKBIT) return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4367 ParkEvent * List = (ParkEvent *) (w & ~LOCKBIT) ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4368 assert (List != NULL, "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4369 assert (List->OnList == intptr_t(Lock), "invariant") ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4370 ParkEvent * nxt = List->ListNext ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4371
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4372 // The following CAS() releases the lock and pops the head element.
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4373 if (Atomic::cmpxchg_ptr (intptr_t(nxt), Lock, w) != w) {
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4374 continue ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4375 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4376 List->OnList = 0 ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4377 OrderAccess::fence() ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4378 List->unpark () ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4379 return ;
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4380 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4381 }
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4382
fa83ab460c54 6988353: refactor contended sync subsystem
acorn
parents: 1871
diff changeset
4383
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 void Threads::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 ALL_JAVA_THREADS(p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 p->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 VMThread* thread = VMThread::vm_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 if (thread != NULL) thread->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 }