src/share/vm/prims/jvmtiRedefineClasses.cpp

Print this page




2809     // been added as a previous version. The new_cp doesn't have any
2810     // cached references to old methods so it doesn't need to be
2811     // updated. We can simply start with the previous version(s) in
2812     // that case.
2813     constantPoolHandle other_cp;
2814     ConstantPoolCache* cp_cache;
2815 
2816     if (ik != _the_class_oop) {
2817       // this klass' constant pool cache may need adjustment
2818       other_cp = constantPoolHandle(ik->constants());
2819       cp_cache = other_cp->cache();
2820       if (cp_cache != NULL) {
2821         cp_cache->adjust_method_entries(_matching_old_methods,
2822                                         _matching_new_methods,
2823                                         _matching_methods_length,
2824                                         &trace_name_printed);
2825       }
2826     }
2827 
2828     // the previous versions' constant pool caches may need adjustment
2829     PreviousVersionWalker pvw(_thread, ik);
2830     for (PreviousVersionNode * pv_node = pvw.next_previous_version();
2831          pv_node != NULL; pv_node = pvw.next_previous_version()) {
2832       other_cp = pv_node->prev_constant_pool();
2833       cp_cache = other_cp->cache();
2834       if (cp_cache != NULL) {
2835         cp_cache->adjust_method_entries(_matching_old_methods,
2836                                         _matching_new_methods,
2837                                         _matching_methods_length,
2838                                         &trace_name_printed);
2839       }
2840     }
2841   }
2842 }
2843 
2844 void VM_RedefineClasses::update_jmethod_ids() {
2845   for (int j = 0; j < _matching_methods_length; ++j) {
2846     Method* old_method = _matching_old_methods[j];
2847     jmethodID jmid = old_method->find_jmethod_id_or_null();
2848     if (jmid != NULL) {
2849       // There is a jmethodID, change it to point to the new method
2850       methodHandle new_method_h(_matching_new_methods[j]);
2851       Method::change_method_associated_with_jmethod_id(jmid, new_method_h());
2852       assert(Method::resolve_jmethod_id(jmid) == _matching_new_methods[j],
2853              "should be replaced");


3453 
3454   swap_annotations(the_class, scratch_class);
3455 
3456   // Replace minor version number of class file
3457   u2 old_minor_version = the_class->minor_version();
3458   the_class->set_minor_version(scratch_class->minor_version());
3459   scratch_class->set_minor_version(old_minor_version);
3460 
3461   // Replace major version number of class file
3462   u2 old_major_version = the_class->major_version();
3463   the_class->set_major_version(scratch_class->major_version());
3464   scratch_class->set_major_version(old_major_version);
3465 
3466   // Replace CP indexes for class and name+type of enclosing method
3467   u2 old_class_idx  = the_class->enclosing_method_class_index();
3468   u2 old_method_idx = the_class->enclosing_method_method_index();
3469   the_class->set_enclosing_method_indices(
3470     scratch_class->enclosing_method_class_index(),
3471     scratch_class->enclosing_method_method_index());
3472   scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx);


3473 
3474   // keep track of previous versions of this class
3475   the_class->add_previous_version(scratch_class, &emcp_methods,
3476     emcp_method_count);
3477 
3478   RC_TIMER_STOP(_timer_rsc_phase1);
3479   RC_TIMER_START(_timer_rsc_phase2);
3480 
3481   // Adjust constantpool caches and vtables for all classes
3482   // that reference methods of the evolved class.
3483   AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
3484   ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
3485 
3486   // JSR-292 support
3487   MemberNameTable* mnt = the_class->member_names();
3488   if (mnt != NULL) {
3489     bool trace_name_printed = false;
3490     mnt->adjust_method_entries(_matching_old_methods,
3491                                _matching_new_methods,
3492                                _matching_methods_length,




2809     // been added as a previous version. The new_cp doesn't have any
2810     // cached references to old methods so it doesn't need to be
2811     // updated. We can simply start with the previous version(s) in
2812     // that case.
2813     constantPoolHandle other_cp;
2814     ConstantPoolCache* cp_cache;
2815 
2816     if (ik != _the_class_oop) {
2817       // this klass' constant pool cache may need adjustment
2818       other_cp = constantPoolHandle(ik->constants());
2819       cp_cache = other_cp->cache();
2820       if (cp_cache != NULL) {
2821         cp_cache->adjust_method_entries(_matching_old_methods,
2822                                         _matching_new_methods,
2823                                         _matching_methods_length,
2824                                         &trace_name_printed);
2825       }
2826     }
2827 
2828     // the previous versions' constant pool caches may need adjustment
2829     for (InstanceKlass* pv_node = ik->previous_versions();
2830          pv_node != NULL;
2831          pv_node = pv_node->previous_versions()) {
2832       cp_cache = pv_node->constants()->cache();

2833       if (cp_cache != NULL) {
2834         cp_cache->adjust_method_entries(_matching_old_methods,
2835                                         _matching_new_methods,
2836                                         _matching_methods_length,
2837                                         &trace_name_printed);
2838       }
2839     }
2840   }
2841 }
2842 
2843 void VM_RedefineClasses::update_jmethod_ids() {
2844   for (int j = 0; j < _matching_methods_length; ++j) {
2845     Method* old_method = _matching_old_methods[j];
2846     jmethodID jmid = old_method->find_jmethod_id_or_null();
2847     if (jmid != NULL) {
2848       // There is a jmethodID, change it to point to the new method
2849       methodHandle new_method_h(_matching_new_methods[j]);
2850       Method::change_method_associated_with_jmethod_id(jmid, new_method_h());
2851       assert(Method::resolve_jmethod_id(jmid) == _matching_new_methods[j],
2852              "should be replaced");


3452 
3453   swap_annotations(the_class, scratch_class);
3454 
3455   // Replace minor version number of class file
3456   u2 old_minor_version = the_class->minor_version();
3457   the_class->set_minor_version(scratch_class->minor_version());
3458   scratch_class->set_minor_version(old_minor_version);
3459 
3460   // Replace major version number of class file
3461   u2 old_major_version = the_class->major_version();
3462   the_class->set_major_version(scratch_class->major_version());
3463   scratch_class->set_major_version(old_major_version);
3464 
3465   // Replace CP indexes for class and name+type of enclosing method
3466   u2 old_class_idx  = the_class->enclosing_method_class_index();
3467   u2 old_method_idx = the_class->enclosing_method_method_index();
3468   the_class->set_enclosing_method_indices(
3469     scratch_class->enclosing_method_class_index(),
3470     scratch_class->enclosing_method_method_index());
3471   scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx);
3472 
3473   the_class->set_has_been_redefined();
3474 
3475   // keep track of previous versions of this class
3476   the_class->add_previous_version(scratch_class, &emcp_methods,
3477     emcp_method_count);
3478 
3479   RC_TIMER_STOP(_timer_rsc_phase1);
3480   RC_TIMER_START(_timer_rsc_phase2);
3481 
3482   // Adjust constantpool caches and vtables for all classes
3483   // that reference methods of the evolved class.
3484   AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD);
3485   ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable);
3486 
3487   // JSR-292 support
3488   MemberNameTable* mnt = the_class->member_names();
3489   if (mnt != NULL) {
3490     bool trace_name_printed = false;
3491     mnt->adjust_method_entries(_matching_old_methods,
3492                                _matching_new_methods,
3493                                _matching_methods_length,