src/share/vm/oops/methodOop.cpp

Print this page




1097   if (WizardMode) signature()->print_symbol_on(st);
1098 }
1099 
1100 
1101 extern "C" {
1102   static int method_compare(methodOop* a, methodOop* b) {
1103     return (*a)->name()->fast_compare((*b)->name());
1104   }
1105 
1106   // Prevent qsort from reordering a previous valid sort by
1107   // considering the address of the methodOops if two methods
1108   // would otherwise compare as equal.  Required to preserve
1109   // optimal access order in the shared archive.  Slower than
1110   // method_compare, only used for shared archive creation.
1111   static int method_compare_idempotent(methodOop* a, methodOop* b) {
1112     int i = method_compare(a, b);
1113     if (i != 0) return i;
1114     return ( a < b ? -1 : (a == b ? 0 : 1));
1115   }
1116 














1117   typedef int (*compareFn)(const void*, const void*);
1118 }
1119 
1120 
1121 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
1122 static void reorder_based_on_method_index(objArrayOop methods,
1123                                           objArrayOop annotations,
1124                                           GrowableArray<oop>* temp_array) {
1125   if (annotations == NULL) {
1126     return;
1127   }
1128 
1129   int length = methods->length();
1130   int i;
1131   // Copy to temp array
1132   temp_array->clear();
1133   for (i = 0; i < length; i++) {
1134     temp_array->append(annotations->obj_at(i));
1135   }
1136 


1149                                  objArrayOop methods_default_annotations,
1150                                  bool idempotent) {
1151   int length = methods->length();
1152   if (length > 1) {
1153     bool do_annotations = false;
1154     if (methods_annotations != NULL ||
1155         methods_parameter_annotations != NULL ||
1156         methods_default_annotations != NULL) {
1157       do_annotations = true;
1158     }
1159     if (do_annotations) {
1160       // Remember current method ordering so we can reorder annotations
1161       for (int i = 0; i < length; i++) {
1162         methodOop m = (methodOop) methods->obj_at(i);
1163         m->set_method_idnum(i);
1164       }
1165     }
1166 
1167     // Use a simple bubble sort for small number of methods since
1168     // qsort requires a functional pointer call for each comparison.
1169     if (UseCompressedOops || length < 8) {
1170       bool sorted = true;
1171       for (int i=length-1; i>0; i--) {
1172         for (int j=0; j<i; j++) {
1173           methodOop m1 = (methodOop)methods->obj_at(j);
1174           methodOop m2 = (methodOop)methods->obj_at(j+1);
1175           if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) {
1176             methods->obj_at_put(j, m2);
1177             methods->obj_at_put(j+1, m1);
1178             sorted = false;
1179           }
1180         }
1181         if (sorted) break;
1182           sorted = true;
1183       }
1184     } else {
1185       // XXX This doesn't work for UseCompressedOops because the compare fn
1186       // will have to decode the methodOop anyway making it not much faster
1187       // than above.
1188       compareFn compare = (compareFn) (idempotent ? method_compare_idempotent : method_compare);
1189       qsort(methods->base(), length, heapOopSize, compare);
1190     }
1191 
1192     // Sort annotations if necessary
1193     assert(methods_annotations == NULL           || methods_annotations->length() == methods->length(), "");
1194     assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
1195     assert(methods_default_annotations == NULL   || methods_default_annotations->length() == methods->length(), "");
1196     if (do_annotations) {
1197       ResourceMark rm;
1198       // Allocate temporary storage
1199       GrowableArray<oop>* temp_array = new GrowableArray<oop>(length);
1200       reorder_based_on_method_index(methods, methods_annotations, temp_array);
1201       reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
1202       reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
1203     }
1204 
1205     // Reset method ordering
1206     for (int i = 0; i < length; i++) {
1207       methodOop m = (methodOop) methods->obj_at(i);
1208       m->set_method_idnum(i);




1097   if (WizardMode) signature()->print_symbol_on(st);
1098 }
1099 
1100 
1101 extern "C" {
1102   static int method_compare(methodOop* a, methodOop* b) {
1103     return (*a)->name()->fast_compare((*b)->name());
1104   }
1105 
1106   // Prevent qsort from reordering a previous valid sort by
1107   // considering the address of the methodOops if two methods
1108   // would otherwise compare as equal.  Required to preserve
1109   // optimal access order in the shared archive.  Slower than
1110   // method_compare, only used for shared archive creation.
1111   static int method_compare_idempotent(methodOop* a, methodOop* b) {
1112     int i = method_compare(a, b);
1113     if (i != 0) return i;
1114     return ( a < b ? -1 : (a == b ? 0 : 1));
1115   }
1116 
1117   // We implement special compare versions for narrow oops to avoid
1118   // testing for UseCompressedOops on every comparison.
1119   static int method_compare_narrow(narrowOop* a, narrowOop* b) {
1120     methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a);
1121     methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b);
1122     return m->name()->fast_compare(n->name());
1123   }
1124 
1125   static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) {
1126     int i = method_compare_narrow(a, b);
1127     if (i != 0) return i;
1128     return ( a < b ? -1 : (a == b ? 0 : 1));
1129   }
1130 
1131   typedef int (*compareFn)(const void*, const void*);
1132 }
1133 
1134 
1135 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
1136 static void reorder_based_on_method_index(objArrayOop methods,
1137                                           objArrayOop annotations,
1138                                           GrowableArray<oop>* temp_array) {
1139   if (annotations == NULL) {
1140     return;
1141   }
1142 
1143   int length = methods->length();
1144   int i;
1145   // Copy to temp array
1146   temp_array->clear();
1147   for (i = 0; i < length; i++) {
1148     temp_array->append(annotations->obj_at(i));
1149   }
1150 


1163                                  objArrayOop methods_default_annotations,
1164                                  bool idempotent) {
1165   int length = methods->length();
1166   if (length > 1) {
1167     bool do_annotations = false;
1168     if (methods_annotations != NULL ||
1169         methods_parameter_annotations != NULL ||
1170         methods_default_annotations != NULL) {
1171       do_annotations = true;
1172     }
1173     if (do_annotations) {
1174       // Remember current method ordering so we can reorder annotations
1175       for (int i = 0; i < length; i++) {
1176         methodOop m = (methodOop) methods->obj_at(i);
1177         m->set_method_idnum(i);
1178       }
1179     }
1180 
1181     // Use a simple bubble sort for small number of methods since
1182     // qsort requires a functional pointer call for each comparison.
1183     if (length < 8) {
1184       bool sorted = true;
1185       for (int i=length-1; i>0; i--) {
1186         for (int j=0; j<i; j++) {
1187           methodOop m1 = (methodOop)methods->obj_at(j);
1188           methodOop m2 = (methodOop)methods->obj_at(j+1);
1189           if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) {
1190             methods->obj_at_put(j, m2);
1191             methods->obj_at_put(j+1, m1);
1192             sorted = false;
1193           }
1194         }
1195         if (sorted) break;
1196           sorted = true;
1197       }
1198     } else {
1199       compareFn compare = 
1200         (UseCompressedOops ?
1201          (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow):
1202          (compareFn) (idempotent ? method_compare_idempotent : method_compare));
1203       qsort(methods->base(), length, heapOopSize, compare);
1204     }
1205 
1206     // Sort annotations if necessary
1207     assert(methods_annotations == NULL           || methods_annotations->length() == methods->length(), "");
1208     assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
1209     assert(methods_default_annotations == NULL   || methods_default_annotations->length() == methods->length(), "");
1210     if (do_annotations) {
1211       ResourceMark rm;
1212       // Allocate temporary storage
1213       GrowableArray<oop>* temp_array = new GrowableArray<oop>(length);
1214       reorder_based_on_method_index(methods, methods_annotations, temp_array);
1215       reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
1216       reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
1217     }
1218 
1219     // Reset method ordering
1220     for (int i = 0; i < length; i++) {
1221       methodOop m = (methodOop) methods->obj_at(i);
1222       m->set_method_idnum(i);