src/share/vm/opto/memnode.cpp

changeset 1535
f96a1a986f7b
parent 1515
7c57aead6d3e
child 1907
c18cbe5936b8
     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------------------------------------------

mercurial