7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity

Sat, 04 Jun 2011 10:36:22 -0700

author
kvn
date
Sat, 04 Jun 2011 10:36:22 -0700
changeset 2951
642c68c75db9
parent 2950
cba7b5c2d53f
child 2952
5cf771a79037

7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
Summary: Mark all associated (same box and obj) lock and unlock nodes for elimination if some of them marked already.
Reviewed-by: iveresov, never

src/share/vm/opto/escape.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/escape.cpp	Fri Jun 03 22:31:43 2011 -0700
     1.2 +++ b/src/share/vm/opto/escape.cpp	Sat Jun 04 10:36:22 2011 -0700
     1.3 @@ -1747,6 +1747,25 @@
     1.4    _collecting = false;
     1.5    assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
     1.6  
     1.7 +  if (EliminateLocks) {
     1.8 +    // Mark locks before changing ideal graph.
     1.9 +    int cnt = C->macro_count();
    1.10 +    for( int i=0; i < cnt; i++ ) {
    1.11 +      Node *n = C->macro_node(i);
    1.12 +      if (n->is_AbstractLock()) { // Lock and Unlock nodes
    1.13 +        AbstractLockNode* alock = n->as_AbstractLock();
    1.14 +        if (!alock->is_eliminated()) {
    1.15 +          PointsToNode::EscapeState es = escape_state(alock->obj_node());
    1.16 +          assert(es != PointsToNode::UnknownEscape, "should know");
    1.17 +          if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
    1.18 +            // Mark it eliminated
    1.19 +            alock->set_eliminated();
    1.20 +          }
    1.21 +        }
    1.22 +      }
    1.23 +    }
    1.24 +  }
    1.25 +
    1.26  #ifndef PRODUCT
    1.27    if (PrintEscapeAnalysis) {
    1.28      dump(); // Dump ConnectionGraph
     2.1 --- a/src/share/vm/opto/macro.cpp	Fri Jun 03 22:31:43 2011 -0700
     2.2 +++ b/src/share/vm/opto/macro.cpp	Sat Jun 04 10:36:22 2011 -0700
     2.3 @@ -1693,25 +1693,31 @@
     2.4                           OptoRuntime::new_array_Java());
     2.5  }
     2.6  
     2.7 -
     2.8 -// we have determined that this lock/unlock can be eliminated, we simply
     2.9 -// eliminate the node without expanding it.
    2.10 -//
    2.11 -// Note:  The membar's associated with the lock/unlock are currently not
    2.12 -//        eliminated.  This should be investigated as a future enhancement.
    2.13 -//
    2.14 -bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
    2.15 -
    2.16 +//-----------------------mark_eliminated_locking_nodes-----------------------
    2.17 +// During EA obj may point to several objects but after few ideal graph
    2.18 +// transformations (CCP) it may point to only one non escaping object
    2.19 +// (but still using phi), corresponding locks and unlocks will be marked
    2.20 +// for elimination. Later obj could be replaced with a new node (new phi)
    2.21 +// and which does not have escape information. And later after some graph
    2.22 +// reshape other locks and unlocks (which were not marked for elimination
    2.23 +// before) are connected to this new obj (phi) but they still will not be
    2.24 +// marked for elimination since new obj has no escape information.
    2.25 +// Mark all associated (same box and obj) lock and unlock nodes for
    2.26 +// elimination if some of them marked already.
    2.27 +void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) {
    2.28    if (!alock->is_eliminated()) {
    2.29 -    return false;
    2.30 +    return;
    2.31    }
    2.32 -  if (alock->is_Lock() && !alock->is_coarsened()) {
    2.33 +  if (!alock->is_coarsened()) { // Eliminated by EA
    2.34        // Create new "eliminated" BoxLock node and use it
    2.35        // in monitor debug info for the same object.
    2.36        BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
    2.37        Node* obj = alock->obj_node();
    2.38        if (!oldbox->is_eliminated()) {
    2.39          BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
    2.40 +        // Note: BoxLock node is marked eliminated only here
    2.41 +        // and it is used to indicate that all associated lock
    2.42 +        // and unlock nodes are marked for elimination.
    2.43          newbox->set_eliminated();
    2.44          transform_later(newbox);
    2.45          // Replace old box node with new box for all users
    2.46 @@ -1720,22 +1726,14 @@
    2.47  
    2.48            bool next_edge = true;
    2.49            Node* u = oldbox->raw_out(i);
    2.50 -          if (u == alock) {
    2.51 -            i++;
    2.52 -            continue; // It will be removed below
    2.53 -          }
    2.54 -          if (u->is_Lock() &&
    2.55 -              u->as_Lock()->obj_node() == obj &&
    2.56 -              // oldbox could be referenced in debug info also
    2.57 -              u->as_Lock()->box_node() == oldbox) {
    2.58 -            assert(u->as_Lock()->is_eliminated(), "sanity");
    2.59 +          if (u->is_AbstractLock() &&
    2.60 +              u->as_AbstractLock()->obj_node() == obj &&
    2.61 +              u->as_AbstractLock()->box_node() == oldbox) {
    2.62 +            // Mark all associated locks and unlocks.
    2.63 +            u->as_AbstractLock()->set_eliminated();
    2.64              _igvn.hash_delete(u);
    2.65              u->set_req(TypeFunc::Parms + 1, newbox);
    2.66              next_edge = false;
    2.67 -#ifdef ASSERT
    2.68 -          } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
    2.69 -            assert(u->as_Unlock()->is_eliminated(), "sanity");
    2.70 -#endif
    2.71            }
    2.72            // Replace old box in monitor debug info.
    2.73            if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
    2.74 @@ -1761,8 +1759,27 @@
    2.75            if (next_edge) i++;
    2.76          } // for (uint i = 0; i < oldbox->outcnt();)
    2.77        } // if (!oldbox->is_eliminated())
    2.78 -  } // if (alock->is_Lock() && !lock->is_coarsened())
    2.79 +  } // if (!alock->is_coarsened())
    2.80 +}
    2.81  
    2.82 +// we have determined that this lock/unlock can be eliminated, we simply
    2.83 +// eliminate the node without expanding it.
    2.84 +//
    2.85 +// Note:  The membar's associated with the lock/unlock are currently not
    2.86 +//        eliminated.  This should be investigated as a future enhancement.
    2.87 +//
    2.88 +bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
    2.89 +
    2.90 +  if (!alock->is_eliminated()) {
    2.91 +    return false;
    2.92 +  }
    2.93 +#ifdef ASSERT
    2.94 +  if (alock->is_Lock() && !alock->is_coarsened()) {
    2.95 +    // Check that new "eliminated" BoxLock node is created.
    2.96 +    BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
    2.97 +    assert(oldbox->is_eliminated(), "should be done already");
    2.98 +  }
    2.99 +#endif
   2.100    CompileLog* log = C->log();
   2.101    if (log != NULL) {
   2.102      log->head("eliminate_lock lock='%d'",
   2.103 @@ -2145,6 +2162,15 @@
   2.104    if (C->macro_count() == 0)
   2.105      return false;
   2.106    // First, attempt to eliminate locks
   2.107 +  int cnt = C->macro_count();
   2.108 +  for (int i=0; i < cnt; i++) {
   2.109 +    Node *n = C->macro_node(i);
   2.110 +    if (n->is_AbstractLock()) { // Lock and Unlock nodes
   2.111 +      // Before elimination mark all associated (same box and obj)
   2.112 +      // lock and unlock nodes.
   2.113 +      mark_eliminated_locking_nodes(n->as_AbstractLock());
   2.114 +    }
   2.115 +  }
   2.116    bool progress = true;
   2.117    while (progress) {
   2.118      progress = false;
     3.1 --- a/src/share/vm/opto/macro.hpp	Fri Jun 03 22:31:43 2011 -0700
     3.2 +++ b/src/share/vm/opto/macro.hpp	Sat Jun 04 10:36:22 2011 -0700
     3.3 @@ -92,6 +92,7 @@
     3.4    void process_users_of_allocation(AllocateNode *alloc);
     3.5  
     3.6    void eliminate_card_mark(Node *cm);
     3.7 +  void mark_eliminated_locking_nodes(AbstractLockNode *alock);
     3.8    bool eliminate_locking_node(AbstractLockNode *alock);
     3.9    void expand_lock_node(LockNode *lock);
    3.10    void expand_unlock_node(UnlockNode *unlock);

mercurial