comparison src/share/vm/oops/methodOop.cpp @ 3780:4bf3cbef0b3e

Merge
author jcoomes
date Wed, 06 Jul 2011 08:43:01 -0700
parents 9dd6c4ba364f 04760e41b01e
children b16582d6c7db
comparison
equal deleted inserted replaced
3760:e2af886d540b 3780:4bf3cbef0b3e
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(), "");