comparison src/share/vm/prims/methodHandles.cpp @ 1138:dd57230ba8fe

6893268: additional dynamic language related optimizations in C2 Summary: C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance. Reviewed-by: kvn, never
author twisti
date Tue, 05 Jan 2010 15:21:25 +0100
parents 389049f3f393
children 4ce7240d622c
comparison
equal deleted inserted replaced
1137:97125851f396 1138:dd57230ba8fe
130 } else { 130 } else {
131 assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?"); 131 assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?");
132 } 132 }
133 return m; 133 return m;
134 } else { 134 } else {
135 assert(vmtarget->is_klass(), "must be class or interface");
135 decode_flags_result |= MethodHandles::_dmf_does_dispatch; 136 decode_flags_result |= MethodHandles::_dmf_does_dispatch;
136 assert(vmtarget->is_klass(), "must be class or interface"); 137 decode_flags_result |= MethodHandles::_dmf_has_receiver;
137 receiver_limit_result = (klassOop)vmtarget; 138 receiver_limit_result = (klassOop)vmtarget;
138 Klass* tk = Klass::cast((klassOop)vmtarget); 139 Klass* tk = Klass::cast((klassOop)vmtarget);
139 if (tk->is_interface()) { 140 if (tk->is_interface()) {
140 // an itable linkage is <interface, itable index> 141 // an itable linkage is <interface, itable index>
141 decode_flags_result |= MethodHandles::_dmf_from_interface; 142 decode_flags_result |= MethodHandles::_dmf_from_interface;
177 } else { 178 } else {
178 // Optimized case: binding a receiver to a non-dispatched DMH 179 // Optimized case: binding a receiver to a non-dispatched DMH
179 // short-circuits directly to the methodOop. 180 // short-circuits directly to the methodOop.
180 // (It might be another argument besides a receiver also.) 181 // (It might be another argument besides a receiver also.)
181 assert(target->is_method(), "must be a simple method"); 182 assert(target->is_method(), "must be a simple method");
183 decode_flags_result |= MethodHandles::_dmf_binds_method;
182 methodOop m = (methodOop) target; 184 methodOop m = (methodOop) target;
183 decode_flags_result |= MethodHandles::_dmf_binds_method; 185 if (!m->is_static())
186 decode_flags_result |= MethodHandles::_dmf_has_receiver;
184 return m; 187 return m;
185 } 188 }
186 } 189 }
187 } 190 }
188 } 191 }
231 // check that signature begins '(L' or '([' (not '(I', '()', etc.) 234 // check that signature begins '(L' or '([' (not '(I', '()', etc.)
232 symbolOop sig = m->signature(); 235 symbolOop sig = m->signature();
233 BasicType recv_bt = char2type(sig->byte_at(1)); 236 BasicType recv_bt = char2type(sig->byte_at(1));
234 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')' 237 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')'
235 assert(sig->byte_at(0) == '(', "must be method sig"); 238 assert(sig->byte_at(0) == '(', "must be method sig");
236 if (recv_bt == T_OBJECT || recv_bt == T_ARRAY) 239 // if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
237 decode_flags_result |= _dmf_has_receiver; 240 // decode_flags_result |= _dmf_has_receiver;
238 } else { 241 } else {
239 // non-static method 242 // non-static method
240 decode_flags_result |= _dmf_has_receiver; 243 decode_flags_result |= _dmf_has_receiver;
241 if (!m->can_be_statically_bound() && !m->is_initializer()) { 244 if (!m->can_be_statically_bound() && !m->is_initializer()) {
242 decode_flags_result |= _dmf_does_dispatch; 245 decode_flags_result |= _dmf_does_dispatch;
816 // Check the name. 819 // Check the name.
817 symbolOop name = ik->name(); 820 symbolOop name = ik->name();
818 for (int i = 0; ; i++) { 821 for (int i = 0; ; i++) {
819 const char* test_name = always_null_names[i]; 822 const char* test_name = always_null_names[i];
820 if (test_name == NULL) break; 823 if (test_name == NULL) break;
821 if (name->equals(test_name, (int) strlen(test_name))) 824 if (name->equals(test_name))
822 return true; 825 return true;
823 } 826 }
824 return false; 827 return false;
825 } 828 }
826 829
1485 assert(slots_pushed <= MethodHandlePushLimit, ""); 1488 assert(slots_pushed <= MethodHandlePushLimit, "");
1486 } else { 1489 } else {
1487 int target_pushes = decode_MethodHandle_stack_pushes(target()); 1490 int target_pushes = decode_MethodHandle_stack_pushes(target());
1488 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct"); 1491 assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
1489 // do not blow the stack; use a Java-based adapter if this limit is exceeded 1492 // do not blow the stack; use a Java-based adapter if this limit is exceeded
1490 if (slots_pushed + target_pushes > MethodHandlePushLimit) 1493 // FIXME
1491 err = "too many bound parameters"; 1494 // if (slots_pushed + target_pushes > MethodHandlePushLimit)
1495 // err = "too many bound parameters";
1492 } 1496 }
1493 } 1497 }
1494 1498
1495 if (err == NULL) { 1499 if (err == NULL) {
1496 // Verify the rest of the method type. 1500 // Verify the rest of the method type.
1515 if (VerifyMethodHandles) { 1519 if (VerifyMethodHandles) {
1516 int insert_after = argnum - 1; 1520 int insert_after = argnum - 1;
1517 verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK); 1521 verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
1518 verify_vmslots(mh, CHECK); 1522 verify_vmslots(mh, CHECK);
1519 } 1523 }
1524
1525 // Get bound type and required slots.
1526 oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
1527 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
1528 int slots_pushed = type2size[ptype];
1520 1529
1521 // If (a) the target is a direct non-dispatched method handle, 1530 // If (a) the target is a direct non-dispatched method handle,
1522 // or (b) the target is a dispatched direct method handle and we 1531 // or (b) the target is a dispatched direct method handle and we
1523 // are binding the receiver, cut out the middle-man. 1532 // are binding the receiver, cut out the middle-man.
1524 // Do this by decoding the DMH and using its methodOop directly as vmtarget. 1533 // Do this by decoding the DMH and using its methodOop directly as vmtarget.
1527 target->klass() == SystemDictionary::DirectMethodHandle_klass() && 1536 target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
1528 (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) { 1537 (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
1529 int decode_flags = 0; klassOop receiver_limit_oop = NULL; 1538 int decode_flags = 0; klassOop receiver_limit_oop = NULL;
1530 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); 1539 methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
1531 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } 1540 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
1532 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - 1); // pos. of 1st arg. 1541 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
1533 assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); 1542 assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
1534 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { 1543 if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
1535 KlassHandle receiver_limit(THREAD, receiver_limit_oop); 1544 KlassHandle receiver_limit(THREAD, receiver_limit_oop);
1536 init_BoundMethodHandle_with_receiver(mh, m, 1545 init_BoundMethodHandle_with_receiver(mh, m,
1537 receiver_limit, decode_flags, 1546 receiver_limit, decode_flags,
1552 if (VerifyMethodHandles) { 1561 if (VerifyMethodHandles) {
1553 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK); 1562 verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
1554 } 1563 }
1555 1564
1556 // Next question: Is this a ref, int, or long bound value? 1565 // Next question: Is this a ref, int, or long bound value?
1557 oop ptype_oop = java_dyn_MethodType::ptype(java_dyn_MethodHandle::type(target()), argnum);
1558 BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
1559 int slots_pushed = type2size[ptype];
1560
1561 MethodHandleEntry* me = NULL; 1566 MethodHandleEntry* me = NULL;
1562 if (ptype == T_OBJECT) { 1567 if (ptype == T_OBJECT) {
1563 if (direct_to_method) me = MethodHandles::entry(_bound_ref_direct_mh); 1568 if (direct_to_method) me = MethodHandles::entry(_bound_ref_direct_mh);
1564 else me = MethodHandles::entry(_bound_ref_mh); 1569 else me = MethodHandles::entry(_bound_ref_mh);
1565 } else if (slots_pushed == 2) { 1570 } else if (slots_pushed == 2) {