comparison src/share/vm/oops/instanceKlass.cpp @ 6934:4735d2c84362

7200776: Implement default methods in interfaces Summary: Add generic type analysis and default method selection algorithms Reviewed-by: coleenp, acorn
author kamg
date Thu, 11 Oct 2012 12:25:42 -0400
parents d8ce2825b193
children e522a00b91aa bd7a7ce2e264 070d523b96a7
comparison
equal deleted inserted replaced
6921:a1b8cf9cf970 6934:4735d2c84362
741 DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_oop()), -1,wait); 741 DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_oop()), -1,wait);
742 THROW_OOP(e()); 742 THROW_OOP(e());
743 } 743 }
744 } 744 }
745 745
746 if (this_oop->has_default_methods()) {
747 // Step 7.5: initialize any interfaces which have default methods
748 for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
749 Klass* iface = this_oop->local_interfaces()->at(i);
750 InstanceKlass* ik = InstanceKlass::cast(iface);
751 if (ik->has_default_methods() && ik->should_be_initialized()) {
752 ik->initialize(THREAD);
753
754 if (HAS_PENDING_EXCEPTION) {
755 Handle e(THREAD, PENDING_EXCEPTION);
756 CLEAR_PENDING_EXCEPTION;
757 {
758 EXCEPTION_MARK;
759 // Locks object, set state, and notify all waiting threads
760 this_oop->set_initialization_state_and_notify(
761 initialization_error, THREAD);
762
763 // ignore any exception thrown, superclass initialization error is
764 // thrown below
765 CLEAR_PENDING_EXCEPTION;
766 }
767 DTRACE_CLASSINIT_PROBE_WAIT(
768 super__failed, InstanceKlass::cast(this_oop()), -1, wait);
769 THROW_OOP(e());
770 }
771 }
772 }
773 }
774
746 // Step 8 775 // Step 8
747 { 776 {
748 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); 777 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
749 JavaThread* jt = (JavaThread*)THREAD; 778 JavaThread* jt = (JavaThread*)THREAD;
750 DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_oop()), -1,wait); 779 DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_oop()), -1,wait);
1250 } 1279 }
1251 return -1; 1280 return -1;
1252 } 1281 }
1253 #endif 1282 #endif
1254 1283
1255 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { 1284 static int binary_search(Array<Method*>* methods, Symbol* name) {
1256 return InstanceKlass::find_method(methods(), name, signature);
1257 }
1258
1259 Method* InstanceKlass::find_method(Array<Method*>* methods, Symbol* name, Symbol* signature) {
1260 int len = methods->length(); 1285 int len = methods->length();
1261 // methods are sorted, so do binary search 1286 // methods are sorted, so do binary search
1262 int l = 0; 1287 int l = 0;
1263 int h = len - 1; 1288 int h = len - 1;
1264 while (l <= h) { 1289 while (l <= h) {
1265 int mid = (l + h) >> 1; 1290 int mid = (l + h) >> 1;
1266 Method* m = methods->at(mid); 1291 Method* m = methods->at(mid);
1267 assert(m->is_method(), "must be method"); 1292 assert(m->is_method(), "must be method");
1268 int res = m->name()->fast_compare(name); 1293 int res = m->name()->fast_compare(name);
1269 if (res == 0) { 1294 if (res == 0) {
1270 // found matching name; do linear search to find matching signature 1295 return mid;
1271 // first, quick check for common case 1296 } else if (res < 0) {
1272 if (m->signature() == signature) return m; 1297 l = mid + 1;
1273 // search downwards through overloaded methods 1298 } else {
1274 int i; 1299 h = mid - 1;
1275 for (i = mid - 1; i >= l; i--) { 1300 }
1301 }
1302 return -1;
1303 }
1304
1305 Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
1306 return InstanceKlass::find_method(methods(), name, signature);
1307 }
1308
1309 Method* InstanceKlass::find_method(
1310 Array<Method*>* methods, Symbol* name, Symbol* signature) {
1311 int hit = binary_search(methods, name);
1312 if (hit != -1) {
1313 Method* m = methods->at(hit);
1314 // Do linear search to find matching signature. First, quick check
1315 // for common case
1316 if (m->signature() == signature) return m;
1317 // search downwards through overloaded methods
1318 int i;
1319 for (i = hit - 1; i >= 0; --i) {
1276 Method* m = methods->at(i); 1320 Method* m = methods->at(i);
1277 assert(m->is_method(), "must be method"); 1321 assert(m->is_method(), "must be method");
1278 if (m->name() != name) break; 1322 if (m->name() != name) break;
1279 if (m->signature() == signature) return m; 1323 if (m->signature() == signature) return m;
1280 } 1324 }
1281 // search upwards 1325 // search upwards
1282 for (i = mid + 1; i <= h; i++) { 1326 for (i = hit + 1; i < methods->length(); ++i) {
1283 Method* m = methods->at(i); 1327 Method* m = methods->at(i);
1284 assert(m->is_method(), "must be method"); 1328 assert(m->is_method(), "must be method");
1285 if (m->name() != name) break; 1329 if (m->name() != name) break;
1286 if (m->signature() == signature) return m; 1330 if (m->signature() == signature) return m;
1287 } 1331 }
1288 // not found 1332 // not found
1289 #ifdef ASSERT 1333 #ifdef ASSERT
1290 int index = linear_search(methods, name, signature); 1334 int index = linear_search(methods, name, signature);
1291 assert(index == -1, err_msg("binary search should have found entry %d", index)); 1335 assert(index == -1, err_msg("binary search should have found entry %d", index));
1292 #endif 1336 #endif
1293 return NULL; 1337 }
1294 } else if (res < 0) {
1295 l = mid + 1;
1296 } else {
1297 h = mid - 1;
1298 }
1299 }
1300 #ifdef ASSERT
1301 int index = linear_search(methods, name, signature);
1302 assert(index == -1, err_msg("binary search should have found entry %d", index));
1303 #endif
1304 return NULL; 1338 return NULL;
1339 }
1340
1341 int InstanceKlass::find_method_by_name(Symbol* name, int* end) {
1342 return find_method_by_name(methods(), name, end);
1343 }
1344
1345 int InstanceKlass::find_method_by_name(
1346 Array<Method*>* methods, Symbol* name, int* end_ptr) {
1347 assert(end_ptr != NULL, "just checking");
1348 int start = binary_search(methods, name);
1349 int end = start + 1;
1350 if (start != -1) {
1351 while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start;
1352 while (end < methods->length() && (methods->at(end))->name() == name) ++end;
1353 *end_ptr = end;
1354 return start;
1355 }
1356 return -1;
1305 } 1357 }
1306 1358
1307 Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { 1359 Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
1308 Klass* klass = const_cast<InstanceKlass*>(this); 1360 Klass* klass = const_cast<InstanceKlass*>(this);
1309 while (klass != NULL) { 1361 while (klass != NULL) {