3371 } |
3372 } |
3372 assert(dead_nodes == 0, "using nodes must be reachable from root"); |
3373 assert(dead_nodes == 0, "using nodes must be reachable from root"); |
3373 } |
3374 } |
3374 } |
3375 } |
3375 } |
3376 } |
|
3377 |
|
3378 // Verify GC barriers consistency |
|
3379 // Currently supported: |
|
3380 // - G1 pre-barriers (see GraphKit::g1_write_barrier_pre()) |
|
3381 void Compile::verify_barriers() { |
|
3382 if (UseG1GC) { |
|
3383 // Verify G1 pre-barriers |
|
3384 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active()); |
|
3385 |
|
3386 ResourceArea *area = Thread::current()->resource_area(); |
|
3387 Unique_Node_List visited(area); |
|
3388 Node_List worklist(area); |
|
3389 // We're going to walk control flow backwards starting from the Root |
|
3390 worklist.push(_root); |
|
3391 while (worklist.size() > 0) { |
|
3392 Node* x = worklist.pop(); |
|
3393 if (x == NULL || x == top()) continue; |
|
3394 if (visited.member(x)) { |
|
3395 continue; |
|
3396 } else { |
|
3397 visited.push(x); |
|
3398 } |
|
3399 |
|
3400 if (x->is_Region()) { |
|
3401 for (uint i = 1; i < x->req(); i++) { |
|
3402 worklist.push(x->in(i)); |
|
3403 } |
|
3404 } else { |
|
3405 worklist.push(x->in(0)); |
|
3406 // We are looking for the pattern: |
|
3407 // /->ThreadLocal |
|
3408 // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset) |
|
3409 // \->ConI(0) |
|
3410 // We want to verify that the If and the LoadB have the same control |
|
3411 // See GraphKit::g1_write_barrier_pre() |
|
3412 if (x->is_If()) { |
|
3413 IfNode *iff = x->as_If(); |
|
3414 if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) { |
|
3415 CmpNode *cmp = iff->in(1)->in(1)->as_Cmp(); |
|
3416 if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0 |
|
3417 && cmp->in(1)->is_Load()) { |
|
3418 LoadNode* load = cmp->in(1)->as_Load(); |
|
3419 if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal |
|
3420 && load->in(2)->in(3)->is_Con() |
|
3421 && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) { |
|
3422 |
|
3423 Node* if_ctrl = iff->in(0); |
|
3424 Node* load_ctrl = load->in(0); |
|
3425 |
|
3426 if (if_ctrl != load_ctrl) { |
|
3427 // Skip possible CProj->NeverBranch in infinite loops |
|
3428 if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj) |
|
3429 && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) { |
|
3430 if_ctrl = if_ctrl->in(0)->in(0); |
|
3431 } |
|
3432 } |
|
3433 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match"); |
|
3434 } |
|
3435 } |
|
3436 } |
|
3437 } |
|
3438 } |
|
3439 } |
|
3440 } |
|
3441 } |
|
3442 |
3376 #endif |
3443 #endif |
3377 |
3444 |
3378 // The Compile object keeps track of failure reasons separately from the ciEnv. |
3445 // The Compile object keeps track of failure reasons separately from the ciEnv. |
3379 // This is required because there is not quite a 1-1 relation between the |
3446 // This is required because there is not quite a 1-1 relation between the |
3380 // ciEnv and its compilation task and the Compile object. Note that one |
3447 // ciEnv and its compilation task and the Compile object. Note that one |