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