13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/c2/g1BarrierSetC2.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetRuntime.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1ThreadLocalData.hpp"
31 #include "gc/g1/heapRegion.hpp"
32 #include "opto/arraycopynode.hpp"
33 #include "opto/graphKit.hpp"
34 #include "opto/idealKit.hpp"
35 #include "opto/macro.hpp"
36 #include "opto/type.hpp"
37 #include "utilities/macros.hpp"
38
39 const TypeFunc *G1BarrierSetC2::write_ref_field_pre_entry_Type() {
40 const Type **fields = TypeTuple::fields(2);
41 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
42 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
43 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
44
45 // create result type (range)
46 fields = TypeTuple::fields(0);
47 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
48
49 return TypeFunc::make(domain, range);
50 }
51
52 const TypeFunc *G1BarrierSetC2::write_ref_field_post_entry_Type() {
53 const Type **fields = TypeTuple::fields(2);
54 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Card addr
55 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
753 if (c != NULL) {
754 c = c->in(0);
755 if (c != NULL) {
756 c = c->in(0);
757 assert(call->in(0) == NULL ||
758 call->in(0)->in(0) == NULL ||
759 call->in(0)->in(0)->in(0) == NULL ||
760 call->in(0)->in(0)->in(0)->in(0) == NULL ||
761 call->in(0)->in(0)->in(0)->in(0)->in(0) == NULL ||
762 c == call->in(0)->in(0)->in(0)->in(0)->in(0), "bad barrier shape");
763 return c;
764 }
765 }
766 }
767 }
768 }
769 }
770 }
771 return c;
772 }
|
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/c2/g1BarrierSetC2.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetRuntime.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1ThreadLocalData.hpp"
31 #include "gc/g1/heapRegion.hpp"
32 #include "opto/arraycopynode.hpp"
33 #include "opto/compile.hpp"
34 #include "opto/graphKit.hpp"
35 #include "opto/idealKit.hpp"
36 #include "opto/macro.hpp"
37 #include "opto/rootnode.hpp"
38 #include "opto/type.hpp"
39 #include "utilities/macros.hpp"
40
41 const TypeFunc *G1BarrierSetC2::write_ref_field_pre_entry_Type() {
42 const Type **fields = TypeTuple::fields(2);
43 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
44 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
45 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
46
47 // create result type (range)
48 fields = TypeTuple::fields(0);
49 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
50
51 return TypeFunc::make(domain, range);
52 }
53
54 const TypeFunc *G1BarrierSetC2::write_ref_field_post_entry_Type() {
55 const Type **fields = TypeTuple::fields(2);
56 fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Card addr
57 fields[TypeFunc::Parms+1] = TypeRawPtr::NOTNULL; // thread
755 if (c != NULL) {
756 c = c->in(0);
757 if (c != NULL) {
758 c = c->in(0);
759 assert(call->in(0) == NULL ||
760 call->in(0)->in(0) == NULL ||
761 call->in(0)->in(0)->in(0) == NULL ||
762 call->in(0)->in(0)->in(0)->in(0) == NULL ||
763 call->in(0)->in(0)->in(0)->in(0)->in(0) == NULL ||
764 c == call->in(0)->in(0)->in(0)->in(0)->in(0), "bad barrier shape");
765 return c;
766 }
767 }
768 }
769 }
770 }
771 }
772 }
773 return c;
774 }
775
776 #ifdef ASSERT
777 void G1BarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase phase) const {
778 // Verify G1 pre-barriers
779 const int marking_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
780
781 ResourceArea *area = Thread::current()->resource_area();
782 Unique_Node_List visited(area);
783 Node_List worklist(area);
784 // We're going to walk control flow backwards starting from the Root
785 worklist.push(compile->root());
786 while (worklist.size() > 0) {
787 Node* x = worklist.pop();
788 if (x == NULL || x == compile->top()) continue;
789 if (visited.member(x)) {
790 continue;
791 } else {
792 visited.push(x);
793 }
794
795 if (x->is_Region()) {
796 for (uint i = 1; i < x->req(); i++) {
797 worklist.push(x->in(i));
798 }
799 } else {
800 worklist.push(x->in(0));
801 // We are looking for the pattern:
802 // /->ThreadLocal
803 // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
804 // \->ConI(0)
805 // We want to verify that the If and the LoadB have the same control
806 // See GraphKit::g1_write_barrier_pre()
807 if (x->is_If()) {
808 IfNode *iff = x->as_If();
809 if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
810 CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
811 if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
812 && cmp->in(1)->is_Load()) {
813 LoadNode* load = cmp->in(1)->as_Load();
814 if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
815 && load->in(2)->in(3)->is_Con()
816 && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
817
818 Node* if_ctrl = iff->in(0);
819 Node* load_ctrl = load->in(0);
820
821 if (if_ctrl != load_ctrl) {
822 // Skip possible CProj->NeverBranch in infinite loops
823 if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
824 && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
825 if_ctrl = if_ctrl->in(0)->in(0);
826 }
827 }
828 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
829 }
830 }
831 }
832 }
833 }
834 }
835 }
836 #endif
|