1.1 --- a/src/share/vm/opto/memnode.cpp Tue Dec 08 16:27:21 2009 -0800 1.2 +++ b/src/share/vm/opto/memnode.cpp Wed Dec 09 16:40:45 2009 -0800 1.3 @@ -123,6 +123,13 @@ 1.4 } else { 1.5 assert(false, "unexpected projection"); 1.6 } 1.7 + } else if (result->is_ClearArray()) { 1.8 + if (!ClearArrayNode::step_through(&result, instance_id, phase)) { 1.9 + // Can not bypass initialization of the instance 1.10 + // we are looking for. 1.11 + break; 1.12 + } 1.13 + // Otherwise skip it (the call updated 'result' value). 1.14 } else if (result->is_MergeMem()) { 1.15 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); 1.16 } 1.17 @@ -537,6 +544,15 @@ 1.18 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { 1.19 mem = mem->in(0)->in(TypeFunc::Memory); 1.20 continue; // (a) advance through independent MemBar memory 1.21 + } else if (mem->is_ClearArray()) { 1.22 + if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) { 1.23 + // (the call updated 'mem' value) 1.24 + continue; // (a) advance through independent allocation memory 1.25 + } else { 1.26 + // Can not bypass initialization of the instance 1.27 + // we are looking for. 1.28 + return mem; 1.29 + } 1.30 } else if (mem->is_MergeMem()) { 1.31 int alias_idx = phase->C->get_alias_index(adr_type()); 1.32 mem = mem->as_MergeMem()->memory_at(alias_idx); 1.33 @@ -2454,6 +2470,31 @@ 1.34 return mem; 1.35 } 1.36 1.37 +//----------------------------step_through---------------------------------- 1.38 +// Return allocation input memory edge if it is different instance 1.39 +// or itself if it is the one we are looking for. 1.40 +bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) { 1.41 + Node* n = *np; 1.42 + assert(n->is_ClearArray(), "sanity"); 1.43 + intptr_t offset; 1.44 + AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset); 1.45 + // This method is called only before Allocate nodes are expanded during 1.46 + // macro nodes expansion. Before that ClearArray nodes are only generated 1.47 + // in LibraryCallKit::generate_arraycopy() which follows allocations. 1.48 + assert(alloc != NULL, "should have allocation"); 1.49 + if (alloc->_idx == instance_id) { 1.50 + // Can not bypass initialization of the instance we are looking for. 1.51 + return false; 1.52 + } 1.53 + // Otherwise skip it. 1.54 + InitializeNode* init = alloc->initialization(); 1.55 + if (init != NULL) 1.56 + *np = init->in(TypeFunc::Memory); 1.57 + else 1.58 + *np = alloc->in(TypeFunc::Memory); 1.59 + return true; 1.60 +} 1.61 + 1.62 //----------------------------clear_memory------------------------------------- 1.63 // Generate code to initialize object storage to zero. 1.64 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, 1.65 @@ -2627,7 +2668,30 @@ 1.66 // Return a node which is more "ideal" than the current node. Strip out 1.67 // control copies 1.68 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.69 - return remove_dead_region(phase, can_reshape) ? this : NULL; 1.70 + if (remove_dead_region(phase, can_reshape)) return this; 1.71 + 1.72 + // Eliminate volatile MemBars for scalar replaced objects. 1.73 + if (can_reshape && req() == (Precedent+1) && 1.74 + (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) { 1.75 + // Volatile field loads and stores. 1.76 + Node* my_mem = in(MemBarNode::Precedent); 1.77 + if (my_mem != NULL && my_mem->is_Mem()) { 1.78 + const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr(); 1.79 + // Check for scalar replaced object reference. 1.80 + if( t_oop != NULL && t_oop->is_known_instance_field() && 1.81 + t_oop->offset() != Type::OffsetBot && 1.82 + t_oop->offset() != Type::OffsetTop) { 1.83 + // Replace MemBar projections by its inputs. 1.84 + PhaseIterGVN* igvn = phase->is_IterGVN(); 1.85 + igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); 1.86 + igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); 1.87 + // Must return either the original node (now dead) or a new node 1.88 + // (Do not return a top here, since that would break the uniqueness of top.) 1.89 + return new (phase->C, 1) ConINode(TypeInt::ZERO); 1.90 + } 1.91 + } 1.92 + } 1.93 + return NULL; 1.94 } 1.95 1.96 //------------------------------Value------------------------------------------