224 log_trace(redefine, class, obsolete, metadata)("calling check_class"); 225 CheckClass check_class(thread); 226 ClassLoaderDataGraph::classes_do(&check_class); 227 #ifdef PRODUCT 228 } 229 #endif 230 } 231 232 void VM_RedefineClasses::doit_epilogue() { 233 unlock_classes(); 234 235 // Free os::malloc allocated memory. 236 os::free(_scratch_classes); 237 238 // Reset the_class to null for error printing. 239 _the_class = NULL; 240 241 if (log_is_enabled(Info, redefine, class, timer)) { 242 // Used to have separate timers for "doit" and "all", but the timer 243 // overhead skewed the measurements. 244 jlong doit_time = _timer_rsc_phase1.milliseconds() + 245 _timer_rsc_phase2.milliseconds(); 246 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time; 247 248 log_info(redefine, class, timer) 249 ("vm_op: all=" UINT64_FORMAT " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, 250 all_time, _timer_vm_op_prologue.milliseconds(), doit_time); 251 log_info(redefine, class, timer) 252 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT, 253 _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()); 254 } 255 } 256 257 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) { 258 // classes for primitives cannot be redefined 259 if (java_lang_Class::is_primitive(klass_mirror)) { 260 return false; 261 } 262 Klass* k = java_lang_Class::as_Klass(klass_mirror); 263 // classes for arrays cannot be redefined 264 if (k == NULL || !k->is_instance_klass()) { 265 return false; 266 } 267 268 // Cannot redefine or retransform an anonymous class. 269 if (InstanceKlass::cast(k)->is_anonymous()) { 270 return false; 271 } 272 return true; 273 } 1808 case Bytecodes::_new : // fall through 1809 case Bytecodes::_putfield : // fall through 1810 case Bytecodes::_putstatic : 1811 { 1812 address p = bcp + 1; 1813 int cp_index = Bytes::get_Java_u2(p); 1814 int new_index = find_new_index(cp_index); 1815 if (new_index != 0) { 1816 // the original index is mapped so update w/ new value 1817 log_trace(redefine, class, constantpool) 1818 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),p2i(bcp), cp_index, new_index); 1819 // Rewriter::rewrite_method() uses put_native_u2() in this 1820 // situation because it is reusing the constant pool index 1821 // location for a native index into the ConstantPoolCache. 1822 // Since we are updating the constant pool index prior to 1823 // verification and ConstantPoolCache initialization, we 1824 // need to keep the new index in Java byte order. 1825 Bytes::put_Java_u2(p, new_index); 1826 } 1827 } break; 1828 } 1829 } // end for each bytecode 1830 1831 // We also need to rewrite the parameter name indexes, if there is 1832 // method parameter data present 1833 if(method->has_method_parameters()) { 1834 const int len = method->method_parameters_length(); 1835 MethodParametersElement* elem = method->method_parameters_start(); 1836 1837 for (int i = 0; i < len; i++) { 1838 const u2 cp_index = elem[i].name_cp_index; 1839 const u2 new_cp_index = find_new_index(cp_index); 1840 if (new_cp_index != 0) { 1841 elem[i].name_cp_index = new_cp_index; 1842 } 1843 } 1844 } 1845 } // end rewrite_cp_refs_in_method() 1846 1847 | 224 log_trace(redefine, class, obsolete, metadata)("calling check_class"); 225 CheckClass check_class(thread); 226 ClassLoaderDataGraph::classes_do(&check_class); 227 #ifdef PRODUCT 228 } 229 #endif 230 } 231 232 void VM_RedefineClasses::doit_epilogue() { 233 unlock_classes(); 234 235 // Free os::malloc allocated memory. 236 os::free(_scratch_classes); 237 238 // Reset the_class to null for error printing. 239 _the_class = NULL; 240 241 if (log_is_enabled(Info, redefine, class, timer)) { 242 // Used to have separate timers for "doit" and "all", but the timer 243 // overhead skewed the measurements. 244 julong doit_time = _timer_rsc_phase1.milliseconds() + 245 _timer_rsc_phase2.milliseconds(); 246 julong all_time = _timer_vm_op_prologue.milliseconds() + doit_time; 247 248 log_info(redefine, class, timer) 249 ("vm_op: all=" JULONG_FORMAT " prologue=" JULONG_FORMAT " doit=" JULONG_FORMAT, 250 all_time, (julong)_timer_vm_op_prologue.milliseconds(), doit_time); 251 log_info(redefine, class, timer) 252 ("redefine_single_class: phase1=" JULONG_FORMAT " phase2=" JULONG_FORMAT, 253 (julong)_timer_rsc_phase1.milliseconds(), (julong)_timer_rsc_phase2.milliseconds()); 254 } 255 } 256 257 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) { 258 // classes for primitives cannot be redefined 259 if (java_lang_Class::is_primitive(klass_mirror)) { 260 return false; 261 } 262 Klass* k = java_lang_Class::as_Klass(klass_mirror); 263 // classes for arrays cannot be redefined 264 if (k == NULL || !k->is_instance_klass()) { 265 return false; 266 } 267 268 // Cannot redefine or retransform an anonymous class. 269 if (InstanceKlass::cast(k)->is_anonymous()) { 270 return false; 271 } 272 return true; 273 } 1808 case Bytecodes::_new : // fall through 1809 case Bytecodes::_putfield : // fall through 1810 case Bytecodes::_putstatic : 1811 { 1812 address p = bcp + 1; 1813 int cp_index = Bytes::get_Java_u2(p); 1814 int new_index = find_new_index(cp_index); 1815 if (new_index != 0) { 1816 // the original index is mapped so update w/ new value 1817 log_trace(redefine, class, constantpool) 1818 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c),p2i(bcp), cp_index, new_index); 1819 // Rewriter::rewrite_method() uses put_native_u2() in this 1820 // situation because it is reusing the constant pool index 1821 // location for a native index into the ConstantPoolCache. 1822 // Since we are updating the constant pool index prior to 1823 // verification and ConstantPoolCache initialization, we 1824 // need to keep the new index in Java byte order. 1825 Bytes::put_Java_u2(p, new_index); 1826 } 1827 } break; 1828 default: 1829 break; 1830 } 1831 } // end for each bytecode 1832 1833 // We also need to rewrite the parameter name indexes, if there is 1834 // method parameter data present 1835 if(method->has_method_parameters()) { 1836 const int len = method->method_parameters_length(); 1837 MethodParametersElement* elem = method->method_parameters_start(); 1838 1839 for (int i = 0; i < len; i++) { 1840 const u2 cp_index = elem[i].name_cp_index; 1841 const u2 new_cp_index = find_new_index(cp_index); 1842 if (new_cp_index != 0) { 1843 elem[i].name_cp_index = new_cp_index; 1844 } 1845 } 1846 } 1847 } // end rewrite_cp_refs_in_method() 1848 1849 |