1.1 --- a/src/share/vm/opto/memnode.cpp Mon Jun 24 18:23:45 2013 -0700 1.2 +++ b/src/share/vm/opto/memnode.cpp Tue Jun 25 12:07:07 2013 -0700 1.3 @@ -2943,11 +2943,19 @@ 1.4 Node* my_mem = in(MemBarNode::Precedent); 1.5 // The MembarAquire may keep an unused LoadNode alive through the Precedent edge 1.6 if ((my_mem != NULL) && (opc == Op_MemBarAcquire) && (my_mem->outcnt() == 1)) { 1.7 - assert(my_mem->unique_out() == this, "sanity"); 1.8 - phase->hash_delete(this); 1.9 - del_req(Precedent); 1.10 - phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later 1.11 - my_mem = NULL; 1.12 + // if the Precedent is a decodeN and its input (a Load) is used at more than one place, 1.13 + // replace this Precedent (decodeN) with the Load instead. 1.14 + if ((my_mem->Opcode() == Op_DecodeN) && (my_mem->in(1)->outcnt() > 1)) { 1.15 + Node* load_node = my_mem->in(1); 1.16 + set_req(MemBarNode::Precedent, load_node); 1.17 + phase->is_IterGVN()->_worklist.push(my_mem); 1.18 + my_mem = load_node; 1.19 + } else { 1.20 + assert(my_mem->unique_out() == this, "sanity"); 1.21 + del_req(Precedent); 1.22 + phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later 1.23 + my_mem = NULL; 1.24 + } 1.25 } 1.26 if (my_mem != NULL && my_mem->is_Mem()) { 1.27 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();