< prev index next >

src/hotspot/share/prims/jvmtiImpl.cpp

Print this page

  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)
< prev index next >