hotspot/src/share/vm/prims/methodHandles.cpp
changeset 4567 7fc02fbe5c7a
parent 4429 d7eb4e2099aa
child 4571 80b553bddc26
equal deleted inserted replaced
4566:b363f6ef4068 4567:7fc02fbe5c7a
   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) {