Mercurial > hg > graal-compiler
annotate src/share/vm/prims/jvmtiThreadState.hpp @ 2461:758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
Summary: Improve error message formatting to give more information to user. Also, catch a corner case related to 6930553 and 6844449.
Reviewed-by: kvn
author | jrose |
---|---|
date | Thu, 07 Apr 2011 17:12:21 -0700 |
parents | f95d63e2154a |
children | af739d5ab23c |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1213
diff
changeset
|
2 * Copyright (c) 2003, 2010, 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:
1213
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1213
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:
1213
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_PRIMS_JVMTITHREADSTATE_HPP |
26 #define SHARE_VM_PRIMS_JVMTITHREADSTATE_HPP | |
27 | |
28 #include "jvmtifiles/jvmti.h" | |
29 #include "memory/allocation.hpp" | |
30 #include "memory/allocation.inline.hpp" | |
31 #include "prims/jvmtiEventController.hpp" | |
32 #include "runtime/thread.hpp" | |
33 #include "utilities/growableArray.hpp" | |
0 | 34 |
35 // | |
36 // Forward Declarations | |
37 // | |
38 | |
39 class JvmtiEnvBase; | |
40 class JvmtiEnvThreadState; | |
41 class JvmtiDynamicCodeEventCollector; | |
42 | |
43 enum JvmtiClassLoadKind { | |
44 jvmti_class_load_kind_load = 100, | |
45 jvmti_class_load_kind_retransform, | |
46 jvmti_class_load_kind_redefine | |
47 }; | |
48 | |
49 /////////////////////////////////////////////////////////////// | |
50 // | |
51 // class JvmtiEnvThreadStateIterator | |
52 // | |
53 // The only safe means of iterating through the JvmtiEnvThreadStates | |
54 // in a JvmtiThreadState. | |
55 // Note that this iteratation includes invalid environments pending | |
56 // deallocation -- in fact, some uses depend on this behavior. | |
57 // | |
58 class JvmtiEnvThreadStateIterator : public StackObj { | |
59 private: | |
60 JvmtiThreadState* state; | |
61 public: | |
62 JvmtiEnvThreadStateIterator(JvmtiThreadState* thread_state); | |
63 ~JvmtiEnvThreadStateIterator(); | |
64 JvmtiEnvThreadState* first(); | |
65 JvmtiEnvThreadState* next(JvmtiEnvThreadState* ets); | |
66 }; | |
67 | |
68 | |
69 /////////////////////////////////////////////////////////////// | |
70 // | |
71 // class JvmtiThreadState | |
72 // | |
73 // The Jvmti state for each thread (across all JvmtiEnv): | |
74 // 1. Local table of enabled events. | |
75 class JvmtiThreadState : public CHeapObj { | |
76 private: | |
77 friend class JvmtiEnv; | |
78 JavaThread *_thread; | |
79 bool _exception_detected; | |
80 bool _exception_caught; | |
81 bool _hide_single_stepping; | |
82 bool _pending_step_for_popframe; | |
83 bool _pending_step_for_earlyret; | |
84 int _hide_level; | |
85 | |
86 // Used to send class being redefined/retransformed and kind of transform | |
87 // info to the class file load hook event handler. | |
88 KlassHandle *_class_being_redefined; | |
89 JvmtiClassLoadKind _class_load_kind; | |
90 | |
91 // This is only valid when is_interp_only_mode() returns true | |
92 int _cur_stack_depth; | |
93 | |
94 JvmtiThreadEventEnable _thread_event_enable; | |
95 | |
96 // for support of JvmtiEnvThreadState | |
97 JvmtiEnvThreadState* _head_env_thread_state; | |
98 | |
99 // doubly-linked linear list of active thread state | |
100 // needed in order to iterate the list without holding Threads_lock | |
101 static JvmtiThreadState *_head; | |
102 JvmtiThreadState *_next; | |
103 JvmtiThreadState *_prev; | |
104 | |
105 // holds the current dynamic code event collector, NULL if no event collector in use | |
106 JvmtiDynamicCodeEventCollector* _dynamic_code_event_collector; | |
107 // holds the current vm object alloc event collector, NULL if no event collector in use | |
108 JvmtiVMObjectAllocEventCollector* _vm_object_alloc_event_collector; | |
109 | |
110 // Should only be created by factory methods | |
111 JvmtiThreadState(JavaThread *thread); | |
112 | |
113 friend class JvmtiEnvThreadStateIterator; | |
114 inline JvmtiEnvThreadState* head_env_thread_state(); | |
115 inline void set_head_env_thread_state(JvmtiEnvThreadState* ets); | |
116 | |
117 public: | |
118 ~JvmtiThreadState(); | |
119 | |
120 // is event_type enabled and usable for this thread in any enviroments? | |
121 bool is_enabled(jvmtiEvent event_type) { | |
122 return _thread_event_enable.is_enabled(event_type); | |
123 } | |
124 | |
125 JvmtiThreadEventEnable *thread_event_enable() { | |
126 return &_thread_event_enable; | |
127 } | |
128 | |
129 // Must only be called in situations where the state is for the current thread and | |
130 // the environment can not go away. To be safe, the returned JvmtiEnvThreadState | |
131 // must be used in such a way as there can be no intervening safepoints. | |
132 inline JvmtiEnvThreadState* env_thread_state(JvmtiEnvBase *env); | |
133 | |
134 static void periodic_clean_up(); | |
135 | |
136 void add_env(JvmtiEnvBase *env); | |
137 | |
138 // Used by the interpreter for fullspeed debugging support | |
139 bool is_interp_only_mode() { return _thread->is_interp_only_mode(); } | |
140 void enter_interp_only_mode(); | |
141 void leave_interp_only_mode(); | |
142 | |
143 // access to the linked list of all JVMTI thread states | |
144 static JvmtiThreadState *first() { | |
145 assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check"); | |
146 return _head; | |
147 } | |
148 | |
149 JvmtiThreadState *next() { | |
150 return _next; | |
151 } | |
152 | |
153 // Current stack depth is only valid when is_interp_only_mode() returns true. | |
154 // These functions should only be called at a safepoint - usually called from same thread. | |
155 // Returns the number of Java activations on the stack. | |
156 int cur_stack_depth(); | |
157 void invalidate_cur_stack_depth(); | |
158 void incr_cur_stack_depth(); | |
159 void decr_cur_stack_depth(); | |
160 | |
161 int count_frames(); | |
162 | |
163 inline JavaThread *get_thread() { return _thread; } | |
164 inline bool is_exception_detected() { return _exception_detected; } | |
165 inline bool is_exception_caught() { return _exception_caught; } | |
166 inline void set_exception_detected() { _exception_detected = true; | |
167 _exception_caught = false; } | |
168 inline void set_exception_caught() { _exception_caught = true; | |
169 _exception_detected = false; } | |
170 | |
171 inline void clear_hide_single_stepping() { | |
172 if (_hide_level > 0) { | |
173 _hide_level--; | |
174 } else { | |
175 assert(_hide_single_stepping, "hide_single_stepping is out of phase"); | |
176 _hide_single_stepping = false; | |
177 } | |
178 } | |
179 inline bool hide_single_stepping() { return _hide_single_stepping; } | |
180 inline void set_hide_single_stepping() { | |
181 if (_hide_single_stepping) { | |
182 _hide_level++; | |
183 } else { | |
184 assert(_hide_level == 0, "hide_level is out of phase"); | |
185 _hide_single_stepping = true; | |
186 } | |
187 } | |
188 | |
189 // Step pending flag is set when PopFrame is called and it is cleared | |
190 // when step for the Pop Frame is completed. | |
191 // This logic is used to distinguish b/w step for pop frame and repeat step. | |
192 void set_pending_step_for_popframe() { _pending_step_for_popframe = true; } | |
193 void clr_pending_step_for_popframe() { _pending_step_for_popframe = false; } | |
194 bool is_pending_step_for_popframe() { return _pending_step_for_popframe; } | |
195 void process_pending_step_for_popframe(); | |
196 | |
197 // Step pending flag is set when ForceEarlyReturn is called and it is cleared | |
198 // when step for the ForceEarlyReturn is completed. | |
199 // This logic is used to distinguish b/w step for early return and repeat step. | |
200 void set_pending_step_for_earlyret() { _pending_step_for_earlyret = true; } | |
201 void clr_pending_step_for_earlyret() { _pending_step_for_earlyret = false; } | |
202 bool is_pending_step_for_earlyret() { return _pending_step_for_earlyret; } | |
203 void process_pending_step_for_earlyret(); | |
204 | |
205 // Setter and getter method is used to send redefined class info | |
206 // when class file load hook event is posted. | |
207 // It is set while loading redefined class and cleared before the | |
208 // class file load hook event is posted. | |
209 inline void set_class_being_redefined(KlassHandle *h_class, JvmtiClassLoadKind kind) { | |
210 _class_being_redefined = h_class; | |
211 _class_load_kind = kind; | |
212 } | |
213 | |
214 inline void clear_class_being_redefined() { | |
215 _class_being_redefined = NULL; | |
216 _class_load_kind = jvmti_class_load_kind_load; | |
217 } | |
218 | |
219 inline KlassHandle *get_class_being_redefined() { | |
220 return _class_being_redefined; | |
221 } | |
222 | |
223 inline JvmtiClassLoadKind get_class_load_kind() { | |
224 return _class_load_kind; | |
225 } | |
226 | |
227 // RedefineClasses support | |
228 // The bug 6214132 caused the verification to fail. | |
229 // | |
230 // Below is the detailed description of the fix approach taken: | |
231 // 1. What's done in RedefineClasses() before verification: | |
232 // a) A reference to the class being redefined (_the_class) and a | |
233 // reference to new version of the class (_scratch_class) are | |
234 // saved here for use during the bytecode verification phase of | |
235 // RedefineClasses. See RedefineVerifyMark for how these fields | |
236 // are managed. | |
237 // b) The _java_mirror field from _the_class is copied to the | |
238 // _java_mirror field in _scratch_class. This means that a jclass | |
239 // returned for _the_class or _scratch_class will refer to the | |
240 // same Java mirror. The verifier will see the "one true mirror" | |
241 // for the class being verified. | |
242 // 2. What is done at verification: | |
243 // When the verifier makes calls into the VM to ask questions about | |
244 // the class being verified, it will pass the jclass to JVM_* functions. | |
245 // The jclass is always pointing to the mirror of _the_class. | |
246 // ~28 JVM_* functions called by the verifier for the information | |
247 // about CP entries and klass structure should check the jvmtiThreadState | |
248 // info about equivalent klass versions and use it to replace a klassOop | |
249 // of _the_class with a klassOop of _scratch_class. The function | |
250 // class_to_verify_considering_redefinition() must be called for it. | |
251 // | |
252 // Note again, that this redirection happens only for the verifier thread. | |
253 // Other threads have very small overhead by checking the existence | |
254 // of the jvmtiThreadSate and the information about klasses equivalence. | |
255 // No JNI functions need to be changed, they don't reference the klass guts. | |
256 // The JavaThread pointer is already available in all JVM_* functions | |
257 // used by the verifier, so there is no extra performance issue with it. | |
258 | |
259 private: | |
260 KlassHandle *_the_class_for_redefinition_verification; | |
261 KlassHandle *_scratch_class_for_redefinition_verification; | |
262 | |
263 public: | |
264 inline void set_class_versions_map(KlassHandle *the_class, | |
265 KlassHandle *scratch_class) { | |
266 _the_class_for_redefinition_verification = the_class; | |
267 _scratch_class_for_redefinition_verification = scratch_class; | |
268 } | |
269 | |
270 inline void clear_class_versions_map() { set_class_versions_map(NULL, NULL); } | |
271 | |
272 static inline | |
273 klassOop class_to_verify_considering_redefinition(klassOop klass, | |
274 JavaThread *thread) { | |
275 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
276 if (state != NULL && state->_the_class_for_redefinition_verification != NULL) { | |
277 if ((*(state->_the_class_for_redefinition_verification))() == klass) { | |
278 klass = (*(state->_scratch_class_for_redefinition_verification))(); | |
279 } | |
280 } | |
281 return klass; | |
282 } | |
283 | |
284 // Todo: get rid of this! | |
285 private: | |
286 bool _debuggable; | |
287 public: | |
288 // Should the thread be enumerated by jvmtiInternal::GetAllThreads? | |
289 bool is_debuggable() { return _debuggable; } | |
290 // If a thread cannot be suspended (has no valid last_java_frame) then it gets marked !debuggable | |
291 void set_debuggable(bool debuggable) { _debuggable = debuggable; } | |
292 | |
293 public: | |
294 | |
295 bool may_be_walked(); | |
296 | |
297 // Thread local event collector setter and getter methods. | |
298 JvmtiDynamicCodeEventCollector* get_dynamic_code_event_collector() { | |
299 return _dynamic_code_event_collector; | |
300 } | |
301 JvmtiVMObjectAllocEventCollector* get_vm_object_alloc_event_collector() { | |
302 return _vm_object_alloc_event_collector; | |
303 } | |
304 void set_dynamic_code_event_collector(JvmtiDynamicCodeEventCollector* collector) { | |
305 _dynamic_code_event_collector = collector; | |
306 } | |
307 void set_vm_object_alloc_event_collector(JvmtiVMObjectAllocEventCollector* collector) { | |
308 _vm_object_alloc_event_collector = collector; | |
309 } | |
310 | |
311 | |
312 // | |
313 // Frame routines | |
314 // | |
315 | |
316 public: | |
317 | |
318 // true when the thread was suspended with a pointer to the last Java frame. | |
319 bool has_last_frame() { return _thread->has_last_Java_frame(); } | |
320 | |
321 void update_for_pop_top_frame(); | |
322 | |
323 // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
608
diff
changeset
|
324 // Can return NULL if JavaThread is exiting. |
0 | 325 inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) { |
326 assert(JvmtiThreadState_lock->is_locked(), "sanity check"); | |
327 | |
328 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
329 if (state == NULL) { | |
608
0386097d43d8
6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents:
0
diff
changeset
|
330 if (thread->is_exiting()) { |
0386097d43d8
6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents:
0
diff
changeset
|
331 // don't add a JvmtiThreadState to a thread that is exiting |
0386097d43d8
6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents:
0
diff
changeset
|
332 return NULL; |
0386097d43d8
6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents:
0
diff
changeset
|
333 } |
0386097d43d8
6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents:
0
diff
changeset
|
334 |
0 | 335 state = new JvmtiThreadState(thread); |
336 } | |
337 return state; | |
338 } | |
339 | |
340 // retrieve or create JvmtiThreadState | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
608
diff
changeset
|
341 // Can return NULL if JavaThread is exiting. |
0 | 342 inline static JvmtiThreadState *state_for(JavaThread *thread) { |
343 JvmtiThreadState *state = thread->jvmti_thread_state(); | |
344 if (state == NULL) { | |
345 MutexLocker mu(JvmtiThreadState_lock); | |
346 // check again with the lock held | |
347 state = state_for_while_locked(thread); | |
348 } else { | |
349 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); | |
350 } | |
351 return state; | |
352 } | |
353 | |
354 // JVMTI ForceEarlyReturn support | |
355 | |
356 // This is set to earlyret_pending to signal that top Java frame | |
357 // should be returned immediately | |
358 public: | |
359 int _earlyret_state; | |
360 TosState _earlyret_tos; | |
361 jvalue _earlyret_value; | |
362 oop _earlyret_oop; // Used to return an oop result into Java code from | |
363 // ForceEarlyReturnObject, GC-preserved | |
364 | |
365 // Setting and clearing earlyret_state | |
366 // earlyret_pending indicates that a ForceEarlyReturn() has been | |
367 // requested and not yet been completed. | |
368 public: | |
369 enum EarlyretState { | |
370 earlyret_inactive = 0, | |
371 earlyret_pending = 1 | |
372 }; | |
373 | |
374 void set_earlyret_pending(void) { _earlyret_state = earlyret_pending; } | |
375 void clr_earlyret_pending(void) { _earlyret_state = earlyret_inactive; } | |
376 bool is_earlyret_pending(void) { return (_earlyret_state == earlyret_pending); } | |
377 | |
378 TosState earlyret_tos() { return _earlyret_tos; } | |
379 oop earlyret_oop() const { return _earlyret_oop; } | |
380 void set_earlyret_oop (oop x) { _earlyret_oop = x; } | |
381 jvalue earlyret_value() { return _earlyret_value; } | |
382 void set_earlyret_value(jvalue val, TosState tos) { _earlyret_tos = tos; _earlyret_value = val; } | |
383 void clr_earlyret_value() { _earlyret_tos = ilgl; _earlyret_value.j = 0L; } | |
384 | |
385 static ByteSize earlyret_state_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_state); } | |
386 static ByteSize earlyret_tos_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_tos); } | |
387 static ByteSize earlyret_oop_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_oop); } | |
388 static ByteSize earlyret_value_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_value); } | |
389 | |
390 void oops_do(OopClosure* f); // GC support | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
609
diff
changeset
|
391 |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
609
diff
changeset
|
392 public: |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
609
diff
changeset
|
393 void set_should_post_on_exceptions(bool val) { _thread->set_should_post_on_exceptions_flag(val ? JNI_TRUE : JNI_FALSE); } |
0 | 394 }; |
395 | |
396 class RedefineVerifyMark : public StackObj { | |
397 private: | |
398 JvmtiThreadState *_state; | |
399 | |
400 public: | |
401 RedefineVerifyMark(KlassHandle *the_class, KlassHandle *scratch_class, | |
402 JvmtiThreadState *state) : _state(state) | |
403 { | |
404 _state->set_class_versions_map(the_class, scratch_class); | |
405 (*scratch_class)->set_java_mirror((*the_class)->java_mirror()); | |
406 } | |
407 | |
408 ~RedefineVerifyMark() { | |
409 _state->clear_class_versions_map(); | |
410 } | |
411 }; | |
412 | |
1972 | 413 #endif // SHARE_VM_PRIMS_JVMTITHREADSTATE_HPP |