Print this page
rev 1021 : 6858164: invokedynamic code needs some cleanup (post-6655638)
Note: The bug ID for this change set was erroneously used to call for review of 6815692.
Summary: Fix several crashers, remove needless paths for boxed-style bootstrap method call, refactor & simplify APIs for rewriter constantPoolOop, remove sun.dyn.CallSiteImpl
Reviewed-by: ?
rev 1026 : imported patch indy.compiler.inline.patch

Split Close
Expand all
Collapse all
          --- old/src/share/vm/prims/methodHandles.cpp
          +++ new/src/share/vm/prims/methodHandles.cpp
↓ open down ↓ 124 lines elided ↑ open up ↑
 125  125          receiver_limit_result = java_lang_Class::as_klassOop(ptype0);
 126  126      }
 127  127      if (vmindex == methodOopDesc::nonvirtual_vtable_index) {
 128  128        // this DMH can be an "invokespecial" version
 129  129        decode_flags_result &= ~_dmf_does_dispatch;
 130  130      } else {
 131  131        assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?");
 132  132      }
 133  133      return m;
 134  134    } else {
 135      -    decode_flags_result |= MethodHandles::_dmf_does_dispatch;
 136  135      assert(vmtarget->is_klass(), "must be class or interface");
      136 +    decode_flags_result |= MethodHandles::_dmf_does_dispatch;
      137 +    decode_flags_result |= MethodHandles::_dmf_has_receiver;
 137  138      receiver_limit_result = (klassOop)vmtarget;
 138  139      Klass* tk = Klass::cast((klassOop)vmtarget);
 139  140      if (tk->is_interface()) {
 140  141        // an itable linkage is <interface, itable index>
 141  142        decode_flags_result |= MethodHandles::_dmf_from_interface;
 142  143        return klassItable::method_for_itable_index((klassOop)vmtarget, vmindex);
 143  144      } else {
 144  145        if (!tk->oop_is_instance())
 145  146          tk = instanceKlass::cast(SystemDictionary::object_klass());
 146  147        return ((instanceKlass*)tk)->method_at_vtable(vmindex);
↓ open down ↓ 25 lines elided ↑ open up ↑
 172  173        continue;
 173  174      } else {
 174  175        if (java_dyn_MethodHandle::is_subclass(tk)) {
 175  176          //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH");
 176  177          return decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
 177  178        } else {
 178  179          // Optimized case:  binding a receiver to a non-dispatched DMH
 179  180          // short-circuits directly to the methodOop.
 180  181          // (It might be another argument besides a receiver also.)
 181  182          assert(target->is_method(), "must be a simple method");
 182      -        methodOop m = (methodOop) target;
 183  183          decode_flags_result |= MethodHandles::_dmf_binds_method;
      184 +        methodOop m = (methodOop) target;
      185 +        if (!m->is_static())
      186 +          decode_flags_result |= MethodHandles::_dmf_has_receiver;
 184  187          return m;
 185  188        }
 186  189      }
 187  190    }
 188  191  }
 189  192  
 190  193  methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
 191  194    assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
 192  195    for (oop amh = mh;;) {
 193  196      // Adapter MHs can be stacked to convert several arguments.
↓ open down ↓ 32 lines elided ↑ open up ↑
 226  229  }
 227  230  
 228  231  methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) {
 229  232    assert(m->is_method(), "");
 230  233    if (m->is_static()) {
 231  234      // check that signature begins '(L' or '([' (not '(I', '()', etc.)
 232  235      symbolOop sig = m->signature();
 233  236      BasicType recv_bt = char2type(sig->byte_at(1));
 234  237      // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')'
 235  238      assert(sig->byte_at(0) == '(', "must be method sig");
 236      -    if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
 237      -      decode_flags_result |= _dmf_has_receiver;
      239 +//     if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
      240 +//       decode_flags_result |= _dmf_has_receiver;
 238  241    } else {
 239  242      // non-static method
 240  243      decode_flags_result |= _dmf_has_receiver;
 241  244      if (!m->can_be_statically_bound() && !m->is_initializer()) {
 242  245        decode_flags_result |= _dmf_does_dispatch;
 243  246        if (Klass::cast(m->method_holder())->is_interface())
 244  247          decode_flags_result |= _dmf_from_interface;
 245  248      }
 246  249    }
 247  250    return m;
↓ open down ↓ 1232 lines elided ↑ open up ↑
1480 1483  
1481 1484    if (err == NULL) {
1482 1485      DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
1483 1486      if (direct_to_method) {
1484 1487        assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
1485 1488        assert(slots_pushed <= MethodHandlePushLimit, "");
1486 1489      } else {
1487 1490        int target_pushes = decode_MethodHandle_stack_pushes(target());
1488 1491        assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
1489 1492        // do not blow the stack; use a Java-based adapter if this limit is exceeded
1490      -      if (slots_pushed + target_pushes > MethodHandlePushLimit)
1491      -        err = "too many bound parameters";
     1493 +      // FIXME
     1494 +      // if (slots_pushed + target_pushes > MethodHandlePushLimit)
     1495 +      //   err = "too many bound parameters";
1492 1496      }
1493 1497    }
1494 1498  
1495 1499    if (err == NULL) {
1496 1500      // Verify the rest of the method type.
1497 1501      err = check_method_type_insertion(java_dyn_MethodHandle::type(mh()),
1498 1502                                        argnum, ptype_handle(),
1499 1503                                        java_dyn_MethodHandle::type(target()));
1500 1504    }
1501 1505  
↓ open down ↓ 9 lines elided ↑ open up ↑
1511 1515    }
1512 1516  
1513 1517    java_dyn_MethodHandle::init_vmslots(mh());
1514 1518  
1515 1519    if (VerifyMethodHandles) {
1516 1520      int insert_after = argnum - 1;
1517 1521      verify_vmargslot(mh, insert_after, sun_dyn_BoundMethodHandle::vmargslot(mh()), CHECK);
1518 1522      verify_vmslots(mh, CHECK);
1519 1523    }
1520 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];
     1529 +
1521 1530    // If (a) the target is a direct non-dispatched method handle,
1522 1531    // or (b) the target is a dispatched direct method handle and we
1523 1532    // are binding the receiver, cut out the middle-man.
1524 1533    // Do this by decoding the DMH and using its methodOop directly as vmtarget.
1525 1534    bool direct_to_method = false;
1526 1535    if (OptimizeMethodHandles &&
1527 1536        target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
1528 1537        (argnum == 0 || sun_dyn_DirectMethodHandle::vmindex(target()) < 0)) {
1529 1538      int decode_flags = 0; klassOop receiver_limit_oop = NULL;
1530 1539      methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
1531 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 1542      assert(sun_dyn_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
1534 1543      if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
1535 1544        KlassHandle receiver_limit(THREAD, receiver_limit_oop);
1536 1545        init_BoundMethodHandle_with_receiver(mh, m,
1537 1546                                             receiver_limit, decode_flags,
1538 1547                                             CHECK);
1539 1548        return;
1540 1549      }
1541 1550  
1542 1551      // Even if it is not a bound receiver, we still might be able
↓ open down ↓ 4 lines elided ↑ open up ↑
1547 1556      }
1548 1557    }
1549 1558    if (!direct_to_method)
1550 1559      sun_dyn_BoundMethodHandle::set_vmtarget(mh(), target());
1551 1560  
1552 1561    if (VerifyMethodHandles) {
1553 1562      verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
1554 1563    }
1555 1564  
1556 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 1566    MethodHandleEntry* me = NULL;
1562 1567    if (ptype == T_OBJECT) {
1563 1568      if (direct_to_method)  me = MethodHandles::entry(_bound_ref_direct_mh);
1564 1569      else                   me = MethodHandles::entry(_bound_ref_mh);
1565 1570    } else if (slots_pushed == 2) {
1566 1571      if (direct_to_method)  me = MethodHandles::entry(_bound_long_direct_mh);
1567 1572      else                   me = MethodHandles::entry(_bound_long_mh);
1568 1573    } else if (slots_pushed == 1) {
1569 1574      if (direct_to_method)  me = MethodHandles::entry(_bound_int_direct_mh);
1570 1575      else                   me = MethodHandles::entry(_bound_int_mh);
↓ open down ↓ 899 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX