--- old/src/share/vm/opto/memnode.cpp Tue Nov 17 16:51:07 2009 +++ new/src/share/vm/opto/memnode.cpp Tue Nov 17 16:51:06 2009 @@ -123,6 +123,19 @@ } else { assert(false, "unexpected projection"); } + } else if (result->Opcode() == Op_ClearArray) { + intptr_t offset; + AllocateNode* alloc = AllocateNode::Ideal_allocation(result->in(3), phase, offset); + // We can not bypass initialization of the instance we are looking for + // or when something is wrong. + if (alloc == NULL || alloc->_idx == (uint)tinst->instance_id()) + break; + // Otherwise skip it. + InitializeNode* init = alloc->initialization(); + if (init != NULL) + result = init->in(TypeFunc::Memory); + else + result = alloc->in(TypeFunc::Memory); } else if (result->is_MergeMem()) { result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); } @@ -537,6 +550,20 @@ } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { mem = mem->in(0)->in(TypeFunc::Memory); continue; // (a) advance through independent MemBar memory + } else if (mem->Opcode() == Op_ClearArray) { + intptr_t offset; + AllocateNode* alloc = AllocateNode::Ideal_allocation(mem->in(3), phase, offset); + // We can not bypass initialization of the instance we are looking for + // or when something is wrong. + if (alloc == NULL || alloc->_idx == (uint)addr_t->instance_id()) + return mem; + // Otherwise skip it. + InitializeNode* init = alloc->initialization(); + if (init != NULL) + mem = init->in(TypeFunc::Memory); + else + mem = alloc->in(TypeFunc::Memory); + continue; // (a) advance through independent allocation memory } else if (mem->is_MergeMem()) { int alias_idx = phase->C->get_alias_index(adr_type()); mem = mem->as_MergeMem()->memory_at(alias_idx); @@ -2606,7 +2633,30 @@ // Return a node which is more "ideal" than the current node. Strip out // control copies Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { - return remove_dead_region(phase, can_reshape) ? this : NULL; + if (remove_dead_region(phase, can_reshape)) return this; + + // Eliminate volatile MemBars for scalar replaced objects. + if (can_reshape && req() == (Precedent+1) && + (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) { + // Volatile field loads and stores. + Node* my_mem = in(MemBarNode::Precedent); + if (my_mem != NULL && my_mem->is_Mem()) { + const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr(); + // Check for scalar replaced object reference. + if( t_oop != NULL && t_oop->is_known_instance_field() && + t_oop->offset() != Type::OffsetBot && + t_oop->offset() != Type::OffsetTop) { + // Replace MemBar projections by its inputs. + PhaseIterGVN* igvn = phase->is_IterGVN(); + igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); + igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); + // Must return either the original node (now dead) or a new node + // (Do not return a top here, since that would break the uniqueness of top.) + return new (phase->C, 1) ConINode(TypeInt::ZERO); + } + } + } + return NULL; } //------------------------------Value------------------------------------------