Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiThreadState.cpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | da91efe96a93 |
children | 0d8d78c0329a |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4841
diff
changeset
|
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "jvmtifiles/jvmtiEnv.hpp" | |
27 #include "memory/gcLocker.hpp" | |
28 #include "memory/resourceArea.hpp" | |
29 #include "prims/jvmtiEventController.inline.hpp" | |
30 #include "prims/jvmtiImpl.hpp" | |
31 #include "prims/jvmtiThreadState.inline.hpp" | |
32 #include "runtime/vframe.hpp" | |
0 | 33 |
34 // marker for when the stack depth has been reset and is now unknown. | |
35 // any negative number would work but small ones might obscure an | |
36 // underrun error. | |
37 static const int UNKNOWN_STACK_DEPTH = -99; | |
38 | |
39 /////////////////////////////////////////////////////////////// | |
40 // | |
41 // class JvmtiThreadState | |
42 // | |
43 // Instances of JvmtiThreadState hang off of each thread. | |
44 // Thread local storage for JVMTI. | |
45 // | |
46 | |
47 JvmtiThreadState *JvmtiThreadState::_head = NULL; | |
48 | |
49 JvmtiThreadState::JvmtiThreadState(JavaThread* thread) | |
50 : _thread_event_enable() { | |
51 assert(JvmtiThreadState_lock->is_locked(), "sanity check"); | |
52 _thread = thread; | |
53 _exception_detected = false; | |
54 _exception_caught = false; | |
55 _debuggable = true; | |
56 _hide_single_stepping = false; | |
57 _hide_level = 0; | |
58 _pending_step_for_popframe = false; | |
59 _class_being_redefined = NULL; | |
60 _class_load_kind = jvmti_class_load_kind_load; | |
61 _head_env_thread_state = NULL; | |
62 _dynamic_code_event_collector = NULL; | |
63 _vm_object_alloc_event_collector = NULL; | |
64 _the_class_for_redefinition_verification = NULL; | |
65 _scratch_class_for_redefinition_verification = NULL; | |
66 | |
67 // JVMTI ForceEarlyReturn support | |
68 _pending_step_for_earlyret = false; | |
69 _earlyret_state = earlyret_inactive; | |
70 _earlyret_tos = ilgl; | |
71 _earlyret_value.j = 0L; | |
72 _earlyret_oop = NULL; | |
73 | |
74 // add all the JvmtiEnvThreadState to the new JvmtiThreadState | |
75 { | |
76 JvmtiEnvIterator it; | |
77 for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) { | |
78 if (env->is_valid()) { | |
79 add_env(env); | |
80 } | |
81 } | |
82 } | |
83 | |
84 // link us into the list | |
85 { | |
86 // The thread state list manipulation code must not have safepoints. | |
87 // See periodic_clean_up(). | |
88 debug_only(No_Safepoint_Verifier nosafepoint;) | |
89 | |
90 _prev = NULL; | |
91 _next = _head; | |
92 if (_head != NULL) { | |
93 _head->_prev = this; | |
94 } | |
95 _head = this; | |
96 } | |
97 | |
98 // set this as the state for the thread | |
99 thread->set_jvmti_thread_state(this); | |
100 } | |
101 | |
102 | |
103 JvmtiThreadState::~JvmtiThreadState() { | |
104 assert(JvmtiThreadState_lock->is_locked(), "sanity check"); | |
105 | |
106 // clear this as the state for the thread | |
107 get_thread()->set_jvmti_thread_state(NULL); | |
108 | |
109 // zap our env thread states | |
110 { | |
111 JvmtiEnvBase::entering_dying_thread_env_iteration(); | |
112 JvmtiEnvThreadStateIterator it(this); | |
113 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ) { | |
114 JvmtiEnvThreadState* zap = ets; | |
115 ets = it.next(ets); | |
116 delete zap; | |
117 } | |
118 JvmtiEnvBase::leaving_dying_thread_env_iteration(); | |
119 } | |
120 | |
121 // remove us from the list | |
122 { | |
123 // The thread state list manipulation code must not have safepoints. | |
124 // See periodic_clean_up(). | |
125 debug_only(No_Safepoint_Verifier nosafepoint;) | |
126 | |
127 if (_prev == NULL) { | |
128 assert(_head == this, "sanity check"); | |
129 _head = _next; | |
130 } else { | |
131 assert(_head != this, "sanity check"); | |
132 _prev->_next = _next; | |
133 } | |
134 if (_next != NULL) { | |
135 _next->_prev = _prev; | |
136 } | |
137 _next = NULL; | |
138 _prev = NULL; | |
139 } | |
140 } | |
141 | |
142 | |
143 void | |
144 JvmtiThreadState::periodic_clean_up() { | |
145 assert(SafepointSynchronize::is_at_safepoint(), "at safepoint"); | |
146 | |
147 // This iteration is initialized with "_head" instead of "JvmtiThreadState::first()" | |
148 // because the latter requires the JvmtiThreadState_lock. | |
149 // This iteration is safe at a safepoint as well, see the No_Safepoint_Verifier | |
150 // asserts at all list manipulation sites. | |
151 for (JvmtiThreadState *state = _head; state != NULL; state = state->next()) { | |
152 // For each environment thread state corresponding to an invalid environment | |
153 // unlink it from the list and deallocate it. | |
154 JvmtiEnvThreadStateIterator it(state); | |
155 JvmtiEnvThreadState* previous_ets = NULL; | |
156 JvmtiEnvThreadState* ets = it.first(); | |
157 while (ets != NULL) { | |
158 if (ets->get_env()->is_valid()) { | |
159 previous_ets = ets; | |
160 ets = it.next(ets); | |
161 } else { | |
162 // This one isn't valid, remove it from the list and deallocate it | |
163 JvmtiEnvThreadState* defunct_ets = ets; | |
164 ets = ets->next(); | |
165 if (previous_ets == NULL) { | |
166 assert(state->head_env_thread_state() == defunct_ets, "sanity check"); | |
167 state->set_head_env_thread_state(ets); | |
168 } else { | |
169 previous_ets->set_next(ets); | |
170 } | |
171 delete defunct_ets; | |
172 } | |
173 } | |
174 } | |
175 } | |
176 | |
177 void JvmtiThreadState::add_env(JvmtiEnvBase *env) { | |
178 assert(JvmtiThreadState_lock->is_locked(), "sanity check"); | |
179 | |
180 JvmtiEnvThreadState *new_ets = new JvmtiEnvThreadState(_thread, env); | |
181 // add this environment thread state to the end of the list (order is important) | |
182 { | |
183 // list deallocation (which occurs at a safepoint) cannot occur simultaneously | |
184 debug_only(No_Safepoint_Verifier nosafepoint;) | |
185 | |
186 JvmtiEnvThreadStateIterator it(this); | |
187 JvmtiEnvThreadState* previous_ets = NULL; | |
188 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
189 previous_ets = ets; | |
190 } | |
191 if (previous_ets == NULL) { | |
192 set_head_env_thread_state(new_ets); | |
193 } else { | |
194 previous_ets->set_next(new_ets); | |
195 } | |
196 } | |
197 } | |
198 | |
199 | |
200 | |
201 | |
202 void JvmtiThreadState::enter_interp_only_mode() { | |
203 assert(_thread->get_interp_only_mode() == 0, "entering interp only when mode not zero"); | |
204 _thread->increment_interp_only_mode(); | |
205 } | |
206 | |
207 | |
208 void JvmtiThreadState::leave_interp_only_mode() { | |
209 assert(_thread->get_interp_only_mode() == 1, "leaving interp only when mode not one"); | |
210 _thread->decrement_interp_only_mode(); | |
211 } | |
212 | |
213 | |
214 // Helper routine used in several places | |
215 int JvmtiThreadState::count_frames() { | |
216 #ifdef ASSERT | |
217 uint32_t debug_bits = 0; | |
218 #endif | |
219 assert(SafepointSynchronize::is_at_safepoint() || | |
220 JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
221 "at safepoint or must be suspended"); | |
222 | |
223 if (!get_thread()->has_last_Java_frame()) return 0; // no Java frames | |
224 | |
225 ResourceMark rm; | |
226 RegisterMap reg_map(get_thread()); | |
227 javaVFrame *jvf = get_thread()->last_java_vframe(®_map); | |
228 int n = 0; | |
229 // tty->print_cr("CSD: counting frames on %s ...", | |
230 // JvmtiTrace::safe_get_thread_name(get_thread())); | |
231 while (jvf != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4841
diff
changeset
|
232 Method* method = jvf->method(); |
0 | 233 // tty->print_cr("CSD: frame - method %s.%s - loc %d", |
234 // method->klass_name()->as_C_string(), | |
235 // method->name()->as_C_string(), | |
236 // jvf->bci() ); | |
237 jvf = jvf->java_sender(); | |
238 n++; | |
239 } | |
240 // tty->print_cr("CSD: frame count: %d", n); | |
241 return n; | |
242 } | |
243 | |
244 | |
245 void JvmtiThreadState::invalidate_cur_stack_depth() { | |
246 Thread *cur = Thread::current(); | |
247 uint32_t debug_bits = 0; | |
248 | |
249 // The caller can be the VMThread at a safepoint, the current thread | |
250 // or the target thread must be suspended. | |
251 guarantee((cur->is_VM_thread() && SafepointSynchronize::is_at_safepoint()) || | |
252 (JavaThread *)cur == get_thread() || | |
253 JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
254 "sanity check"); | |
255 | |
256 _cur_stack_depth = UNKNOWN_STACK_DEPTH; | |
257 } | |
258 | |
259 void JvmtiThreadState::incr_cur_stack_depth() { | |
260 guarantee(JavaThread::current() == get_thread(), "must be current thread"); | |
261 | |
262 if (!is_interp_only_mode()) { | |
263 _cur_stack_depth = UNKNOWN_STACK_DEPTH; | |
264 } | |
265 if (_cur_stack_depth != UNKNOWN_STACK_DEPTH) { | |
266 ++_cur_stack_depth; | |
267 } | |
268 } | |
269 | |
270 void JvmtiThreadState::decr_cur_stack_depth() { | |
271 guarantee(JavaThread::current() == get_thread(), "must be current thread"); | |
272 | |
273 if (!is_interp_only_mode()) { | |
274 _cur_stack_depth = UNKNOWN_STACK_DEPTH; | |
275 } | |
276 if (_cur_stack_depth != UNKNOWN_STACK_DEPTH) { | |
277 --_cur_stack_depth; | |
278 assert(_cur_stack_depth >= 0, "incr/decr_cur_stack_depth mismatch"); | |
279 } | |
280 } | |
281 | |
282 int JvmtiThreadState::cur_stack_depth() { | |
283 uint32_t debug_bits = 0; | |
284 guarantee(JavaThread::current() == get_thread() || | |
285 JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits), | |
286 "must be current thread or suspended"); | |
287 | |
288 if (!is_interp_only_mode() || _cur_stack_depth == UNKNOWN_STACK_DEPTH) { | |
289 _cur_stack_depth = count_frames(); | |
290 } else { | |
291 // heavy weight assert | |
292 assert(_cur_stack_depth == count_frames(), | |
293 "cur_stack_depth out of sync"); | |
294 } | |
295 return _cur_stack_depth; | |
296 } | |
297 | |
298 bool JvmtiThreadState::may_be_walked() { | |
299 return (get_thread()->is_being_ext_suspended() || (JavaThread::current() == get_thread())); | |
300 } | |
301 | |
302 | |
303 void JvmtiThreadState::process_pending_step_for_popframe() { | |
304 // We are single stepping as the last part of the PopFrame() dance | |
305 // so we have some house keeping to do. | |
306 | |
307 JavaThread *thr = get_thread(); | |
308 if (thr->popframe_condition() != JavaThread::popframe_inactive) { | |
309 // If the popframe_condition field is not popframe_inactive, then | |
310 // we missed all of the popframe_field cleanup points: | |
311 // | |
312 // - unpack_frames() was not called (nothing to deopt) | |
313 // - remove_activation_preserving_args_entry() was not called | |
314 // (did not get suspended in a call_vm() family call and did | |
315 // not complete a call_vm() family call on the way here) | |
316 thr->clear_popframe_condition(); | |
317 } | |
318 | |
319 // clearing the flag indicates we are done with the PopFrame() dance | |
320 clr_pending_step_for_popframe(); | |
321 | |
4841
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
322 // If exception was thrown in this frame, need to reset jvmti thread state. |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
323 // Single stepping may not get enabled correctly by the agent since |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
324 // exception state is passed in MethodExit event which may be sent at some |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
325 // time in the future. JDWP agent ignores MethodExit events if caused by |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
326 // an exception. |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
327 // |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
328 if (is_exception_detected()) { |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
329 clear_exception_detected(); |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
330 } |
0 | 331 // If step is pending for popframe then it may not be |
332 // a repeat step. The new_bci and method_id is same as current_bci | |
333 // and current method_id after pop and step for recursive calls. | |
334 // Force the step by clearing the last location. | |
335 JvmtiEnvThreadStateIterator it(this); | |
336 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
337 ets->clear_current_location(); | |
338 } | |
339 } | |
340 | |
341 | |
342 // Class: JvmtiThreadState | |
343 // Function: update_for_pop_top_frame | |
344 // Description: | |
345 // This function removes any frame pop notification request for | |
346 // the top frame and invalidates both the current stack depth and | |
347 // all cached frameIDs. | |
348 // | |
349 // Called by: PopFrame | |
350 // | |
351 void JvmtiThreadState::update_for_pop_top_frame() { | |
352 if (is_interp_only_mode()) { | |
353 // remove any frame pop notification request for the top frame | |
354 // in any environment | |
355 int popframe_number = cur_stack_depth(); | |
356 { | |
357 JvmtiEnvThreadStateIterator it(this); | |
358 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
359 if (ets->is_frame_pop(popframe_number)) { | |
360 ets->clear_frame_pop(popframe_number); | |
361 } | |
362 } | |
363 } | |
364 // force stack depth to be recalculated | |
365 invalidate_cur_stack_depth(); | |
366 } else { | |
367 assert(!is_enabled(JVMTI_EVENT_FRAME_POP), "Must have no framepops set"); | |
368 } | |
369 } | |
370 | |
371 | |
372 void JvmtiThreadState::process_pending_step_for_earlyret() { | |
373 // We are single stepping as the last part of the ForceEarlyReturn | |
374 // dance so we have some house keeping to do. | |
375 | |
376 if (is_earlyret_pending()) { | |
377 // If the earlyret_state field is not earlyret_inactive, then | |
378 // we missed all of the earlyret_field cleanup points: | |
379 // | |
380 // - remove_activation() was not called | |
381 // (did not get suspended in a call_vm() family call and did | |
382 // not complete a call_vm() family call on the way here) | |
383 // | |
384 // One legitimate way for us to miss all the cleanup points is | |
385 // if we got here right after handling a compiled return. If that | |
386 // is the case, then we consider our return from compiled code to | |
387 // complete the ForceEarlyReturn request and we clear the condition. | |
388 clr_earlyret_pending(); | |
389 set_earlyret_oop(NULL); | |
390 clr_earlyret_value(); | |
391 } | |
392 | |
393 // clearing the flag indicates we are done with | |
394 // the ForceEarlyReturn() dance | |
395 clr_pending_step_for_earlyret(); | |
396 | |
4841
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
397 // If exception was thrown in this frame, need to reset jvmti thread state. |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
398 // Single stepping may not get enabled correctly by the agent since |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
399 // exception state is passed in MethodExit event which may be sent at some |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
400 // time in the future. JDWP agent ignores MethodExit events if caused by |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
401 // an exception. |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
402 // |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
403 if (is_exception_detected()) { |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
404 clear_exception_detected(); |
af739d5ab23c
6972759: Step over not working after thrown exception and Pop
bpittore
parents:
1972
diff
changeset
|
405 } |
0 | 406 // If step is pending for earlyret then it may not be a repeat step. |
407 // The new_bci and method_id is same as current_bci and current | |
408 // method_id after earlyret and step for recursive calls. | |
409 // Force the step by clearing the last location. | |
410 JvmtiEnvThreadStateIterator it(this); | |
411 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { | |
412 ets->clear_current_location(); | |
413 } | |
414 } | |
415 | |
416 void JvmtiThreadState::oops_do(OopClosure* f) { | |
417 f->do_oop((oop*) &_earlyret_oop); | |
418 } |