src/share/vm/opto/macro.cpp

changeset 2951
642c68c75db9
parent 2877
bad7ecd0b6ed
child 2985
e3cbc9ddd434
     1.1 --- a/src/share/vm/opto/macro.cpp	Fri Jun 03 22:31:43 2011 -0700
     1.2 +++ b/src/share/vm/opto/macro.cpp	Sat Jun 04 10:36:22 2011 -0700
     1.3 @@ -1693,25 +1693,31 @@
     1.4                           OptoRuntime::new_array_Java());
     1.5  }
     1.6  
     1.7 -
     1.8 -// we have determined that this lock/unlock can be eliminated, we simply
     1.9 -// eliminate the node without expanding it.
    1.10 -//
    1.11 -// Note:  The membar's associated with the lock/unlock are currently not
    1.12 -//        eliminated.  This should be investigated as a future enhancement.
    1.13 -//
    1.14 -bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
    1.15 -
    1.16 +//-----------------------mark_eliminated_locking_nodes-----------------------
    1.17 +// During EA obj may point to several objects but after few ideal graph
    1.18 +// transformations (CCP) it may point to only one non escaping object
    1.19 +// (but still using phi), corresponding locks and unlocks will be marked
    1.20 +// for elimination. Later obj could be replaced with a new node (new phi)
    1.21 +// and which does not have escape information. And later after some graph
    1.22 +// reshape other locks and unlocks (which were not marked for elimination
    1.23 +// before) are connected to this new obj (phi) but they still will not be
    1.24 +// marked for elimination since new obj has no escape information.
    1.25 +// Mark all associated (same box and obj) lock and unlock nodes for
    1.26 +// elimination if some of them marked already.
    1.27 +void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
    1.28    if (!alock->is_eliminated()) {
    1.29 -    return false;
    1.30 +    return;
    1.31    }
    1.32 -  if (alock->is_Lock() && !alock->is_coarsened()) {
    1.33 +  if (!alock->is_coarsened()) { // Eliminated by EA
    1.34        // Create new "eliminated" BoxLock node and use it
    1.35        // in monitor debug info for the same object.
    1.36        BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
    1.37        Node* obj = alock->obj_node();
    1.38        if (!oldbox->is_eliminated()) {
    1.39          BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
    1.40 +        // Note: BoxLock node is marked eliminated only here
    1.41 +        // and it is used to indicate that all associated lock
    1.42 +        // and unlock nodes are marked for elimination.
    1.43          newbox->set_eliminated();
    1.44          transform_later(newbox);
    1.45          // Replace old box node with new box for all users
    1.46 @@ -1720,22 +1726,14 @@
    1.47  
    1.48            bool next_edge = true;
    1.49            Node* u = oldbox->raw_out(i);
    1.50 -          if (u == alock) {
    1.51 -            i++;
    1.52 -            continue; // It will be removed below
    1.53 -          }
    1.54 -          if (u->is_Lock() &&
    1.55 -              u->as_Lock()->obj_node() == obj &&
    1.56 -              // oldbox could be referenced in debug info also
    1.57 -              u->as_Lock()->box_node() == oldbox) {
    1.58 -            assert(u->as_Lock()->is_eliminated(), "sanity");
    1.59 +          if (u->is_AbstractLock() &&
    1.60 +              u->as_AbstractLock()->obj_node() == obj &&
    1.61 +              u->as_AbstractLock()->box_node() == oldbox) {
    1.62 +            // Mark all associated locks and unlocks.
    1.63 +            u->as_AbstractLock()->set_eliminated();
    1.64              _igvn.hash_delete(u);
    1.65              u->set_req(TypeFunc::Parms + 1, newbox);
    1.66              next_edge = false;
    1.67 -#ifdef ASSERT
    1.68 -          } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
    1.69 -            assert(u->as_Unlock()->is_eliminated(), "sanity");
    1.70 -#endif
    1.71            }
    1.72            // Replace old box in monitor debug info.
    1.73            if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
    1.74 @@ -1761,8 +1759,27 @@
    1.75            if (next_edge) i++;
    1.76          } // for (uint i = 0; i < oldbox->outcnt();)
    1.77        } // if (!oldbox->is_eliminated())
    1.78 -  } // if (alock->is_Lock() && !lock->is_coarsened())
    1.79 +  } // if (!alock->is_coarsened())
    1.80 +}
    1.81  
    1.82 +// we have determined that this lock/unlock can be eliminated, we simply
    1.83 +// eliminate the node without expanding it.
    1.84 +//
    1.85 +// Note:  The membar's associated with the lock/unlock are currently not
    1.86 +//        eliminated.  This should be investigated as a future enhancement.
    1.87 +//
    1.88 +bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
    1.89 +
    1.90 +  if (!alock->is_eliminated()) {
    1.91 +    return false;
    1.92 +  }
    1.93 +#ifdef ASSERT
    1.94 +  if (alock->is_Lock() && !alock->is_coarsened()) {
    1.95 +    // Check that new "eliminated" BoxLock node is created.
    1.96 +    BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
    1.97 +    assert(oldbox->is_eliminated(), "should be done already");
    1.98 +  }
    1.99 +#endif
   1.100    CompileLog* log = C->log();
   1.101    if (log != NULL) {
   1.102      log->head("eliminate_lock lock='%d'",
   1.103 @@ -2145,6 +2162,15 @@
   1.104    if (C->macro_count() == 0)
   1.105      return false;
   1.106    // First, attempt to eliminate locks
   1.107 +  int cnt = C->macro_count();
   1.108 +  for (int i=0; i < cnt; i++) {
   1.109 +    Node *n = C->macro_node(i);
   1.110 +    if (n->is_AbstractLock()) { // Lock and Unlock nodes
   1.111 +      // Before elimination mark all associated (same box and obj)
   1.112 +      // lock and unlock nodes.
   1.113 +      mark_eliminated_locking_nodes(n->as_AbstractLock());
   1.114 +    }
   1.115 +  }
   1.116    bool progress = true;
   1.117    while (progress) {
   1.118      progress = false;

mercurial