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 |
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 |