src/share/vm/runtime/sharedRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File JDK-8022494 Sdiff src/share/vm/runtime

src/share/vm/runtime/sharedRuntime.cpp

Print this page




2546   _total_args_passed = total_args_passed;
2547   _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode);
2548   memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType));
2549 }
2550 
2551 
2552 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
2553   if (length != _code_length) {
2554     return false;
2555   }
2556   for (int i = 0; i < length; i++) {
2557     if (buffer[i] != _saved_code[i]) {
2558       return false;
2559     }
2560   }
2561   return true;
2562 }
2563 #endif
2564 
2565 
2566 // Create a native wrapper for this native method.  The wrapper converts the
2567 // java compiled calling convention to the native convention, handlizes
2568 // arguments, and transitions to native.  On return from the native we transition
2569 // back to java blocking if a safepoint is in progress.
2570 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) {


2571   ResourceMark rm;
2572   nmethod* nm = NULL;
2573 
2574   assert(method->is_native(), "must be native");
2575   assert(method->is_method_handle_intrinsic() ||
2576          method->has_native_function(), "must have something valid to call!");
2577 
2578   {
2579     // perform the work while holding the lock, but perform any printing outside the lock
2580     MutexLocker mu(AdapterHandlerLibrary_lock);
2581     // See if somebody beat us to it
2582     nm = method->code();
2583     if (nm) {
2584       return nm;











2585     }
2586 
2587     ResourceMark rm;
2588 

2589     BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
2590     if (buf != NULL) {
2591       CodeBuffer buffer(buf);
2592       double locs_buf[20];
2593       buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
2594       MacroAssembler _masm(&buffer);
2595 
2596       // Fill in the signature array, for the calling-convention call.
2597       const int total_args_passed = method->size_of_parameters();
2598 
2599       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
2600       VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
2601       int i=0;
2602       if( !method->is_static() )  // Pass in receiver first
2603         sig_bt[i++] = T_OBJECT;
2604       SignatureStream ss(method->signature());
2605       for( ; !ss.at_return_type(); ss.next()) {
2606         sig_bt[i++] = ss.type();  // Collect remaining bits of signature
2607         if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
2608           sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
2609       }
2610       assert(i == total_args_passed, "");
2611       BasicType ret_type = ss.type();
2612 
2613       // Now get the compiled-Java layout as input (or output) arguments.
2614       // NOTE: Stubs for compiled entry points of method handle intrinsics
2615       // are just trampolines so the argument registers must be outgoing ones.
2616       const bool is_outgoing = method->is_method_handle_intrinsic();
2617       int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
2618 
2619       // Generate the compiled-to-native wrapper code
2620       nm = SharedRuntime::generate_native_wrapper(&_masm,
2621                                                   method,
2622                                                   compile_id,
2623                                                   sig_bt,
2624                                                   regs,
2625                                                   ret_type);
2626     }
2627   }

2628 
2629   // Must unlock before calling set_code
2630 
2631   // Install the generated code.
2632   if (nm != NULL) {
2633     if (PrintCompilation) {
2634       ttyLocker ttyl;
2635       CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
2636     }
2637     method->set_code(method, nm);
2638     nm->post_compiled_method_load_event();
2639   } else {
2640     // CodeCache is full, disable compilation
2641     CompileBroker::handle_full_code_cache();
2642   }
2643   return nm;
2644 }
2645 
2646 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread))
2647   assert(thread == JavaThread::current(), "must be");
2648   // The code is about to enter a JNI lazy critical native method and
2649   // _needs_gc is true, so if this thread is already in a critical
2650   // section then just return, otherwise this thread should block
2651   // until needs_gc has been cleared.
2652   if (thread->in_critical()) {
2653     return;
2654   }
2655   // Lock and unlock a critical section to give the system a chance to block
2656   GC_locker::lock_critical(thread);
2657   GC_locker::unlock_critical(thread);
2658 JRT_END
2659 
2660 #ifdef HAVE_DTRACE_H
2661 // Create a dtrace nmethod for this method.  The wrapper converts the
2662 // java compiled calling convention to the native convention, makes a dummy call
2663 // (actually nops for the size of the call instruction, which become a trap if




2546   _total_args_passed = total_args_passed;
2547   _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode);
2548   memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType));
2549 }
2550 
2551 
2552 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
2553   if (length != _code_length) {
2554     return false;
2555   }
2556   for (int i = 0; i < length; i++) {
2557     if (buffer[i] != _saved_code[i]) {
2558       return false;
2559     }
2560   }
2561   return true;
2562 }
2563 #endif
2564 
2565 
2566 /**
2567  * Create a native wrapper for this native method.  The wrapper converts the
2568  * Java-compiled calling convention to the native convention, handles
2569  * arguments, and transitions to native.  On return from the native we transition
2570  * back to java blocking if a safepoint is in progress.
2571  */
2572 void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
2573   ResourceMark rm;
2574   nmethod* nm = NULL;
2575 
2576   assert(method->is_native(), "must be native");
2577   assert(method->is_method_handle_intrinsic() ||
2578          method->has_native_function(), "must have something valid to call!");
2579 
2580   {
2581     // perform the work while holding the lock, but perform any printing outside the lock
2582     MutexLocker mu(AdapterHandlerLibrary_lock);
2583     // See if somebody beat us to it
2584     nm = method->code();
2585     if (nm != NULL) {
2586       return;
2587     }
2588 
2589     const int compile_id = CompileBroker::assign_compile_id(method, CompileBroker::standard_entry_bci);
2590     if (compile_id == 0) {
2591       // The compilation falls outside the allowed range. Note that this can only happen in debug
2592       // build if the cIStart(OSR) and CIStop(OSR) flags at are specified. Since currently this wrapper
2593       // must be generated for method handle intrinsics (8026407), print out a warning.
2594       if (method->is_method_handle_intrinsic()) {
2595         warning("Must generate wrapper for method handle intrinsic");
2596         return;
2597       }
2598     }
2599 

2600 
2601     ResourceMark rm;
2602     BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
2603     if (buf != NULL) {
2604       CodeBuffer buffer(buf);
2605       double locs_buf[20];
2606       buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
2607       MacroAssembler _masm(&buffer);
2608 
2609       // Fill in the signature array, for the calling-convention call.
2610       const int total_args_passed = method->size_of_parameters();
2611 
2612       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
2613       VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
2614       int i=0;
2615       if( !method->is_static() )  // Pass in receiver first
2616         sig_bt[i++] = T_OBJECT;
2617       SignatureStream ss(method->signature());
2618       for( ; !ss.at_return_type(); ss.next()) {
2619         sig_bt[i++] = ss.type();  // Collect remaining bits of signature
2620         if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
2621           sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
2622       }
2623       assert(i == total_args_passed, "");
2624       BasicType ret_type = ss.type();
2625 
2626       // Now get the compiled-Java layout as input (or output) arguments.
2627       // NOTE: Stubs for compiled entry points of method handle intrinsics
2628       // are just trampolines so the argument registers must be outgoing ones.
2629       const bool is_outgoing = method->is_method_handle_intrinsic();
2630       int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
2631 
2632       // Generate the compiled-to-native wrapper code
2633       nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
2634 
2635       if (nm != NULL) {
2636         method->set_code(method, nm);


2637       }
2638     }
2639   } // Unlock AdapterHandlerLibrary_lock
2640 

2641 
2642   // Install the generated code.
2643   if (nm != NULL) {
2644     if (PrintCompilation) {
2645       ttyLocker ttyl;
2646       CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
2647     }

2648     nm->post_compiled_method_load_event();
2649   } else {
2650     // CodeCache is full, disable compilation
2651     CompileBroker::handle_full_code_cache();
2652   }

2653 }
2654 
2655 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread))
2656   assert(thread == JavaThread::current(), "must be");
2657   // The code is about to enter a JNI lazy critical native method and
2658   // _needs_gc is true, so if this thread is already in a critical
2659   // section then just return, otherwise this thread should block
2660   // until needs_gc has been cleared.
2661   if (thread->in_critical()) {
2662     return;
2663   }
2664   // Lock and unlock a critical section to give the system a chance to block
2665   GC_locker::lock_critical(thread);
2666   GC_locker::unlock_critical(thread);
2667 JRT_END
2668 
2669 #ifdef HAVE_DTRACE_H
2670 // Create a dtrace nmethod for this method.  The wrapper converts the
2671 // java compiled calling convention to the native convention, makes a dummy call
2672 // (actually nops for the size of the call instruction, which become a trap if


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