comparison src/share/vm/runtime/sharedRuntime.cpp @ 710:e5b0439ef4ae

6655638: dynamic languages need method handles Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.) Reviewed-by: kvn, twisti, never
author jrose
date Wed, 08 Apr 2009 10:56:49 -0700
parents c89f86385056
children 45463a04ca27
comparison
equal deleted inserted replaced
709:1d037ecd7960 710:e5b0439ef4ae
1469 Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at( 1469 Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at(
1470 cc->index(), thread)); 1470 cc->index(), thread));
1471 return generate_class_cast_message(objName, targetKlass->external_name()); 1471 return generate_class_cast_message(objName, targetKlass->external_name());
1472 } 1472 }
1473 1473
1474 char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
1475 oopDesc* required,
1476 oopDesc* actual) {
1477 assert(EnableMethodHandles, "");
1478 oop singleKlass = wrong_method_type_is_for_single_argument(thread, required);
1479 if (singleKlass != NULL) {
1480 const char* objName = "argument or return value";
1481 if (actual != NULL) {
1482 // be flexible about the junk passed in:
1483 klassOop ak = (actual->is_klass()
1484 ? (klassOop)actual
1485 : actual->klass());
1486 objName = Klass::cast(ak)->external_name();
1487 }
1488 Klass* targetKlass = Klass::cast(required->is_klass()
1489 ? (klassOop)required
1490 : java_lang_Class::as_klassOop(required));
1491 return generate_class_cast_message(objName, targetKlass->external_name());
1492 } else {
1493 // %%% need to get the MethodType string, without messing around too much
1494 // Get a signature from the invoke instruction
1495 const char* mhName = "method handle";
1496 const char* targetType = "the required signature";
1497 vframeStream vfst(thread, true);
1498 if (!vfst.at_end()) {
1499 Bytecode_invoke* call = Bytecode_invoke_at(vfst.method(), vfst.bci());
1500 methodHandle target;
1501 {
1502 EXCEPTION_MARK;
1503 target = call->static_target(THREAD);
1504 if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; }
1505 }
1506 if (target.not_null()
1507 && target->is_method_handle_invoke()
1508 && required == target->method_handle_type()) {
1509 targetType = target->signature()->as_C_string();
1510 }
1511 }
1512 klassOop kignore; int fignore;
1513 methodOop actual_method = MethodHandles::decode_method(actual,
1514 kignore, fignore);
1515 if (actual_method != NULL) {
1516 if (actual_method->name() == vmSymbols::invoke_name())
1517 mhName = "$";
1518 else
1519 mhName = actual_method->signature()->as_C_string();
1520 if (mhName[0] == '$')
1521 mhName = actual_method->signature()->as_C_string();
1522 }
1523 return generate_class_cast_message(mhName, targetType,
1524 " cannot be called as ");
1525 }
1526 }
1527
1528 oop SharedRuntime::wrong_method_type_is_for_single_argument(JavaThread* thr,
1529 oopDesc* required) {
1530 if (required == NULL) return NULL;
1531 if (required->klass() == SystemDictionary::class_klass())
1532 return required;
1533 if (required->is_klass())
1534 return Klass::cast(klassOop(required))->java_mirror();
1535 return NULL;
1536 }
1537
1538
1474 char* SharedRuntime::generate_class_cast_message( 1539 char* SharedRuntime::generate_class_cast_message(
1475 const char* objName, const char* targetKlassName) { 1540 const char* objName, const char* targetKlassName, const char* desc) {
1476 const char* desc = " cannot be cast to ";
1477 size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1; 1541 size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
1478 1542
1479 char* message = NEW_RESOURCE_ARRAY(char, msglen); 1543 char* message = NEW_RESOURCE_ARRAY(char, msglen);
1480 if (NULL == message) { 1544 if (NULL == message) {
1481 // Shouldn't happen, but don't cause even more problems if it does 1545 // Shouldn't happen, but don't cause even more problems if it does