1.1 --- a/src/share/vm/oops/methodOop.cpp Fri Jun 24 12:38:49 2011 -0400 1.2 +++ b/src/share/vm/oops/methodOop.cpp Tue Jun 28 14:23:27 2011 +0200 1.3 @@ -49,6 +49,7 @@ 1.4 #include "runtime/relocator.hpp" 1.5 #include "runtime/sharedRuntime.hpp" 1.6 #include "runtime/signature.hpp" 1.7 +#include "utilities/quickSort.hpp" 1.8 #include "utilities/xmlstream.hpp" 1.9 1.10 1.11 @@ -1204,41 +1205,6 @@ 1.12 if (WizardMode) signature()->print_symbol_on(st); 1.13 } 1.14 1.15 - 1.16 -extern "C" { 1.17 - static int method_compare(methodOop* a, methodOop* b) { 1.18 - return (*a)->name()->fast_compare((*b)->name()); 1.19 - } 1.20 - 1.21 - // Prevent qsort from reordering a previous valid sort by 1.22 - // considering the address of the methodOops if two methods 1.23 - // would otherwise compare as equal. Required to preserve 1.24 - // optimal access order in the shared archive. Slower than 1.25 - // method_compare, only used for shared archive creation. 1.26 - static int method_compare_idempotent(methodOop* a, methodOop* b) { 1.27 - int i = method_compare(a, b); 1.28 - if (i != 0) return i; 1.29 - return ( a < b ? -1 : (a == b ? 0 : 1)); 1.30 - } 1.31 - 1.32 - // We implement special compare versions for narrow oops to avoid 1.33 - // testing for UseCompressedOops on every comparison. 1.34 - static int method_compare_narrow(narrowOop* a, narrowOop* b) { 1.35 - methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a); 1.36 - methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b); 1.37 - return m->name()->fast_compare(n->name()); 1.38 - } 1.39 - 1.40 - static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) { 1.41 - int i = method_compare_narrow(a, b); 1.42 - if (i != 0) return i; 1.43 - return ( a < b ? -1 : (a == b ? 0 : 1)); 1.44 - } 1.45 - 1.46 - typedef int (*compareFn)(const void*, const void*); 1.47 -} 1.48 - 1.49 - 1.50 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array 1.51 static void reorder_based_on_method_index(objArrayOop methods, 1.52 objArrayOop annotations, 1.53 @@ -1262,6 +1228,14 @@ 1.54 } 1.55 } 1.56 1.57 +// Comparer for sorting an object array containing 1.58 +// methodOops. 1.59 +template <class T> 1.60 +static int method_comparator(T a, T b) { 1.61 + methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a); 1.62 + methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b); 1.63 + return m->name()->fast_compare(n->name()); 1.64 +} 1.65 1.66 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array 1.67 void methodOopDesc::sort_methods(objArrayOop methods, 1.68 @@ -1284,30 +1258,19 @@ 1.69 m->set_method_idnum(i); 1.70 } 1.71 } 1.72 - 1.73 - // Use a simple bubble sort for small number of methods since 1.74 - // qsort requires a functional pointer call for each comparison. 1.75 - if (length < 8) { 1.76 - bool sorted = true; 1.77 - for (int i=length-1; i>0; i--) { 1.78 - for (int j=0; j<i; j++) { 1.79 - methodOop m1 = (methodOop)methods->obj_at(j); 1.80 - methodOop m2 = (methodOop)methods->obj_at(j+1); 1.81 - if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { 1.82 - methods->obj_at_put(j, m2); 1.83 - methods->obj_at_put(j+1, m1); 1.84 - sorted = false; 1.85 - } 1.86 - } 1.87 - if (sorted) break; 1.88 - sorted = true; 1.89 + { 1.90 + No_Safepoint_Verifier nsv; 1.91 + if (UseCompressedOops) { 1.92 + QuickSort::sort<narrowOop>((narrowOop*)(methods->base()), length, method_comparator<narrowOop>, idempotent); 1.93 + } else { 1.94 + QuickSort::sort<oop>((oop*)(methods->base()), length, method_comparator<oop>, idempotent); 1.95 } 1.96 - } else { 1.97 - compareFn compare = 1.98 - (UseCompressedOops ? 1.99 - (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow): 1.100 - (compareFn) (idempotent ? method_compare_idempotent : method_compare)); 1.101 - qsort(methods->base(), length, heapOopSize, compare); 1.102 + if (UseConcMarkSweepGC) { 1.103 + // For CMS we need to dirty the cards for the array 1.104 + BarrierSet* bs = Universe::heap()->barrier_set(); 1.105 + assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); 1.106 + bs->write_ref_array(methods->base(), length); 1.107 + } 1.108 } 1.109 1.110 // Sort annotations if necessary