hotspot/src/share/vm/oops/methodOop.cpp
changeset 10002 2d83be3a0927
parent 9134 189a8c094016
child 10003 06c862a55fa4
equal deleted inserted replaced
10001:8aa7f885326e 10002:2d83be3a0927
    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(), "");