3829 } |
3832 } |
3830 assert(!dead_nodes, "using nodes must be reachable from root"); |
3833 assert(!dead_nodes, "using nodes must be reachable from root"); |
3831 } |
3834 } |
3832 } |
3835 } |
3833 } |
3836 } |
3834 |
|
3835 // Verify GC barriers consistency |
|
3836 // Currently supported: |
|
3837 // - G1 pre-barriers (see GraphKit::g1_write_barrier_pre()) |
|
3838 void Compile::verify_barriers() { |
|
3839 #if INCLUDE_G1GC |
|
3840 if (UseG1GC) { |
|
3841 // Verify G1 pre-barriers |
|
3842 const int marking_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()); |
|
3843 |
|
3844 ResourceArea *area = Thread::current()->resource_area(); |
|
3845 Unique_Node_List visited(area); |
|
3846 Node_List worklist(area); |
|
3847 // We're going to walk control flow backwards starting from the Root |
|
3848 worklist.push(_root); |
|
3849 while (worklist.size() > 0) { |
|
3850 Node* x = worklist.pop(); |
|
3851 if (x == NULL || x == top()) continue; |
|
3852 if (visited.member(x)) { |
|
3853 continue; |
|
3854 } else { |
|
3855 visited.push(x); |
|
3856 } |
|
3857 |
|
3858 if (x->is_Region()) { |
|
3859 for (uint i = 1; i < x->req(); i++) { |
|
3860 worklist.push(x->in(i)); |
|
3861 } |
|
3862 } else { |
|
3863 worklist.push(x->in(0)); |
|
3864 // We are looking for the pattern: |
|
3865 // /->ThreadLocal |
|
3866 // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset) |
|
3867 // \->ConI(0) |
|
3868 // We want to verify that the If and the LoadB have the same control |
|
3869 // See GraphKit::g1_write_barrier_pre() |
|
3870 if (x->is_If()) { |
|
3871 IfNode *iff = x->as_If(); |
|
3872 if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) { |
|
3873 CmpNode *cmp = iff->in(1)->in(1)->as_Cmp(); |
|
3874 if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0 |
|
3875 && cmp->in(1)->is_Load()) { |
|
3876 LoadNode* load = cmp->in(1)->as_Load(); |
|
3877 if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal |
|
3878 && load->in(2)->in(3)->is_Con() |
|
3879 && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) { |
|
3880 |
|
3881 Node* if_ctrl = iff->in(0); |
|
3882 Node* load_ctrl = load->in(0); |
|
3883 |
|
3884 if (if_ctrl != load_ctrl) { |
|
3885 // Skip possible CProj->NeverBranch in infinite loops |
|
3886 if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj) |
|
3887 && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) { |
|
3888 if_ctrl = if_ctrl->in(0)->in(0); |
|
3889 } |
|
3890 } |
|
3891 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match"); |
|
3892 } |
|
3893 } |
|
3894 } |
|
3895 } |
|
3896 } |
|
3897 } |
|
3898 } |
|
3899 #endif |
|
3900 } |
|
3901 |
|
3902 #endif |
3837 #endif |
3903 |
3838 |
3904 // The Compile object keeps track of failure reasons separately from the ciEnv. |
3839 // The Compile object keeps track of failure reasons separately from the ciEnv. |
3905 // This is required because there is not quite a 1-1 relation between the |
3840 // This is required because there is not quite a 1-1 relation between the |
3906 // ciEnv and its compilation task and the Compile object. Note that one |
3841 // ciEnv and its compilation task and the Compile object. Note that one |