comparison src/share/vm/runtime/sharedRuntime.cpp @ 17611:d6e7180abab5

8026478: -XX:+VerifyAdapterSharing is broken Summary: Fix by considering all checks in StubRoutines Reviewed-by: kvn, twisti
author anoll
date Thu, 19 Dec 2013 06:09:16 +0100
parents df832bd8edb9
children 69dc1be43fce
comparison
equal deleted inserted replaced
17610:908afcc9d1cb 17611:d6e7180abab5
2398 assert(ic_miss != NULL, "must have handler"); 2398 assert(ic_miss != NULL, "must have handler");
2399 2399
2400 ResourceMark rm; 2400 ResourceMark rm;
2401 2401
2402 NOT_PRODUCT(int insts_size); 2402 NOT_PRODUCT(int insts_size);
2403 AdapterBlob* B = NULL; 2403 AdapterBlob* new_adapter = NULL;
2404 AdapterHandlerEntry* entry = NULL; 2404 AdapterHandlerEntry* entry = NULL;
2405 AdapterFingerPrint* fingerprint = NULL; 2405 AdapterFingerPrint* fingerprint = NULL;
2406 { 2406 {
2407 MutexLocker mu(AdapterHandlerLibrary_lock); 2407 MutexLocker mu(AdapterHandlerLibrary_lock);
2408 // make sure data structure is initialized 2408 // make sure data structure is initialized
2430 // Lookup method signature's fingerprint 2430 // Lookup method signature's fingerprint
2431 entry = _adapters->lookup(total_args_passed, sig_bt); 2431 entry = _adapters->lookup(total_args_passed, sig_bt);
2432 2432
2433 #ifdef ASSERT 2433 #ifdef ASSERT
2434 AdapterHandlerEntry* shared_entry = NULL; 2434 AdapterHandlerEntry* shared_entry = NULL;
2435 if (VerifyAdapterSharing && entry != NULL) { 2435 // Start adapter sharing verification only after the VM is booted.
2436 if (VerifyAdapterSharing && (entry != NULL)) {
2436 shared_entry = entry; 2437 shared_entry = entry;
2437 entry = NULL; 2438 entry = NULL;
2438 } 2439 }
2439 #endif 2440 #endif
2440 2441
2446 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); 2447 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
2447 2448
2448 // Make a C heap allocated version of the fingerprint to store in the adapter 2449 // Make a C heap allocated version of the fingerprint to store in the adapter
2449 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); 2450 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt);
2450 2451
2452 // StubRoutines::code2() is initialized after this function can be called. As a result,
2453 // VerifyAdapterCalls and VerifyAdapterSharing can fail if we re-use code that generated
2454 // prior to StubRoutines::code2() being set. Checks refer to checks generated in an I2C
2455 // stub that ensure that an I2C stub is called from an interpreter frame.
2456 bool contains_all_checks = StubRoutines::code2() != NULL;
2457
2451 // Create I2C & C2I handlers 2458 // Create I2C & C2I handlers
2452
2453 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache 2459 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
2454 if (buf != NULL) { 2460 if (buf != NULL) {
2455 CodeBuffer buffer(buf); 2461 CodeBuffer buffer(buf);
2456 short buffer_locs[20]; 2462 short buffer_locs[20];
2457 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, 2463 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
2458 sizeof(buffer_locs)/sizeof(relocInfo)); 2464 sizeof(buffer_locs)/sizeof(relocInfo));
2465
2459 MacroAssembler _masm(&buffer); 2466 MacroAssembler _masm(&buffer);
2460
2461 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, 2467 entry = SharedRuntime::generate_i2c2i_adapters(&_masm,
2462 total_args_passed, 2468 total_args_passed,
2463 comp_args_on_stack, 2469 comp_args_on_stack,
2464 sig_bt, 2470 sig_bt,
2465 regs, 2471 regs,
2466 fingerprint); 2472 fingerprint);
2467
2468 #ifdef ASSERT 2473 #ifdef ASSERT
2469 if (VerifyAdapterSharing) { 2474 if (VerifyAdapterSharing) {
2470 if (shared_entry != NULL) { 2475 if (shared_entry != NULL) {
2471 assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), 2476 assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match");
2472 "code must match");
2473 // Release the one just created and return the original 2477 // Release the one just created and return the original
2474 _adapters->free_entry(entry); 2478 _adapters->free_entry(entry);
2475 return shared_entry; 2479 return shared_entry;
2476 } else { 2480 } else {
2477 entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); 2481 entry->save_code(buf->code_begin(), buffer.insts_size());
2478 } 2482 }
2479 } 2483 }
2480 #endif 2484 #endif
2481 2485
2482 B = AdapterBlob::create(&buffer); 2486 new_adapter = AdapterBlob::create(&buffer);
2483 NOT_PRODUCT(insts_size = buffer.insts_size()); 2487 NOT_PRODUCT(insts_size = buffer.insts_size());
2484 } 2488 }
2485 if (B == NULL) { 2489 if (new_adapter == NULL) {
2486 // CodeCache is full, disable compilation 2490 // CodeCache is full, disable compilation
2487 // Ought to log this but compile log is only per compile thread 2491 // Ought to log this but compile log is only per compile thread
2488 // and we're some non descript Java thread. 2492 // and we're some non descript Java thread.
2489 MutexUnlocker mu(AdapterHandlerLibrary_lock); 2493 MutexUnlocker mu(AdapterHandlerLibrary_lock);
2490 CompileBroker::handle_full_code_cache(); 2494 CompileBroker::handle_full_code_cache();
2491 return NULL; // Out of CodeCache space 2495 return NULL; // Out of CodeCache space
2492 } 2496 }
2493 entry->relocate(B->content_begin()); 2497 entry->relocate(new_adapter->content_begin());
2494 #ifndef PRODUCT 2498 #ifndef PRODUCT
2495 // debugging suppport 2499 // debugging suppport
2496 if (PrintAdapterHandlers || PrintStubCode) { 2500 if (PrintAdapterHandlers || PrintStubCode) {
2497 ttyLocker ttyl; 2501 ttyLocker ttyl;
2498 entry->print_adapter_on(tty); 2502 entry->print_adapter_on(tty);
2507 tty->cr(); 2511 tty->cr();
2508 } 2512 }
2509 } 2513 }
2510 } 2514 }
2511 #endif 2515 #endif
2512 2516 // Add the entry only if the entry contains all required checks (see sharedRuntime_xxx.cpp)
2513 _adapters->add(entry); 2517 // The checks are inserted only if -XX:+VerifyAdapterCalls is specified.
2518 if (contains_all_checks || !VerifyAdapterCalls) {
2519 _adapters->add(entry);
2520 }
2514 } 2521 }
2515 // Outside of the lock 2522 // Outside of the lock
2516 if (B != NULL) { 2523 if (new_adapter != NULL) {
2517 char blob_id[256]; 2524 char blob_id[256];
2518 jio_snprintf(blob_id, 2525 jio_snprintf(blob_id,
2519 sizeof(blob_id), 2526 sizeof(blob_id),
2520 "%s(%s)@" PTR_FORMAT, 2527 "%s(%s)@" PTR_FORMAT,
2521 B->name(), 2528 new_adapter->name(),
2522 fingerprint->as_string(), 2529 fingerprint->as_string(),
2523 B->content_begin()); 2530 new_adapter->content_begin());
2524 Forte::register_stub(blob_id, B->content_begin(), B->content_end()); 2531 Forte::register_stub(blob_id, new_adapter->content_begin(),new_adapter->content_end());
2525 2532
2526 if (JvmtiExport::should_post_dynamic_code_generated()) { 2533 if (JvmtiExport::should_post_dynamic_code_generated()) {
2527 JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end()); 2534 JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end());
2528 } 2535 }
2529 } 2536 }
2530 return entry; 2537 return entry;
2531 } 2538 }
2532 2539
2554 2561
2555 void AdapterHandlerEntry::deallocate() { 2562 void AdapterHandlerEntry::deallocate() {
2556 delete _fingerprint; 2563 delete _fingerprint;
2557 #ifdef ASSERT 2564 #ifdef ASSERT
2558 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); 2565 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);
2559 if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode);
2560 #endif 2566 #endif
2561 } 2567 }
2562 2568
2563 2569
2564 #ifdef ASSERT 2570 #ifdef ASSERT
2565 // Capture the code before relocation so that it can be compared 2571 // Capture the code before relocation so that it can be compared
2566 // against other versions. If the code is captured after relocation 2572 // against other versions. If the code is captured after relocation
2567 // then relative instructions won't be equivalent. 2573 // then relative instructions won't be equivalent.
2568 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { 2574 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) {
2569 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); 2575 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode);
2570 _code_length = length; 2576 _saved_code_length = length;
2571 memcpy(_saved_code, buffer, length); 2577 memcpy(_saved_code, buffer, length);
2572 _total_args_passed = total_args_passed; 2578 }
2573 _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode); 2579
2574 memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); 2580
2575 } 2581 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) {
2576 2582 if (length != _saved_code_length) {
2577
2578 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
2579 if (length != _code_length) {
2580 return false; 2583 return false;
2581 } 2584 }
2582 for (int i = 0; i < length; i++) { 2585
2583 if (buffer[i] != _saved_code[i]) { 2586 return (memcmp(buffer, _saved_code, length) == 0) ? true : false;
2584 return false;
2585 }
2586 }
2587 return true;
2588 } 2587 }
2589 #endif 2588 #endif
2590 2589
2591 2590
2592 // Create a native wrapper for this native method. The wrapper converts the 2591 // Create a native wrapper for this native method. The wrapper converts the