250 class JvmtiExceptionEventMark : public JvmtiLocationEventMark {
251 private:
252 jobject _exc;
253
254 public:
255 JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) :
256 JvmtiLocationEventMark(thread, method, location),
257 _exc(to_jobject(exception())) {};
258 jobject exception() { return _exc; }
259 };
260
261 class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark {
262 private:
263 const char *_class_name;
264 jobject _jloader;
265 jobject _protection_domain;
266 jclass _class_being_redefined;
267
268 public:
269 JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name,
270 Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) {
271 _class_name = name != NULL? name->as_utf8() : NULL;
272 _jloader = (jobject)to_jobject(class_loader());
273 _protection_domain = (jobject)to_jobject(prot_domain());
274 if (class_being_redefined == NULL) {
275 _class_being_redefined = NULL;
276 } else {
277 _class_being_redefined = (jclass)to_jclass((*class_being_redefined)());
278 }
279 };
280 const char *class_name() {
281 return _class_name;
282 }
283 jobject jloader() {
284 return _jloader;
285 }
286 jobject protection_domain() {
287 return _protection_domain;
288 }
289 jclass class_being_redefined() {
290 return _class_being_redefined;
291 }
292 };
293
294 //////////////////////////////////////////////////////////////////////////////
295
296 int JvmtiExport::_field_access_count = 0;
297 int JvmtiExport::_field_modification_count = 0;
718 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
719 } else {
720 MutexLocker mu(JvmtiThreadState_lock);
721 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
722 }
723 }
724
725 class JvmtiClassFileLoadHookPoster : public StackObj {
726 private:
727 Symbol* _h_name;
728 Handle _class_loader;
729 Handle _h_protection_domain;
730 unsigned char ** _data_ptr;
731 unsigned char ** _end_ptr;
732 JavaThread * _thread;
733 jint _curr_len;
734 unsigned char * _curr_data;
735 JvmtiEnv * _curr_env;
736 JvmtiCachedClassFileData ** _cached_class_file_ptr;
737 JvmtiThreadState * _state;
738 KlassHandle * _h_class_being_redefined;
739 JvmtiClassLoadKind _load_kind;
740 bool _has_been_modified;
741
742 public:
743 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
744 Handle h_protection_domain,
745 unsigned char **data_ptr, unsigned char **end_ptr,
746 JvmtiCachedClassFileData **cache_ptr) {
747 _h_name = h_name;
748 _class_loader = class_loader;
749 _h_protection_domain = h_protection_domain;
750 _data_ptr = data_ptr;
751 _end_ptr = end_ptr;
752 _thread = JavaThread::current();
753 _curr_len = *end_ptr - *data_ptr;
754 _curr_data = *data_ptr;
755 _curr_env = NULL;
756 _cached_class_file_ptr = cache_ptr;
757 _has_been_modified = false;
758
759 _state = _thread->jvmti_thread_state();
760 if (_state != NULL) {
761 _h_class_being_redefined = _state->get_class_being_redefined();
762 _load_kind = _state->get_class_load_kind();
763 Klass* klass = (_h_class_being_redefined == NULL) ? NULL : (*_h_class_being_redefined)();
764 if (_load_kind != jvmti_class_load_kind_load && klass != NULL) {
765 ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();
766 assert(module_entry != NULL, "module_entry should always be set");
767 if (module_entry->is_named() &&
768 module_entry->module() != NULL &&
769 !module_entry->has_default_read_edges()) {
770 if (!module_entry->set_has_default_read_edges()) {
771 // We won a potential race.
772 // Add read edges to the unnamed modules of the bootstrap and app class loaders
773 Handle class_module(_thread, JNIHandles::resolve(module_entry->module())); // Obtain j.l.r.Module
774 JvmtiExport::add_default_read_edges(class_module, _thread);
775 }
776 }
777 }
778 // Clear class_being_redefined flag here. The action
779 // from agent handler could generate a new class file load
780 // hook event and if it is not cleared the new event generated
781 // from regular class file load could have this stale redefined
782 // class handle info.
783 _state->clear_class_being_redefined();
784 } else {
785 // redefine and retransform will always set the thread state
786 _h_class_being_redefined = (KlassHandle *) NULL;
787 _load_kind = jvmti_class_load_kind_load;
788 }
789 }
790
791 void post() {
792 post_all_envs();
793 copy_modified_data();
794 }
795
796 bool has_been_modified() { return _has_been_modified; }
797
798 private:
799 void post_all_envs() {
800 if (_load_kind != jvmti_class_load_kind_retransform) {
801 // for class load and redefine,
802 // call the non-retransformable agents
803 JvmtiEnvIterator it;
804 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
805 if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
806 // non-retransformable agents cannot retransform back,
811 }
812 JvmtiEnvIterator it;
813 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
814 // retransformable agents get all events
815 if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
816 // retransformable agents need to cache the original class file
817 // bytes if changes are made via the ClassFileLoadHook
818 post_to_env(env, true);
819 }
820 }
821 }
822
823 void post_to_env(JvmtiEnv* env, bool caching_needed) {
824 if (env->phase() == JVMTI_PHASE_PRIMORDIAL && !env->early_class_hook_env()) {
825 return;
826 }
827 unsigned char *new_data = NULL;
828 jint new_len = 0;
829 JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
830 _h_protection_domain,
831 _h_class_being_redefined);
832 JvmtiJavaThreadEventTransition jet(_thread);
833 jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
834 if (callback != NULL) {
835 (*callback)(env->jvmti_external(), jem.jni_env(),
836 jem.class_being_redefined(),
837 jem.jloader(), jem.class_name(),
838 jem.protection_domain(),
839 _curr_len, _curr_data,
840 &new_len, &new_data);
841 }
842 if (new_data != NULL) {
843 // this agent has modified class data.
844 _has_been_modified = true;
845 if (caching_needed && *_cached_class_file_ptr == NULL) {
846 // data has been changed by the new retransformable agent
847 // and it hasn't already been cached, cache it
848 JvmtiCachedClassFileData *p;
849 p = (JvmtiCachedClassFileData *)os::malloc(
850 offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
851 if (p == NULL) {
1138 state->clear_hide_single_stepping();
1139 }
1140 }
1141
1142
1143 bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
1144 JvmtiThreadState *state = thread->jvmti_thread_state();
1145 if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
1146 state->set_hide_single_stepping();
1147 return true;
1148 } else {
1149 return false;
1150 }
1151 }
1152
1153 void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
1154 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1155 return;
1156 }
1157 HandleMark hm(thread);
1158 KlassHandle kh(thread, klass);
1159
1160 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Trg Class Load triggered",
1161 JvmtiTrace::safe_get_thread_name(thread)));
1162 JvmtiThreadState* state = thread->jvmti_thread_state();
1163 if (state == NULL) {
1164 return;
1165 }
1166 JvmtiEnvThreadStateIterator it(state);
1167 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1168 if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
1169 JvmtiEnv *env = ets->get_env();
1170 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1171 continue;
1172 }
1173 EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Evt Class Load sent %s",
1174 JvmtiTrace::safe_get_thread_name(thread),
1175 kh()==NULL? "NULL" : kh()->external_name() ));
1176 JvmtiClassEventMark jem(thread, kh());
1177 JvmtiJavaThreadEventTransition jet(thread);
1178 jvmtiEventClassLoad callback = env->callbacks()->ClassLoad;
1179 if (callback != NULL) {
1180 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
1181 }
1182 }
1183 }
1184 }
1185
1186
1187 void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
1188 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1189 return;
1190 }
1191 HandleMark hm(thread);
1192 KlassHandle kh(thread, klass);
1193
1194 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Trg Class Prepare triggered",
1195 JvmtiTrace::safe_get_thread_name(thread)));
1196 JvmtiThreadState* state = thread->jvmti_thread_state();
1197 if (state == NULL) {
1198 return;
1199 }
1200 JvmtiEnvThreadStateIterator it(state);
1201 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1202 if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
1203 JvmtiEnv *env = ets->get_env();
1204 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1205 continue;
1206 }
1207 EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Evt Class Prepare sent %s",
1208 JvmtiTrace::safe_get_thread_name(thread),
1209 kh()==NULL? "NULL" : kh()->external_name() ));
1210 JvmtiClassEventMark jem(thread, kh());
1211 JvmtiJavaThreadEventTransition jet(thread);
1212 jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare;
1213 if (callback != NULL) {
1214 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
1215 }
1216 }
1217 }
1218 }
1219
1220 void JvmtiExport::post_class_unload(Klass* klass) {
1221 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1222 return;
1223 }
1224 Thread *thread = Thread::current();
1225 HandleMark hm(thread);
1226 KlassHandle kh(thread, klass);
1227
1228 EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Trg Class Unload triggered" ));
1229 if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
1230 assert(thread->is_VM_thread(), "wrong thread");
1231
1232 // get JavaThread for whom we are proxy
1233 Thread *calling_thread = ((VMThread *)thread)->vm_operation()->calling_thread();
1234 if (!calling_thread->is_Java_thread()) {
1235 // cannot post an event to a non-JavaThread
1236 return;
1237 }
1238 JavaThread *real_thread = (JavaThread *)calling_thread;
1239
1240 JvmtiEnvIterator it;
1241 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1242 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1243 continue;
1244 }
1245 if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
1246 EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Evt Class Unload sent %s",
1247 kh()==NULL? "NULL" : kh()->external_name() ));
1248
1249 // do everything manually, since this is a proxy - needs special care
1250 JNIEnv* jni_env = real_thread->jni_environment();
1251 jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj());
1252 jclass jk = (jclass)JNIHandles::make_local(real_thread, kh()->java_mirror());
1253
1254 // Before we call the JVMTI agent, we have to set the state in the
1255 // thread for which we are proxying.
1256 JavaThreadState prev_state = real_thread->thread_state();
1257 assert(((Thread *)real_thread)->is_ConcurrentGC_thread() ||
1258 (real_thread->is_Java_thread() && prev_state == _thread_blocked),
1259 "should be ConcurrentGCThread or JavaThread at safepoint");
1260 real_thread->set_thread_state(_thread_in_native);
1261
1262 jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
1263 if (callback != NULL) {
1264 (*callback)(env->jvmti_external(), jni_env, jt, jk);
1265 }
1266
1267 assert(real_thread->thread_state() == _thread_in_native,
1268 "JavaThread should be in native");
1269 real_thread->set_thread_state(prev_state);
1270
1271 JNIHandles::destroy_local(jk);
1272 JNIHandles::destroy_local(jt);
1578 // It's okay to clear these exceptions here because we duplicate
1579 // this lookup in InterpreterRuntime::exception_handler_for_exception.
1580 EXCEPTION_MARK;
1581
1582 bool should_repeat;
1583 vframeStream st(thread);
1584 assert(!st.at_end(), "cannot be at end");
1585 Method* current_method = NULL;
1586 // A GC may occur during the Method::fast_exception_handler_bci_for()
1587 // call below if it needs to load the constraint class. Using a
1588 // methodHandle to keep the 'current_method' from being deallocated
1589 // if GC happens.
1590 methodHandle current_mh = methodHandle(thread, current_method);
1591 int current_bci = -1;
1592 do {
1593 current_method = st.method();
1594 current_mh = methodHandle(thread, current_method);
1595 current_bci = st.bci();
1596 do {
1597 should_repeat = false;
1598 KlassHandle eh_klass(thread, exception_handle()->klass());
1599 current_bci = Method::fast_exception_handler_bci_for(
1600 current_mh, eh_klass, current_bci, THREAD);
1601 if (HAS_PENDING_EXCEPTION) {
1602 exception_handle = Handle(thread, PENDING_EXCEPTION);
1603 CLEAR_PENDING_EXCEPTION;
1604 should_repeat = true;
1605 }
1606 } while (should_repeat && (current_bci != -1));
1607 st.next();
1608 } while ((current_bci < 0) && (!st.at_end()));
1609
1610 jmethodID catch_jmethodID;
1611 if (current_bci < 0) {
1612 catch_jmethodID = 0;
1613 current_bci = 0;
1614 } else {
1615 catch_jmethodID = jem.to_jmethodID(current_mh);
1616 }
1617
1618 JvmtiJavaThreadEventTransition jet(thread);
1726 return obj;
1727 }
1728
1729 void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,
1730 Klass* klass, jfieldID fieldID, bool is_static) {
1731 // We must be called with a Java context in order to provide reasonable
1732 // values for the klazz, method, and location fields. The callers of this
1733 // function don't make the call unless there is a Java context.
1734 assert(thread->has_last_Java_frame(), "must be called with a Java context");
1735
1736 ResourceMark rm;
1737 fieldDescriptor fd;
1738 // if get_field_descriptor finds fieldID to be invalid, then we just bail
1739 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
1740 assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");
1741 if (!valid_fieldID) return;
1742 // field accesses are not watched so bail
1743 if (!fd.is_field_access_watched()) return;
1744
1745 HandleMark hm(thread);
1746 KlassHandle h_klass(thread, klass);
1747 Handle h_obj;
1748 if (!is_static) {
1749 // non-static field accessors have an object, but we need a handle
1750 assert(obj != NULL, "non-static needs an object");
1751 h_obj = Handle(thread, obj);
1752 }
1753 post_field_access(thread,
1754 thread->last_frame().interpreter_frame_method(),
1755 thread->last_frame().interpreter_frame_bcp(),
1756 h_klass, h_obj, fieldID);
1757 }
1758
1759 void JvmtiExport::post_field_access(JavaThread *thread, Method* method,
1760 address location, KlassHandle field_klass, Handle object, jfieldID field) {
1761
1762 HandleMark hm(thread);
1763 methodHandle mh(thread, method);
1764
1765 JvmtiThreadState *state = thread->jvmti_thread_state();
1766 if (state == NULL) {
1767 return;
1768 }
1769 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Trg Field Access event triggered",
1770 JvmtiTrace::safe_get_thread_name(thread)));
1771 JvmtiEnvThreadStateIterator it(state);
1772 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1773 if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {
1774 EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Evt Field Access event sent %s.%s @ " INTX_FORMAT,
1775 JvmtiTrace::safe_get_thread_name(thread),
1776 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1777 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1778 location - mh()->code_base() ));
1779
1780 JvmtiEnv *env = ets->get_env();
1781 JvmtiLocationEventMark jem(thread, mh, location);
1782 jclass field_jclass = jem.to_jclass(field_klass());
1783 jobject field_jobject = jem.to_jobject(object());
1784 JvmtiJavaThreadEventTransition jet(thread);
1785 jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess;
1786 if (callback != NULL) {
1787 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1788 jem.jni_methodID(), jem.location(),
1789 field_jclass, field_jobject, field);
1790 }
1791 }
1792 }
1793 }
1794
1795 oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj,
1796 Klass* klass, jfieldID fieldID, bool is_static,
1797 char sig_type, jvalue *value) {
1798 if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
1799 // At least one field modification watch is set so we have more work
1800 // to do. This wrapper is used by entry points that allow us
1801 // to create handles in post_field_modification_by_jni().
1802 post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
1830 // function don't make the call unless there is a Java context.
1831 assert(thread->has_last_Java_frame(), "must be called with Java context");
1832
1833 ResourceMark rm;
1834 fieldDescriptor fd;
1835 // if get_field_descriptor finds fieldID to be invalid, then we just bail
1836 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
1837 assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");
1838 if (!valid_fieldID) return;
1839 // field modifications are not watched so bail
1840 if (!fd.is_field_modification_watched()) return;
1841
1842 HandleMark hm(thread);
1843
1844 Handle h_obj;
1845 if (!is_static) {
1846 // non-static field accessors have an object, but we need a handle
1847 assert(obj != NULL, "non-static needs an object");
1848 h_obj = Handle(thread, obj);
1849 }
1850 KlassHandle h_klass(thread, klass);
1851 post_field_modification(thread,
1852 thread->last_frame().interpreter_frame_method(),
1853 thread->last_frame().interpreter_frame_bcp(),
1854 h_klass, h_obj, fieldID, sig_type, value);
1855 }
1856
1857 void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method,
1858 address location, KlassHandle field_klass, Handle object, jfieldID field,
1859 char sig_type, jvalue *value) {
1860
1861 if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') {
1862 // 'I' instructions are used for byte, char, short and int.
1863 // determine which it really is, and convert
1864 fieldDescriptor fd;
1865 bool found = JvmtiEnv::get_field_descriptor(field_klass(), field, &fd);
1866 // should be found (if not, leave as is)
1867 if (found) {
1868 jint ival = value->i;
1869 // convert value from int to appropriate type
1870 switch (fd.field_type()) {
1871 case T_BOOLEAN:
1872 sig_type = 'Z';
1873 value->i = 0; // clear it
1874 value->z = (jboolean)ival;
1875 break;
1876 case T_BYTE:
1877 sig_type = 'B';
1878 value->i = 0; // clear it
1879 value->b = (jbyte)ival;
1880 break;
1881 case T_CHAR:
1882 sig_type = 'C';
1883 value->i = 0; // clear it
1884 value->c = (jchar)ival;
1885 break;
1900 }
1901
1902 assert(sig_type != '[', "array should have sig_type == 'L'");
1903 bool handle_created = false;
1904
1905 // convert oop to JNI handle.
1906 if (sig_type == 'L') {
1907 handle_created = true;
1908 value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l);
1909 }
1910
1911 post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);
1912
1913 // Destroy the JNI handle allocated above.
1914 if (handle_created) {
1915 JNIHandles::destroy_local(value->l);
1916 }
1917 }
1918
1919 void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,
1920 address location, KlassHandle field_klass, Handle object, jfieldID field,
1921 char sig_type, jvalue *value_ptr) {
1922
1923 HandleMark hm(thread);
1924 methodHandle mh(thread, method);
1925
1926 JvmtiThreadState *state = thread->jvmti_thread_state();
1927 if (state == NULL) {
1928 return;
1929 }
1930 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
1931 ("[%s] Trg Field Modification event triggered",
1932 JvmtiTrace::safe_get_thread_name(thread)));
1933
1934 JvmtiEnvThreadStateIterator it(state);
1935 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1936 if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {
1937 EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
1938 ("[%s] Evt Field Modification event sent %s.%s @ " INTX_FORMAT,
1939 JvmtiTrace::safe_get_thread_name(thread),
1940 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1941 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1942 location - mh()->code_base() ));
1943
1944 JvmtiEnv *env = ets->get_env();
1945 JvmtiLocationEventMark jem(thread, mh, location);
1946 jclass field_jclass = jem.to_jclass(field_klass());
1947 jobject field_jobject = jem.to_jobject(object());
1948 JvmtiJavaThreadEventTransition jet(thread);
1949 jvmtiEventFieldModification callback = env->callbacks()->FieldModification;
1950 if (callback != NULL) {
1951 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1952 jem.jni_methodID(), jem.location(),
1953 field_jclass, field_jobject, field, sig_type, *value_ptr);
1954 }
1955 }
1956 }
1957 }
1958
1959 void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) {
1960 JavaThread* thread = JavaThread::current();
1961 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
1962
1963 HandleMark hm(thread);
1964 methodHandle mh(thread, method);
1965
1966 EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Trg Native Method Bind event triggered",
|
250 class JvmtiExceptionEventMark : public JvmtiLocationEventMark {
251 private:
252 jobject _exc;
253
254 public:
255 JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) :
256 JvmtiLocationEventMark(thread, method, location),
257 _exc(to_jobject(exception())) {};
258 jobject exception() { return _exc; }
259 };
260
261 class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark {
262 private:
263 const char *_class_name;
264 jobject _jloader;
265 jobject _protection_domain;
266 jclass _class_being_redefined;
267
268 public:
269 JvmtiClassFileLoadEventMark(JavaThread *thread, Symbol* name,
270 Handle class_loader, Handle prot_domain, Klass* class_being_redefined) : JvmtiThreadEventMark(thread) {
271 _class_name = name != NULL? name->as_utf8() : NULL;
272 _jloader = (jobject)to_jobject(class_loader());
273 _protection_domain = (jobject)to_jobject(prot_domain());
274 if (class_being_redefined == NULL) {
275 _class_being_redefined = NULL;
276 } else {
277 _class_being_redefined = (jclass)to_jclass(class_being_redefined);
278 }
279 };
280 const char *class_name() {
281 return _class_name;
282 }
283 jobject jloader() {
284 return _jloader;
285 }
286 jobject protection_domain() {
287 return _protection_domain;
288 }
289 jclass class_being_redefined() {
290 return _class_being_redefined;
291 }
292 };
293
294 //////////////////////////////////////////////////////////////////////////////
295
296 int JvmtiExport::_field_access_count = 0;
297 int JvmtiExport::_field_modification_count = 0;
718 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
719 } else {
720 MutexLocker mu(JvmtiThreadState_lock);
721 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
722 }
723 }
724
725 class JvmtiClassFileLoadHookPoster : public StackObj {
726 private:
727 Symbol* _h_name;
728 Handle _class_loader;
729 Handle _h_protection_domain;
730 unsigned char ** _data_ptr;
731 unsigned char ** _end_ptr;
732 JavaThread * _thread;
733 jint _curr_len;
734 unsigned char * _curr_data;
735 JvmtiEnv * _curr_env;
736 JvmtiCachedClassFileData ** _cached_class_file_ptr;
737 JvmtiThreadState * _state;
738 Klass* _class_being_redefined;
739 JvmtiClassLoadKind _load_kind;
740 bool _has_been_modified;
741
742 public:
743 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
744 Handle h_protection_domain,
745 unsigned char **data_ptr, unsigned char **end_ptr,
746 JvmtiCachedClassFileData **cache_ptr) {
747 _h_name = h_name;
748 _class_loader = class_loader;
749 _h_protection_domain = h_protection_domain;
750 _data_ptr = data_ptr;
751 _end_ptr = end_ptr;
752 _thread = JavaThread::current();
753 _curr_len = *end_ptr - *data_ptr;
754 _curr_data = *data_ptr;
755 _curr_env = NULL;
756 _cached_class_file_ptr = cache_ptr;
757 _has_been_modified = false;
758
759 _state = _thread->jvmti_thread_state();
760 if (_state != NULL) {
761 _class_being_redefined = _state->get_class_being_redefined();
762 _load_kind = _state->get_class_load_kind();
763 Klass* klass = (_class_being_redefined == NULL) ? NULL : _class_being_redefined;
764 if (_load_kind != jvmti_class_load_kind_load && klass != NULL) {
765 ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();
766 assert(module_entry != NULL, "module_entry should always be set");
767 if (module_entry->is_named() &&
768 module_entry->module() != NULL &&
769 !module_entry->has_default_read_edges()) {
770 if (!module_entry->set_has_default_read_edges()) {
771 // We won a potential race.
772 // Add read edges to the unnamed modules of the bootstrap and app class loaders
773 Handle class_module(_thread, JNIHandles::resolve(module_entry->module())); // Obtain j.l.r.Module
774 JvmtiExport::add_default_read_edges(class_module, _thread);
775 }
776 }
777 }
778 // Clear class_being_redefined flag here. The action
779 // from agent handler could generate a new class file load
780 // hook event and if it is not cleared the new event generated
781 // from regular class file load could have this stale redefined
782 // class handle info.
783 _state->clear_class_being_redefined();
784 } else {
785 // redefine and retransform will always set the thread state
786 _class_being_redefined = NULL;
787 _load_kind = jvmti_class_load_kind_load;
788 }
789 }
790
791 void post() {
792 post_all_envs();
793 copy_modified_data();
794 }
795
796 bool has_been_modified() { return _has_been_modified; }
797
798 private:
799 void post_all_envs() {
800 if (_load_kind != jvmti_class_load_kind_retransform) {
801 // for class load and redefine,
802 // call the non-retransformable agents
803 JvmtiEnvIterator it;
804 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
805 if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
806 // non-retransformable agents cannot retransform back,
811 }
812 JvmtiEnvIterator it;
813 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
814 // retransformable agents get all events
815 if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
816 // retransformable agents need to cache the original class file
817 // bytes if changes are made via the ClassFileLoadHook
818 post_to_env(env, true);
819 }
820 }
821 }
822
823 void post_to_env(JvmtiEnv* env, bool caching_needed) {
824 if (env->phase() == JVMTI_PHASE_PRIMORDIAL && !env->early_class_hook_env()) {
825 return;
826 }
827 unsigned char *new_data = NULL;
828 jint new_len = 0;
829 JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
830 _h_protection_domain,
831 _class_being_redefined);
832 JvmtiJavaThreadEventTransition jet(_thread);
833 jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
834 if (callback != NULL) {
835 (*callback)(env->jvmti_external(), jem.jni_env(),
836 jem.class_being_redefined(),
837 jem.jloader(), jem.class_name(),
838 jem.protection_domain(),
839 _curr_len, _curr_data,
840 &new_len, &new_data);
841 }
842 if (new_data != NULL) {
843 // this agent has modified class data.
844 _has_been_modified = true;
845 if (caching_needed && *_cached_class_file_ptr == NULL) {
846 // data has been changed by the new retransformable agent
847 // and it hasn't already been cached, cache it
848 JvmtiCachedClassFileData *p;
849 p = (JvmtiCachedClassFileData *)os::malloc(
850 offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
851 if (p == NULL) {
1138 state->clear_hide_single_stepping();
1139 }
1140 }
1141
1142
1143 bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
1144 JvmtiThreadState *state = thread->jvmti_thread_state();
1145 if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
1146 state->set_hide_single_stepping();
1147 return true;
1148 } else {
1149 return false;
1150 }
1151 }
1152
1153 void JvmtiExport::post_class_load(JavaThread *thread, Klass* klass) {
1154 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1155 return;
1156 }
1157 HandleMark hm(thread);
1158
1159 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Trg Class Load triggered",
1160 JvmtiTrace::safe_get_thread_name(thread)));
1161 JvmtiThreadState* state = thread->jvmti_thread_state();
1162 if (state == NULL) {
1163 return;
1164 }
1165 JvmtiEnvThreadStateIterator it(state);
1166 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1167 if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
1168 JvmtiEnv *env = ets->get_env();
1169 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1170 continue;
1171 }
1172 EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("[%s] Evt Class Load sent %s",
1173 JvmtiTrace::safe_get_thread_name(thread),
1174 klass==NULL? "NULL" : klass->external_name() ));
1175 JvmtiClassEventMark jem(thread, klass);
1176 JvmtiJavaThreadEventTransition jet(thread);
1177 jvmtiEventClassLoad callback = env->callbacks()->ClassLoad;
1178 if (callback != NULL) {
1179 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
1180 }
1181 }
1182 }
1183 }
1184
1185
1186 void JvmtiExport::post_class_prepare(JavaThread *thread, Klass* klass) {
1187 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1188 return;
1189 }
1190 HandleMark hm(thread);
1191
1192 EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Trg Class Prepare triggered",
1193 JvmtiTrace::safe_get_thread_name(thread)));
1194 JvmtiThreadState* state = thread->jvmti_thread_state();
1195 if (state == NULL) {
1196 return;
1197 }
1198 JvmtiEnvThreadStateIterator it(state);
1199 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1200 if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
1201 JvmtiEnv *env = ets->get_env();
1202 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1203 continue;
1204 }
1205 EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("[%s] Evt Class Prepare sent %s",
1206 JvmtiTrace::safe_get_thread_name(thread),
1207 klass==NULL? "NULL" : klass->external_name() ));
1208 JvmtiClassEventMark jem(thread, klass);
1209 JvmtiJavaThreadEventTransition jet(thread);
1210 jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare;
1211 if (callback != NULL) {
1212 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
1213 }
1214 }
1215 }
1216 }
1217
1218 void JvmtiExport::post_class_unload(Klass* klass) {
1219 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
1220 return;
1221 }
1222 Thread *thread = Thread::current();
1223 HandleMark hm(thread);
1224
1225 EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Trg Class Unload triggered" ));
1226 if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
1227 assert(thread->is_VM_thread(), "wrong thread");
1228
1229 // get JavaThread for whom we are proxy
1230 Thread *calling_thread = ((VMThread *)thread)->vm_operation()->calling_thread();
1231 if (!calling_thread->is_Java_thread()) {
1232 // cannot post an event to a non-JavaThread
1233 return;
1234 }
1235 JavaThread *real_thread = (JavaThread *)calling_thread;
1236
1237 JvmtiEnvIterator it;
1238 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1239 if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
1240 continue;
1241 }
1242 if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
1243 EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Evt Class Unload sent %s",
1244 klass==NULL? "NULL" : klass->external_name() ));
1245
1246 // do everything manually, since this is a proxy - needs special care
1247 JNIEnv* jni_env = real_thread->jni_environment();
1248 jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj());
1249 jclass jk = (jclass)JNIHandles::make_local(real_thread, klass->java_mirror());
1250
1251 // Before we call the JVMTI agent, we have to set the state in the
1252 // thread for which we are proxying.
1253 JavaThreadState prev_state = real_thread->thread_state();
1254 assert(((Thread *)real_thread)->is_ConcurrentGC_thread() ||
1255 (real_thread->is_Java_thread() && prev_state == _thread_blocked),
1256 "should be ConcurrentGCThread or JavaThread at safepoint");
1257 real_thread->set_thread_state(_thread_in_native);
1258
1259 jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
1260 if (callback != NULL) {
1261 (*callback)(env->jvmti_external(), jni_env, jt, jk);
1262 }
1263
1264 assert(real_thread->thread_state() == _thread_in_native,
1265 "JavaThread should be in native");
1266 real_thread->set_thread_state(prev_state);
1267
1268 JNIHandles::destroy_local(jk);
1269 JNIHandles::destroy_local(jt);
1575 // It's okay to clear these exceptions here because we duplicate
1576 // this lookup in InterpreterRuntime::exception_handler_for_exception.
1577 EXCEPTION_MARK;
1578
1579 bool should_repeat;
1580 vframeStream st(thread);
1581 assert(!st.at_end(), "cannot be at end");
1582 Method* current_method = NULL;
1583 // A GC may occur during the Method::fast_exception_handler_bci_for()
1584 // call below if it needs to load the constraint class. Using a
1585 // methodHandle to keep the 'current_method' from being deallocated
1586 // if GC happens.
1587 methodHandle current_mh = methodHandle(thread, current_method);
1588 int current_bci = -1;
1589 do {
1590 current_method = st.method();
1591 current_mh = methodHandle(thread, current_method);
1592 current_bci = st.bci();
1593 do {
1594 should_repeat = false;
1595 Klass* eh_klass = exception_handle()->klass();
1596 current_bci = Method::fast_exception_handler_bci_for(
1597 current_mh, eh_klass, current_bci, THREAD);
1598 if (HAS_PENDING_EXCEPTION) {
1599 exception_handle = Handle(thread, PENDING_EXCEPTION);
1600 CLEAR_PENDING_EXCEPTION;
1601 should_repeat = true;
1602 }
1603 } while (should_repeat && (current_bci != -1));
1604 st.next();
1605 } while ((current_bci < 0) && (!st.at_end()));
1606
1607 jmethodID catch_jmethodID;
1608 if (current_bci < 0) {
1609 catch_jmethodID = 0;
1610 current_bci = 0;
1611 } else {
1612 catch_jmethodID = jem.to_jmethodID(current_mh);
1613 }
1614
1615 JvmtiJavaThreadEventTransition jet(thread);
1723 return obj;
1724 }
1725
1726 void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,
1727 Klass* klass, jfieldID fieldID, bool is_static) {
1728 // We must be called with a Java context in order to provide reasonable
1729 // values for the klazz, method, and location fields. The callers of this
1730 // function don't make the call unless there is a Java context.
1731 assert(thread->has_last_Java_frame(), "must be called with a Java context");
1732
1733 ResourceMark rm;
1734 fieldDescriptor fd;
1735 // if get_field_descriptor finds fieldID to be invalid, then we just bail
1736 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
1737 assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");
1738 if (!valid_fieldID) return;
1739 // field accesses are not watched so bail
1740 if (!fd.is_field_access_watched()) return;
1741
1742 HandleMark hm(thread);
1743 Handle h_obj;
1744 if (!is_static) {
1745 // non-static field accessors have an object, but we need a handle
1746 assert(obj != NULL, "non-static needs an object");
1747 h_obj = Handle(thread, obj);
1748 }
1749 post_field_access(thread,
1750 thread->last_frame().interpreter_frame_method(),
1751 thread->last_frame().interpreter_frame_bcp(),
1752 klass, h_obj, fieldID);
1753 }
1754
1755 void JvmtiExport::post_field_access(JavaThread *thread, Method* method,
1756 address location, Klass* field_klass, Handle object, jfieldID field) {
1757
1758 HandleMark hm(thread);
1759 methodHandle mh(thread, method);
1760
1761 JvmtiThreadState *state = thread->jvmti_thread_state();
1762 if (state == NULL) {
1763 return;
1764 }
1765 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Trg Field Access event triggered",
1766 JvmtiTrace::safe_get_thread_name(thread)));
1767 JvmtiEnvThreadStateIterator it(state);
1768 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1769 if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {
1770 EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("[%s] Evt Field Access event sent %s.%s @ " INTX_FORMAT,
1771 JvmtiTrace::safe_get_thread_name(thread),
1772 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1773 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1774 location - mh()->code_base() ));
1775
1776 JvmtiEnv *env = ets->get_env();
1777 JvmtiLocationEventMark jem(thread, mh, location);
1778 jclass field_jclass = jem.to_jclass(field_klass);
1779 jobject field_jobject = jem.to_jobject(object());
1780 JvmtiJavaThreadEventTransition jet(thread);
1781 jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess;
1782 if (callback != NULL) {
1783 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1784 jem.jni_methodID(), jem.location(),
1785 field_jclass, field_jobject, field);
1786 }
1787 }
1788 }
1789 }
1790
1791 oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj,
1792 Klass* klass, jfieldID fieldID, bool is_static,
1793 char sig_type, jvalue *value) {
1794 if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
1795 // At least one field modification watch is set so we have more work
1796 // to do. This wrapper is used by entry points that allow us
1797 // to create handles in post_field_modification_by_jni().
1798 post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
1826 // function don't make the call unless there is a Java context.
1827 assert(thread->has_last_Java_frame(), "must be called with Java context");
1828
1829 ResourceMark rm;
1830 fieldDescriptor fd;
1831 // if get_field_descriptor finds fieldID to be invalid, then we just bail
1832 bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
1833 assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");
1834 if (!valid_fieldID) return;
1835 // field modifications are not watched so bail
1836 if (!fd.is_field_modification_watched()) return;
1837
1838 HandleMark hm(thread);
1839
1840 Handle h_obj;
1841 if (!is_static) {
1842 // non-static field accessors have an object, but we need a handle
1843 assert(obj != NULL, "non-static needs an object");
1844 h_obj = Handle(thread, obj);
1845 }
1846 post_field_modification(thread,
1847 thread->last_frame().interpreter_frame_method(),
1848 thread->last_frame().interpreter_frame_bcp(),
1849 klass, h_obj, fieldID, sig_type, value);
1850 }
1851
1852 void JvmtiExport::post_raw_field_modification(JavaThread *thread, Method* method,
1853 address location, Klass* field_klass, Handle object, jfieldID field,
1854 char sig_type, jvalue *value) {
1855
1856 if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'B' || sig_type == 'C' || sig_type == 'S') {
1857 // 'I' instructions are used for byte, char, short and int.
1858 // determine which it really is, and convert
1859 fieldDescriptor fd;
1860 bool found = JvmtiEnv::get_field_descriptor(field_klass, field, &fd);
1861 // should be found (if not, leave as is)
1862 if (found) {
1863 jint ival = value->i;
1864 // convert value from int to appropriate type
1865 switch (fd.field_type()) {
1866 case T_BOOLEAN:
1867 sig_type = 'Z';
1868 value->i = 0; // clear it
1869 value->z = (jboolean)ival;
1870 break;
1871 case T_BYTE:
1872 sig_type = 'B';
1873 value->i = 0; // clear it
1874 value->b = (jbyte)ival;
1875 break;
1876 case T_CHAR:
1877 sig_type = 'C';
1878 value->i = 0; // clear it
1879 value->c = (jchar)ival;
1880 break;
1895 }
1896
1897 assert(sig_type != '[', "array should have sig_type == 'L'");
1898 bool handle_created = false;
1899
1900 // convert oop to JNI handle.
1901 if (sig_type == 'L') {
1902 handle_created = true;
1903 value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l);
1904 }
1905
1906 post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);
1907
1908 // Destroy the JNI handle allocated above.
1909 if (handle_created) {
1910 JNIHandles::destroy_local(value->l);
1911 }
1912 }
1913
1914 void JvmtiExport::post_field_modification(JavaThread *thread, Method* method,
1915 address location, Klass* field_klass, Handle object, jfieldID field,
1916 char sig_type, jvalue *value_ptr) {
1917
1918 HandleMark hm(thread);
1919 methodHandle mh(thread, method);
1920
1921 JvmtiThreadState *state = thread->jvmti_thread_state();
1922 if (state == NULL) {
1923 return;
1924 }
1925 EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
1926 ("[%s] Trg Field Modification event triggered",
1927 JvmtiTrace::safe_get_thread_name(thread)));
1928
1929 JvmtiEnvThreadStateIterator it(state);
1930 for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
1931 if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {
1932 EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
1933 ("[%s] Evt Field Modification event sent %s.%s @ " INTX_FORMAT,
1934 JvmtiTrace::safe_get_thread_name(thread),
1935 (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
1936 (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
1937 location - mh()->code_base() ));
1938
1939 JvmtiEnv *env = ets->get_env();
1940 JvmtiLocationEventMark jem(thread, mh, location);
1941 jclass field_jclass = jem.to_jclass(field_klass);
1942 jobject field_jobject = jem.to_jobject(object());
1943 JvmtiJavaThreadEventTransition jet(thread);
1944 jvmtiEventFieldModification callback = env->callbacks()->FieldModification;
1945 if (callback != NULL) {
1946 (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
1947 jem.jni_methodID(), jem.location(),
1948 field_jclass, field_jobject, field, sig_type, *value_ptr);
1949 }
1950 }
1951 }
1952 }
1953
1954 void JvmtiExport::post_native_method_bind(Method* method, address* function_ptr) {
1955 JavaThread* thread = JavaThread::current();
1956 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
1957
1958 HandleMark hm(thread);
1959 methodHandle mh(thread, method);
1960
1961 EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("[%s] Trg Native Method Bind event triggered",
|