1 /*
2 * Copyright (c) 2003, 2025, 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 *
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/klass.inline.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "oops/oopHandle.inline.hpp"
39 #include "prims/jvmtiAgentThread.hpp"
40 #include "prims/jvmtiEventController.inline.hpp"
41 #include "prims/jvmtiImpl.hpp"
42 #include "prims/jvmtiRedefineClasses.hpp"
43 #include "runtime/atomicAccess.hpp"
44 #include "runtime/continuation.hpp"
45 #include "runtime/deoptimization.hpp"
46 #include "runtime/frame.inline.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/interfaceSupport.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50 #include "runtime/javaThread.hpp"
51 #include "runtime/jniHandles.hpp"
52 #include "runtime/os.hpp"
53 #include "runtime/serviceThread.hpp"
54 #include "runtime/signature.hpp"
55 #include "runtime/threadSMR.hpp"
56 #include "runtime/vframe.inline.hpp"
57 #include "runtime/vframe_hp.hpp"
58 #include "runtime/vmOperations.hpp"
59 #include "utilities/exceptions.hpp"
60
61 //
62 // class JvmtiAgentThread
63 //
64 // JavaThread used to wrap a thread started by an agent
65 // using the JVMTI method RunAgentThread.
66 //
67
68 JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
69 : JavaThread(start_function_wrapper) {
70 _env = env;
71 _start_fn = start_fn;
310
311
312 ///////////////////////////////////////////////////////////////
313 //
314 // class VM_BaseGetOrSetLocal
315 //
316
317 const jvalue VM_BaseGetOrSetLocal::_DEFAULT_VALUE = {0L};
318 // Constructor for non-object getter
319
320 VM_BaseGetOrSetLocal::VM_BaseGetOrSetLocal(JavaThread* calling_thread, jint depth,
321 jint index, BasicType type, jvalue value, bool set, bool self)
322 : _calling_thread(calling_thread)
323 , _depth(depth)
324 , _index(index)
325 , _type(type)
326 , _value(value)
327 , _jvf(nullptr)
328 , _set(set)
329 , _self(self)
330 , _result(JVMTI_ERROR_NONE)
331 {
332 }
333
334 // Check that the klass is assignable to a type with the given signature.
335 // Another solution could be to use the function Klass::is_subtype_of(type).
336 // But the type class can be forced to load/initialize eagerly in such a case.
337 // This may cause unexpected consequences like CFLH or class-init JVMTI events.
338 // It is better to avoid such a behavior.
339 bool VM_BaseGetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
340 assert(ty_sign != nullptr, "type signature must not be null");
341 assert(thread != nullptr, "thread must not be null");
342 assert(klass != nullptr, "klass must not be null");
343
344 int len = (int) strlen(ty_sign);
345 if (ty_sign[0] == JVM_SIGNATURE_CLASS &&
346 ty_sign[len-1] == JVM_SIGNATURE_ENDCLASS) { // Need pure class/interface name
347 ty_sign++;
348 len -= 2;
349 }
459 BasicType slot_type = locals->at(_index)->type();
460
461 if (slot_type == T_CONFLICT) {
462 _result = JVMTI_ERROR_INVALID_SLOT;
463 return false;
464 }
465 if (extra_slot) {
466 BasicType extra_slot_type = locals->at(_index + 1)->type();
467 if (extra_slot_type != T_INT) {
468 _result = JVMTI_ERROR_INVALID_SLOT;
469 return false;
470 }
471 }
472 if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) {
473 _result = JVMTI_ERROR_TYPE_MISMATCH;
474 return false;
475 }
476 return true;
477 }
478
479 static bool can_be_deoptimized(vframe* vf) {
480 return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
481 }
482
483 bool VM_GetOrSetLocal::doit_prologue() {
484 if (!_eb.deoptimize_objects(_depth, _depth)) {
485 // The target frame is affected by a reallocation failure.
486 _result = JVMTI_ERROR_OUT_OF_MEMORY;
487 return false;
488 }
489
490 return true;
491 }
492
493 void VM_BaseGetOrSetLocal::doit() {
494 _jvf = get_java_vframe();
495 if (_jvf == nullptr) {
496 return;
497 };
498
593 default: ShouldNotReachHere();
594 }
595 _jvf->set_locals(locals);
596 } else {
597 if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
598 assert(getting_receiver(), "Can only get here when getting receiver");
599 oop receiver = _jvf->fr().get_native_receiver();
600 _value.l = JNIHandles::make_local(_calling_thread, receiver);
601 } else {
602 StackValueCollection *locals = _jvf->locals();
603
604 switch (_type) {
605 case T_INT: _value.i = locals->int_at (_index); break;
606 case T_LONG: _value.j = locals->long_at (_index); break;
607 case T_FLOAT: _value.f = locals->float_at (_index); break;
608 case T_DOUBLE: _value.d = locals->double_at(_index); break;
609 case T_OBJECT: {
610 // Wrap the oop to be returned in a local JNI handle since
611 // oops_do() no longer applies after doit() is finished.
612 oop obj = locals->obj_at(_index)();
613 _value.l = JNIHandles::make_local(_calling_thread, obj);
614 break;
615 }
616 default: ShouldNotReachHere();
617 }
618 }
619 }
620 }
621
622 bool VM_BaseGetOrSetLocal::allow_nested_vm_operations() const {
623 return true; // May need to deoptimize
624 }
625
626
627 ///////////////////////////////////////////////////////////////
628 //
629 // class VM_GetOrSetLocal
630 //
631
632 // Constructor for non-object getter
633 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, bool self)
634 : VM_BaseGetOrSetLocal(nullptr, depth, index, type, _DEFAULT_VALUE, false, self),
635 _thread(thread),
636 _eb(false, nullptr, nullptr)
637 {
638 }
639
640 // Constructor for object or non-object setter
641 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value, bool self)
|
1 /*
2 * Copyright (c) 2003, 2026, 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 *
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/klass.inline.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "oops/oopHandle.inline.hpp"
39 #include "prims/jvmtiAgentThread.hpp"
40 #include "prims/jvmtiEventController.inline.hpp"
41 #include "prims/jvmtiImpl.hpp"
42 #include "prims/jvmtiRedefineClasses.hpp"
43 #include "runtime/atomicAccess.hpp"
44 #include "runtime/continuation.hpp"
45 #include "runtime/deoptimization.hpp"
46 #include "runtime/frame.inline.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/interfaceSupport.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50 #include "runtime/javaThread.hpp"
51 #include "runtime/jniHandles.inline.hpp"
52 #include "runtime/os.hpp"
53 #include "runtime/serviceThread.hpp"
54 #include "runtime/signature.hpp"
55 #include "runtime/threadSMR.hpp"
56 #include "runtime/vframe.inline.hpp"
57 #include "runtime/vframe_hp.hpp"
58 #include "runtime/vmOperations.hpp"
59 #include "utilities/exceptions.hpp"
60
61 //
62 // class JvmtiAgentThread
63 //
64 // JavaThread used to wrap a thread started by an agent
65 // using the JVMTI method RunAgentThread.
66 //
67
68 JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
69 : JavaThread(start_function_wrapper) {
70 _env = env;
71 _start_fn = start_fn;
310
311
312 ///////////////////////////////////////////////////////////////
313 //
314 // class VM_BaseGetOrSetLocal
315 //
316
317 const jvalue VM_BaseGetOrSetLocal::_DEFAULT_VALUE = {0L};
318 // Constructor for non-object getter
319
320 VM_BaseGetOrSetLocal::VM_BaseGetOrSetLocal(JavaThread* calling_thread, jint depth,
321 jint index, BasicType type, jvalue value, bool set, bool self)
322 : _calling_thread(calling_thread)
323 , _depth(depth)
324 , _index(index)
325 , _type(type)
326 , _value(value)
327 , _jvf(nullptr)
328 , _set(set)
329 , _self(self)
330 , _need_clone(false)
331 , _result(JVMTI_ERROR_NONE)
332 {
333 }
334
335 // Check that the klass is assignable to a type with the given signature.
336 // Another solution could be to use the function Klass::is_subtype_of(type).
337 // But the type class can be forced to load/initialize eagerly in such a case.
338 // This may cause unexpected consequences like CFLH or class-init JVMTI events.
339 // It is better to avoid such a behavior.
340 bool VM_BaseGetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
341 assert(ty_sign != nullptr, "type signature must not be null");
342 assert(thread != nullptr, "thread must not be null");
343 assert(klass != nullptr, "klass must not be null");
344
345 int len = (int) strlen(ty_sign);
346 if (ty_sign[0] == JVM_SIGNATURE_CLASS &&
347 ty_sign[len-1] == JVM_SIGNATURE_ENDCLASS) { // Need pure class/interface name
348 ty_sign++;
349 len -= 2;
350 }
460 BasicType slot_type = locals->at(_index)->type();
461
462 if (slot_type == T_CONFLICT) {
463 _result = JVMTI_ERROR_INVALID_SLOT;
464 return false;
465 }
466 if (extra_slot) {
467 BasicType extra_slot_type = locals->at(_index + 1)->type();
468 if (extra_slot_type != T_INT) {
469 _result = JVMTI_ERROR_INVALID_SLOT;
470 return false;
471 }
472 }
473 if (_type != slot_type && (_type == T_OBJECT || slot_type != T_INT)) {
474 _result = JVMTI_ERROR_TYPE_MISMATCH;
475 return false;
476 }
477 return true;
478 }
479
480 void VM_BaseGetOrSetLocal::check_and_clone_this_value_object() {
481 oop obj = JNIHandles::resolve(_value.l);
482 HandleMark hm(_calling_thread);
483 Handle obj_h(_calling_thread, obj);
484
485 assert(_type == T_OBJECT, "sanity check");
486 assert(obj != nullptr, "expected non-null oop");
487 assert(obj_h()->is_inline(), "expected inline oop");
488 assert(_index == 0, "expected slot 0 for THIS object");
489
490 InlineKlass* klass = InlineKlass::cast(obj_h()->klass());
491 inlineOop obj_copy = klass->allocate_instance(_calling_thread);
492 if (obj_copy == nullptr) {
493 _result = JVMTI_ERROR_OUT_OF_MEMORY;
494 } else {
495 inlineOop thisObj = inlineOop(obj_h());
496 // copy object payload into the object snapshot
497 BufferedValuePayload src(thisObj);
498 BufferedValuePayload dst(obj_copy, klass);
499 src.copy_to(dst);
500
501 // Must ensure the content of the buffered value is visible
502 // before publishing the buffered value oop
503 OrderAccess::storestore();
504 }
505 _value.l = JNIHandles::make_local(_calling_thread, obj_copy);
506 }
507
508 static bool can_be_deoptimized(vframe* vf) {
509 return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
510 }
511
512 bool VM_GetOrSetLocal::doit_prologue() {
513 if (!_eb.deoptimize_objects(_depth, _depth)) {
514 // The target frame is affected by a reallocation failure.
515 _result = JVMTI_ERROR_OUT_OF_MEMORY;
516 return false;
517 }
518
519 return true;
520 }
521
522 void VM_BaseGetOrSetLocal::doit() {
523 _jvf = get_java_vframe();
524 if (_jvf == nullptr) {
525 return;
526 };
527
622 default: ShouldNotReachHere();
623 }
624 _jvf->set_locals(locals);
625 } else {
626 if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
627 assert(getting_receiver(), "Can only get here when getting receiver");
628 oop receiver = _jvf->fr().get_native_receiver();
629 _value.l = JNIHandles::make_local(_calling_thread, receiver);
630 } else {
631 StackValueCollection *locals = _jvf->locals();
632
633 switch (_type) {
634 case T_INT: _value.i = locals->int_at (_index); break;
635 case T_LONG: _value.j = locals->long_at (_index); break;
636 case T_FLOAT: _value.f = locals->float_at (_index); break;
637 case T_DOUBLE: _value.d = locals->double_at(_index); break;
638 case T_OBJECT: {
639 // Wrap the oop to be returned in a local JNI handle since
640 // oops_do() no longer applies after doit() is finished.
641 oop obj = locals->obj_at(_index)();
642
643 if (Arguments::is_valhalla_enabled()) {
644 bool is_ctor = _jvf->method()->is_object_constructor();
645 if (is_ctor && _index == 0 && obj != nullptr && obj->is_inline()) {
646 _need_clone = true; // need to allocate an object snapshot in doit_epilogue
647 }
648 }
649 _value.l = JNIHandles::make_local(_calling_thread, obj);
650 break;
651 }
652 default: ShouldNotReachHere();
653 }
654 }
655 }
656 }
657
658 void VM_BaseGetOrSetLocal::doit_epilogue() {
659 if (_need_clone) {
660 check_and_clone_this_value_object();
661 }
662 }
663
664 bool VM_BaseGetOrSetLocal::allow_nested_vm_operations() const {
665 return true; // May need to deoptimize
666 }
667
668
669 ///////////////////////////////////////////////////////////////
670 //
671 // class VM_GetOrSetLocal
672 //
673
674 // Constructor for non-object getter
675 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, bool self)
676 : VM_BaseGetOrSetLocal(nullptr, depth, index, type, _DEFAULT_VALUE, false, self),
677 _thread(thread),
678 _eb(false, nullptr, nullptr)
679 {
680 }
681
682 // Constructor for object or non-object setter
683 VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, jint index, BasicType type, jvalue value, bool self)
|