Tue, 20 Mar 2012 13:10:13 -0700
7154997: assert(false) failed: not G1 barrier raw StoreP
Summary: Skip only G1 cases and explicitly set global escape state in unsafe cases.
Reviewed-by: never
src/share/vm/opto/escape.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/escape.cpp Fri Mar 16 23:52:03 2012 -0700 1.2 +++ b/src/share/vm/opto/escape.cpp Tue Mar 20 13:10:13 2012 -0700 1.3 @@ -467,21 +467,41 @@ 1.4 int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot); 1.5 assert(offs != Type::OffsetBot, "offset must be a constant"); 1.6 } 1.7 +#endif 1.8 } else { 1.9 // Ignore copy the displaced header to the BoxNode (OSR compilation). 1.10 if (adr->is_BoxLock()) 1.11 break; 1.12 - 1.13 - if (!adr->is_AddP()) { 1.14 - n->dump(1); 1.15 - assert(adr->is_AddP(), "expecting an AddP"); 1.16 + // Stored value escapes in unsafe access. 1.17 + if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) { 1.18 + // Pointer stores in G1 barriers looks like unsafe access. 1.19 + // Ignore such stores to be able scalar replace non-escaping 1.20 + // allocations. 1.21 + if (UseG1GC && adr->is_AddP()) { 1.22 + Node* base = get_addp_base(adr); 1.23 + if (base->Opcode() == Op_LoadP && 1.24 + base->in(MemNode::Address)->is_AddP()) { 1.25 + adr = base->in(MemNode::Address); 1.26 + Node* tls = get_addp_base(adr); 1.27 + if (tls->Opcode() == Op_ThreadLocal) { 1.28 + int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot); 1.29 + if (offs == in_bytes(JavaThread::satb_mark_queue_offset() + 1.30 + PtrQueue::byte_offset_of_buf())) { 1.31 + break; // G1 pre barier previous oop value store. 1.32 + } 1.33 + if (offs == in_bytes(JavaThread::dirty_card_queue_offset() + 1.34 + PtrQueue::byte_offset_of_buf())) { 1.35 + break; // G1 post barier card address store. 1.36 + } 1.37 + } 1.38 + } 1.39 + } 1.40 + delayed_worklist->push(n); // Process unsafe access later. 1.41 + break; 1.42 } 1.43 - // Ignore G1 barrier's stores. 1.44 - if (!UseG1GC || (opcode != Op_StoreP) || 1.45 - (adr_type != TypeRawPtr::BOTTOM)) { 1.46 - n->dump(1); 1.47 - assert(false, "not G1 barrier raw StoreP"); 1.48 - } 1.49 +#ifdef ASSERT 1.50 + n->dump(1); 1.51 + assert(false, "not unsafe or G1 barrier raw StoreP"); 1.52 #endif 1.53 } 1.54 break; 1.55 @@ -636,6 +656,20 @@ 1.56 assert(ptn != NULL, "node should be registered"); 1.57 add_edge(adr_ptn, ptn); 1.58 break; 1.59 + } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) { 1.60 + // Stored value escapes in unsafe access. 1.61 + Node *val = n->in(MemNode::ValueIn); 1.62 + PointsToNode* ptn = ptnode_adr(val->_idx); 1.63 + assert(ptn != NULL, "node should be registered"); 1.64 + ptn->set_escape_state(PointsToNode::GlobalEscape); 1.65 + // Add edge to object for unsafe access with offset. 1.66 + PointsToNode* adr_ptn = ptnode_adr(adr->_idx); 1.67 + assert(adr_ptn != NULL, "node should be registered"); 1.68 + if (adr_ptn->is_Field()) { 1.69 + assert(adr_ptn->as_Field()->is_oop(), "should be oop field"); 1.70 + add_edge(adr_ptn, ptn); 1.71 + } 1.72 + break; 1.73 } 1.74 ELSE_FAIL("Op_StoreP"); 1.75 }