47 #include "runtime/frame.inline.hpp" |
47 #include "runtime/frame.inline.hpp" |
48 #include "runtime/handles.inline.hpp" |
48 #include "runtime/handles.inline.hpp" |
49 #include "runtime/relocator.hpp" |
49 #include "runtime/relocator.hpp" |
50 #include "runtime/sharedRuntime.hpp" |
50 #include "runtime/sharedRuntime.hpp" |
51 #include "runtime/signature.hpp" |
51 #include "runtime/signature.hpp" |
|
52 #include "utilities/quickSort.hpp" |
52 #include "utilities/xmlstream.hpp" |
53 #include "utilities/xmlstream.hpp" |
53 |
54 |
54 |
55 |
55 // Implementation of methodOopDesc |
56 // Implementation of methodOopDesc |
56 |
57 |
1205 #endif |
1206 #endif |
1206 name()->print_symbol_on(st); |
1207 name()->print_symbol_on(st); |
1207 if (WizardMode) signature()->print_symbol_on(st); |
1208 if (WizardMode) signature()->print_symbol_on(st); |
1208 } |
1209 } |
1209 |
1210 |
1210 |
|
1211 extern "C" { |
|
1212 static int method_compare(methodOop* a, methodOop* b) { |
|
1213 return (*a)->name()->fast_compare((*b)->name()); |
|
1214 } |
|
1215 |
|
1216 // Prevent qsort from reordering a previous valid sort by |
|
1217 // considering the address of the methodOops if two methods |
|
1218 // would otherwise compare as equal. Required to preserve |
|
1219 // optimal access order in the shared archive. Slower than |
|
1220 // method_compare, only used for shared archive creation. |
|
1221 static int method_compare_idempotent(methodOop* a, methodOop* b) { |
|
1222 int i = method_compare(a, b); |
|
1223 if (i != 0) return i; |
|
1224 return ( a < b ? -1 : (a == b ? 0 : 1)); |
|
1225 } |
|
1226 |
|
1227 // We implement special compare versions for narrow oops to avoid |
|
1228 // testing for UseCompressedOops on every comparison. |
|
1229 static int method_compare_narrow(narrowOop* a, narrowOop* b) { |
|
1230 methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a); |
|
1231 methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b); |
|
1232 return m->name()->fast_compare(n->name()); |
|
1233 } |
|
1234 |
|
1235 static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) { |
|
1236 int i = method_compare_narrow(a, b); |
|
1237 if (i != 0) return i; |
|
1238 return ( a < b ? -1 : (a == b ? 0 : 1)); |
|
1239 } |
|
1240 |
|
1241 typedef int (*compareFn)(const void*, const void*); |
|
1242 } |
|
1243 |
|
1244 |
|
1245 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1211 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1246 static void reorder_based_on_method_index(objArrayOop methods, |
1212 static void reorder_based_on_method_index(objArrayOop methods, |
1247 objArrayOop annotations, |
1213 objArrayOop annotations, |
1248 GrowableArray<oop>* temp_array) { |
1214 GrowableArray<oop>* temp_array) { |
1249 if (annotations == NULL) { |
1215 if (annotations == NULL) { |
1263 methodOop m = (methodOop) methods->obj_at(i); |
1229 methodOop m = (methodOop) methods->obj_at(i); |
1264 annotations->obj_at_put(i, temp_array->at(m->method_idnum())); |
1230 annotations->obj_at_put(i, temp_array->at(m->method_idnum())); |
1265 } |
1231 } |
1266 } |
1232 } |
1267 |
1233 |
|
1234 // Comparer for sorting an object array containing |
|
1235 // methodOops. |
|
1236 template <class T> |
|
1237 static int method_comparator(T a, T b) { |
|
1238 methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a); |
|
1239 methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b); |
|
1240 return m->name()->fast_compare(n->name()); |
|
1241 } |
1268 |
1242 |
1269 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1243 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1270 void methodOopDesc::sort_methods(objArrayOop methods, |
1244 void methodOopDesc::sort_methods(objArrayOop methods, |
1271 objArrayOop methods_annotations, |
1245 objArrayOop methods_annotations, |
1272 objArrayOop methods_parameter_annotations, |
1246 objArrayOop methods_parameter_annotations, |
1285 for (int i = 0; i < length; i++) { |
1259 for (int i = 0; i < length; i++) { |
1286 methodOop m = (methodOop) methods->obj_at(i); |
1260 methodOop m = (methodOop) methods->obj_at(i); |
1287 m->set_method_idnum(i); |
1261 m->set_method_idnum(i); |
1288 } |
1262 } |
1289 } |
1263 } |
1290 |
1264 { |
1291 // Use a simple bubble sort for small number of methods since |
1265 No_Safepoint_Verifier nsv; |
1292 // qsort requires a functional pointer call for each comparison. |
1266 if (UseCompressedOops) { |
1293 if (length < 8) { |
1267 QuickSort::sort<narrowOop>((narrowOop*)(methods->base()), length, method_comparator<narrowOop>, idempotent); |
1294 bool sorted = true; |
1268 } else { |
1295 for (int i=length-1; i>0; i--) { |
1269 QuickSort::sort<oop>((oop*)(methods->base()), length, method_comparator<oop>, idempotent); |
1296 for (int j=0; j<i; j++) { |
|
1297 methodOop m1 = (methodOop)methods->obj_at(j); |
|
1298 methodOop m2 = (methodOop)methods->obj_at(j+1); |
|
1299 if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { |
|
1300 methods->obj_at_put(j, m2); |
|
1301 methods->obj_at_put(j+1, m1); |
|
1302 sorted = false; |
|
1303 } |
|
1304 } |
|
1305 if (sorted) break; |
|
1306 sorted = true; |
|
1307 } |
1270 } |
1308 } else { |
1271 if (UseConcMarkSweepGC) { |
1309 compareFn compare = |
1272 // For CMS we need to dirty the cards for the array |
1310 (UseCompressedOops ? |
1273 BarrierSet* bs = Universe::heap()->barrier_set(); |
1311 (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow): |
1274 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
1312 (compareFn) (idempotent ? method_compare_idempotent : method_compare)); |
1275 bs->write_ref_array(methods->base(), length); |
1313 qsort(methods->base(), length, heapOopSize, compare); |
1276 } |
1314 } |
1277 } |
1315 |
1278 |
1316 // Sort annotations if necessary |
1279 // Sort annotations if necessary |
1317 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); |
1280 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); |
1318 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); |
1281 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); |