94 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 95 int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size; 96 97 jobject MethodHandles::_raise_exception_method; 98 99 #ifdef ASSERT 100 bool MethodHandles::spot_check_entry_names() { 101 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); 102 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); 103 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); 104 assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), ""); 105 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); 106 return true; 107 } 108 #endif 109 110 111 //------------------------------------------------------------------------------ 112 // MethodHandles::generate_adapters 113 // 114 void MethodHandles::generate_adapters(TRAPS) { 115 if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return; 116 117 assert(_adapter_code == NULL, "generate only once"); 118 119 ResourceMark rm; 120 TraceTime timer("MethodHandles adapters generation", TraceStartupTime); 121 _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size); 122 if (_adapter_code == NULL) 123 vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters"); 124 CodeBuffer code(_adapter_code); 125 MethodHandlesAdapterGenerator g(&code); 126 g.generate(CHECK); 127 } 128 129 130 //------------------------------------------------------------------------------ 131 // MethodHandlesAdapterGenerator::generate 132 // 133 void MethodHandlesAdapterGenerator::generate(TRAPS) { 134 // Generate generic method handle adapters. 135 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 136 ek < MethodHandles::_EK_LIMIT; 137 ek = MethodHandles::EntryKind(1 + (int)ek)) { 138 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 139 MethodHandles::generate_method_handle_stub(_masm, ek, CHECK); 140 } 141 } 142 143 144 void MethodHandles::set_enabled(bool z) { 145 if (_enabled != z) { 146 guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles"); 147 _enabled = z; 148 } 149 } 150 151 // Note: A method which does not have a TRAPS argument cannot block in the GC 152 // or throw exceptions. Such methods are used in this file to do something quick 153 // and local, like parse a data structure. For speed, such methods work on plain 154 // oops, not handles. Trapping methods uniformly operate on handles. 155 156 methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, 157 klassOop& receiver_limit_result, int& decode_flags_result) { 158 if (vmtarget == NULL) return NULL; 159 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); 2604 MethodHandles::set_enabled(false); 2605 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2606 enable_MH = false; 2607 env->ExceptionClear(); 2608 } 2609 } 2610 2611 if (enable_MH) { 2612 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); 2613 if (MHI_klass.not_null()) { 2614 symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); 2615 symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); 2616 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) 2617 ->find_method(raiseException_name(), raiseException_sig()); 2618 if (raiseException_method != NULL && raiseException_method->is_static()) { 2619 MethodHandles::set_raise_exception_method(raiseException_method); 2620 } else { 2621 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2622 enable_MH = false; 2623 } 2624 } 2625 } 2626 2627 if (enable_MH) { 2628 MethodHandles::set_enabled(true); 2629 } 2630 2631 if (!EnableInvokeDynamic) { 2632 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable."); 2633 return; // bind nothing 2634 } 2635 2636 { 2637 ThreadToNativeFromVM ttnfv(thread); 2638 2639 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod)); 2640 if (env->ExceptionOccurred()) { 2641 MethodHandles::set_enabled(false); 2642 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2643 env->ExceptionClear(); 2644 } else { 2645 MethodHandles::set_enabled(true); 2646 } 2647 } 2648 2649 // Generate method handles adapters if enabled. 2650 if (MethodHandles::enabled()) { 2651 MethodHandles::generate_adapters(CHECK); 2652 } 2653 } 2654 JVM_END | 94 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 95 int MethodHandles::_adapter_code_size = StubRoutines::method_handles_adapters_code_size; 96 97 jobject MethodHandles::_raise_exception_method; 98 99 #ifdef ASSERT 100 bool MethodHandles::spot_check_entry_names() { 101 assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), ""); 102 assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), ""); 103 assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), ""); 104 assert(!strcmp(entry_name(_adapter_ricochet), "adapter_ricochet"), ""); 105 assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), ""); 106 return true; 107 } 108 #endif 109 110 111 //------------------------------------------------------------------------------ 112 // MethodHandles::generate_adapters 113 // 114 void MethodHandles::generate_adapters() { 115 if (!EnableMethodHandles || SystemDictionary::MethodHandle_klass() == NULL) return; 116 117 assert(_adapter_code == NULL, "generate only once"); 118 119 ResourceMark rm; 120 TraceTime timer("MethodHandles adapters generation", TraceStartupTime); 121 _adapter_code = MethodHandlesAdapterBlob::create(_adapter_code_size); 122 if (_adapter_code == NULL) 123 vm_exit_out_of_memory(_adapter_code_size, "CodeCache: no room for MethodHandles adapters"); 124 CodeBuffer code(_adapter_code); 125 MethodHandlesAdapterGenerator g(&code); 126 g.generate(); 127 } 128 129 130 //------------------------------------------------------------------------------ 131 // MethodHandlesAdapterGenerator::generate 132 // 133 void MethodHandlesAdapterGenerator::generate() { 134 // Generate generic method handle adapters. 135 for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST; 136 ek < MethodHandles::_EK_LIMIT; 137 ek = MethodHandles::EntryKind(1 + (int)ek)) { 138 StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek)); 139 MethodHandles::generate_method_handle_stub(_masm, ek); 140 } 141 } 142 143 144 void MethodHandles::set_enabled(bool z) { 145 if (_enabled != z) { 146 guarantee(z && EnableMethodHandles, "can only enable once, and only if -XX:+EnableMethodHandles"); 147 _enabled = z; 148 } 149 } 150 151 // Note: A method which does not have a TRAPS argument cannot block in the GC 152 // or throw exceptions. Such methods are used in this file to do something quick 153 // and local, like parse a data structure. For speed, such methods work on plain 154 // oops, not handles. Trapping methods uniformly operate on handles. 155 156 methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, 157 klassOop& receiver_limit_result, int& decode_flags_result) { 158 if (vmtarget == NULL) return NULL; 159 assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); 2604 MethodHandles::set_enabled(false); 2605 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2606 enable_MH = false; 2607 env->ExceptionClear(); 2608 } 2609 } 2610 2611 if (enable_MH) { 2612 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); 2613 if (MHI_klass.not_null()) { 2614 symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); 2615 symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); 2616 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) 2617 ->find_method(raiseException_name(), raiseException_sig()); 2618 if (raiseException_method != NULL && raiseException_method->is_static()) { 2619 MethodHandles::set_raise_exception_method(raiseException_method); 2620 } else { 2621 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2622 enable_MH = false; 2623 } 2624 } else { 2625 enable_MH = false; 2626 } 2627 } 2628 2629 if (enable_MH) { 2630 // We need to link the MethodHandleImpl klass before we generate 2631 // the method handle adapters as the _raise_exception adapter uses 2632 // one of its methods (and its c2i-adapter). 2633 KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass(); 2634 instanceKlass* ik = instanceKlass::cast(k()); 2635 ik->link_class(CHECK); 2636 2637 MethodHandles::generate_adapters(); 2638 MethodHandles::set_enabled(true); 2639 } 2640 2641 if (!EnableInvokeDynamic) { 2642 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable."); 2643 return; // bind nothing 2644 } 2645 2646 { 2647 ThreadToNativeFromVM ttnfv(thread); 2648 2649 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod)); 2650 if (env->ExceptionOccurred()) { 2651 MethodHandles::set_enabled(false); 2652 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2653 env->ExceptionClear(); 2654 } else { 2655 MethodHandles::set_enabled(true); 2656 } 2657 } 2658 } 2659 JVM_END |