1187 if (name == NULL) return true;
1188 klassOop klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD);
1189 if (klass == NULL) return true;
1190 }
1191 }
1192 return false;
1193 }
1194
1195 // Exposed so field engineers can debug VM
1196 void methodOopDesc::print_short_name(outputStream* st) {
1197 ResourceMark rm;
1198 #ifdef PRODUCT
1199 st->print(" %s::", method_holder()->klass_part()->external_name());
1200 #else
1201 st->print(" %s::", method_holder()->klass_part()->internal_name());
1202 #endif
1203 name()->print_symbol_on(st);
1204 if (WizardMode) signature()->print_symbol_on(st);
1205 }
1206
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
1243 static void reorder_based_on_method_index(objArrayOop methods,
1244 objArrayOop annotations,
1245 GrowableArray<oop>* temp_array) {
1246 if (annotations == NULL) {
1247 return;
1248 }
1249
1250 int length = methods->length();
1251 int i;
1252 // Copy to temp array
1253 temp_array->clear();
1254 for (i = 0; i < length; i++) {
1255 temp_array->append(annotations->obj_at(i));
1256 }
1257
1258 // Copy back using old method indices
1259 for (i = 0; i < length; i++) {
1260 methodOop m = (methodOop) methods->obj_at(i);
1261 annotations->obj_at_put(i, temp_array->at(m->method_idnum()));
1262 }
1263 }
1264
1265
1266 // 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,
1268 objArrayOop methods_annotations,
1269 objArrayOop methods_parameter_annotations,
1270 objArrayOop methods_default_annotations,
1271 bool idempotent) {
1272 int length = methods->length();
1273 if (length > 1) {
1274 bool do_annotations = false;
1275 if (methods_annotations != NULL ||
1276 methods_parameter_annotations != NULL ||
1277 methods_default_annotations != NULL) {
1278 do_annotations = true;
1279 }
1280 if (do_annotations) {
1281 // Remember current method ordering so we can reorder annotations
1282 for (int i = 0; i < length; i++) {
1283 methodOop m = (methodOop) methods->obj_at(i);
1284 m->set_method_idnum(i);
1286 }
1287
1288 // Use a simple bubble sort for small number of methods since
1289 // qsort requires a functional pointer call for each comparison.
1290 if (length < 8) {
1291 bool sorted = true;
1292 for (int i=length-1; i>0; i--) {
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 }
1305 } else {
1306 compareFn compare =
1307 (UseCompressedOops ?
1308 (compareFn) (idempotent ? method_compare_narrow_idempotent : method_compare_narrow):
1309 (compareFn) (idempotent ? method_compare_idempotent : method_compare));
1310 qsort(methods->base(), length, heapOopSize, compare);
1311 }
1312
1313 // Sort annotations if necessary
1314 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), "");
1315 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
1316 assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), "");
1317 if (do_annotations) {
1318 ResourceMark rm;
1319 // Allocate temporary storage
1320 GrowableArray<oop>* temp_array = new GrowableArray<oop>(length);
1321 reorder_based_on_method_index(methods, methods_annotations, temp_array);
1322 reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
1323 reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
1324 }
1325
1326 // Reset method ordering
1327 for (int i = 0; i < length; i++) {
1328 methodOop m = (methodOop) methods->obj_at(i);
1329 m->set_method_idnum(i);
1330 }
|
1187 if (name == NULL) return true;
1188 klassOop klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD);
1189 if (klass == NULL) return true;
1190 }
1191 }
1192 return false;
1193 }
1194
1195 // Exposed so field engineers can debug VM
1196 void methodOopDesc::print_short_name(outputStream* st) {
1197 ResourceMark rm;
1198 #ifdef PRODUCT
1199 st->print(" %s::", method_holder()->klass_part()->external_name());
1200 #else
1201 st->print(" %s::", method_holder()->klass_part()->internal_name());
1202 #endif
1203 name()->print_symbol_on(st);
1204 if (WizardMode) signature()->print_symbol_on(st);
1205 }
1206
1207 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
1208 static void reorder_based_on_method_index(objArrayOop methods,
1209 objArrayOop annotations,
1210 GrowableArray<oop>* temp_array) {
1211 if (annotations == NULL) {
1212 return;
1213 }
1214
1215 int length = methods->length();
1216 int i;
1217 // Copy to temp array
1218 temp_array->clear();
1219 for (i = 0; i < length; i++) {
1220 temp_array->append(annotations->obj_at(i));
1221 }
1222
1223 // Copy back using old method indices
1224 for (i = 0; i < length; i++) {
1225 methodOop m = (methodOop) methods->obj_at(i);
1226 annotations->obj_at_put(i, temp_array->at(m->method_idnum()));
1227 }
1228 }
1229
1230 // Comparer for sorting an object array containing
1231 // methodOops.
1232 template <class T>
1233 static int method_comparer(T a, T b) {
1234 methodOop m = (methodOop)oopDesc::decode_heap_oop_not_null(a);
1235 methodOop n = (methodOop)oopDesc::decode_heap_oop_not_null(b);
1236 return m->name()->fast_compare(n->name());
1237 }
1238
1239 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
1240 void methodOopDesc::sort_methods(objArrayOop methods,
1241 objArrayOop methods_annotations,
1242 objArrayOop methods_parameter_annotations,
1243 objArrayOop methods_default_annotations,
1244 bool idempotent) {
1245 int length = methods->length();
1246 if (length > 1) {
1247 bool do_annotations = false;
1248 if (methods_annotations != NULL ||
1249 methods_parameter_annotations != NULL ||
1250 methods_default_annotations != NULL) {
1251 do_annotations = true;
1252 }
1253 if (do_annotations) {
1254 // Remember current method ordering so we can reorder annotations
1255 for (int i = 0; i < length; i++) {
1256 methodOop m = (methodOop) methods->obj_at(i);
1257 m->set_method_idnum(i);
1259 }
1260
1261 // Use a simple bubble sort for small number of methods since
1262 // qsort requires a functional pointer call for each comparison.
1263 if (length < 8) {
1264 bool sorted = true;
1265 for (int i=length-1; i>0; i--) {
1266 for (int j=0; j<i; j++) {
1267 methodOop m1 = (methodOop)methods->obj_at(j);
1268 methodOop m2 = (methodOop)methods->obj_at(j+1);
1269 if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) {
1270 methods->obj_at_put(j, m2);
1271 methods->obj_at_put(j+1, m1);
1272 sorted = false;
1273 }
1274 }
1275 if (sorted) break;
1276 sorted = true;
1277 }
1278 } else {
1279 if (UseCompressedOops) {
1280 methods->sort<narrowOop>(method_comparer<narrowOop>, idempotent);
1281 } else {
1282 methods->sort<oop>(method_comparer<oop>, idempotent);
1283 }
1284 }
1285
1286 // Sort annotations if necessary
1287 assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), "");
1288 assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), "");
1289 assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), "");
1290 if (do_annotations) {
1291 ResourceMark rm;
1292 // Allocate temporary storage
1293 GrowableArray<oop>* temp_array = new GrowableArray<oop>(length);
1294 reorder_based_on_method_index(methods, methods_annotations, temp_array);
1295 reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array);
1296 reorder_based_on_method_index(methods, methods_default_annotations, temp_array);
1297 }
1298
1299 // Reset method ordering
1300 for (int i = 0; i < length; i++) {
1301 methodOop m = (methodOop) methods->obj_at(i);
1302 m->set_method_idnum(i);
1303 }
|