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

src/share/vm/runtime/sharedRuntime.cpp

Print this page




2389     // Fill in the signature array, for the calling-convention call.
2390     int total_args_passed = method->size_of_parameters(); // All args on stack
2391 
2392     BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
2393     VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
2394     int i = 0;
2395     if (!method->is_static())  // Pass in receiver first
2396       sig_bt[i++] = T_OBJECT;
2397     for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
2398       sig_bt[i++] = ss.type();  // Collect remaining bits of signature
2399       if (ss.type() == T_LONG || ss.type() == T_DOUBLE)
2400         sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
2401     }
2402     assert(i == total_args_passed, "");
2403 
2404     // Lookup method signature's fingerprint
2405     entry = _adapters->lookup(total_args_passed, sig_bt);
2406 
2407 #ifdef ASSERT
2408     AdapterHandlerEntry* shared_entry = NULL;
2409     if (VerifyAdapterSharing && entry != NULL) {

2410       shared_entry = entry;
2411       entry = NULL;
2412     }
2413 #endif
2414 
2415     if (entry != NULL) {









2416       return entry;
2417     }

2418 
2419     // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
2420     int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
2421 
2422     // Make a C heap allocated version of the fingerprint to store in the adapter
2423     fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
2424 
2425     // Create I2C & C2I handlers
2426 
2427     BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
2428     if (buf != NULL) {
2429       CodeBuffer buffer(buf);
2430       short buffer_locs[20];
2431       buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
2432                                              sizeof(buffer_locs)/sizeof(relocInfo));
2433       MacroAssembler _masm(&buffer);
2434 


2435       entry = SharedRuntime::generate_i2c2i_adapters(&_masm,
2436                                                      total_args_passed,
2437                                                      comp_args_on_stack,
2438                                                      sig_bt,
2439                                                      regs,
2440                                                      fingerprint);
2441 
2442 #ifdef ASSERT
2443       if (VerifyAdapterSharing) {
2444         if (shared_entry != NULL) {
2445           assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt),
2446                  "code must match");
2447           // Release the one just created and return the original
2448           _adapters->free_entry(entry);
2449           return shared_entry;
2450         } else  {
2451           entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt);
2452         }
2453       }
2454 #endif
2455 
2456       B = AdapterBlob::create(&buffer);
2457       NOT_PRODUCT(insts_size = buffer.insts_size());
2458     }
2459     if (B == NULL) {
2460       // CodeCache is full, disable compilation
2461       // Ought to log this but compile log is only per compile thread
2462       // and we're some non descript Java thread.
2463       MutexUnlocker mu(AdapterHandlerLibrary_lock);
2464       CompileBroker::handle_full_code_cache();
2465       return NULL; // Out of CodeCache space
2466     }
2467     entry->relocate(B->content_begin());
2468 #ifndef PRODUCT
2469     // debugging suppport
2470     if (PrintAdapterHandlers || PrintStubCode) {
2471       ttyLocker ttyl;


2513 }
2514 
2515 void AdapterHandlerEntry::relocate(address new_base) {
2516   address old_base = base_address();
2517   assert(old_base != NULL, "");
2518   ptrdiff_t delta = new_base - old_base;
2519   if (_i2c_entry != NULL)
2520     _i2c_entry += delta;
2521   if (_c2i_entry != NULL)
2522     _c2i_entry += delta;
2523   if (_c2i_unverified_entry != NULL)
2524     _c2i_unverified_entry += delta;
2525   assert(base_address() == new_base, "");
2526 }
2527 
2528 
2529 void AdapterHandlerEntry::deallocate() {
2530   delete _fingerprint;
2531 #ifdef ASSERT
2532   if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);
2533   if (_saved_sig)  FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode);
2534 #endif
2535 }
2536 
2537 
2538 #ifdef ASSERT
2539 // Capture the code before relocation so that it can be compared
2540 // against other versions.  If the code is captured after relocation
2541 // then relative instructions won't be equivalent.
2542 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
2543   _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode);
2544   _code_length = length;
2545   memcpy(_saved_code, buffer, length);
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




2389     // Fill in the signature array, for the calling-convention call.
2390     int total_args_passed = method->size_of_parameters(); // All args on stack
2391 
2392     BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
2393     VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
2394     int i = 0;
2395     if (!method->is_static())  // Pass in receiver first
2396       sig_bt[i++] = T_OBJECT;
2397     for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
2398       sig_bt[i++] = ss.type();  // Collect remaining bits of signature
2399       if (ss.type() == T_LONG || ss.type() == T_DOUBLE)
2400         sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
2401     }
2402     assert(i == total_args_passed, "");
2403 
2404     // Lookup method signature's fingerprint
2405     entry = _adapters->lookup(total_args_passed, sig_bt);
2406 
2407 #ifdef ASSERT
2408     AdapterHandlerEntry* shared_entry = NULL;
2409     // Start adapter sharing verification only after the VM is booted.
2410     if (VerifyAdapterSharing && (entry != NULL) && entry->contains_all_checks()) {
2411       shared_entry = entry;
2412       entry = NULL;
2413     }
2414 #endif
2415 
2416     if (entry != NULL) {
2417       // Re-use generated adapter only if VM is booted (StubRoutines::code2() != NULL
2418       // or VerifyAdapterCalls and VerifyAdapterSharing is false. The reason is that
2419       // gen_i2c_adapter() generates code based on the existence of StubRoutines::code1()
2420       // and StubRoutines::code2(). Since these fields can be initialized after adapters
2421       // are generated, VerifyAdapterCalls potentially reports a false error and/or
2422       // VerifyAdapterSharing will fail.
2423       if (!entry->contains_all_checks()) {
2424         _adapters->free_entry(entry);
2425       } else {
2426         return entry;
2427       }
2428     }
2429 
2430     // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
2431     int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
2432 
2433     // Make a C heap allocated version of the fingerprint to store in the adapter
2434     fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
2435 
2436     // Create I2C & C2I handlers
2437 
2438     BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
2439     if (buf != NULL) {
2440       CodeBuffer buffer(buf);
2441       short buffer_locs[20];
2442       buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
2443                                              sizeof(buffer_locs)/sizeof(relocInfo));

2444 
2445       bool contains_all_checks = (StubRoutines::code2() != NULL) || !VerifyAdapterCalls;
2446       MacroAssembler _masm(&buffer);
2447       entry = SharedRuntime::generate_i2c2i_adapters(&_masm,
2448                                                      total_args_passed,
2449                                                      comp_args_on_stack,
2450                                                      sig_bt,
2451                                                      regs,
2452                                                      fingerprint);
2453       entry->set_contains_all_checks(contains_all_checks);
2454 #ifdef ASSERT
2455       if (VerifyAdapterSharing) {
2456         if (shared_entry != NULL) {
2457           assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match");

2458           // Release the one just created and return the original
2459           _adapters->free_entry(entry);
2460           return shared_entry;
2461         } else  {
2462           entry->save_code(buf->code_begin(), buffer.insts_size());
2463         }
2464       }
2465 #endif
2466 
2467       B = AdapterBlob::create(&buffer);
2468       NOT_PRODUCT(insts_size = buffer.insts_size());
2469     }
2470     if (B == NULL) {
2471       // CodeCache is full, disable compilation
2472       // Ought to log this but compile log is only per compile thread
2473       // and we're some non descript Java thread.
2474       MutexUnlocker mu(AdapterHandlerLibrary_lock);
2475       CompileBroker::handle_full_code_cache();
2476       return NULL; // Out of CodeCache space
2477     }
2478     entry->relocate(B->content_begin());
2479 #ifndef PRODUCT
2480     // debugging suppport
2481     if (PrintAdapterHandlers || PrintStubCode) {
2482       ttyLocker ttyl;


2524 }
2525 
2526 void AdapterHandlerEntry::relocate(address new_base) {
2527   address old_base = base_address();
2528   assert(old_base != NULL, "");
2529   ptrdiff_t delta = new_base - old_base;
2530   if (_i2c_entry != NULL)
2531     _i2c_entry += delta;
2532   if (_c2i_entry != NULL)
2533     _c2i_entry += delta;
2534   if (_c2i_unverified_entry != NULL)
2535     _c2i_unverified_entry += delta;
2536   assert(base_address() == new_base, "");
2537 }
2538 
2539 
2540 void AdapterHandlerEntry::deallocate() {
2541   delete _fingerprint;
2542 #ifdef ASSERT
2543   if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);

2544 #endif
2545 }
2546 
2547 
2548 #ifdef ASSERT
2549 // Capture the code before relocation so that it can be compared
2550 // against other versions.  If the code is captured after relocation
2551 // then relative instructions won't be equivalent.
2552 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) {
2553   _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode);
2554   _saved_code_length = length;
2555   memcpy(_saved_code, buffer, length);



2556 }
2557 
2558 
2559 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) {
2560   if (length != _saved_code_length) {




2561     return false;
2562   }
2563 
2564   return (memcmp(buffer, _saved_code, length) == 0) ? true : false;
2565 }
2566 #endif
2567 
2568 
2569 // Create a native wrapper for this native method.  The wrapper converts the
2570 // java compiled calling convention to the native convention, handlizes
2571 // arguments, and transitions to native.  On return from the native we transition
2572 // back to java blocking if a safepoint is in progress.
2573 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) {
2574   ResourceMark rm;
2575   nmethod* nm = NULL;
2576 
2577   assert(method->is_native(), "must be native");
2578   assert(method->is_method_handle_intrinsic() ||
2579          method->has_native_function(), "must have something valid to call!");
2580 
2581   {
2582     // perform the work while holding the lock, but perform any printing outside the lock
2583     MutexLocker mu(AdapterHandlerLibrary_lock);
2584     // See if somebody beat us to it


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