Mercurial > hg > graal-compiler
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 |