Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/sharedRuntime.cpp @ 14198:b8b5791fa045
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 | 570aaefce624 |
children | 22ae97935e05 |
comparison
equal
deleted
inserted
replaced
14197:d49557091d18 | 14198:b8b5791fa045 |
---|---|
2380 assert(ic_miss != NULL, "must have handler"); | 2380 assert(ic_miss != NULL, "must have handler"); |
2381 | 2381 |
2382 ResourceMark rm; | 2382 ResourceMark rm; |
2383 | 2383 |
2384 NOT_PRODUCT(int insts_size); | 2384 NOT_PRODUCT(int insts_size); |
2385 AdapterBlob* B = NULL; | 2385 AdapterBlob* new_adapter = NULL; |
2386 AdapterHandlerEntry* entry = NULL; | 2386 AdapterHandlerEntry* entry = NULL; |
2387 AdapterFingerPrint* fingerprint = NULL; | 2387 AdapterFingerPrint* fingerprint = NULL; |
2388 { | 2388 { |
2389 MutexLocker mu(AdapterHandlerLibrary_lock); | 2389 MutexLocker mu(AdapterHandlerLibrary_lock); |
2390 // make sure data structure is initialized | 2390 // make sure data structure is initialized |
2412 // Lookup method signature's fingerprint | 2412 // Lookup method signature's fingerprint |
2413 entry = _adapters->lookup(total_args_passed, sig_bt); | 2413 entry = _adapters->lookup(total_args_passed, sig_bt); |
2414 | 2414 |
2415 #ifdef ASSERT | 2415 #ifdef ASSERT |
2416 AdapterHandlerEntry* shared_entry = NULL; | 2416 AdapterHandlerEntry* shared_entry = NULL; |
2417 if (VerifyAdapterSharing && entry != NULL) { | 2417 // Start adapter sharing verification only after the VM is booted. |
2418 if (VerifyAdapterSharing && (entry != NULL)) { | |
2418 shared_entry = entry; | 2419 shared_entry = entry; |
2419 entry = NULL; | 2420 entry = NULL; |
2420 } | 2421 } |
2421 #endif | 2422 #endif |
2422 | 2423 |
2428 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | 2429 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
2429 | 2430 |
2430 // Make a C heap allocated version of the fingerprint to store in the adapter | 2431 // Make a C heap allocated version of the fingerprint to store in the adapter |
2431 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); | 2432 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); |
2432 | 2433 |
2434 // StubRoutines::code2() is initialized after this function can be called. As a result, | |
2435 // VerifyAdapterCalls and VerifyAdapterSharing can fail if we re-use code that generated | |
2436 // prior to StubRoutines::code2() being set. Checks refer to checks generated in an I2C | |
2437 // stub that ensure that an I2C stub is called from an interpreter frame. | |
2438 bool contains_all_checks = StubRoutines::code2() != NULL; | |
2439 | |
2433 // Create I2C & C2I handlers | 2440 // Create I2C & C2I handlers |
2434 | |
2435 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache | 2441 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
2436 if (buf != NULL) { | 2442 if (buf != NULL) { |
2437 CodeBuffer buffer(buf); | 2443 CodeBuffer buffer(buf); |
2438 short buffer_locs[20]; | 2444 short buffer_locs[20]; |
2439 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, | 2445 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, |
2440 sizeof(buffer_locs)/sizeof(relocInfo)); | 2446 sizeof(buffer_locs)/sizeof(relocInfo)); |
2447 | |
2441 MacroAssembler _masm(&buffer); | 2448 MacroAssembler _masm(&buffer); |
2442 | |
2443 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, | 2449 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, |
2444 total_args_passed, | 2450 total_args_passed, |
2445 comp_args_on_stack, | 2451 comp_args_on_stack, |
2446 sig_bt, | 2452 sig_bt, |
2447 regs, | 2453 regs, |
2448 fingerprint); | 2454 fingerprint); |
2449 | |
2450 #ifdef ASSERT | 2455 #ifdef ASSERT |
2451 if (VerifyAdapterSharing) { | 2456 if (VerifyAdapterSharing) { |
2452 if (shared_entry != NULL) { | 2457 if (shared_entry != NULL) { |
2453 assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), | 2458 assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size()), "code must match"); |
2454 "code must match"); | |
2455 // Release the one just created and return the original | 2459 // Release the one just created and return the original |
2456 _adapters->free_entry(entry); | 2460 _adapters->free_entry(entry); |
2457 return shared_entry; | 2461 return shared_entry; |
2458 } else { | 2462 } else { |
2459 entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); | 2463 entry->save_code(buf->code_begin(), buffer.insts_size()); |
2460 } | 2464 } |
2461 } | 2465 } |
2462 #endif | 2466 #endif |
2463 | 2467 |
2464 B = AdapterBlob::create(&buffer); | 2468 new_adapter = AdapterBlob::create(&buffer); |
2465 NOT_PRODUCT(insts_size = buffer.insts_size()); | 2469 NOT_PRODUCT(insts_size = buffer.insts_size()); |
2466 } | 2470 } |
2467 if (B == NULL) { | 2471 if (new_adapter == NULL) { |
2468 // CodeCache is full, disable compilation | 2472 // CodeCache is full, disable compilation |
2469 // Ought to log this but compile log is only per compile thread | 2473 // Ought to log this but compile log is only per compile thread |
2470 // and we're some non descript Java thread. | 2474 // and we're some non descript Java thread. |
2471 MutexUnlocker mu(AdapterHandlerLibrary_lock); | 2475 MutexUnlocker mu(AdapterHandlerLibrary_lock); |
2472 CompileBroker::handle_full_code_cache(); | 2476 CompileBroker::handle_full_code_cache(); |
2473 return NULL; // Out of CodeCache space | 2477 return NULL; // Out of CodeCache space |
2474 } | 2478 } |
2475 entry->relocate(B->content_begin()); | 2479 entry->relocate(new_adapter->content_begin()); |
2476 #ifndef PRODUCT | 2480 #ifndef PRODUCT |
2477 // debugging suppport | 2481 // debugging suppport |
2478 if (PrintAdapterHandlers || PrintStubCode) { | 2482 if (PrintAdapterHandlers || PrintStubCode) { |
2479 ttyLocker ttyl; | 2483 ttyLocker ttyl; |
2480 entry->print_adapter_on(tty); | 2484 entry->print_adapter_on(tty); |
2489 tty->cr(); | 2493 tty->cr(); |
2490 } | 2494 } |
2491 } | 2495 } |
2492 } | 2496 } |
2493 #endif | 2497 #endif |
2494 | 2498 // Add the entry only if the entry contains all required checks (see sharedRuntime_xxx.cpp) |
2495 _adapters->add(entry); | 2499 // The checks are inserted only if -XX:+VerifyAdapterCalls is specified. |
2500 if (contains_all_checks || !VerifyAdapterCalls) { | |
2501 _adapters->add(entry); | |
2502 } | |
2496 } | 2503 } |
2497 // Outside of the lock | 2504 // Outside of the lock |
2498 if (B != NULL) { | 2505 if (new_adapter != NULL) { |
2499 char blob_id[256]; | 2506 char blob_id[256]; |
2500 jio_snprintf(blob_id, | 2507 jio_snprintf(blob_id, |
2501 sizeof(blob_id), | 2508 sizeof(blob_id), |
2502 "%s(%s)@" PTR_FORMAT, | 2509 "%s(%s)@" PTR_FORMAT, |
2503 B->name(), | 2510 new_adapter->name(), |
2504 fingerprint->as_string(), | 2511 fingerprint->as_string(), |
2505 B->content_begin()); | 2512 new_adapter->content_begin()); |
2506 Forte::register_stub(blob_id, B->content_begin(), B->content_end()); | 2513 Forte::register_stub(blob_id, new_adapter->content_begin(),new_adapter->content_end()); |
2507 | 2514 |
2508 if (JvmtiExport::should_post_dynamic_code_generated()) { | 2515 if (JvmtiExport::should_post_dynamic_code_generated()) { |
2509 JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end()); | 2516 JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end()); |
2510 } | 2517 } |
2511 } | 2518 } |
2512 return entry; | 2519 return entry; |
2513 } | 2520 } |
2514 | 2521 |
2536 | 2543 |
2537 void AdapterHandlerEntry::deallocate() { | 2544 void AdapterHandlerEntry::deallocate() { |
2538 delete _fingerprint; | 2545 delete _fingerprint; |
2539 #ifdef ASSERT | 2546 #ifdef ASSERT |
2540 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); | 2547 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode); |
2541 if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode); | |
2542 #endif | 2548 #endif |
2543 } | 2549 } |
2544 | 2550 |
2545 | 2551 |
2546 #ifdef ASSERT | 2552 #ifdef ASSERT |
2547 // Capture the code before relocation so that it can be compared | 2553 // Capture the code before relocation so that it can be compared |
2548 // against other versions. If the code is captured after relocation | 2554 // against other versions. If the code is captured after relocation |
2549 // then relative instructions won't be equivalent. | 2555 // then relative instructions won't be equivalent. |
2550 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { | 2556 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length) { |
2551 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); | 2557 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode); |
2552 _code_length = length; | 2558 _saved_code_length = length; |
2553 memcpy(_saved_code, buffer, length); | 2559 memcpy(_saved_code, buffer, length); |
2554 _total_args_passed = total_args_passed; | 2560 } |
2555 _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode); | 2561 |
2556 memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); | 2562 |
2557 } | 2563 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { |
2558 | 2564 if (length != _saved_code_length) { |
2559 | |
2560 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { | |
2561 if (length != _code_length) { | |
2562 return false; | 2565 return false; |
2563 } | 2566 } |
2564 for (int i = 0; i < length; i++) { | 2567 |
2565 if (buffer[i] != _saved_code[i]) { | 2568 return (memcmp(buffer, _saved_code, length) == 0) ? true : false; |
2566 return false; | |
2567 } | |
2568 } | |
2569 return true; | |
2570 } | 2569 } |
2571 #endif | 2570 #endif |
2572 | 2571 |
2573 | 2572 |
2574 // Create a native wrapper for this native method. The wrapper converts the | 2573 // Create a native wrapper for this native method. The wrapper converts the |