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

src/share/vm/prims/methodHandles.cpp

Print this page




  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
src/share/vm/prims/methodHandles.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File