comparison src/share/vm/code/compiledIC.cpp @ 10408:836a62f43af9

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 19 Jun 2013 10:45:56 +0200
parents b9a918201d47 a6e09d6dd8e5
children cefad50507d8
comparison
equal deleted inserted replaced
10086:e0fb8a213650 10408:836a62f43af9
42 #include "utilities/events.hpp" 42 #include "utilities/events.hpp"
43 43
44 44
45 // Every time a compiled IC is changed or its type is being accessed, 45 // Every time a compiled IC is changed or its type is being accessed,
46 // either the CompiledIC_lock must be set or we must be at a safe point. 46 // either the CompiledIC_lock must be set or we must be at a safe point.
47
48
49 // Release the CompiledICHolder* associated with this call site is there is one.
50 void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) {
51 // This call site might have become stale so inspect it carefully.
52 NativeCall* call = nativeCall_at(call_site->addr());
53 if (is_icholder_entry(call->destination())) {
54 NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value());
55 InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data());
56 }
57 }
58
59
60 bool CompiledIC::is_icholder_call_site(virtual_call_Relocation* call_site) {
61 // This call site might have become stale so inspect it carefully.
62 NativeCall* call = nativeCall_at(call_site->addr());
63 return is_icholder_entry(call->destination());
64 }
65
66 47
67 //----------------------------------------------------------------------------- 48 //-----------------------------------------------------------------------------
68 // Low-level access to an inline cache. Private, since they might not be 49 // Low-level access to an inline cache. Private, since they might not be
69 // MT-safe to use. 50 // MT-safe to use.
70 51
495 bool CompiledIC::is_icholder_entry(address entry) { 476 bool CompiledIC::is_icholder_entry(address entry) {
496 CodeBlob* cb = CodeCache::find_blob_unsafe(entry); 477 CodeBlob* cb = CodeCache::find_blob_unsafe(entry);
497 return (cb != NULL && cb->is_adapter_blob()); 478 return (cb != NULL && cb->is_adapter_blob());
498 } 479 }
499 480
500
501 CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
502 : _ic_call(call)
503 {
504 address ic_call = call->instruction_address();
505
506 assert(ic_call != NULL, "ic_call address must be set");
507 assert(nm != NULL, "must pass nmethod");
508 assert(nm->contains(ic_call), "must be in nmethod");
509
510 // search for the ic_call at the given address
511 RelocIterator iter(nm, ic_call, ic_call+1);
512 bool ret = iter.next();
513 assert(ret == true, "relocInfo must exist at this address");
514 assert(iter.addr() == ic_call, "must find ic_call");
515 if (iter.type() == relocInfo::virtual_call_type) {
516 virtual_call_Relocation* r = iter.virtual_call_reloc();
517 _is_optimized = false;
518 _value = nativeMovConstReg_at(r->cached_value());
519 } else {
520 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
521 _is_optimized = true;
522 _value = NULL;
523 }
524 }
525
526
527 // ---------------------------------------------------------------------------- 481 // ----------------------------------------------------------------------------
528 482
529 void CompiledStaticCall::set_to_clean() { 483 void CompiledStaticCall::set_to_clean() {
530 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call"); 484 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
531 // Reset call site 485 // Reset call site
556 // must be in the stub part of the nmethod that contains the call 510 // must be in the stub part of the nmethod that contains the call
557 nmethod* nm = CodeCache::find_nmethod(instruction_address()); 511 nmethod* nm = CodeCache::find_nmethod(instruction_address());
558 return nm->stub_contains(destination()); 512 return nm->stub_contains(destination());
559 } 513 }
560 514
561
562 void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
563 address stub=find_stub();
564 #ifdef GRAAL
565 if (stub == NULL) {
566 set_destination_mt_safe(entry);
567 return;
568 }
569 #endif
570 guarantee(stub != NULL, "stub not found");
571
572 if (TraceICs) {
573 ResourceMark rm;
574 tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
575 instruction_address(),
576 callee->name_and_sig_as_C_string());
577 }
578
579 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); // creation also verifies the object
580 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
581
582 assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(), "a) MT-unsafe modification of inline cache");
583 assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry, "b) MT-unsafe modification of inline cache");
584
585 // Update stub
586 method_holder->set_data((intptr_t)callee());
587 jump->set_jump_destination(entry);
588
589 // Update jump to call
590 set_destination_mt_safe(stub);
591 }
592
593
594 void CompiledStaticCall::set(const StaticCallInfo& info) { 515 void CompiledStaticCall::set(const StaticCallInfo& info) {
595 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call"); 516 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
596 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); 517 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
597 // Updating a cache to the wrong entry can cause bugs that are very hard 518 // Updating a cache to the wrong entry can cause bugs that are very hard
598 // to track down - if cache entry gets invalid - we just clean it. In 519 // to track down - if cache entry gets invalid - we just clean it. In
630 // puts a converter-frame on the stack to save arguments. 551 // puts a converter-frame on the stack to save arguments.
631 info._to_interpreter = true; 552 info._to_interpreter = true;
632 info._entry = m()->get_c2i_entry(); 553 info._entry = m()->get_c2i_entry();
633 } 554 }
634 } 555 }
635
636
637 void CompiledStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
638 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
639 // Reset stub
640 address stub = static_stub->addr();
641 assert(stub!=NULL, "stub not found");
642 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); // creation also verifies the object
643 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
644 method_holder->set_data(0);
645 jump->set_jump_destination((address)-1);
646 }
647
648 556
649 address CompiledStaticCall::find_stub() { 557 address CompiledStaticCall::find_stub() {
650 // Find reloc. information containing this call-site 558 // Find reloc. information containing this call-site
651 RelocIterator iter((nmethod*)NULL, instruction_address()); 559 RelocIterator iter((nmethod*)NULL, instruction_address());
652 while (iter.next()) { 560 while (iter.next()) {
681 } 589 }
682 assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted() 590 assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted()
683 || is_optimized() || is_megamorphic(), "sanity check"); 591 || is_optimized() || is_megamorphic(), "sanity check");
684 } 592 }
685 593
686
687 void CompiledIC::print() { 594 void CompiledIC::print() {
688 print_compiled_ic(); 595 print_compiled_ic();
689 tty->cr(); 596 tty->cr();
690 } 597 }
691 598
692
693 void CompiledIC::print_compiled_ic() { 599 void CompiledIC::print_compiled_ic() {
694 tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT, 600 tty->print("Inline cache at " INTPTR_FORMAT ", calling %s " INTPTR_FORMAT " cached_value " INTPTR_FORMAT,
695 instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination(), is_optimized() ? NULL : cached_value()); 601 instruction_address(), is_call_to_interpreted() ? "interpreted " : "", ic_destination(), is_optimized() ? NULL : cached_value());
696 } 602 }
697
698 603
699 void CompiledStaticCall::print() { 604 void CompiledStaticCall::print() {
700 tty->print("static call at " INTPTR_FORMAT " -> ", instruction_address()); 605 tty->print("static call at " INTPTR_FORMAT " -> ", instruction_address());
701 if (is_clean()) { 606 if (is_clean()) {
702 tty->print("clean"); 607 tty->print("clean");
706 tty->print("interpreted"); 611 tty->print("interpreted");
707 } 612 }
708 tty->cr(); 613 tty->cr();
709 } 614 }
710 615
711 void CompiledStaticCall::verify() { 616 #endif // !PRODUCT
712 // Verify call
713 NativeCall::verify();
714 if (os::is_MP()) {
715 verify_alignment();
716 }
717
718 // Verify stub
719 address stub = find_stub();
720 #ifndef GRAAL
721 assert(stub != NULL, "no stub found for static call");
722 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub); // creation also verifies the object
723 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
724 #endif
725
726 // Verify state
727 assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
728 }
729
730 #endif