Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiRedefineClasses.cpp @ 8031:927a311d00f9
8007320: NPG: move method annotations
Summary: allocate method annotations and attach to ConstMethod if present
Reviewed-by: dcubed, jiangli, sspitsyn, iklam
author | coleenp |
---|---|
date | Mon, 11 Feb 2013 14:06:22 -0500 |
parents | 8d9fc28831cc |
children | 56c364daccc3 |
comparison
equal
deleted
inserted
replaced
8030:f989aff6946f | 8031:927a311d00f9 |
---|---|
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 return new_ref_i; | 491 return new_ref_i; |
492 } // end find_or_append_indirect_entry() | 492 } // end find_or_append_indirect_entry() |
493 | |
494 | |
495 void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class, TRAPS) { | |
496 AnnotationArray* save; | |
497 | |
498 Annotations* sca = scratch_class->annotations(); | |
499 if (sca == NULL) return; | |
500 | |
501 save = sca->get_method_annotations_of(i); | |
502 sca->set_method_annotations_of(scratch_class, i, sca->get_method_annotations_of(j), CHECK); | |
503 sca->set_method_annotations_of(scratch_class, j, save, CHECK); | |
504 | |
505 save = sca->get_method_parameter_annotations_of(i); | |
506 sca->set_method_parameter_annotations_of(scratch_class, i, sca->get_method_parameter_annotations_of(j), CHECK); | |
507 sca->set_method_parameter_annotations_of(scratch_class, j, save, CHECK); | |
508 | |
509 save = sca->get_method_default_annotations_of(i); | |
510 sca->set_method_default_annotations_of(scratch_class, i, sca->get_method_default_annotations_of(j), CHECK); | |
511 sca->set_method_default_annotations_of(scratch_class, j, save, CHECK); | |
512 } | |
513 | 493 |
514 | 494 |
515 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( | 495 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( |
516 instanceKlassHandle the_class, | 496 instanceKlassHandle the_class, |
517 instanceKlassHandle scratch_class) { | 497 instanceKlassHandle scratch_class) { |
691 if (idnum_owner != NULL) { | 671 if (idnum_owner != NULL) { |
692 // There is already a method assigned this idnum -- switch them | 672 // There is already a method assigned this idnum -- switch them |
693 idnum_owner->set_method_idnum(new_num); | 673 idnum_owner->set_method_idnum(new_num); |
694 } | 674 } |
695 k_new_method->set_method_idnum(old_num); | 675 k_new_method->set_method_idnum(old_num); |
696 swap_all_method_annotations(old_num, new_num, scratch_class, thread); | 676 if (thread->has_pending_exception()) { |
697 if (thread->has_pending_exception()) { | 677 return JVMTI_ERROR_OUT_OF_MEMORY; |
698 return JVMTI_ERROR_OUT_OF_MEMORY; | 678 } |
699 } | |
700 } | 679 } |
701 } | 680 } |
702 RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]", | 681 RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]", |
703 k_new_method->name_and_sig_as_C_string(), ni, | 682 k_new_method->name_and_sig_as_C_string(), ni, |
704 k_old_method->name_and_sig_as_C_string(), oi)); | 683 k_old_method->name_and_sig_as_C_string(), oi)); |
727 if (idnum_owner != NULL) { | 706 if (idnum_owner != NULL) { |
728 // There is already a method assigned this idnum -- switch them | 707 // There is already a method assigned this idnum -- switch them |
729 idnum_owner->set_method_idnum(new_num); | 708 idnum_owner->set_method_idnum(new_num); |
730 } | 709 } |
731 k_new_method->set_method_idnum(num); | 710 k_new_method->set_method_idnum(num); |
732 swap_all_method_annotations(new_num, num, scratch_class, thread); | |
733 if (thread->has_pending_exception()) { | 711 if (thread->has_pending_exception()) { |
734 return JVMTI_ERROR_OUT_OF_MEMORY; | 712 return JVMTI_ERROR_OUT_OF_MEMORY; |
735 } | 713 } |
736 } | 714 } |
737 RC_TRACE(0x00008000, ("Method added: new: %s [%d]", | 715 RC_TRACE(0x00008000, ("Method added: new: %s [%d]", |
1893 | 1871 |
1894 // Rewrite constant pool references in a fields_annotations field. | 1872 // Rewrite constant pool references in a fields_annotations field. |
1895 bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations( | 1873 bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations( |
1896 instanceKlassHandle scratch_class, TRAPS) { | 1874 instanceKlassHandle scratch_class, TRAPS) { |
1897 | 1875 |
1898 Annotations* sca = scratch_class->annotations(); | 1876 Array<AnnotationArray*>* fields_annotations = scratch_class->fields_annotations(); |
1899 if (sca == NULL) return true; | |
1900 | |
1901 Array<AnnotationArray*>* fields_annotations = sca->fields_annotations(); | |
1902 | 1877 |
1903 if (fields_annotations == NULL || fields_annotations->length() == 0) { | 1878 if (fields_annotations == NULL || fields_annotations->length() == 0) { |
1904 // no fields_annotations so nothing to do | 1879 // no fields_annotations so nothing to do |
1905 return true; | 1880 return true; |
1906 } | 1881 } |
1931 | 1906 |
1932 // Rewrite constant pool references in a methods_annotations field. | 1907 // Rewrite constant pool references in a methods_annotations field. |
1933 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations( | 1908 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations( |
1934 instanceKlassHandle scratch_class, TRAPS) { | 1909 instanceKlassHandle scratch_class, TRAPS) { |
1935 | 1910 |
1936 Annotations* sca = scratch_class->annotations(); | 1911 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
1937 if (sca == NULL) return true; | 1912 Method* m = scratch_class->methods()->at(i); |
1938 | 1913 AnnotationArray* method_annotations = m->constMethod()->method_annotations(); |
1939 Array<AnnotationArray*>* methods_annotations = sca->methods_annotations(); | 1914 |
1940 | |
1941 if (methods_annotations == NULL || methods_annotations->length() == 0) { | |
1942 // no methods_annotations so nothing to do | |
1943 return true; | |
1944 } | |
1945 | |
1946 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1947 ("methods_annotations length=%d", methods_annotations->length())); | |
1948 | |
1949 for (int i = 0; i < methods_annotations->length(); i++) { | |
1950 AnnotationArray* method_annotations = methods_annotations->at(i); | |
1951 if (method_annotations == NULL || method_annotations->length() == 0) { | 1915 if (method_annotations == NULL || method_annotations->length() == 0) { |
1952 // this method does not have any annotations so skip it | 1916 // this method does not have any annotations so skip it |
1953 continue; | 1917 continue; |
1954 } | 1918 } |
1955 | 1919 |
1981 // } | 1945 // } |
1982 // | 1946 // |
1983 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations( | 1947 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations( |
1984 instanceKlassHandle scratch_class, TRAPS) { | 1948 instanceKlassHandle scratch_class, TRAPS) { |
1985 | 1949 |
1986 Annotations* sca = scratch_class->annotations(); | 1950 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
1987 if (sca == NULL) return true; | 1951 Method* m = scratch_class->methods()->at(i); |
1988 | 1952 AnnotationArray* method_parameter_annotations = m->constMethod()->parameter_annotations(); |
1989 Array<AnnotationArray*>* methods_parameter_annotations = | |
1990 sca->methods_parameter_annotations(); | |
1991 | |
1992 if (methods_parameter_annotations == NULL | |
1993 || methods_parameter_annotations->length() == 0) { | |
1994 // no methods_parameter_annotations so nothing to do | |
1995 return true; | |
1996 } | |
1997 | |
1998 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1999 ("methods_parameter_annotations length=%d", | |
2000 methods_parameter_annotations->length())); | |
2001 | |
2002 for (int i = 0; i < methods_parameter_annotations->length(); i++) { | |
2003 AnnotationArray* method_parameter_annotations = methods_parameter_annotations->at(i); | |
2004 if (method_parameter_annotations == NULL | 1953 if (method_parameter_annotations == NULL |
2005 || method_parameter_annotations->length() == 0) { | 1954 || method_parameter_annotations->length() == 0) { |
2006 // this method does not have any parameter annotations so skip it | 1955 // this method does not have any parameter annotations so skip it |
2007 continue; | 1956 continue; |
2008 } | 1957 } |
2048 // } | 1997 // } |
2049 // | 1998 // |
2050 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations( | 1999 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations( |
2051 instanceKlassHandle scratch_class, TRAPS) { | 2000 instanceKlassHandle scratch_class, TRAPS) { |
2052 | 2001 |
2053 Annotations* sca = scratch_class->annotations(); | 2002 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
2054 if (sca == NULL) return true; | 2003 Method* m = scratch_class->methods()->at(i); |
2055 | 2004 AnnotationArray* method_default_annotations = m->constMethod()->default_annotations(); |
2056 Array<AnnotationArray*>* methods_default_annotations = | |
2057 sca->methods_default_annotations(); | |
2058 | |
2059 if (methods_default_annotations == NULL | |
2060 || methods_default_annotations->length() == 0) { | |
2061 // no methods_default_annotations so nothing to do | |
2062 return true; | |
2063 } | |
2064 | |
2065 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2066 ("methods_default_annotations length=%d", | |
2067 methods_default_annotations->length())); | |
2068 | |
2069 for (int i = 0; i < methods_default_annotations->length(); i++) { | |
2070 AnnotationArray* method_default_annotations = methods_default_annotations->at(i); | |
2071 if (method_default_annotations == NULL | 2005 if (method_default_annotations == NULL |
2072 || method_default_annotations->length() == 0) { | 2006 || method_default_annotations->length() == 0) { |
2073 // this method does not have any default annotations so skip it | 2007 // this method does not have any default annotations so skip it |
2074 continue; | 2008 continue; |
2075 } | 2009 } |
3070 assert(_matching_methods_length + _deleted_methods_length == _old_methods->length(), "sanity"); | 3004 assert(_matching_methods_length + _deleted_methods_length == _old_methods->length(), "sanity"); |
3071 assert(_matching_methods_length + _added_methods_length == _new_methods->length(), "sanity"); | 3005 assert(_matching_methods_length + _added_methods_length == _new_methods->length(), "sanity"); |
3072 } | 3006 } |
3073 | 3007 |
3074 | 3008 |
3009 void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class, | |
3010 instanceKlassHandle scratch_class) { | |
3011 // Since there is currently no rewriting of type annotations indexes | |
3012 // into the CP, we null out type annotations on scratch_class before | |
3013 // we swap annotations with the_class rather than facing the | |
3014 // possibility of shipping annotations with broken indexes to | |
3015 // Java-land. | |
3016 ClassLoaderData* loader_data = scratch_class->class_loader_data(); | |
3017 AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations(); | |
3018 if (new_class_type_annotations != NULL) { | |
3019 MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations); | |
3020 scratch_class->annotations()->set_class_type_annotations(NULL); | |
3021 } | |
3022 Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations(); | |
3023 if (new_field_type_annotations != NULL) { | |
3024 Annotations::free_contents(loader_data, new_field_type_annotations); | |
3025 scratch_class->annotations()->set_fields_type_annotations(NULL); | |
3026 } | |
3027 | |
3028 // Swap annotation fields values | |
3029 Annotations* old_annotations = the_class->annotations(); | |
3030 the_class->set_annotations(scratch_class->annotations()); | |
3031 scratch_class->set_annotations(old_annotations); | |
3032 } | |
3033 | |
3075 | 3034 |
3076 // Install the redefinition of a class: | 3035 // Install the redefinition of a class: |
3077 // - house keeping (flushing breakpoints and caches, deoptimizing | 3036 // - house keeping (flushing breakpoints and caches, deoptimizing |
3078 // dependent compiled code) | 3037 // dependent compiled code) |
3079 // - replacing parts in the_class with parts from scratch_class | 3038 // - replacing parts in the_class with parts from scratch_class |
3280 flags.clear_has_localvariable_table(); | 3239 flags.clear_has_localvariable_table(); |
3281 } | 3240 } |
3282 the_class->set_access_flags(flags); | 3241 the_class->set_access_flags(flags); |
3283 } | 3242 } |
3284 | 3243 |
3285 // Since there is currently no rewriting of type annotations indexes | 3244 swap_annotations(the_class, scratch_class); |
3286 // into the CP, we null out type annotations on scratch_class before | |
3287 // we swap annotations with the_class rather than facing the | |
3288 // possibility of shipping annotations with broken indexes to | |
3289 // Java-land. | |
3290 Annotations* new_annotations = scratch_class->annotations(); | |
3291 if (new_annotations != NULL) { | |
3292 Annotations* new_type_annotations = new_annotations->type_annotations(); | |
3293 if (new_type_annotations != NULL) { | |
3294 MetadataFactory::free_metadata(scratch_class->class_loader_data(), new_type_annotations); | |
3295 new_annotations->set_type_annotations(NULL); | |
3296 } | |
3297 } | |
3298 // Swap annotation fields values | |
3299 Annotations* old_annotations = the_class->annotations(); | |
3300 the_class->set_annotations(scratch_class->annotations()); | |
3301 scratch_class->set_annotations(old_annotations); | |
3302 | 3245 |
3303 // Replace minor version number of class file | 3246 // Replace minor version number of class file |
3304 u2 old_minor_version = the_class->minor_version(); | 3247 u2 old_minor_version = the_class->minor_version(); |
3305 the_class->set_minor_version(scratch_class->minor_version()); | 3248 the_class->set_minor_version(scratch_class->minor_version()); |
3306 scratch_class->set_minor_version(old_minor_version); | 3249 scratch_class->set_minor_version(old_minor_version); |