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.