< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "code/dependencyContext.hpp"
  31 #include "compiler/compileBroker.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "interpreter/oopMapCache.hpp"
  34 #include "interpreter/linkResolver.hpp"
  35 #include "memory/allocation.inline.hpp"
  36 #include "memory/oopFactory.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/objArrayKlass.hpp"
  40 #include "oops/objArrayOop.inline.hpp"
  41 #include "oops/oop.inline.hpp"
  42 #include "oops/typeArrayOop.inline.hpp"
  43 #include "prims/methodHandles.hpp"
  44 #include "runtime/compilationPolicy.hpp"
  45 #include "runtime/deoptimization.hpp"
  46 #include "runtime/fieldDescriptor.inline.hpp"
  47 #include "runtime/handles.inline.hpp"
  48 #include "runtime/interfaceSupport.inline.hpp"
  49 #include "runtime/javaCalls.hpp"
  50 #include "runtime/jniHandles.inline.hpp"
  51 #include "runtime/timerTrace.hpp"
  52 #include "runtime/reflection.hpp"
  53 #include "runtime/safepointVerifiers.hpp"
  54 #include "runtime/signature.hpp"
  55 #include "runtime/stubRoutines.hpp"
  56 #include "utilities/exceptions.hpp"
  57 
  58 
  59 /*
  60  * JSR 292 reference implementation: method handles
  61  * The JDK 7 reference implementation represented method handle
  62  * combinations as chains.  Each link in the chain had a "vmentry"
  63  * field which pointed at a bit of assembly code which performed
  64  * one transformation before dispatching to the next link in the chain.
  65  *


 503   if (is_signature_polymorphic_name(klass, name)) {
 504     InstanceKlass* iklass = InstanceKlass::cast(klass);
 505     int me;
 506     int ms = iklass->find_method_by_name(name, &me);
 507     assert(ms != -1, "");
 508     for (; ms < me; ms++) {
 509       Method* m = iklass->methods()->at(ms);
 510       int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC;
 511       int flags = m->access_flags().as_int();
 512       if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) {
 513         return true;
 514       }
 515     }
 516   }
 517   return false;
 518 }
 519 
 520 // convert the external string or reflective type to an internal signature
 521 Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) {
 522   if (java_lang_invoke_MethodType::is_instance(type_str)) {
 523     return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found);
 524   } else if (java_lang_Class::is_instance(type_str)) {
 525     return java_lang_Class::as_signature(type_str, false);
 526   } else if (java_lang_String::is_instance_inlined(type_str)) {
 527     if (intern_if_not_found) {
 528       return java_lang_String::as_symbol(type_str);
 529     } else {
 530       return java_lang_String::as_symbol_or_null(type_str);
 531     }
 532   } else {
 533     THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL);
 534   }
 535 }
 536 
 537 static const char OBJ_SIG[] = "Ljava/lang/Object;";
 538 enum { OBJ_SIG_LEN = 18 };
 539 
 540 bool MethodHandles::is_basic_type_signature(Symbol* sig) {
 541   assert(vmSymbols::object_signature()->utf8_length() == (int)OBJ_SIG_LEN, "");
 542   assert(vmSymbols::object_signature()->equals(OBJ_SIG), "");
 543   const int len = sig->utf8_length();
 544   for (int i = 0; i < len; i++) {
 545     switch (sig->char_at(i)) {
 546     case 'L':
 547       // only java/lang/Object is valid here
 548       if (sig->index_of_at(i, OBJ_SIG, OBJ_SIG_LEN) != i)


 586     for (SignatureStream ss(sig); !ss.is_done(); ss.next()) {
 587       BasicType bt = ss.type();
 588       size_t this_arg_pos = buffer.size();
 589       if (ss.at_return_type()) {
 590         buffer.put(')');
 591       }
 592       if (arg_pos == keep_arg_pos) {
 593         buffer.write((char*) ss.raw_bytes(),
 594                      (int)   ss.raw_length());
 595       } else if (bt == T_OBJECT || bt == T_ARRAY) {
 596         buffer.write(OBJ_SIG, OBJ_SIG_LEN);
 597       } else {
 598         if (is_subword_type(bt))
 599           bt = T_INT;
 600         buffer.put(type2char(bt));
 601       }
 602       arg_pos++;
 603     }
 604     const char* sigstr =       buffer.base();
 605     int         siglen = (int) buffer.size();
 606     bsig = SymbolTable::new_symbol(sigstr, siglen);
 607   }
 608   assert(is_basic_type_signature(bsig) ||
 609          // detune assert in case the injected argument is not a basic type:
 610          keep_last_arg, "");
 611   return bsig;
 612 }
 613 
 614 void MethodHandles::print_as_basic_type_signature_on(outputStream* st,
 615                                                      Symbol* sig,
 616                                                      bool keep_arrays,
 617                                                      bool keep_basic_names) {
 618   st = st ? st : tty;
 619   int len  = sig->utf8_length();
 620   int array = 0;
 621   bool prev_type = false;
 622   for (int i = 0; i < len; i++) {
 623     char ch = sig->char_at(i);
 624     switch (ch) {
 625     case '(': case ')':
 626       prev_type = false;


1085   assert_locked_or_safepoint(CodeCache_lock);
1086 
1087   oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
1088   DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1089   deps.remove_dependent_nmethod(nm);
1090 }
1091 
1092 void MethodHandles::clean_dependency_context(oop call_site) {
1093   oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
1094   DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1095   deps.clean_unloading_dependents();
1096 }
1097 
1098 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
1099   assert_lock_strong(Compile_lock);
1100 
1101   int marked = 0;
1102   CallSiteDepChange changes(call_site, target);
1103   {
1104     NoSafepointVerifier nsv;
1105     MutexLocker mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1106 
1107     oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site());
1108     DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1109     marked = deps.mark_dependent_nmethods(changes);
1110   }
1111   if (marked > 0) {
1112     // At least one nmethod has been marked for deoptimization.
1113     Deoptimization::deoptimize_all_marked();

1114   }
1115 }
1116 
1117 void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
1118   if (TraceMethodHandles) {
1119     const char* name = vmIntrinsics::name_at(iid);
1120     if (*name == '_')  name += 1;
1121     const size_t len = strlen(name) + 50;
1122     char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
1123     const char* suffix = "";
1124     if (is_signature_polymorphic(iid)) {
1125       if (is_signature_polymorphic_static(iid))
1126         suffix = "/static";
1127       else
1128         suffix = "/private";
1129     }
1130     jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
1131     trace_method_handle(_masm, qname);
1132     // Note:  Don't free the allocated char array because it's used
1133     // during runtime.


1483   }
1484   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1485   caller->constants()->
1486     copy_bootstrap_arguments_at(bss_index_in_pool,
1487                                 start, end, buf, pos,
1488                                 (resolve == JNI_TRUE), ifna, CHECK);
1489 }
1490 JVM_END
1491 
1492 // It is called by a Cleaner object which ensures that dropped CallSites properly
1493 // deallocate their dependency information.
1494 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1495   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1496   {
1497     // Walk all nmethods depending on this call site.
1498     MutexLocker mu1(Compile_lock, thread);
1499 
1500     int marked = 0;
1501     {
1502       NoSafepointVerifier nsv;
1503       MutexLocker mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1504       DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1505       marked = deps.remove_all_dependents();
1506     }
1507     if (marked > 0) {
1508       // At least one nmethod has been marked for deoptimization
1509       Deoptimization::deoptimize_all_marked();

1510     }
1511   }
1512 }
1513 JVM_END
1514 
1515 /**
1516  * Throws a java/lang/UnsupportedOperationException unconditionally.
1517  * This is required by the specification of MethodHandle.invoke if
1518  * invoked directly.
1519  */
1520 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1521   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1522   return NULL;
1523 }
1524 JVM_END
1525 
1526 /**
1527  * Throws a java/lang/UnsupportedOperationException unconditionally.
1528  * This is required by the specification of MethodHandle.invokeExact if
1529  * invoked directly.




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"

  28 #include "code/codeCache.hpp"
  29 #include "code/dependencyContext.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "interpreter/oopMapCache.hpp"
  33 #include "interpreter/linkResolver.hpp"
  34 #include "memory/allocation.inline.hpp"
  35 #include "memory/oopFactory.hpp"
  36 #include "memory/resourceArea.hpp"


  37 #include "oops/objArrayOop.inline.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "oops/typeArrayOop.inline.hpp"
  40 #include "prims/methodHandles.hpp"
  41 #include "runtime/compilationPolicy.hpp"

  42 #include "runtime/fieldDescriptor.inline.hpp"
  43 #include "runtime/handles.inline.hpp"
  44 #include "runtime/interfaceSupport.inline.hpp"
  45 #include "runtime/javaCalls.hpp"
  46 #include "runtime/jniHandles.inline.hpp"
  47 #include "runtime/timerTrace.hpp"
  48 #include "runtime/reflection.hpp"
  49 #include "runtime/safepointVerifiers.hpp"
  50 #include "runtime/signature.hpp"
  51 #include "runtime/stubRoutines.hpp"
  52 #include "utilities/exceptions.hpp"
  53 
  54 
  55 /*
  56  * JSR 292 reference implementation: method handles
  57  * The JDK 7 reference implementation represented method handle
  58  * combinations as chains.  Each link in the chain had a "vmentry"
  59  * field which pointed at a bit of assembly code which performed
  60  * one transformation before dispatching to the next link in the chain.
  61  *


 499   if (is_signature_polymorphic_name(klass, name)) {
 500     InstanceKlass* iklass = InstanceKlass::cast(klass);
 501     int me;
 502     int ms = iklass->find_method_by_name(name, &me);
 503     assert(ms != -1, "");
 504     for (; ms < me; ms++) {
 505       Method* m = iklass->methods()->at(ms);
 506       int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS | JVM_ACC_PUBLIC;
 507       int flags = m->access_flags().as_int();
 508       if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) {
 509         return true;
 510       }
 511     }
 512   }
 513   return false;
 514 }
 515 
 516 // convert the external string or reflective type to an internal signature
 517 Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) {
 518   if (java_lang_invoke_MethodType::is_instance(type_str)) {
 519     return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found, THREAD);
 520   } else if (java_lang_Class::is_instance(type_str)) {
 521     return java_lang_Class::as_signature(type_str, false, THREAD);
 522   } else if (java_lang_String::is_instance_inlined(type_str)) {
 523     if (intern_if_not_found) {
 524       return java_lang_String::as_symbol(type_str, THREAD);
 525     } else {
 526       return java_lang_String::as_symbol_or_null(type_str);
 527     }
 528   } else {
 529     THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL);
 530   }
 531 }
 532 
 533 static const char OBJ_SIG[] = "Ljava/lang/Object;";
 534 enum { OBJ_SIG_LEN = 18 };
 535 
 536 bool MethodHandles::is_basic_type_signature(Symbol* sig) {
 537   assert(vmSymbols::object_signature()->utf8_length() == (int)OBJ_SIG_LEN, "");
 538   assert(vmSymbols::object_signature()->equals(OBJ_SIG), "");
 539   const int len = sig->utf8_length();
 540   for (int i = 0; i < len; i++) {
 541     switch (sig->char_at(i)) {
 542     case 'L':
 543       // only java/lang/Object is valid here
 544       if (sig->index_of_at(i, OBJ_SIG, OBJ_SIG_LEN) != i)


 582     for (SignatureStream ss(sig); !ss.is_done(); ss.next()) {
 583       BasicType bt = ss.type();
 584       size_t this_arg_pos = buffer.size();
 585       if (ss.at_return_type()) {
 586         buffer.put(')');
 587       }
 588       if (arg_pos == keep_arg_pos) {
 589         buffer.write((char*) ss.raw_bytes(),
 590                      (int)   ss.raw_length());
 591       } else if (bt == T_OBJECT || bt == T_ARRAY) {
 592         buffer.write(OBJ_SIG, OBJ_SIG_LEN);
 593       } else {
 594         if (is_subword_type(bt))
 595           bt = T_INT;
 596         buffer.put(type2char(bt));
 597       }
 598       arg_pos++;
 599     }
 600     const char* sigstr =       buffer.base();
 601     int         siglen = (int) buffer.size();
 602     bsig = SymbolTable::new_symbol(sigstr, siglen, THREAD);
 603   }
 604   assert(is_basic_type_signature(bsig) ||
 605          // detune assert in case the injected argument is not a basic type:
 606          keep_last_arg, "");
 607   return bsig;
 608 }
 609 
 610 void MethodHandles::print_as_basic_type_signature_on(outputStream* st,
 611                                                      Symbol* sig,
 612                                                      bool keep_arrays,
 613                                                      bool keep_basic_names) {
 614   st = st ? st : tty;
 615   int len  = sig->utf8_length();
 616   int array = 0;
 617   bool prev_type = false;
 618   for (int i = 0; i < len; i++) {
 619     char ch = sig->char_at(i);
 620     switch (ch) {
 621     case '(': case ')':
 622       prev_type = false;


1081   assert_locked_or_safepoint(CodeCache_lock);
1082 
1083   oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
1084   DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1085   deps.remove_dependent_nmethod(nm);
1086 }
1087 
1088 void MethodHandles::clean_dependency_context(oop call_site) {
1089   oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
1090   DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1091   deps.clean_unloading_dependents();
1092 }
1093 
1094 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
1095   assert_lock_strong(Compile_lock);
1096 
1097   int marked = 0;
1098   CallSiteDepChange changes(call_site, target);
1099   {
1100     NoSafepointVerifier nsv;
1101     MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1102 
1103     oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site());
1104     DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
1105     marked = deps.mark_dependent_nmethods(changes);
1106   }
1107   if (marked > 0) {
1108     // At least one nmethod has been marked for deoptimization.
1109     VM_Deoptimize op;
1110     VMThread::execute(&op);
1111   }
1112 }
1113 
1114 void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
1115   if (TraceMethodHandles) {
1116     const char* name = vmIntrinsics::name_at(iid);
1117     if (*name == '_')  name += 1;
1118     const size_t len = strlen(name) + 50;
1119     char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
1120     const char* suffix = "";
1121     if (is_signature_polymorphic(iid)) {
1122       if (is_signature_polymorphic_static(iid))
1123         suffix = "/static";
1124       else
1125         suffix = "/private";
1126     }
1127     jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
1128     trace_method_handle(_masm, qname);
1129     // Note:  Don't free the allocated char array because it's used
1130     // during runtime.


1480   }
1481   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1482   caller->constants()->
1483     copy_bootstrap_arguments_at(bss_index_in_pool,
1484                                 start, end, buf, pos,
1485                                 (resolve == JNI_TRUE), ifna, CHECK);
1486 }
1487 JVM_END
1488 
1489 // It is called by a Cleaner object which ensures that dropped CallSites properly
1490 // deallocate their dependency information.
1491 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1492   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1493   {
1494     // Walk all nmethods depending on this call site.
1495     MutexLocker mu1(Compile_lock, thread);
1496 
1497     int marked = 0;
1498     {
1499       NoSafepointVerifier nsv;
1500       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1501       DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1502       marked = deps.remove_all_dependents();
1503     }
1504     if (marked > 0) {
1505       // At least one nmethod has been marked for deoptimization
1506       VM_Deoptimize op;
1507       VMThread::execute(&op);
1508     }
1509   }
1510 }
1511 JVM_END
1512 
1513 /**
1514  * Throws a java/lang/UnsupportedOperationException unconditionally.
1515  * This is required by the specification of MethodHandle.invoke if
1516  * invoked directly.
1517  */
1518 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1519   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1520   return NULL;
1521 }
1522 JVM_END
1523 
1524 /**
1525  * Throws a java/lang/UnsupportedOperationException unconditionally.
1526  * This is required by the specification of MethodHandle.invokeExact if
1527  * invoked directly.


< prev index next >