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) { |