< prev index next >

src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp

Print this page
rev 52415 : 8213384: Move G1/C2 barrier verification into G1BarrierSetC2


  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
< prev index next >