src/share/vm/prims/jvmtiRedefineClasses.cpp

changeset 9745
0e3d6188f198
parent 9184
fbcbfd2753b5
child 9748
628176d22495
equal deleted inserted replaced
9744:b02fb6a07ed5 9745:0e3d6188f198
65 _class_defs = class_defs; 65 _class_defs = class_defs;
66 _class_load_kind = class_load_kind; 66 _class_load_kind = class_load_kind;
67 _res = JVMTI_ERROR_NONE; 67 _res = JVMTI_ERROR_NONE;
68 } 68 }
69 69
70 static inline InstanceKlass* get_ik(jclass def) {
71 oop mirror = JNIHandles::resolve_non_null(def);
72 return InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
73 }
74
75 // If any of the classes are being redefined, wait
76 // Parallel constant pool merging leads to indeterminate constant pools.
77 void VM_RedefineClasses::lock_classes() {
78 MutexLocker ml(RedefineClasses_lock);
79 bool has_redefined;
80 do {
81 has_redefined = false;
82 // Go through classes each time until none are being redefined.
83 for (int i = 0; i < _class_count; i++) {
84 if (get_ik(_class_defs[i].klass)->is_being_redefined()) {
85 RedefineClasses_lock->wait();
86 has_redefined = true;
87 break; // for loop
88 }
89 }
90 } while (has_redefined);
91 for (int i = 0; i < _class_count; i++) {
92 get_ik(_class_defs[i].klass)->set_is_being_redefined(true);
93 }
94 RedefineClasses_lock->notify_all();
95 }
96
97 void VM_RedefineClasses::unlock_classes() {
98 MutexLocker ml(RedefineClasses_lock);
99 for (int i = 0; i < _class_count; i++) {
100 assert(get_ik(_class_defs[i].klass)->is_being_redefined(),
101 "should be being redefined to get here");
102 get_ik(_class_defs[i].klass)->set_is_being_redefined(false);
103 }
104 RedefineClasses_lock->notify_all();
105 }
106
70 bool VM_RedefineClasses::doit_prologue() { 107 bool VM_RedefineClasses::doit_prologue() {
71 if (_class_count == 0) { 108 if (_class_count == 0) {
72 _res = JVMTI_ERROR_NONE; 109 _res = JVMTI_ERROR_NONE;
73 return false; 110 return false;
74 } 111 }
87 } 124 }
88 if (_class_defs[i].class_bytes == NULL) { 125 if (_class_defs[i].class_bytes == NULL) {
89 _res = JVMTI_ERROR_NULL_POINTER; 126 _res = JVMTI_ERROR_NULL_POINTER;
90 return false; 127 return false;
91 } 128 }
129
130 oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
131 // classes for primitives and arrays cannot be redefined
132 // check here so following code can assume these classes are InstanceKlass
133 if (!is_modifiable_class(mirror)) {
134 _res = JVMTI_ERROR_UNMODIFIABLE_CLASS;
135 return false;
136 }
92 } 137 }
93 138
94 // Start timer after all the sanity checks; not quite accurate, but 139 // Start timer after all the sanity checks; not quite accurate, but
95 // better than adding a bunch of stop() calls. 140 // better than adding a bunch of stop() calls.
96 RC_TIMER_START(_timer_vm_op_prologue); 141 RC_TIMER_START(_timer_vm_op_prologue);
97 142
143 lock_classes();
98 // We first load new class versions in the prologue, because somewhere down the 144 // We first load new class versions in the prologue, because somewhere down the
99 // call chain it is required that the current thread is a Java thread. 145 // call chain it is required that the current thread is a Java thread.
100 _res = load_new_class_versions(Thread::current()); 146 _res = load_new_class_versions(Thread::current());
101 if (_res != JVMTI_ERROR_NONE) { 147 if (_res != JVMTI_ERROR_NONE) {
102 // free any successfully created classes, since none are redefined 148 // free any successfully created classes, since none are redefined
109 } 155 }
110 } 156 }
111 // Free os::malloc allocated memory in load_new_class_version. 157 // Free os::malloc allocated memory in load_new_class_version.
112 os::free(_scratch_classes); 158 os::free(_scratch_classes);
113 RC_TIMER_STOP(_timer_vm_op_prologue); 159 RC_TIMER_STOP(_timer_vm_op_prologue);
160 unlock_classes();
114 return false; 161 return false;
115 } 162 }
116 163
117 RC_TIMER_STOP(_timer_vm_op_prologue); 164 RC_TIMER_STOP(_timer_vm_op_prologue);
118 return true; 165 return true;
168 } 215 }
169 #endif 216 #endif
170 } 217 }
171 218
172 void VM_RedefineClasses::doit_epilogue() { 219 void VM_RedefineClasses::doit_epilogue() {
220 unlock_classes();
221
173 // Free os::malloc allocated memory. 222 // Free os::malloc allocated memory.
174 os::free(_scratch_classes); 223 os::free(_scratch_classes);
175 224
176 // Reset the_class_oop to null for error printing. 225 // Reset the_class_oop to null for error printing.
177 _the_class_oop = NULL; 226 _the_class_oop = NULL;
959 for (int i = 0; i < _class_count; i++) { 1008 for (int i = 0; i < _class_count; i++) {
960 // Create HandleMark so that any handles created while loading new class 1009 // Create HandleMark so that any handles created while loading new class
961 // versions are deleted. Constant pools are deallocated while merging 1010 // versions are deleted. Constant pools are deallocated while merging
962 // constant pools 1011 // constant pools
963 HandleMark hm(THREAD); 1012 HandleMark hm(THREAD);
964 1013 instanceKlassHandle the_class(THREAD, get_ik(_class_defs[i].klass));
965 oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
966 // classes for primitives cannot be redefined
967 if (!is_modifiable_class(mirror)) {
968 return JVMTI_ERROR_UNMODIFIABLE_CLASS;
969 }
970 Klass* the_class_oop = java_lang_Class::as_Klass(mirror);
971 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
972 Symbol* the_class_sym = the_class->name(); 1014 Symbol* the_class_sym = the_class->name();
973 1015
974 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark 1016 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
975 RC_TRACE_WITH_THREAD(0x00000001, THREAD, 1017 RC_TRACE_WITH_THREAD(0x00000001, THREAD,
976 ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)", 1018 ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)",
3853 Klass* scratch_class_oop, TRAPS) { 3895 Klass* scratch_class_oop, TRAPS) {
3854 3896
3855 HandleMark hm(THREAD); // make sure handles from this call are freed 3897 HandleMark hm(THREAD); // make sure handles from this call are freed
3856 RC_TIMER_START(_timer_rsc_phase1); 3898 RC_TIMER_START(_timer_rsc_phase1);
3857 3899
3858 instanceKlassHandle scratch_class(scratch_class_oop); 3900 instanceKlassHandle scratch_class(THREAD, scratch_class_oop);
3859 3901 instanceKlassHandle the_class(THREAD, get_ik(the_jclass));
3860 oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass);
3861 Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror);
3862 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
3863 3902
3864 // Remove all breakpoints in methods of this class 3903 // Remove all breakpoints in methods of this class
3865 JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); 3904 JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
3866 jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); 3905 jvmti_breakpoints.clearall_in_class_at_safepoint(the_class());
3867 3906
3868 // Deoptimize all compiled code that depends on this class 3907 // Deoptimize all compiled code that depends on this class
3869 flush_dependent_code(the_class, THREAD); 3908 flush_dependent_code(the_class, THREAD);
3870 3909
3871 _old_methods = the_class->methods(); 3910 _old_methods = the_class->methods();
3872 _new_methods = scratch_class->methods(); 3911 _new_methods = scratch_class->methods();
3873 _the_class_oop = the_class_oop; 3912 _the_class_oop = the_class();
3874 compute_added_deleted_matching_methods(); 3913 compute_added_deleted_matching_methods();
3875 update_jmethod_ids(); 3914 update_jmethod_ids();
3876 3915
3877 // Attach new constant pool to the original klass. The original 3916 // Attach new constant pool to the original klass. The original
3878 // klass still refers to the old constant pool (for now). 3917 // klass still refers to the old constant pool (for now).
4092 4131
4093 // RC_TRACE macro has an embedded ResourceMark 4132 // RC_TRACE macro has an embedded ResourceMark
4094 RC_TRACE_WITH_THREAD(0x00000001, THREAD, 4133 RC_TRACE_WITH_THREAD(0x00000001, THREAD,
4095 ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)", 4134 ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
4096 the_class->external_name(), 4135 the_class->external_name(),
4097 java_lang_Class::classRedefinedCount(the_class_mirror), 4136 java_lang_Class::classRedefinedCount(the_class->java_mirror()),
4098 os::available_memory() >> 10)); 4137 os::available_memory() >> 10));
4099 4138
4100 { 4139 {
4101 ResourceMark rm(THREAD); 4140 ResourceMark rm(THREAD);
4102 Events::log_redefinition(THREAD, "redefined class name=%s, count=%d", 4141 Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
4103 the_class->external_name(), 4142 the_class->external_name(),
4104 java_lang_Class::classRedefinedCount(the_class_mirror)); 4143 java_lang_Class::classRedefinedCount(the_class->java_mirror()));
4105 4144
4106 } 4145 }
4107 RC_TIMER_STOP(_timer_rsc_phase2); 4146 RC_TIMER_STOP(_timer_rsc_phase2);
4108 } // end redefine_single_class() 4147 } // end redefine_single_class()
4109 4148

mercurial