src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7086585 Sdiff src/share/vm/prims

src/share/vm/prims/methodHandles.cpp

Print this page




 503   IS_TYPE        = java_lang_invoke_MemberName::MN_IS_TYPE,
 504   SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
 505   SEARCH_INTERFACES   = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
 506   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
 507   VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED
 508 };
 509 
 510 Handle MethodHandles::new_MemberName(TRAPS) {
 511   Handle empty;
 512   instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
 513   if (!k->is_initialized())  k->initialize(CHECK_(empty));
 514   return Handle(THREAD, k->allocate_instance(THREAD));
 515 }
 516 
 517 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
 518   if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
 519     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
 520     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
 521     int mods  = java_lang_reflect_Field::modifiers(target_oop);
 522     klassOop k = java_lang_Class::as_klassOop(clazz);
 523     int offset = instanceKlass::cast(k)->offset_from_fields(slot);
 524     init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
 525   } else {
 526     KlassHandle receiver_limit; int decode_flags = 0;
 527     methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags);
 528     bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
 529     init_MemberName(mname_oop, m(), do_dispatch);
 530   }
 531 }
 532 
 533 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
 534   int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
 535                | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
 536   oop vmtarget = m;
 537   int vmindex  = methodOopDesc::invalid_vtable_index;  // implies no info yet
 538   if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
 539     vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
 540   assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
 541   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
 542   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
 543   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);


1615 }
1616 
1617 void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
1618   // Verify type.
1619   Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
1620   verify_method_type(m, mtype, false, KlassHandle(), CHECK);
1621 
1622   // Verify vmslots.
1623   if (java_lang_invoke_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
1624     THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
1625   }
1626 }
1627 
1628 void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
1629   // Check arguments.
1630   if (mh.is_null() || m.is_null() ||
1631       (!do_dispatch && m->is_abstract())) {
1632     THROW(vmSymbols::java_lang_InternalError());
1633   }
1634 
1635   java_lang_invoke_MethodHandle::init_vmslots(mh());
1636 
1637   if (VerifyMethodHandles) {
1638     // The privileged code which invokes this routine should not make
1639     // a mistake about types, but it's better to verify.
1640     verify_DirectMethodHandle(mh, m, CHECK);
1641   }
1642 
1643   // Finally, after safety checks are done, link to the target method.
1644   // We will follow the same path as the latter part of
1645   // InterpreterRuntime::resolve_invoke(), which first finds the method
1646   // and then decides how to populate the constant pool cache entry
1647   // that links the interpreter calls to the method.  We need the same
1648   // bits, and will use the same calling sequence code.
1649 
1650   int    vmindex = methodOopDesc::garbage_vtable_index;
1651   Handle vmtarget;
1652 
1653   instanceKlass::cast(m->method_holder())->link_class(CHECK);
1654 
1655   MethodHandleEntry* me = NULL;
1656   if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) {


1739                                                          int decode_flags,
1740                                                          TRAPS) {
1741   // Check arguments.
1742   if (mh.is_null() || original_m.is_null()) {
1743     THROW(vmSymbols::java_lang_InternalError());
1744   }
1745 
1746   KlassHandle receiver_klass;
1747   {
1748     oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh());
1749     if (receiver_oop != NULL)
1750       receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
1751   }
1752   methodHandle m = dispatch_decoded_method(original_m,
1753                                            receiver_limit, decode_flags,
1754                                            receiver_klass,
1755                                            CHECK);
1756   if (m.is_null())      { THROW(vmSymbols::java_lang_InternalError()); }
1757   if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
1758 
1759   java_lang_invoke_MethodHandle::init_vmslots(mh());
1760   int vmargslot = m->size_of_parameters() - 1;
1761   assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
1762 
1763   if (VerifyMethodHandles) {
1764     verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
1765   }
1766 
1767   java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
1768 
1769   DEBUG_ONLY(KlassHandle junk1; int junk2);
1770   assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
1771   assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
1772 
1773   // Done!
1774   java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
1775 }
1776 
1777 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
1778                                              bool direct_to_method, TRAPS) {
1779   ResourceMark rm;


1845   }
1846 
1847   if (err == NULL) {
1848     // Verify the rest of the method type.
1849     err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()),
1850                                       argnum, ptype_handle(),
1851                                       java_lang_invoke_MethodHandle::type(target()));
1852   }
1853 
1854   if (err != NULL) {
1855     THROW_MSG(vmSymbols::java_lang_InternalError(), err);
1856   }
1857 }
1858 
1859 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
1860   // Check arguments.
1861   if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) {
1862     THROW(vmSymbols::java_lang_InternalError());
1863   }
1864 
1865   java_lang_invoke_MethodHandle::init_vmslots(mh());
1866   int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh());
1867 
1868   if (VerifyMethodHandles) {
1869     int insert_after = argnum - 1;
1870     verify_vmargslot(mh, insert_after, argslot, CHECK);
1871     verify_vmslots(mh, CHECK);
1872   }
1873 
1874   // Get bound type and required slots.
1875   BasicType ptype;
1876   {
1877     oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
1878     ptype = java_lang_Class::as_BasicType(ptype_oop);
1879   }
1880   int slots_pushed = type2size[ptype];
1881 
1882   // If (a) the target is a direct non-dispatched method handle,
1883   // or (b) the target is a dispatched direct method handle and we
1884   // are binding the receiver, cut out the middle-man.
1885   // Do this by decoding the DMH and using its methodOop directly as vmtarget.


2669 }
2670 
2671 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) {
2672   Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target()));
2673   Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype()));
2674   if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
2675   if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) {
2676     if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) {
2677       // fill it in
2678       Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform()));
2679       TempNewSymbol erased_signature
2680         = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK);
2681       methodOop cookie
2682         = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(),
2683                                                       erased_signature,
2684                                                       SystemDictionaryHandles::Object_klass(),
2685                                                       THREAD);
2686       java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie);
2687     }
2688   }

2689 }
2690 
2691 #ifdef ASSERT
2692 
2693 extern "C"
2694 void print_method_handle(oop mh);
2695 
2696 static void stress_method_handle_walk_impl(Handle mh, TRAPS) {
2697   if (StressMethodHandleWalk) {
2698     // Exercise the MethodHandleWalk code in various ways and validate
2699     // the resulting method oop.  Some of these produce output so they
2700     // are guarded under Verbose.
2701     ResourceMark rm;
2702     HandleMark hm;
2703     if (Verbose) {
2704       print_method_handle(mh());
2705     }
2706     TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK);
2707     Handle mt = java_lang_invoke_MethodHandle::type(mh());
2708     TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK);




 503   IS_TYPE        = java_lang_invoke_MemberName::MN_IS_TYPE,
 504   SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
 505   SEARCH_INTERFACES   = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
 506   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
 507   VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED
 508 };
 509 
 510 Handle MethodHandles::new_MemberName(TRAPS) {
 511   Handle empty;
 512   instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
 513   if (!k->is_initialized())  k->initialize(CHECK_(empty));
 514   return Handle(THREAD, k->allocate_instance(THREAD));
 515 }
 516 
 517 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
 518   if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
 519     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
 520     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
 521     int mods  = java_lang_reflect_Field::modifiers(target_oop);
 522     klassOop k = java_lang_Class::as_klassOop(clazz);
 523     int offset = instanceKlass::cast(k)->field_offset(slot);
 524     init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
 525   } else {
 526     KlassHandle receiver_limit; int decode_flags = 0;
 527     methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags);
 528     bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
 529     init_MemberName(mname_oop, m(), do_dispatch);
 530   }
 531 }
 532 
 533 void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
 534   int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
 535                | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
 536   oop vmtarget = m;
 537   int vmindex  = methodOopDesc::invalid_vtable_index;  // implies no info yet
 538   if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
 539     vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
 540   assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
 541   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
 542   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
 543   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);


1615 }
1616 
1617 void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
1618   // Verify type.
1619   Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
1620   verify_method_type(m, mtype, false, KlassHandle(), CHECK);
1621 
1622   // Verify vmslots.
1623   if (java_lang_invoke_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
1624     THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
1625   }
1626 }
1627 
1628 void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
1629   // Check arguments.
1630   if (mh.is_null() || m.is_null() ||
1631       (!do_dispatch && m->is_abstract())) {
1632     THROW(vmSymbols::java_lang_InternalError());
1633   }
1634 


1635   if (VerifyMethodHandles) {
1636     // The privileged code which invokes this routine should not make
1637     // a mistake about types, but it's better to verify.
1638     verify_DirectMethodHandle(mh, m, CHECK);
1639   }
1640 
1641   // Finally, after safety checks are done, link to the target method.
1642   // We will follow the same path as the latter part of
1643   // InterpreterRuntime::resolve_invoke(), which first finds the method
1644   // and then decides how to populate the constant pool cache entry
1645   // that links the interpreter calls to the method.  We need the same
1646   // bits, and will use the same calling sequence code.
1647 
1648   int    vmindex = methodOopDesc::garbage_vtable_index;
1649   Handle vmtarget;
1650 
1651   instanceKlass::cast(m->method_holder())->link_class(CHECK);
1652 
1653   MethodHandleEntry* me = NULL;
1654   if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) {


1737                                                          int decode_flags,
1738                                                          TRAPS) {
1739   // Check arguments.
1740   if (mh.is_null() || original_m.is_null()) {
1741     THROW(vmSymbols::java_lang_InternalError());
1742   }
1743 
1744   KlassHandle receiver_klass;
1745   {
1746     oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh());
1747     if (receiver_oop != NULL)
1748       receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
1749   }
1750   methodHandle m = dispatch_decoded_method(original_m,
1751                                            receiver_limit, decode_flags,
1752                                            receiver_klass,
1753                                            CHECK);
1754   if (m.is_null())      { THROW(vmSymbols::java_lang_InternalError()); }
1755   if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
1756 

1757   int vmargslot = m->size_of_parameters() - 1;
1758   assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
1759 
1760   if (VerifyMethodHandles) {
1761     verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
1762   }
1763 
1764   java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
1765 
1766   DEBUG_ONLY(KlassHandle junk1; int junk2);
1767   assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
1768   assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
1769 
1770   // Done!
1771   java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
1772 }
1773 
1774 void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
1775                                              bool direct_to_method, TRAPS) {
1776   ResourceMark rm;


1842   }
1843 
1844   if (err == NULL) {
1845     // Verify the rest of the method type.
1846     err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()),
1847                                       argnum, ptype_handle(),
1848                                       java_lang_invoke_MethodHandle::type(target()));
1849   }
1850 
1851   if (err != NULL) {
1852     THROW_MSG(vmSymbols::java_lang_InternalError(), err);
1853   }
1854 }
1855 
1856 void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
1857   // Check arguments.
1858   if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) {
1859     THROW(vmSymbols::java_lang_InternalError());
1860   }
1861 

1862   int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh());
1863 
1864   if (VerifyMethodHandles) {
1865     int insert_after = argnum - 1;
1866     verify_vmargslot(mh, insert_after, argslot, CHECK);
1867     verify_vmslots(mh, CHECK);
1868   }
1869 
1870   // Get bound type and required slots.
1871   BasicType ptype;
1872   {
1873     oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
1874     ptype = java_lang_Class::as_BasicType(ptype_oop);
1875   }
1876   int slots_pushed = type2size[ptype];
1877 
1878   // If (a) the target is a direct non-dispatched method handle,
1879   // or (b) the target is a dispatched direct method handle and we
1880   // are binding the receiver, cut out the middle-man.
1881   // Do this by decoding the DMH and using its methodOop directly as vmtarget.


2665 }
2666 
2667 void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) {
2668   Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target()));
2669   Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype()));
2670   if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
2671   if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) {
2672     if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) {
2673       // fill it in
2674       Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform()));
2675       TempNewSymbol erased_signature
2676         = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK);
2677       methodOop cookie
2678         = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(),
2679                                                       erased_signature,
2680                                                       SystemDictionaryHandles::Object_klass(),
2681                                                       THREAD);
2682       java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie);
2683     }
2684   }
2685   assert(java_lang_invoke_MethodTypeForm::vmslots(mtform()) == argument_slot_count(mtype()), "must agree");
2686 }
2687 
2688 #ifdef ASSERT
2689 
2690 extern "C"
2691 void print_method_handle(oop mh);
2692 
2693 static void stress_method_handle_walk_impl(Handle mh, TRAPS) {
2694   if (StressMethodHandleWalk) {
2695     // Exercise the MethodHandleWalk code in various ways and validate
2696     // the resulting method oop.  Some of these produce output so they
2697     // are guarded under Verbose.
2698     ResourceMark rm;
2699     HandleMark hm;
2700     if (Verbose) {
2701       print_method_handle(mh());
2702     }
2703     TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK);
2704     Handle mt = java_lang_invoke_MethodHandle::type(mh());
2705     TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK);


src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File