diff -r e2af886d540b -r 4bf3cbef0b3e src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Fri Jul 01 13:07:16 2011 -0700 +++ b/src/share/vm/oops/methodOop.cpp Wed Jul 06 08:43:01 2011 -0700 @@ -49,6 +49,7 @@ #include "runtime/relocator.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" +#include "utilities/quickSort.hpp" #include "utilities/xmlstream.hpp" @@ -1207,41 +1208,6 @@ if (WizardMode) signature()->print_symbol_on(st); } - -extern "C" { - static int method_compare(methodOop* a, methodOop* b) { - return (*a)->name()->fast_compare((*b)->name()); - } - - // Prevent qsort from reordering a previous valid sort by - // considering the address of the methodOops if two methods - // would otherwise compare as equal. Required to preserve - // optimal access order in the shared archive. Slower than - // method_compare, only used for shared archive creation. - static int method_compare_idempotent(methodOop* a, methodOop* b) { - int i = method_compare(a, b); - if (i != 0) return i; - return ( a < b ? -1 : (a == b ? 0 : 1)); - } - - // We implement special compare versions for narrow oops to avoid - // testing for UseCompressedOops on every comparison. - static int method_compare_narrow(narrowOop* a, narrowOop* b) { - methodOop m = (methodOop)oopDesc::load_decode_heap_oop(a); - methodOop n = (methodOop)oopDesc::load_decode_heap_oop(b); - return m->name()->fast_compare(n->name()); - } - - static int method_compare_narrow_idempotent(narrowOop* a, narrowOop* b) { - int i = method_compare_narrow(a, b); - if (i != 0) return i; - return ( a < b ? -1 : (a == b ? 0 : 1)); - } - - typedef int (*compareFn)(const void*, const void*); -} - - // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array static void reorder_based_on_method_index(objArrayOop methods, objArrayOop annotations, @@ -1265,6 +1231,14 @@ } } +// Comparer for sorting an object array containing +// methodOops. +template +static int method_comparator(T a, T b) { + methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a); + methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b); + return m->name()->fast_compare(n->name()); +} // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array void methodOopDesc::sort_methods(objArrayOop methods, @@ -1287,30 +1261,19 @@ m->set_method_idnum(i); } } - - // Use a simple bubble sort for small number of methods since - // qsort requires a functional pointer call for each comparison. - if (length < 8) { - bool sorted = true; - for (int i=length-1; i>0; i--) { - for (int j=0; jobj_at(j); - methodOop m2 = (methodOop)methods->obj_at(j+1); - if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { - methods->obj_at_put(j, m2); - methods->obj_at_put(j+1, m1); - sorted = false; - } - } - if (sorted) break; - sorted = true; + { + No_Safepoint_Verifier nsv; + if (UseCompressedOops) { + QuickSort::sort((narrowOop*)(methods->base()), length, method_comparator, idempotent); + } else { + QuickSort::sort((oop*)(methods->base()), length, method_comparator, idempotent); } - } else { - compareFn compare = - (UseCompressedOops ? - (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow): - (compareFn) (idempotent ? method_compare_idempotent : method_compare)); - qsort(methods->base(), length, heapOopSize, compare); + if (UseConcMarkSweepGC) { + // For CMS we need to dirty the cards for the array + BarrierSet* bs = Universe::heap()->barrier_set(); + assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); + bs->write_ref_array(methods->base(), length); + } } // Sort annotations if necessary