Mercurial > hg > graal-compiler
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) { |