Mercurial > hg > truffle
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 |