annotate src/share/vm/prims/jvmtiEnvThreadState.cpp @ 13415:c8c2d6b82499

8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers Summary: Fix a race between VMOp_GetCurrentLocation reaching a safepoint and arget thread exiting from Java execution Reviewed-by: sla, dholmes, dsamersoff Contributed-by: serguei.spitsyn@oracle.com
author sspitsyn
date Tue, 03 Dec 2013 15:41:35 -0800
parents da91efe96a93
children de6a9e811145
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6197
diff changeset
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
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: 0
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: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "jvmtifiles/jvmtiEnv.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "prims/jvmtiEnvThreadState.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "prims/jvmtiEventController.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "prims/jvmtiImpl.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "runtime/handles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "runtime/signature.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "runtime/vframe.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "runtime/vm_operations.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 ///////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
43 //
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // class JvmtiFramePop
a61af66fc99e Initial load
duke
parents:
diff changeset
45 //
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
48 void JvmtiFramePop::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 tty->print_cr("_frame_number=%d", _frame_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 }
a61af66fc99e Initial load
duke
parents:
diff changeset
51 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 ///////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
55 //
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // class JvmtiFramePops - private methods
a61af66fc99e Initial load
duke
parents:
diff changeset
57 //
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 void
a61af66fc99e Initial load
duke
parents:
diff changeset
60 JvmtiFramePops::set(JvmtiFramePop& fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 if (_pops->find(fp.frame_number()) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _pops->append(fp.frame_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 void
a61af66fc99e Initial load
duke
parents:
diff changeset
68 JvmtiFramePops::clear(JvmtiFramePop& fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 assert(_pops->length() > 0, "No more frame pops");
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 _pops->remove(fp.frame_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 int
a61af66fc99e Initial load
duke
parents:
diff changeset
76 JvmtiFramePops::clear_to(JvmtiFramePop& fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 int cleared = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 int index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 while (index < _pops->length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 JvmtiFramePop pop = JvmtiFramePop(_pops->at(index));
a61af66fc99e Initial load
duke
parents:
diff changeset
81 if (pop.above_on_stack(fp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 _pops->remove_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 ++cleared;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 ++index;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return cleared;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92 ///////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // class JvmtiFramePops - public methods
a61af66fc99e Initial load
duke
parents:
diff changeset
95 //
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 JvmtiFramePops::JvmtiFramePops() {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 1972
diff changeset
98 _pops = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int> (2, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 JvmtiFramePops::~JvmtiFramePops() {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // return memory to c_heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 delete _pops;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
108 void JvmtiFramePops::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 int n = _pops->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
112 for (int i=0; i<n; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 JvmtiFramePop fp = JvmtiFramePop(_pops->at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
114 tty->print("%d: ", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
115 fp.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 tty->print_cr("");
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 ///////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // class JvmtiEnvThreadState
a61af66fc99e Initial load
duke
parents:
diff changeset
124 //
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // Instances of JvmtiEnvThreadState hang off of each JvmtiThreadState,
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // one per JvmtiEnv.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 //
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 JvmtiEnvThreadState::JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env) :
a61af66fc99e Initial load
duke
parents:
diff changeset
130 _event_enable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 _env = (JvmtiEnv*)env;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 _frame_pops = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 _current_bci = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 _current_method_id = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 _breakpoint_posted = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 _single_stepping_posted = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
139 _agent_thread_local_storage_data = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 JvmtiEnvThreadState::~JvmtiEnvThreadState() {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 delete _frame_pops;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 _frame_pops = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // Given that a new (potential) event has come in,
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // maintain the current JVMTI location on a per-thread per-env basis
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // and use it to filter out duplicate events:
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // - instruction rewrites
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // - breakpoint followed by single step
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // - single step at a breakpoint
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6197
diff changeset
153 void JvmtiEnvThreadState::compare_and_set_current_location(Method* new_method,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
154 address new_location, jvmtiEvent event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 int new_bci = new_location - new_method->code_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // The method is identified and stored as a jmethodID which is safe in this
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // case because the class cannot be unloaded while a method is executing.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 jmethodID new_method_id = new_method->jmethod_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // the last breakpoint or single step was at this same location
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (_current_bci == new_bci && _current_method_id == new_method_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 switch (event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 case JVMTI_EVENT_BREAKPOINT:
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Repeat breakpoint is complicated. If we previously posted a breakpoint
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // event at this location and if we also single stepped at this location
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // then we skip the duplicate breakpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
169 _breakpoint_posted = _breakpoint_posted && _single_stepping_posted;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 case JVMTI_EVENT_SINGLE_STEP:
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Repeat single step is easy: just don't post it again.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // If step is pending for popframe then it may not be
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // a repeat step. The new_bci and method_id is same as current_bci
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // and current method_id after pop and step for recursive calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // This has been handled by clearing the location
a61af66fc99e Initial load
duke
parents:
diff changeset
177 _single_stepping_posted = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
180 assert(false, "invalid event value passed");
a61af66fc99e Initial load
duke
parents:
diff changeset
181 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 set_current_location(new_method_id, new_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 _breakpoint_posted = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 _single_stepping_posted = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
194 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
196 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
197 "frame pop data only accessible from same thread or while suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 if (_frame_pops == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 _frame_pops = new JvmtiFramePops();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 assert(_frame_pops != NULL, "_frame_pops != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return _frame_pops;
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 bool JvmtiEnvThreadState::has_frame_pops() {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 return _frame_pops == NULL? false : (_frame_pops->length() > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 void JvmtiEnvThreadState::set_frame_pop(int frame_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
213 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
215 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
216 "frame pop data only accessible from same thread or while suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
217 JvmtiFramePop fpop(frame_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 JvmtiEventController::set_frame_pop(this, fpop);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
223 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
224 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
226 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
227 "frame pop data only accessible from same thread or while suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 JvmtiFramePop fpop(frame_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 JvmtiEventController::clear_frame_pop(this, fpop);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
235 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
237 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
238 "frame pop data only accessible from same thread or while suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
239 JvmtiFramePop fpop(frame_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 JvmtiEventController::clear_to_frame_pop(this, fpop);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
246 uint32_t debug_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
248 assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
249 "frame pop data only accessible from same thread or while suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 JvmtiFramePop fp(cur_frame_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 return get_frame_pops()->contains(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 class VM_GetCurrentLocation : public VM_Operation {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
260 JavaThread *_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 jmethodID _method_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 int _bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
265 VM_GetCurrentLocation(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 VMOp_Type type() const { return VMOp_GetCurrentLocation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 void doit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 ResourceMark rmark; // _thread != Thread::current()
a61af66fc99e Initial load
duke
parents:
diff changeset
271 RegisterMap rm(_thread, false);
13415
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
272 // There can be a race condition between a VM_Operation reaching a safepoint
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
273 // and the target thread exiting from Java execution.
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
274 // We must recheck the last Java frame still exists.
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
275 if (_thread->has_last_Java_frame()) {
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
276 javaVFrame* vf = _thread->last_java_vframe(&rm);
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
277 assert(vf != NULL, "must have last java frame");
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
278 Method* method = vf->method();
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
279 _method_id = method->jmethod_id();
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
280 _bci = vf->bci();
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
281 } else {
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
282 // Clear current location as the target thread has no Java frames anymore.
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
283 _method_id = (jmethodID)NULL;
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
284 _bci = 0;
c8c2d6b82499 8028126: nsk/jvmti/scenarios/hotswap/HS101/hs101t006 Crashed the vm on Solaris-sparc64 fastdebug builds: only current thread can flush its registers
sspitsyn
parents: 6725
diff changeset
285 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 void get_current_location(jmethodID *method_id, int *bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 *method_id = _method_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 *bci = _bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 };
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool enabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 assert(event_type == JVMTI_EVENT_SINGLE_STEP || event_type == JVMTI_EVENT_BREAKPOINT,
a61af66fc99e Initial load
duke
parents:
diff changeset
295 "must be single-step or breakpoint event");
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // Current location is used to detect the following:
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // 1) a breakpoint event followed by single-stepping to the same bci
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // 2) single-step to a bytecode that will be transformed to a fast version
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // We skip to avoid posting the duplicate single-stepping event.
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // If single-stepping is disabled, clear current location so that
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // single-stepping to the same method and bcp at a later time will be
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // detected if single-stepping is enabled at that time (see 4388912).
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // If single-stepping is enabled, set the current location to the
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // current method and bcp. This covers the following type of case,
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // e.g., the debugger stepi command:
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // - bytecode single stepped
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // - SINGLE_STEP event posted and SINGLE_STEP event disabled
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // - SINGLE_STEP event reenabled
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // - bytecode rewritten to fast version
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // If breakpoint event is disabled, clear current location only if
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // single-stepping is not enabled. Otherwise, keep the thread location
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // to detect any duplicate events.
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if (enabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // If enabling breakpoint, no need to reset.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // Can't do anything if empty stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (event_type == JVMTI_EVENT_SINGLE_STEP && _thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 jmethodID method_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
323 int bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // The java thread stack may not be walkable for a running thread
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // so get current location at safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 VM_GetCurrentLocation op(_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 op.get_current_location(&method_id, &bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 set_current_location(method_id, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 } else if (event_type == JVMTI_EVENT_SINGLE_STEP || !is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // If this is to disable breakpoint, also check if single-step is not enabled
a61af66fc99e Initial load
duke
parents:
diff changeset
333 clear_current_location();
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }