1 | /* |
2 | * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. |
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 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "classfile/symbolTable.hpp" |
27 | #include "classfile/systemDictionary.hpp" |
28 | #include "interpreter/interpreter.hpp" |
29 | #include "interpreter/oopMapCache.hpp" |
30 | #include "jvmtifiles/jvmtiEnv.hpp" |
31 | #include "logging/log.hpp" |
32 | #include "logging/logStream.hpp" |
33 | #include "memory/allocation.inline.hpp" |
34 | #include "memory/resourceArea.hpp" |
35 | #include "oops/instanceKlass.hpp" |
36 | #include "oops/oop.inline.hpp" |
37 | #include "prims/jvmtiAgentThread.hpp" |
38 | #include "prims/jvmtiEventController.inline.hpp" |
39 | #include "prims/jvmtiImpl.hpp" |
40 | #include "prims/jvmtiRedefineClasses.hpp" |
41 | #include "runtime/atomic.hpp" |
42 | #include "runtime/deoptimization.hpp" |
43 | #include "runtime/frame.inline.hpp" |
44 | #include "runtime/handles.inline.hpp" |
45 | #include "runtime/interfaceSupport.inline.hpp" |
46 | #include "runtime/javaCalls.hpp" |
47 | #include "runtime/os.hpp" |
48 | #include "runtime/serviceThread.hpp" |
49 | #include "runtime/signature.hpp" |
50 | #include "runtime/thread.inline.hpp" |
51 | #include "runtime/threadSMR.hpp" |
52 | #include "runtime/vframe.hpp" |
53 | #include "runtime/vframe_hp.hpp" |
54 | #include "runtime/vmOperations.hpp" |
55 | #include "utilities/exceptions.hpp" |
56 | |
57 | // |
58 | // class JvmtiAgentThread |
59 | // |
60 | // JavaThread used to wrap a thread started by an agent |
61 | // using the JVMTI method RunAgentThread. |
62 | // |
63 | |
64 | JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg) |
65 | : JavaThread(start_function_wrapper) { |
66 | _env = env; |
67 | _start_fn = start_fn; |
68 | _start_arg = start_arg; |
69 | } |
70 | |
71 | void |
72 | JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) { |
73 | // It is expected that any Agent threads will be created as |
74 | // Java Threads. If this is the case, notification of the creation |
75 | // of the thread is given in JavaThread::thread_main(). |
76 | assert(thread->is_Java_thread(), "debugger thread should be a Java Thread" ); |
77 | assert(thread == JavaThread::current(), "sanity check" ); |
78 | |
79 | JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread; |
80 | dthread->call_start_function(); |
81 | } |
82 | |
83 | void |
84 | JvmtiAgentThread::call_start_function() { |
85 | ThreadToNativeFromVM transition(this); |
86 | _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg); |
87 | } |
88 | |
89 | |
90 | // |
91 | // class GrowableCache - private methods |
92 | // |
93 | |
94 | void GrowableCache::recache() { |
95 | int len = _elements->length(); |
96 | |
97 | FREE_C_HEAP_ARRAY(address, _cache); |
98 | _cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal); |
99 | |
100 | for (int i=0; i<len; i++) { |
101 | _cache[i] = _elements->at(i)->getCacheValue(); |
102 | // |
103 | // The cache entry has gone bad. Without a valid frame pointer |
104 | // value, the entry is useless so we simply delete it in product |
105 | // mode. The call to remove() will rebuild the cache again |
106 | // without the bad entry. |
107 | // |
108 | if (_cache[i] == NULL) { |
109 | assert(false, "cannot recache NULL elements" ); |
110 | remove(i); |
111 | return; |
112 | } |
113 | } |
114 | _cache[len] = NULL; |
115 | |
116 | _listener_fun(_this_obj,_cache); |
117 | } |
118 | |
119 | bool GrowableCache::equals(void* v, GrowableElement *e2) { |
120 | GrowableElement *e1 = (GrowableElement *) v; |
121 | assert(e1 != NULL, "e1 != NULL" ); |
122 | assert(e2 != NULL, "e2 != NULL" ); |
123 | |
124 | return e1->equals(e2); |
125 | } |
126 | |
127 | // |
128 | // class GrowableCache - public methods |
129 | // |
130 | |
131 | GrowableCache::GrowableCache() { |
132 | _this_obj = NULL; |
133 | _listener_fun = NULL; |
134 | _elements = NULL; |
135 | _cache = NULL; |
136 | } |
137 | |
138 | GrowableCache::~GrowableCache() { |
139 | clear(); |
140 | delete _elements; |
141 | FREE_C_HEAP_ARRAY(address, _cache); |
142 | } |
143 | |
144 | void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) { |
145 | _this_obj = this_obj; |
146 | _listener_fun = listener_fun; |
147 | _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<GrowableElement*>(5,true); |
148 | recache(); |
149 | } |
150 | |
151 | // number of elements in the collection |
152 | int GrowableCache::length() { |
153 | return _elements->length(); |
154 | } |
155 | |
156 | // get the value of the index element in the collection |
157 | GrowableElement* GrowableCache::at(int index) { |
158 | GrowableElement *e = (GrowableElement *) _elements->at(index); |
159 | assert(e != NULL, "e != NULL" ); |
160 | return e; |
161 | } |
162 | |
163 | int GrowableCache::find(GrowableElement* e) { |
164 | return _elements->find(e, GrowableCache::equals); |
165 | } |
166 | |
167 | // append a copy of the element to the end of the collection |
168 | void GrowableCache::append(GrowableElement* e) { |
169 | GrowableElement *new_e = e->clone(); |
170 | _elements->append(new_e); |
171 | recache(); |
172 | } |
173 | |
174 | // insert a copy of the element using lessthan() |
175 | void GrowableCache::insert(GrowableElement* e) { |
176 | GrowableElement *new_e = e->clone(); |
177 | _elements->append(new_e); |
178 | |
179 | int n = length()-2; |
180 | for (int i=n; i>=0; i--) { |
181 | GrowableElement *e1 = _elements->at(i); |
182 | GrowableElement *e2 = _elements->at(i+1); |
183 | if (e2->lessThan(e1)) { |
184 | _elements->at_put(i+1, e1); |
185 | _elements->at_put(i, e2); |
186 | } |
187 | } |
188 | |
189 | recache(); |
190 | } |
191 | |
192 | // remove the element at index |
193 | void GrowableCache::remove (int index) { |
194 | GrowableElement *e = _elements->at(index); |
195 | assert(e != NULL, "e != NULL" ); |
196 | _elements->remove(e); |
197 | delete e; |
198 | recache(); |
199 | } |
200 | |
201 | // clear out all elements, release all heap space and |
202 | // let our listener know that things have changed. |
203 | void GrowableCache::clear() { |
204 | int len = _elements->length(); |
205 | for (int i=0; i<len; i++) { |
206 | delete _elements->at(i); |
207 | } |
208 | _elements->clear(); |
209 | recache(); |
210 | } |
211 | |
212 | void GrowableCache::oops_do(OopClosure* f) { |
213 | int len = _elements->length(); |
214 | for (int i=0; i<len; i++) { |
215 | GrowableElement *e = _elements->at(i); |
216 | e->oops_do(f); |
217 | } |
218 | } |
219 | |
220 | void GrowableCache::metadata_do(void f(Metadata*)) { |
221 | int len = _elements->length(); |
222 | for (int i=0; i<len; i++) { |
223 | GrowableElement *e = _elements->at(i); |
224 | e->metadata_do(f); |
225 | } |
226 | } |
227 | |
228 | void GrowableCache::gc_epilogue() { |
229 | int len = _elements->length(); |
230 | for (int i=0; i<len; i++) { |
231 | _cache[i] = _elements->at(i)->getCacheValue(); |
232 | } |
233 | } |
234 | |
235 | // |
236 | // class JvmtiBreakpoint |
237 | // |
238 | |
239 | JvmtiBreakpoint::JvmtiBreakpoint() { |
240 | _method = NULL; |
241 | _bci = 0; |
242 | _class_holder = NULL; |
243 | } |
244 | |
245 | JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) { |
246 | _method = m_method; |
247 | _class_holder = _method->method_holder()->klass_holder(); |
248 | #ifdef CHECK_UNHANDLED_OOPS |
249 | // _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are |
250 | // sometimes allocated on the heap. |
251 | // |
252 | // The code handling JvmtiBreakpoints allocated on the stack can't be |
253 | // interrupted by a GC until _class_holder is reachable by the GC via the |
254 | // oops_do method. |
255 | Thread::current()->allow_unhandled_oop(&_class_holder); |
256 | #endif // CHECK_UNHANDLED_OOPS |
257 | assert(_method != NULL, "_method != NULL" ); |
258 | _bci = (int) location; |
259 | assert(_bci >= 0, "_bci >= 0" ); |
260 | } |
261 | |
262 | void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) { |
263 | _method = bp._method; |
264 | _bci = bp._bci; |
265 | _class_holder = bp._class_holder; |
266 | } |
267 | |
268 | bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) { |
269 | Unimplemented(); |
270 | return false; |
271 | } |
272 | |
273 | bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) { |
274 | return _method == bp._method |
275 | && _bci == bp._bci; |
276 | } |
277 | |
278 | bool JvmtiBreakpoint::is_valid() { |
279 | // class loader can be NULL |
280 | return _method != NULL && |
281 | _bci >= 0; |
282 | } |
283 | |
284 | address JvmtiBreakpoint::getBcp() const { |
285 | return _method->bcp_from(_bci); |
286 | } |
287 | |
288 | void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { |
289 | ((Method*)_method->*meth_act)(_bci); |
290 | |
291 | // add/remove breakpoint to/from versions of the method that are EMCP. |
292 | Thread *thread = Thread::current(); |
293 | InstanceKlass* ik = _method->method_holder(); |
294 | Symbol* m_name = _method->name(); |
295 | Symbol* m_signature = _method->signature(); |
296 | |
297 | // search previous versions if they exist |
298 | for (InstanceKlass* pv_node = ik->previous_versions(); |
299 | pv_node != NULL; |
300 | pv_node = pv_node->previous_versions()) { |
301 | Array<Method*>* methods = pv_node->methods(); |
302 | |
303 | for (int i = methods->length() - 1; i >= 0; i--) { |
304 | Method* method = methods->at(i); |
305 | // Only set breakpoints in running EMCP methods. |
306 | if (method->is_running_emcp() && |
307 | method->name() == m_name && |
308 | method->signature() == m_signature) { |
309 | ResourceMark rm; |
310 | log_debug(redefine, class, breakpoint) |
311 | ("%sing breakpoint in %s(%s)" , meth_act == &Method::set_breakpoint ? "sett" : "clear" , |
312 | method->name()->as_C_string(), method->signature()->as_C_string()); |
313 | (method->*meth_act)(_bci); |
314 | break; |
315 | } |
316 | } |
317 | } |
318 | } |
319 | |
320 | void JvmtiBreakpoint::set() { |
321 | each_method_version_do(&Method::set_breakpoint); |
322 | } |
323 | |
324 | void JvmtiBreakpoint::clear() { |
325 | each_method_version_do(&Method::clear_breakpoint); |
326 | } |
327 | |
328 | void JvmtiBreakpoint::print_on(outputStream* out) const { |
329 | #ifndef PRODUCT |
330 | ResourceMark rm; |
331 | const char *class_name = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string(); |
332 | const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string(); |
333 | out->print("Breakpoint(%s,%s,%d,%p)" , class_name, method_name, _bci, getBcp()); |
334 | #endif |
335 | } |
336 | |
337 | |
338 | // |
339 | // class VM_ChangeBreakpoints |
340 | // |
341 | // Modify the Breakpoints data structure at a safepoint |
342 | // |
343 | |
344 | void VM_ChangeBreakpoints::doit() { |
345 | switch (_operation) { |
346 | case SET_BREAKPOINT: |
347 | _breakpoints->set_at_safepoint(*_bp); |
348 | break; |
349 | case CLEAR_BREAKPOINT: |
350 | _breakpoints->clear_at_safepoint(*_bp); |
351 | break; |
352 | default: |
353 | assert(false, "Unknown operation" ); |
354 | } |
355 | } |
356 | |
357 | void VM_ChangeBreakpoints::oops_do(OopClosure* f) { |
358 | // The JvmtiBreakpoints in _breakpoints will be visited via |
359 | // JvmtiExport::oops_do. |
360 | if (_bp != NULL) { |
361 | _bp->oops_do(f); |
362 | } |
363 | } |
364 | |
365 | void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) { |
366 | // Walk metadata in breakpoints to keep from being deallocated with RedefineClasses |
367 | if (_bp != NULL) { |
368 | _bp->metadata_do(f); |
369 | } |
370 | } |
371 | |
372 | // |
373 | // class JvmtiBreakpoints |
374 | // |
375 | // a JVMTI internal collection of JvmtiBreakpoint |
376 | // |
377 | |
378 | JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) { |
379 | _bps.initialize(this,listener_fun); |
380 | } |
381 | |
382 | JvmtiBreakpoints:: ~JvmtiBreakpoints() {} |
383 | |
384 | void JvmtiBreakpoints::oops_do(OopClosure* f) { |
385 | _bps.oops_do(f); |
386 | } |
387 | |
388 | void JvmtiBreakpoints::metadata_do(void f(Metadata*)) { |
389 | _bps.metadata_do(f); |
390 | } |
391 | |
392 | void JvmtiBreakpoints::gc_epilogue() { |
393 | _bps.gc_epilogue(); |
394 | } |
395 | |
396 | void JvmtiBreakpoints::print() { |
397 | #ifndef PRODUCT |
398 | LogTarget(Trace, jvmti) log; |
399 | LogStream log_stream(log); |
400 | |
401 | int n = _bps.length(); |
402 | for (int i=0; i<n; i++) { |
403 | JvmtiBreakpoint& bp = _bps.at(i); |
404 | log_stream.print("%d: " , i); |
405 | bp.print_on(&log_stream); |
406 | log_stream.cr(); |
407 | } |
408 | #endif |
409 | } |
410 | |
411 | |
412 | void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) { |
413 | assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint" ); |
414 | |
415 | int i = _bps.find(bp); |
416 | if (i == -1) { |
417 | _bps.append(bp); |
418 | bp.set(); |
419 | } |
420 | } |
421 | |
422 | void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) { |
423 | assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint" ); |
424 | |
425 | int i = _bps.find(bp); |
426 | if (i != -1) { |
427 | _bps.remove(i); |
428 | bp.clear(); |
429 | } |
430 | } |
431 | |
432 | int JvmtiBreakpoints::length() { return _bps.length(); } |
433 | |
434 | int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) { |
435 | if ( _bps.find(bp) != -1) { |
436 | return JVMTI_ERROR_DUPLICATE; |
437 | } |
438 | VM_ChangeBreakpoints set_breakpoint(VM_ChangeBreakpoints::SET_BREAKPOINT, &bp); |
439 | VMThread::execute(&set_breakpoint); |
440 | return JVMTI_ERROR_NONE; |
441 | } |
442 | |
443 | int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) { |
444 | if ( _bps.find(bp) == -1) { |
445 | return JVMTI_ERROR_NOT_FOUND; |
446 | } |
447 | |
448 | VM_ChangeBreakpoints clear_breakpoint(VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp); |
449 | VMThread::execute(&clear_breakpoint); |
450 | return JVMTI_ERROR_NONE; |
451 | } |
452 | |
453 | void JvmtiBreakpoints::clearall_in_class_at_safepoint(Klass* klass) { |
454 | bool changed = true; |
455 | // We are going to run thru the list of bkpts |
456 | // and delete some. This deletion probably alters |
457 | // the list in some implementation defined way such |
458 | // that when we delete entry i, the next entry might |
459 | // no longer be at i+1. To be safe, each time we delete |
460 | // an entry, we'll just start again from the beginning. |
461 | // We'll stop when we make a pass thru the whole list without |
462 | // deleting anything. |
463 | while (changed) { |
464 | int len = _bps.length(); |
465 | changed = false; |
466 | for (int i = 0; i < len; i++) { |
467 | JvmtiBreakpoint& bp = _bps.at(i); |
468 | if (bp.method()->method_holder() == klass) { |
469 | bp.clear(); |
470 | _bps.remove(i); |
471 | // This changed 'i' so we have to start over. |
472 | changed = true; |
473 | break; |
474 | } |
475 | } |
476 | } |
477 | } |
478 | |
479 | // |
480 | // class JvmtiCurrentBreakpoints |
481 | // |
482 | |
483 | JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints = NULL; |
484 | address * JvmtiCurrentBreakpoints::_breakpoint_list = NULL; |
485 | |
486 | |
487 | JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() { |
488 | if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints); |
489 | _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun); |
490 | assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL" ); |
491 | return (*_jvmti_breakpoints); |
492 | } |
493 | |
494 | void JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) { |
495 | JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj; |
496 | assert(this_jvmti != NULL, "this_jvmti != NULL" ); |
497 | |
498 | debug_only(int n = this_jvmti->length();); |
499 | assert(cache[n] == NULL, "cache must be NULL terminated" ); |
500 | |
501 | set_breakpoint_list(cache); |
502 | } |
503 | |
504 | |
505 | void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) { |
506 | if (_jvmti_breakpoints != NULL) { |
507 | _jvmti_breakpoints->oops_do(f); |
508 | } |
509 | } |
510 | |
511 | void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) { |
512 | if (_jvmti_breakpoints != NULL) { |
513 | _jvmti_breakpoints->metadata_do(f); |
514 | } |
515 | } |
516 | |
517 | void JvmtiCurrentBreakpoints::gc_epilogue() { |
518 | if (_jvmti_breakpoints != NULL) { |
519 | _jvmti_breakpoints->gc_epilogue(); |
520 | } |
521 | } |
522 | |
523 | /////////////////////////////////////////////////////////////// |
524 | // |
525 | // class VM_GetOrSetLocal |
526 | // |
527 | |
528 | // Constructor for non-object getter |
529 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type) |
530 | : _thread(thread) |
531 | , _calling_thread(NULL) |
532 | , _depth(depth) |
533 | , _index(index) |
534 | , _type(type) |
535 | , _jvf(NULL) |
536 | , _set(false) |
537 | , _result(JVMTI_ERROR_NONE) |
538 | { |
539 | } |
540 | |
541 | // Constructor for object or non-object setter |
542 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value) |
543 | : _thread(thread) |
544 | , _calling_thread(NULL) |
545 | , _depth(depth) |
546 | , _index(index) |
547 | , _type(type) |
548 | , _value(value) |
549 | , _jvf(NULL) |
550 | , _set(true) |
551 | , _result(JVMTI_ERROR_NONE) |
552 | { |
553 | } |
554 | |
555 | // Constructor for object getter |
556 | VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index) |
557 | : _thread(thread) |
558 | , _calling_thread(calling_thread) |
559 | , _depth(depth) |
560 | , _index(index) |
561 | , _type(T_OBJECT) |
562 | , _jvf(NULL) |
563 | , _set(false) |
564 | , _result(JVMTI_ERROR_NONE) |
565 | { |
566 | } |
567 | |
568 | vframe *VM_GetOrSetLocal::get_vframe() { |
569 | if (!_thread->has_last_Java_frame()) { |
570 | return NULL; |
571 | } |
572 | RegisterMap reg_map(_thread); |
573 | vframe *vf = _thread->last_java_vframe(®_map); |
574 | int d = 0; |
575 | while ((vf != NULL) && (d < _depth)) { |
576 | vf = vf->java_sender(); |
577 | d++; |
578 | } |
579 | return vf; |
580 | } |
581 | |
582 | javaVFrame *VM_GetOrSetLocal::get_java_vframe() { |
583 | vframe* vf = get_vframe(); |
584 | if (vf == NULL) { |
585 | _result = JVMTI_ERROR_NO_MORE_FRAMES; |
586 | return NULL; |
587 | } |
588 | javaVFrame *jvf = (javaVFrame*)vf; |
589 | |
590 | if (!vf->is_java_frame()) { |
591 | _result = JVMTI_ERROR_OPAQUE_FRAME; |
592 | return NULL; |
593 | } |
594 | return jvf; |
595 | } |
596 | |
597 | // Check that the klass is assignable to a type with the given signature. |
598 | // Another solution could be to use the function Klass::is_subtype_of(type). |
599 | // But the type class can be forced to load/initialize eagerly in such a case. |
600 | // This may cause unexpected consequences like CFLH or class-init JVMTI events. |
601 | // It is better to avoid such a behavior. |
602 | bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) { |
603 | assert(ty_sign != NULL, "type signature must not be NULL" ); |
604 | assert(thread != NULL, "thread must not be NULL" ); |
605 | assert(klass != NULL, "klass must not be NULL" ); |
606 | |
607 | int len = (int) strlen(ty_sign); |
608 | if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name |
609 | ty_sign++; |
610 | len -= 2; |
611 | } |
612 | TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len); |
613 | if (klass->name() == ty_sym) { |
614 | return true; |
615 | } |
616 | // Compare primary supers |
617 | int super_depth = klass->super_depth(); |
618 | int idx; |
619 | for (idx = 0; idx < super_depth; idx++) { |
620 | if (klass->primary_super_of_depth(idx)->name() == ty_sym) { |
621 | return true; |
622 | } |
623 | } |
624 | // Compare secondary supers |
625 | const Array<Klass*>* sec_supers = klass->secondary_supers(); |
626 | for (idx = 0; idx < sec_supers->length(); idx++) { |
627 | if (((Klass*) sec_supers->at(idx))->name() == ty_sym) { |
628 | return true; |
629 | } |
630 | } |
631 | return false; |
632 | } |
633 | |
634 | // Checks error conditions: |
635 | // JVMTI_ERROR_INVALID_SLOT |
636 | // JVMTI_ERROR_TYPE_MISMATCH |
637 | // Returns: 'true' - everything is Ok, 'false' - error code |
638 | |
639 | bool VM_GetOrSetLocal::check_slot_type_lvt(javaVFrame* jvf) { |
640 | Method* method_oop = jvf->method(); |
641 | jint num_entries = method_oop->localvariable_table_length(); |
642 | if (num_entries == 0) { |
643 | _result = JVMTI_ERROR_INVALID_SLOT; |
644 | return false; // There are no slots |
645 | } |
646 | int signature_idx = -1; |
647 | int vf_bci = jvf->bci(); |
648 | LocalVariableTableElement* table = method_oop->localvariable_table_start(); |
649 | for (int i = 0; i < num_entries; i++) { |
650 | int start_bci = table[i].start_bci; |
651 | int end_bci = start_bci + table[i].length; |
652 | |
653 | // Here we assume that locations of LVT entries |
654 | // with the same slot number cannot be overlapped |
655 | if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) { |
656 | signature_idx = (int) table[i].descriptor_cp_index; |
657 | break; |
658 | } |
659 | } |
660 | if (signature_idx == -1) { |
661 | _result = JVMTI_ERROR_INVALID_SLOT; |
662 | return false; // Incorrect slot index |
663 | } |
664 | Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx); |
665 | const char* signature = (const char *) sign_sym->as_utf8(); |
666 | BasicType slot_type = char2type(signature[0]); |
667 | |
668 | switch (slot_type) { |
669 | case T_BYTE: |
670 | case T_SHORT: |
671 | case T_CHAR: |
672 | case T_BOOLEAN: |
673 | slot_type = T_INT; |
674 | break; |
675 | case T_ARRAY: |
676 | slot_type = T_OBJECT; |
677 | break; |
678 | default: |
679 | break; |
680 | }; |
681 | if (_type != slot_type) { |
682 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
683 | return false; |
684 | } |
685 | |
686 | jobject jobj = _value.l; |
687 | if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed |
688 | // Check that the jobject class matches the return type signature. |
689 | JavaThread* cur_thread = JavaThread::current(); |
690 | HandleMark hm(cur_thread); |
691 | |
692 | Handle obj(cur_thread, JNIHandles::resolve_external_guard(jobj)); |
693 | NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); |
694 | Klass* ob_k = obj->klass(); |
695 | NULL_CHECK(ob_k, (_result = JVMTI_ERROR_INVALID_OBJECT, false)); |
696 | |
697 | if (!is_assignable(signature, ob_k, cur_thread)) { |
698 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
699 | return false; |
700 | } |
701 | } |
702 | return true; |
703 | } |
704 | |
705 | bool VM_GetOrSetLocal::check_slot_type_no_lvt(javaVFrame* jvf) { |
706 | Method* method_oop = jvf->method(); |
707 | jint = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0; |
708 | |
709 | if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) { |
710 | _result = JVMTI_ERROR_INVALID_SLOT; |
711 | return false; |
712 | } |
713 | StackValueCollection *locals = _jvf->locals(); |
714 | BasicType slot_type = locals->at(_index)->type(); |
715 | |
716 | if (slot_type == T_CONFLICT) { |
717 | _result = JVMTI_ERROR_INVALID_SLOT; |
718 | return false; |
719 | } |
720 | if (extra_slot) { |
721 | BasicType = locals->at(_index + 1)->type(); |
722 | if (extra_slot_type != T_INT) { |
723 | _result = JVMTI_ERROR_INVALID_SLOT; |
724 | return false; |
725 | } |
726 | } |
727 | if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) { |
728 | _result = JVMTI_ERROR_TYPE_MISMATCH; |
729 | return false; |
730 | } |
731 | return true; |
732 | } |
733 | |
734 | static bool can_be_deoptimized(vframe* vf) { |
735 | return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); |
736 | } |
737 | |
738 | bool VM_GetOrSetLocal::doit_prologue() { |
739 | _jvf = get_java_vframe(); |
740 | NULL_CHECK(_jvf, false); |
741 | |
742 | Method* method_oop = _jvf->method(); |
743 | if (method_oop->is_native()) { |
744 | if (getting_receiver() && !method_oop->is_static()) { |
745 | return true; |
746 | } else { |
747 | _result = JVMTI_ERROR_OPAQUE_FRAME; |
748 | return false; |
749 | } |
750 | } |
751 | |
752 | if (!check_slot_type_no_lvt(_jvf)) { |
753 | return false; |
754 | } |
755 | if (method_oop->has_localvariable_table()) { |
756 | return check_slot_type_lvt(_jvf); |
757 | } |
758 | return true; |
759 | } |
760 | |
761 | void VM_GetOrSetLocal::doit() { |
762 | InterpreterOopMap oop_mask; |
763 | _jvf->method()->mask_for(_jvf->bci(), &oop_mask); |
764 | if (oop_mask.is_dead(_index)) { |
765 | // The local can be invalid and uninitialized in the scope of current bci |
766 | _result = JVMTI_ERROR_INVALID_SLOT; |
767 | return; |
768 | } |
769 | if (_set) { |
770 | // Force deoptimization of frame if compiled because it's |
771 | // possible the compiler emitted some locals as constant values, |
772 | // meaning they are not mutable. |
773 | if (can_be_deoptimized(_jvf)) { |
774 | |
775 | // Schedule deoptimization so that eventually the local |
776 | // update will be written to an interpreter frame. |
777 | Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id()); |
778 | |
779 | // Now store a new value for the local which will be applied |
780 | // once deoptimization occurs. Note however that while this |
781 | // write is deferred until deoptimization actually happens |
782 | // can vframe created after this point will have its locals |
783 | // reflecting this update so as far as anyone can see the |
784 | // write has already taken place. |
785 | |
786 | // If we are updating an oop then get the oop from the handle |
787 | // since the handle will be long gone by the time the deopt |
788 | // happens. The oop stored in the deferred local will be |
789 | // gc'd on its own. |
790 | if (_type == T_OBJECT) { |
791 | _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l)); |
792 | } |
793 | // Re-read the vframe so we can see that it is deoptimized |
794 | // [ Only need because of assert in update_local() ] |
795 | _jvf = get_java_vframe(); |
796 | ((compiledVFrame*)_jvf)->update_local(_type, _index, _value); |
797 | return; |
798 | } |
799 | StackValueCollection *locals = _jvf->locals(); |
800 | HandleMark hm; |
801 | |
802 | switch (_type) { |
803 | case T_INT: locals->set_int_at (_index, _value.i); break; |
804 | case T_LONG: locals->set_long_at (_index, _value.j); break; |
805 | case T_FLOAT: locals->set_float_at (_index, _value.f); break; |
806 | case T_DOUBLE: locals->set_double_at(_index, _value.d); break; |
807 | case T_OBJECT: { |
808 | Handle ob_h(Thread::current(), JNIHandles::resolve_external_guard(_value.l)); |
809 | locals->set_obj_at (_index, ob_h); |
810 | break; |
811 | } |
812 | default: ShouldNotReachHere(); |
813 | } |
814 | _jvf->set_locals(locals); |
815 | } else { |
816 | if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) { |
817 | assert(getting_receiver(), "Can only get here when getting receiver" ); |
818 | oop receiver = _jvf->fr().get_native_receiver(); |
819 | _value.l = JNIHandles::make_local(_calling_thread, receiver); |
820 | } else { |
821 | StackValueCollection *locals = _jvf->locals(); |
822 | |
823 | switch (_type) { |
824 | case T_INT: _value.i = locals->int_at (_index); break; |
825 | case T_LONG: _value.j = locals->long_at (_index); break; |
826 | case T_FLOAT: _value.f = locals->float_at (_index); break; |
827 | case T_DOUBLE: _value.d = locals->double_at(_index); break; |
828 | case T_OBJECT: { |
829 | // Wrap the oop to be returned in a local JNI handle since |
830 | // oops_do() no longer applies after doit() is finished. |
831 | oop obj = locals->obj_at(_index)(); |
832 | _value.l = JNIHandles::make_local(_calling_thread, obj); |
833 | break; |
834 | } |
835 | default: ShouldNotReachHere(); |
836 | } |
837 | } |
838 | } |
839 | } |
840 | |
841 | |
842 | bool VM_GetOrSetLocal::allow_nested_vm_operations() const { |
843 | return true; // May need to deoptimize |
844 | } |
845 | |
846 | |
847 | VM_GetReceiver::VM_GetReceiver( |
848 | JavaThread* thread, JavaThread* caller_thread, jint depth) |
849 | : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {} |
850 | |
851 | ///////////////////////////////////////////////////////////////////////////////////////// |
852 | |
853 | // |
854 | // class JvmtiSuspendControl - see comments in jvmtiImpl.hpp |
855 | // |
856 | |
857 | bool JvmtiSuspendControl::suspend(JavaThread *java_thread) { |
858 | // external suspend should have caught suspending a thread twice |
859 | |
860 | // Immediate suspension required for JPDA back-end so JVMTI agent threads do |
861 | // not deadlock due to later suspension on transitions while holding |
862 | // raw monitors. Passing true causes the immediate suspension. |
863 | // java_suspend() will catch threads in the process of exiting |
864 | // and will ignore them. |
865 | java_thread->java_suspend(); |
866 | |
867 | // It would be nice to have the following assertion in all the time, |
868 | // but it is possible for a racing resume request to have resumed |
869 | // this thread right after we suspended it. Temporarily enable this |
870 | // assertion if you are chasing a different kind of bug. |
871 | // |
872 | // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL || |
873 | // java_thread->is_being_ext_suspended(), "thread is not suspended"); |
874 | |
875 | if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) { |
876 | // check again because we can get delayed in java_suspend(): |
877 | // the thread is in process of exiting. |
878 | return false; |
879 | } |
880 | |
881 | return true; |
882 | } |
883 | |
884 | bool JvmtiSuspendControl::resume(JavaThread *java_thread) { |
885 | // external suspend should have caught resuming a thread twice |
886 | assert(java_thread->is_being_ext_suspended(), "thread should be suspended" ); |
887 | |
888 | // resume thread |
889 | { |
890 | // must always grab Threads_lock, see JVM_SuspendThread |
891 | MutexLocker ml(Threads_lock); |
892 | java_thread->java_resume(); |
893 | } |
894 | |
895 | return true; |
896 | } |
897 | |
898 | |
899 | void JvmtiSuspendControl::print() { |
900 | #ifndef PRODUCT |
901 | LogStreamHandle(Trace, jvmti) log_stream; |
902 | log_stream.print("Suspended Threads: [" ); |
903 | for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) { |
904 | #ifdef JVMTI_TRACE |
905 | const char *name = JvmtiTrace::safe_get_thread_name(thread); |
906 | #else |
907 | const char *name = "" ; |
908 | #endif /*JVMTI_TRACE */ |
909 | log_stream.print("%s(%c " , name, thread->is_being_ext_suspended() ? 'S' : '_'); |
910 | if (!thread->has_last_Java_frame()) { |
911 | log_stream.print("no stack" ); |
912 | } |
913 | log_stream.print(") " ); |
914 | } |
915 | log_stream.print_cr("]" ); |
916 | #endif |
917 | } |
918 | |
919 | JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( |
920 | nmethod* nm) { |
921 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); |
922 | event._event_data.compiled_method_load = nm; |
923 | // Keep the nmethod alive until the ServiceThread can process |
924 | // this deferred event. |
925 | nmethodLocker::lock_nmethod(nm); |
926 | return event; |
927 | } |
928 | |
929 | JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( |
930 | nmethod* nm, jmethodID id, const void* code) { |
931 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); |
932 | event._event_data.compiled_method_unload.nm = nm; |
933 | event._event_data.compiled_method_unload.method_id = id; |
934 | event._event_data.compiled_method_unload.code_begin = code; |
935 | // Keep the nmethod alive until the ServiceThread can process |
936 | // this deferred event. This will keep the memory for the |
937 | // generated code from being reused too early. We pass |
938 | // zombie_ok == true here so that our nmethod that was just |
939 | // made into a zombie can be locked. |
940 | nmethodLocker::lock_nmethod(nm, true /* zombie_ok */); |
941 | return event; |
942 | } |
943 | |
944 | JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event( |
945 | const char* name, const void* code_begin, const void* code_end) { |
946 | JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED); |
947 | // Need to make a copy of the name since we don't know how long |
948 | // the event poster will keep it around after we enqueue the |
949 | // deferred event and return. strdup() failure is handled in |
950 | // the post() routine below. |
951 | event._event_data.dynamic_code_generated.name = os::strdup(name); |
952 | event._event_data.dynamic_code_generated.code_begin = code_begin; |
953 | event._event_data.dynamic_code_generated.code_end = code_end; |
954 | return event; |
955 | } |
956 | |
957 | void JvmtiDeferredEvent::post() { |
958 | assert(ServiceThread::is_service_thread(Thread::current()), |
959 | "Service thread must post enqueued events" ); |
960 | switch(_type) { |
961 | case TYPE_COMPILED_METHOD_LOAD: { |
962 | nmethod* nm = _event_data.compiled_method_load; |
963 | JvmtiExport::post_compiled_method_load(nm); |
964 | // done with the deferred event so unlock the nmethod |
965 | nmethodLocker::unlock_nmethod(nm); |
966 | break; |
967 | } |
968 | case TYPE_COMPILED_METHOD_UNLOAD: { |
969 | nmethod* nm = _event_data.compiled_method_unload.nm; |
970 | JvmtiExport::post_compiled_method_unload( |
971 | _event_data.compiled_method_unload.method_id, |
972 | _event_data.compiled_method_unload.code_begin); |
973 | // done with the deferred event so unlock the nmethod |
974 | nmethodLocker::unlock_nmethod(nm); |
975 | break; |
976 | } |
977 | case TYPE_DYNAMIC_CODE_GENERATED: { |
978 | JvmtiExport::post_dynamic_code_generated_internal( |
979 | // if strdup failed give the event a default name |
980 | (_event_data.dynamic_code_generated.name == NULL) |
981 | ? "unknown_code" : _event_data.dynamic_code_generated.name, |
982 | _event_data.dynamic_code_generated.code_begin, |
983 | _event_data.dynamic_code_generated.code_end); |
984 | if (_event_data.dynamic_code_generated.name != NULL) { |
985 | // release our copy |
986 | os::free((void *)_event_data.dynamic_code_generated.name); |
987 | } |
988 | break; |
989 | } |
990 | default: |
991 | ShouldNotReachHere(); |
992 | } |
993 | } |
994 | |
995 | JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL; |
996 | JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL; |
997 | |
998 | bool JvmtiDeferredEventQueue::has_events() { |
999 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
1000 | return _queue_head != NULL; |
1001 | } |
1002 | |
1003 | void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) { |
1004 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
1005 | |
1006 | // Events get added to the end of the queue (and are pulled off the front). |
1007 | QueueNode* node = new QueueNode(event); |
1008 | if (_queue_tail == NULL) { |
1009 | _queue_tail = _queue_head = node; |
1010 | } else { |
1011 | assert(_queue_tail->next() == NULL, "Must be the last element in the list" ); |
1012 | _queue_tail->set_next(node); |
1013 | _queue_tail = node; |
1014 | } |
1015 | |
1016 | Service_lock->notify_all(); |
1017 | assert((_queue_head == NULL) == (_queue_tail == NULL), |
1018 | "Inconsistent queue markers" ); |
1019 | } |
1020 | |
1021 | JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() { |
1022 | assert(Service_lock->owned_by_self(), "Must own Service_lock" ); |
1023 | |
1024 | assert(_queue_head != NULL, "Nothing to dequeue" ); |
1025 | |
1026 | if (_queue_head == NULL) { |
1027 | // Just in case this happens in product; it shouldn't but let's not crash |
1028 | return JvmtiDeferredEvent(); |
1029 | } |
1030 | |
1031 | QueueNode* node = _queue_head; |
1032 | _queue_head = _queue_head->next(); |
1033 | if (_queue_head == NULL) { |
1034 | _queue_tail = NULL; |
1035 | } |
1036 | |
1037 | assert((_queue_head == NULL) == (_queue_tail == NULL), |
1038 | "Inconsistent queue markers" ); |
1039 | |
1040 | JvmtiDeferredEvent event = node->event(); |
1041 | delete node; |
1042 | return event; |
1043 | } |
1044 | |