Mercurial > hg > truffle
comparison src/share/vm/oops/methodOop.cpp @ 4137:04b9a2566eec
Merge with hsx23/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 21:40:27 +0100 |
parents | be4ca325525a f94227b6117b |
children | 33df1aeaebbf |
comparison
equal
deleted
inserted
replaced
3737:9dc19b7d89a3 | 4137:04b9a2566eec |
---|---|
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 |
917 | 918 |
918 methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, | 919 methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, |
919 Symbol* name, | 920 Symbol* name, |
920 Symbol* signature, | 921 Symbol* signature, |
921 Handle method_type, TRAPS) { | 922 Handle method_type, TRAPS) { |
923 ResourceMark rm; | |
922 methodHandle empty; | 924 methodHandle empty; |
923 | 925 |
924 assert(holder() == SystemDictionary::MethodHandle_klass(), | 926 assert(holder() == SystemDictionary::MethodHandle_klass(), |
925 "must be a JSR 292 magic type"); | 927 "must be a JSR 292 magic type"); |
926 | 928 |
1245 #endif | 1247 #endif |
1246 name()->print_symbol_on(st); | 1248 name()->print_symbol_on(st); |
1247 if (WizardMode) signature()->print_symbol_on(st); | 1249 if (WizardMode) signature()->print_symbol_on(st); |
1248 } | 1250 } |
1249 | 1251 |
1250 | |
1251 extern "C" { | |
1252 static int method_compare(methodOop* a, methodOop* b) { | |
1253 return (*a)->name()->fast_compare((*b)->name()); | |
1254 } | |
1255 | |
1256 // Prevent qsort from reordering a previous valid sort by | |
1257 // considering the address of the methodOops if two methods | |
1258 // would otherwise compare as equal. Required to preserve | |
1259 // optimal access order in the shared archive. Slower than | |
1260 // method_compare, only used for shared archive creation. | |
1261 static int method_compare_idempotent(methodOop* a, methodOop* b) { | |
1262 int i = method_compare(a, b); | |
1263 if (i != 0) return i; | |
1264 return ( a < b ? -1 : (a == b ? 0 : 1)); | |
1265 } | |
1266 | |
1267 // We implement special compare versions for narrow oops to avoid | |
1268 // testing for UseCompressedOops on every comparison. | |
1269 static int method_compare_narrow(narrowOop* a, narrowOop* b) { | |
1270 methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a); | |
1271 methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b); | |
1272 return m->name()->fast_compare(n->name()); | |
1273 } | |
1274 | |
1275 static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) { | |
1276 int i = method_compare_narrow(a, b); | |
1277 if (i != 0) return i; | |
1278 return ( a < b ? -1 : (a == b ? 0 : 1)); | |
1279 } | |
1280 | |
1281 typedef int (*compareFn)(const void*, const void*); | |
1282 } | |
1283 | |
1284 | |
1285 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array | 1252 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1286 static void reorder_based_on_method_index(objArrayOop methods, | 1253 static void reorder_based_on_method_index(objArrayOop methods, |
1287 objArrayOop annotations, | 1254 objArrayOop annotations, |
1288 GrowableArray<oop>* temp_array) { | 1255 GrowableArray<oop>* temp_array) { |
1289 if (annotations == NULL) { | 1256 if (annotations == NULL) { |
1303 methodOop m = (methodOop) methods->obj_at(i); | 1270 methodOop m = (methodOop) methods->obj_at(i); |
1304 annotations->obj_at_put(i, temp_array->at(m->method_idnum())); | 1271 annotations->obj_at_put(i, temp_array->at(m->method_idnum())); |
1305 } | 1272 } |
1306 } | 1273 } |
1307 | 1274 |
1275 // Comparer for sorting an object array containing | |
1276 // methodOops. | |
1277 // Used non-template method_comparator methods since | |
1278 // Visual Studio 2003 compiler generates incorrect | |
1279 // optimized code for it. | |
1280 static int method_comparator_narrowOop(narrowOop a, narrowOop b) { | |
1281 methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a); | |
1282 methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b); | |
1283 return m->name()->fast_compare(n->name()); | |
1284 } | |
1285 static int method_comparator_oop(oop a, oop b) { | |
1286 methodOop m = (methodOop)a; | |
1287 methodOop n = (methodOop)b; | |
1288 return m->name()->fast_compare(n->name()); | |
1289 } | |
1308 | 1290 |
1309 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array | 1291 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array |
1310 void methodOopDesc::sort_methods(objArrayOop methods, | 1292 void methodOopDesc::sort_methods(objArrayOop methods, |
1311 objArrayOop methods_annotations, | 1293 objArrayOop methods_annotations, |
1312 objArrayOop methods_parameter_annotations, | 1294 objArrayOop methods_parameter_annotations, |
1325 for (int i = 0; i < length; i++) { | 1307 for (int i = 0; i < length; i++) { |
1326 methodOop m = (methodOop) methods->obj_at(i); | 1308 methodOop m = (methodOop) methods->obj_at(i); |
1327 m->set_method_idnum(i); | 1309 m->set_method_idnum(i); |
1328 } | 1310 } |
1329 } | 1311 } |
1330 | 1312 { |
1331 // Use a simple bubble sort for small number of methods since | 1313 No_Safepoint_Verifier nsv; |
1332 // qsort requires a functional pointer call for each comparison. | 1314 if (UseCompressedOops) { |
1333 if (length < 8) { | 1315 QuickSort::sort<narrowOop>((narrowOop*)(methods->base()), length, method_comparator_narrowOop, idempotent); |
1334 bool sorted = true; | 1316 } else { |
1335 for (int i=length-1; i>0; i--) { | 1317 QuickSort::sort<oop>((oop*)(methods->base()), length, method_comparator_oop, idempotent); |
1336 for (int j=0; j<i; j++) { | |
1337 methodOop m1 = (methodOop)methods->obj_at(j); | |
1338 methodOop m2 = (methodOop)methods->obj_at(j+1); | |
1339 if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { | |
1340 methods->obj_at_put(j, m2); | |
1341 methods->obj_at_put(j+1, m1); | |
1342 sorted = false; | |
1343 } | |
1344 } | |
1345 if (sorted) break; | |
1346 sorted = true; | |
1347 } | 1318 } |
1348 } else { | 1319 if (UseConcMarkSweepGC) { |
1349 compareFn compare = | 1320 // For CMS we need to dirty the cards for the array |
1350 (UseCompressedOops ? | 1321 BarrierSet* bs = Universe::heap()->barrier_set(); |
1351 (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow): | 1322 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
1352 (compareFn) (idempotent ? method_compare_idempotent : method_compare)); | 1323 bs->write_ref_array(methods->base(), length); |
1353 qsort(methods->base(), length, heapOopSize, compare); | 1324 } |
1354 } | 1325 } |
1355 | 1326 |
1356 // Sort annotations if necessary | 1327 // Sort annotations if necessary |
1357 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); | 1328 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); |
1358 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); | 1329 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); |