< prev index next >

src/share/vm/opto/callnode.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -21,10 +21,11 @@
  * questions.
  *
  */
 
 #include "precompiled.hpp"
+#include "compiler/compileLog.hpp"
 #include "ci/bcEscapeAnalyzer.hpp"
 #include "compiler/oopMap.hpp"
 #include "opto/callGenerator.hpp"
 #include "opto/callnode.hpp"
 #include "opto/castnode.hpp"

@@ -1671,10 +1672,13 @@
     if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
       // to eliminate all associated locks/unlocks.
+#ifdef ASSERT
+      this->log_lock_optimization(phase,"eliminate_lock_set_non_esc1");
+#endif
       this->set_non_esc_obj();
       return result;
     }
 
     //

@@ -1732,10 +1736,13 @@
         // as eliminatable
         for (int i = 0; i < lock_ops.length(); i++) {
           AbstractLockNode* lock = lock_ops.at(i);
 
           // Mark it eliminated by coarsening and update any counters
+#ifdef ASSERT
+          lock->log_lock_optimization(phase, "eliminate_lock_set_coarsened");
+#endif
           lock->set_coarsened();
         }
       } else if (ctrl->is_Region() &&
                  iter->_worklist.member(ctrl)) {
         // We weren't able to find any opportunities but the region this

@@ -1782,10 +1789,52 @@
     }
   }
   return false;
 }
 
+#ifdef ASSERT
+bool LockNode::is_nested_lock_region_debug(Phase * p) {
+  BoxLockNode* box = box_node()->as_BoxLock();
+  int stk_slot = box->stack_slot();
+  if (stk_slot <= 0) {
+    this->log_lock_optimization(p, "eliminate_lock_INLR_1");
+    return false; // External lock or it is not Box (Phi node).
+  }
+
+  // Ignore complex cases: merged locks or multiple locks.
+  Node* obj = obj_node();
+  LockNode* unique_lock = NULL;
+  if (!box->is_simple_lock_region(&unique_lock, obj)) {
+    this->log_lock_optimization(p, "eliminate_lock_INLR_2a");
+    return false;
+  }
+  if (unique_lock != this) {
+    this->log_lock_optimization(p, "eliminate_lock_INLR_2b");
+    return false;
+  }
+
+  // Look for external lock for the same object.
+  SafePointNode* sfn = this->as_SafePoint();
+  JVMState* youngest_jvms = sfn->jvms();
+  int max_depth = youngest_jvms->depth();
+  for (int depth = 1; depth <= max_depth; depth++) {
+    JVMState* jvms = youngest_jvms->of_depth(depth);
+    int num_mon  = jvms->nof_monitors();
+    // Loop over monitors
+    for (int idx = 0; idx < num_mon; idx++) {
+      Node* obj_node = sfn->monitor_obj(jvms, idx);
+      BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock();
+      if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) {
+        return true;
+      }
+    }
+  }
+  this->log_lock_optimization(p, "eliminate_lock_INLR_3");
+  return false;
+}
+#endif
+
 //=============================================================================
 uint UnlockNode::size_of() const { return sizeof(*this); }
 
 //=============================================================================
 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {

@@ -1810,16 +1859,44 @@
     if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
       // to eliminate all associated locks/unlocks.
+#ifdef ASSERT
+      this->log_lock_optimization(phase, "eliminate_lock_set_non_esc2");
+#endif
       this->set_non_esc_obj();
     }
   }
   return result;
 }
 
+const char * AbstractLockNode::kind_as_string() const {
+      return is_coarsened() ? "coarsened" :
+                  is_nested() ? "nested" :
+                      is_non_esc_obj() ? "non_escaping" : "?";
+}
+
+void AbstractLockNode::log_lock_optimization(Phase *phase, const char * tag)  const {
+    Compile * C = phase->C;
+    CompileLog* log = C->log();
+    if (log != NULL) {
+      log->begin_head("%s lock='%d' compile_id='%d' class_id='%s' kind='%s'",
+            tag, is_Lock(), C->compile_id(),
+            is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?",
+            kind_as_string());
+      log->stamp();
+      log->end_head();
+      JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms();
+      while (p != NULL) {
+        log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
+        p = p->caller();
+      }
+      log->tail(tag);
+    }
+}
+
 ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled)
   : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM),
     _alloc_tightly_coupled(alloc_tightly_coupled),
     _kind(None),
     _arguments_validated(false) {
< prev index next >