src/share/vm/opto/compile.cpp

changeset 6070
94a83e0f9ce1
parent 5991
b2ee5dc63353
child 6071
613e6a6fc328
     1.1 --- a/src/share/vm/opto/compile.cpp	Tue Nov 05 00:59:30 2013 -0800
     1.2 +++ b/src/share/vm/opto/compile.cpp	Tue Nov 05 01:57:18 2013 -0800
     1.3 @@ -848,6 +848,7 @@
     1.4    }
     1.5  #endif
     1.6  
     1.7 +  NOT_PRODUCT( verify_barriers(); )
     1.8    // Now that we know the size of all the monitors we can add a fixed slot
     1.9    // for the original deopt pc.
    1.10  
    1.11 @@ -3368,6 +3369,72 @@
    1.12      }
    1.13    }
    1.14  }
    1.15 +
    1.16 +// Verify GC barriers consistency
    1.17 +// Currently supported:
    1.18 +// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
    1.19 +void Compile::verify_barriers() {
    1.20 +  if (UseG1GC) {
    1.21 +    // Verify G1 pre-barriers
    1.22 +    const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active());
    1.23 +
    1.24 +    ResourceArea *area = Thread::current()->resource_area();
    1.25 +    Unique_Node_List visited(area);
    1.26 +    Node_List worklist(area);
    1.27 +    // We're going to walk control flow backwards starting from the Root
    1.28 +    worklist.push(_root);
    1.29 +    while (worklist.size() > 0) {
    1.30 +      Node* x = worklist.pop();
    1.31 +      if (x == NULL || x == top()) continue;
    1.32 +      if (visited.member(x)) {
    1.33 +        continue;
    1.34 +      } else {
    1.35 +        visited.push(x);
    1.36 +      }
    1.37 +
    1.38 +      if (x->is_Region()) {
    1.39 +        for (uint i = 1; i < x->req(); i++) {
    1.40 +          worklist.push(x->in(i));
    1.41 +        }
    1.42 +      } else {
    1.43 +        worklist.push(x->in(0));
    1.44 +        // We are looking for the pattern:
    1.45 +        //                            /->ThreadLocal
    1.46 +        // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
    1.47 +        //              \->ConI(0)
    1.48 +        // We want to verify that the If and the LoadB have the same control
    1.49 +        // See GraphKit::g1_write_barrier_pre()
    1.50 +        if (x->is_If()) {
    1.51 +          IfNode *iff = x->as_If();
    1.52 +          if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
    1.53 +            CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
    1.54 +            if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
    1.55 +                && cmp->in(1)->is_Load()) {
    1.56 +              LoadNode* load = cmp->in(1)->as_Load();
    1.57 +              if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
    1.58 +                  && load->in(2)->in(3)->is_Con()
    1.59 +                  && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
    1.60 +
    1.61 +                Node* if_ctrl = iff->in(0);
    1.62 +                Node* load_ctrl = load->in(0);
    1.63 +
    1.64 +                if (if_ctrl != load_ctrl) {
    1.65 +                  // Skip possible CProj->NeverBranch in infinite loops
    1.66 +                  if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
    1.67 +                      && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
    1.68 +                    if_ctrl = if_ctrl->in(0)->in(0);
    1.69 +                  }
    1.70 +                }
    1.71 +                assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
    1.72 +              }
    1.73 +            }
    1.74 +          }
    1.75 +        }
    1.76 +      }
    1.77 +    }
    1.78 +  }
    1.79 +}
    1.80 +
    1.81  #endif
    1.82  
    1.83  // The Compile object keeps track of failure reasons separately from the ciEnv.

mercurial