570 MutexLocker mu(JvmtiThreadState_lock);
571 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
572 }
573 }
574
575 class JvmtiClassFileLoadHookPoster : public StackObj {
576 private:
577 Symbol* _h_name;
578 Handle _class_loader;
579 Handle _h_protection_domain;
580 unsigned char ** _data_ptr;
581 unsigned char ** _end_ptr;
582 JavaThread * _thread;
583 jint _curr_len;
584 unsigned char * _curr_data;
585 JvmtiEnv * _curr_env;
586 JvmtiCachedClassFileData ** _cached_class_file_ptr;
587 JvmtiThreadState * _state;
588 KlassHandle * _h_class_being_redefined;
589 JvmtiClassLoadKind _load_kind;
590
591 public:
592 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
593 Handle h_protection_domain,
594 unsigned char **data_ptr, unsigned char **end_ptr,
595 JvmtiCachedClassFileData **cache_ptr) {
596 _h_name = h_name;
597 _class_loader = class_loader;
598 _h_protection_domain = h_protection_domain;
599 _data_ptr = data_ptr;
600 _end_ptr = end_ptr;
601 _thread = JavaThread::current();
602 _curr_len = *end_ptr - *data_ptr;
603 _curr_data = *data_ptr;
604 _curr_env = NULL;
605 _cached_class_file_ptr = cache_ptr;
606
607 _state = _thread->jvmti_thread_state();
608 if (_state != NULL) {
609 _h_class_being_redefined = _state->get_class_being_redefined();
610 _load_kind = _state->get_class_load_kind();
611 Klass* klass = (_h_class_being_redefined == NULL) ? NULL : (*_h_class_being_redefined)();
612 if (_load_kind != jvmti_class_load_kind_load && klass != NULL) {
613 ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();
614 assert(module_entry != NULL, "module_entry should always be set");
615 if (module_entry->is_named() &&
616 module_entry->module() != NULL &&
617 !module_entry->has_default_read_edges()) {
618 if (!module_entry->set_has_default_read_edges()) {
619 // We won a potential race.
620 // Add read edges to the unnamed modules of the bootstrap and app class loaders
621 Handle class_module(_thread, JNIHandles::resolve(module_entry->module())); // Obtain j.l.r.Module
622 JvmtiExport::add_default_read_edges(class_module, _thread);
623 }
624 }
625 }
626 // Clear class_being_redefined flag here. The action
627 // from agent handler could generate a new class file load
628 // hook event and if it is not cleared the new event generated
629 // from regular class file load could have this stale redefined
630 // class handle info.
631 _state->clear_class_being_redefined();
632 } else {
633 // redefine and retransform will always set the thread state
634 _h_class_being_redefined = (KlassHandle *) NULL;
635 _load_kind = jvmti_class_load_kind_load;
636 }
637 }
638
639 void post() {
640 post_all_envs();
641 copy_modified_data();
642 }
643
644 private:
645 void post_all_envs() {
646 if (_load_kind != jvmti_class_load_kind_retransform) {
647 // for class load and redefine,
648 // call the non-retransformable agents
649 JvmtiEnvIterator it;
650 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
651 if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
652 // non-retransformable agents cannot retransform back,
653 // so no need to cache the original class file bytes
654 post_to_env(env, false);
655 }
656 }
657 }
658 JvmtiEnvIterator it;
659 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
660 // retransformable agents get all events
661 if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
662 // retransformable agents need to cache the original class file
663 // bytes if changes are made via the ClassFileLoadHook
670 if (env->phase() == JVMTI_PHASE_PRIMORDIAL && !env->early_class_hook_env()) {
671 return;
672 }
673 unsigned char *new_data = NULL;
674 jint new_len = 0;
675 JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
676 _h_protection_domain,
677 _h_class_being_redefined);
678 JvmtiJavaThreadEventTransition jet(_thread);
679 jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
680 if (callback != NULL) {
681 (*callback)(env->jvmti_external(), jem.jni_env(),
682 jem.class_being_redefined(),
683 jem.jloader(), jem.class_name(),
684 jem.protection_domain(),
685 _curr_len, _curr_data,
686 &new_len, &new_data);
687 }
688 if (new_data != NULL) {
689 // this agent has modified class data.
690 if (caching_needed && *_cached_class_file_ptr == NULL) {
691 // data has been changed by the new retransformable agent
692 // and it hasn't already been cached, cache it
693 JvmtiCachedClassFileData *p;
694 p = (JvmtiCachedClassFileData *)os::malloc(
695 offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
696 if (p == NULL) {
697 vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,
698 OOM_MALLOC_ERROR,
699 "unable to allocate cached copy of original class bytes");
700 }
701 p->length = _curr_len;
702 memcpy(p->data, _curr_data, _curr_len);
703 *_cached_class_file_ptr = p;
704 }
705
706 if (_curr_data != *_data_ptr) {
707 // curr_data is previous agent modified class data.
708 // And this has been changed by the new agent so
709 // we can delete it now.
717 // memory allocated by this agent.
718 _curr_env = env;
719 }
720 }
721
722 void copy_modified_data() {
723 // if one of the agent has modified class file data.
724 // Copy modified class data to new resources array.
725 if (_curr_data != *_data_ptr) {
726 *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);
727 memcpy(*_data_ptr, _curr_data, _curr_len);
728 *_end_ptr = *_data_ptr + _curr_len;
729 _curr_env->Deallocate(_curr_data);
730 }
731 }
732 };
733
734 bool JvmtiExport::_should_post_class_file_load_hook = false;
735
736 // this entry is for class file load hook on class load, redefine and retransform
737 void JvmtiExport::post_class_file_load_hook(Symbol* h_name,
738 Handle class_loader,
739 Handle h_protection_domain,
740 unsigned char **data_ptr,
741 unsigned char **end_ptr,
742 JvmtiCachedClassFileData **cache_ptr) {
743 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
744 return;
745 }
746
747 JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
748 h_protection_domain,
749 data_ptr, end_ptr,
750 cache_ptr);
751 poster.post();
752 }
753
754 void JvmtiExport::report_unsupported(bool on) {
755 // If any JVMTI service is turned on, we need to exit before native code
756 // tries to access nonexistant services.
757 if (on) {
758 vm_exit_during_initialization("Java Kernel does not support JVMTI.");
759 }
760 }
761
762
763 static inline Klass* oop_to_klass(oop obj) {
764 Klass* k = obj->klass();
765
766 // if the object is a java.lang.Class then return the java mirror
767 if (k == SystemDictionary::Class_klass()) {
768 if (!java_lang_Class::is_primitive(obj)) {
769 k = java_lang_Class::as_Klass(obj);
770 assert(k != NULL, "class for non-primitive mirror must exist");
771 }
|
570 MutexLocker mu(JvmtiThreadState_lock);
571 return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
572 }
573 }
574
575 class JvmtiClassFileLoadHookPoster : public StackObj {
576 private:
577 Symbol* _h_name;
578 Handle _class_loader;
579 Handle _h_protection_domain;
580 unsigned char ** _data_ptr;
581 unsigned char ** _end_ptr;
582 JavaThread * _thread;
583 jint _curr_len;
584 unsigned char * _curr_data;
585 JvmtiEnv * _curr_env;
586 JvmtiCachedClassFileData ** _cached_class_file_ptr;
587 JvmtiThreadState * _state;
588 KlassHandle * _h_class_being_redefined;
589 JvmtiClassLoadKind _load_kind;
590 bool _has_been_modified;
591
592 public:
593 inline JvmtiClassFileLoadHookPoster(Symbol* h_name, Handle class_loader,
594 Handle h_protection_domain,
595 unsigned char **data_ptr, unsigned char **end_ptr,
596 JvmtiCachedClassFileData **cache_ptr) {
597 _h_name = h_name;
598 _class_loader = class_loader;
599 _h_protection_domain = h_protection_domain;
600 _data_ptr = data_ptr;
601 _end_ptr = end_ptr;
602 _thread = JavaThread::current();
603 _curr_len = *end_ptr - *data_ptr;
604 _curr_data = *data_ptr;
605 _curr_env = NULL;
606 _cached_class_file_ptr = cache_ptr;
607 _has_been_modified = false;
608
609 _state = _thread->jvmti_thread_state();
610 if (_state != NULL) {
611 _h_class_being_redefined = _state->get_class_being_redefined();
612 _load_kind = _state->get_class_load_kind();
613 Klass* klass = (_h_class_being_redefined == NULL) ? NULL : (*_h_class_being_redefined)();
614 if (_load_kind != jvmti_class_load_kind_load && klass != NULL) {
615 ModuleEntry* module_entry = InstanceKlass::cast(klass)->module();
616 assert(module_entry != NULL, "module_entry should always be set");
617 if (module_entry->is_named() &&
618 module_entry->module() != NULL &&
619 !module_entry->has_default_read_edges()) {
620 if (!module_entry->set_has_default_read_edges()) {
621 // We won a potential race.
622 // Add read edges to the unnamed modules of the bootstrap and app class loaders
623 Handle class_module(_thread, JNIHandles::resolve(module_entry->module())); // Obtain j.l.r.Module
624 JvmtiExport::add_default_read_edges(class_module, _thread);
625 }
626 }
627 }
628 // Clear class_being_redefined flag here. The action
629 // from agent handler could generate a new class file load
630 // hook event and if it is not cleared the new event generated
631 // from regular class file load could have this stale redefined
632 // class handle info.
633 _state->clear_class_being_redefined();
634 } else {
635 // redefine and retransform will always set the thread state
636 _h_class_being_redefined = (KlassHandle *) NULL;
637 _load_kind = jvmti_class_load_kind_load;
638 }
639 }
640
641 void post() {
642 post_all_envs();
643 copy_modified_data();
644 }
645
646 bool has_been_modified() { return _has_been_modified; }
647
648 private:
649 void post_all_envs() {
650 if (_load_kind != jvmti_class_load_kind_retransform) {
651 // for class load and redefine,
652 // call the non-retransformable agents
653 JvmtiEnvIterator it;
654 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
655 if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
656 // non-retransformable agents cannot retransform back,
657 // so no need to cache the original class file bytes
658 post_to_env(env, false);
659 }
660 }
661 }
662 JvmtiEnvIterator it;
663 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
664 // retransformable agents get all events
665 if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
666 // retransformable agents need to cache the original class file
667 // bytes if changes are made via the ClassFileLoadHook
674 if (env->phase() == JVMTI_PHASE_PRIMORDIAL && !env->early_class_hook_env()) {
675 return;
676 }
677 unsigned char *new_data = NULL;
678 jint new_len = 0;
679 JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
680 _h_protection_domain,
681 _h_class_being_redefined);
682 JvmtiJavaThreadEventTransition jet(_thread);
683 jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
684 if (callback != NULL) {
685 (*callback)(env->jvmti_external(), jem.jni_env(),
686 jem.class_being_redefined(),
687 jem.jloader(), jem.class_name(),
688 jem.protection_domain(),
689 _curr_len, _curr_data,
690 &new_len, &new_data);
691 }
692 if (new_data != NULL) {
693 // this agent has modified class data.
694 _has_been_modified = true;
695 if (caching_needed && *_cached_class_file_ptr == NULL) {
696 // data has been changed by the new retransformable agent
697 // and it hasn't already been cached, cache it
698 JvmtiCachedClassFileData *p;
699 p = (JvmtiCachedClassFileData *)os::malloc(
700 offset_of(JvmtiCachedClassFileData, data) + _curr_len, mtInternal);
701 if (p == NULL) {
702 vm_exit_out_of_memory(offset_of(JvmtiCachedClassFileData, data) + _curr_len,
703 OOM_MALLOC_ERROR,
704 "unable to allocate cached copy of original class bytes");
705 }
706 p->length = _curr_len;
707 memcpy(p->data, _curr_data, _curr_len);
708 *_cached_class_file_ptr = p;
709 }
710
711 if (_curr_data != *_data_ptr) {
712 // curr_data is previous agent modified class data.
713 // And this has been changed by the new agent so
714 // we can delete it now.
722 // memory allocated by this agent.
723 _curr_env = env;
724 }
725 }
726
727 void copy_modified_data() {
728 // if one of the agent has modified class file data.
729 // Copy modified class data to new resources array.
730 if (_curr_data != *_data_ptr) {
731 *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);
732 memcpy(*_data_ptr, _curr_data, _curr_len);
733 *_end_ptr = *_data_ptr + _curr_len;
734 _curr_env->Deallocate(_curr_data);
735 }
736 }
737 };
738
739 bool JvmtiExport::_should_post_class_file_load_hook = false;
740
741 // this entry is for class file load hook on class load, redefine and retransform
742 bool JvmtiExport::post_class_file_load_hook(Symbol* h_name,
743 Handle class_loader,
744 Handle h_protection_domain,
745 unsigned char **data_ptr,
746 unsigned char **end_ptr,
747 JvmtiCachedClassFileData **cache_ptr) {
748 if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
749 return false;
750 }
751
752 JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
753 h_protection_domain,
754 data_ptr, end_ptr,
755 cache_ptr);
756 poster.post();
757 return poster.has_been_modified();
758 }
759
760 void JvmtiExport::report_unsupported(bool on) {
761 // If any JVMTI service is turned on, we need to exit before native code
762 // tries to access nonexistant services.
763 if (on) {
764 vm_exit_during_initialization("Java Kernel does not support JVMTI.");
765 }
766 }
767
768
769 static inline Klass* oop_to_klass(oop obj) {
770 Klass* k = obj->klass();
771
772 // if the object is a java.lang.Class then return the java mirror
773 if (k == SystemDictionary::Class_klass()) {
774 if (!java_lang_Class::is_primitive(obj)) {
775 k = java_lang_Class::as_Klass(obj);
776 assert(k != NULL, "class for non-primitive mirror must exist");
777 }
|