8069412: Locks need better debug-printing support

Fri, 20 Feb 2015 22:12:53 -0500

author
drchase
date
Fri, 20 Feb 2015 22:12:53 -0500
changeset 7605
6e8e0bf87bbe
parent 7582
9d6eb2757167
child 7606
d0934ced01ac

8069412: Locks need better debug-printing support
Summary: Added better debug-printing support and enhanced LogCompilation tool
Reviewed-by: kvn, roland, dholmes

src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java file | annotate | diff | comparison | revisions
src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java file | annotate | diff | comparison | revisions
src/share/vm/oops/markOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/callnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/callnode.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/escape.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/basicLock.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/vframe.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Wed Feb 11 18:56:26 2015 -0800
     1.2 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java	Fri Feb 20 22:12:53 2015 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -24,12 +24,12 @@
    1.11  
    1.12  /**
    1.13   * A SAX based parser of LogCompilation output from HotSpot.  It takes a complete
    1.14 - * @author never
    1.15   */
    1.16  
    1.17  package com.sun.hotspot.tools.compiler;
    1.18  
    1.19  import java.io.FileReader;
    1.20 +import java.io.PrintStream;
    1.21  import java.io.Reader;
    1.22  import java.util.ArrayList;
    1.23  import java.util.Collections;
    1.24 @@ -133,6 +133,44 @@
    1.25          }
    1.26      };
    1.27  
    1.28 +    class Jvms {
    1.29 +        Jvms(Method method, int bci) {
    1.30 +            this.method = method;
    1.31 +            this.bci = bci;
    1.32 +        }
    1.33 +        final public Method method;
    1.34 +        final public int bci;
    1.35 +        final public String toString() {
    1.36 +            return "@" + bci + " " + method;
    1.37 +        }
    1.38 +    }
    1.39 +
    1.40 +    class LockElimination extends BasicLogEvent {
    1.41 +
    1.42 +        ArrayList<Jvms> jvms = new ArrayList<Jvms>(1);
    1.43 +        final String kind;
    1.44 +        final String classId;
    1.45 +        final String tagName;
    1.46 +        LockElimination(String tagName, double start, String id, String kind, String classId) {
    1.47 +            super(start, id);
    1.48 +            this.kind = kind;
    1.49 +            this.classId = classId;
    1.50 +            this.tagName = tagName;
    1.51 +        }
    1.52 +
    1.53 +        @Override
    1.54 +        public void print(PrintStream stream) {
    1.55 +            stream.printf("%s %s %s %s  %.3f ", getId(), tagName, kind, classId, getStart());
    1.56 +            stream.print(jvms.toString());
    1.57 +            stream.print("\n");
    1.58 +        }
    1.59 +
    1.60 +        void addJVMS(Method method, int bci) {
    1.61 +            jvms.add(new Jvms(method, bci));
    1.62 +        }
    1.63 +
    1.64 +    }
    1.65 +
    1.66      private ArrayList<LogEvent> events = new ArrayList<LogEvent>();
    1.67  
    1.68      private HashMap<String, String> types = new HashMap<String, String>();
    1.69 @@ -145,6 +183,7 @@
    1.70      private Compilation compile;
    1.71      private CallSite site;
    1.72      private Stack<Phase> phaseStack = new Stack<Phase>();
    1.73 +    private LockElimination currentLockElimination;
    1.74      private UncommonTrapEvent currentTrap;
    1.75      private Stack<CallSite> late_inline_scope;
    1.76  
    1.77 @@ -188,7 +227,12 @@
    1.78          }
    1.79  
    1.80          LogParser log = new LogParser();
    1.81 -        p.parse(new InputSource(reader), log);
    1.82 +        try {
    1.83 +            p.parse(new InputSource(reader), log);
    1.84 +        } catch (Throwable th) {
    1.85 +            th.printStackTrace();
    1.86 +            // Carry on with what we've got...
    1.87 +        }
    1.88  
    1.89          // Associate compilations with their NMethods
    1.90          for (NMethod nm : log.nmethods.values()) {
    1.91 @@ -370,6 +414,15 @@
    1.92                  // uncommon trap inserted during parsing.
    1.93                  // ignore for now
    1.94              }
    1.95 +        } else if (qname.startsWith("eliminate_lock")) {
    1.96 +            String id = atts.getValue("compile_id");
    1.97 +            if (id != null) {
    1.98 +                id = makeId(atts);
    1.99 +                String kind = atts.getValue("kind");
   1.100 +                String classId = atts.getValue("class_id");
   1.101 +                currentLockElimination = new LockElimination(qname, Double.parseDouble(search(atts, "stamp")), id, kind, classId);
   1.102 +                events.add(currentLockElimination);
   1.103 +            }
   1.104          } else if (qname.equals("late_inline")) {
   1.105              late_inline_scope = new Stack<CallSite>();
   1.106              site = new CallSite(-999, method(search(atts, "method")));
   1.107 @@ -378,13 +431,14 @@
   1.108              // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
   1.109              if (currentTrap != null) {
   1.110                  currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
   1.111 +            } else if (currentLockElimination != null) {
   1.112 +                  currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
   1.113              } else if (late_inline_scope != null) {
   1.114                  bci = Integer.parseInt(search(atts, "bci"));
   1.115                  site = new CallSite(bci, method(search(atts, "method")));
   1.116                  late_inline_scope.push(site);
   1.117              } else {
   1.118                  // Ignore <eliminate_allocation type='667'>,
   1.119 -                //        <eliminate_lock lock='1'>,
   1.120                  //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
   1.121              }
   1.122          } else if (qname.equals("nmethod")) {
   1.123 @@ -437,6 +491,8 @@
   1.124              scopes.pop();
   1.125          } else if (qname.equals("uncommon_trap")) {
   1.126              currentTrap = null;
   1.127 +        } else if (qname.startsWith("eliminate_lock")) {
   1.128 +            currentLockElimination = null;
   1.129          } else if (qname.equals("late_inline")) {
   1.130              // Populate late inlining info.
   1.131  
   1.132 @@ -445,8 +501,8 @@
   1.133              CallSite caller = late_inline_scope.pop();
   1.134              Method m = compile.getMethod();
   1.135              if (m != caller.getMethod()) {
   1.136 -                System.out.println(m);
   1.137 -                System.out.println(caller.getMethod() + " bci: " + bci);
   1.138 +                System.err.println(m);
   1.139 +                System.err.println(caller.getMethod() + " bci: " + bci);
   1.140                  throw new InternalError("call site and late_inline info don't match");
   1.141              }
   1.142  
     2.1 --- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Wed Feb 11 18:56:26 2015 -0800
     2.2 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java	Fri Feb 20 22:12:53 2015 -0500
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -50,7 +50,7 @@
    2.11      }
    2.12  
    2.13      public void print(PrintStream stream) {
    2.14 -        stream.printf("%s uncommon trap %s %s\n", getId(), getReason(), getAction());
    2.15 +        stream.printf("%s uncommon trap %.3f %s %s\n", getId(), getStart(), getReason(), getAction());
    2.16          stream.print(getJvms());
    2.17      }
    2.18  
     3.1 --- a/src/share/vm/oops/markOop.cpp	Wed Feb 11 18:56:26 2015 -0800
     3.2 +++ b/src/share/vm/oops/markOop.cpp	Fri Feb 20 22:12:53 2015 -0500
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -25,17 +25,40 @@
    3.11  #include "precompiled.hpp"
    3.12  #include "oops/markOop.hpp"
    3.13  #include "runtime/thread.inline.hpp"
    3.14 +#include "runtime/objectMonitor.inline.hpp"
    3.15  
    3.16  PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    3.17  
    3.18  void markOopDesc::print_on(outputStream* st) const {
    3.19 -  if (is_locked()) {
    3.20 -    st->print("locked(" INTPTR_FORMAT ")->", value());
    3.21 -    markOop(*(markOop*)value())->print_on(st);
    3.22 +  if (is_marked()) {
    3.23 +    st->print(" marked(" INTPTR_FORMAT ")", value());
    3.24 +  } else if (is_locked()) {
    3.25 +    st->print(" locked(" INTPTR_FORMAT ")->", value());
    3.26 +    if (is_neutral()) {
    3.27 +      st->print("is_neutral");
    3.28 +      if (has_no_hash()) st->print(" no_hash");
    3.29 +      else st->print(" hash=" INTPTR_FORMAT, hash());
    3.30 +      st->print(" age=%d", age());
    3.31 +    } else if (has_bias_pattern()) {
    3.32 +      st->print("is_biased");
    3.33 +      JavaThread* jt = biased_locker();
    3.34 +      st->print(" biased_locker=" INTPTR_FORMAT, p2i(jt));
    3.35 +    } else if (has_monitor()) {
    3.36 +      ObjectMonitor* mon = monitor();
    3.37 +      if (mon == NULL)
    3.38 +        st->print("monitor=NULL");
    3.39 +      else {
    3.40 +        BasicLock * bl = (BasicLock *) mon->owner();
    3.41 +        st->print("monitor={count="INTPTR_FORMAT",waiters="INTPTR_FORMAT",recursions="INTPTR_FORMAT",owner="INTPTR_FORMAT"}",
    3.42 +                mon->count(), mon->waiters(), mon->recursions(), p2i(bl));
    3.43 +      }
    3.44 +    } else {
    3.45 +      st->print("??");
    3.46 +    }
    3.47    } else {
    3.48      assert(is_unlocked() || has_bias_pattern(), "just checking");
    3.49      st->print("mark(");
    3.50 -    if (has_bias_pattern())  st->print("biased,");
    3.51 +    if (has_bias_pattern()) st->print("biased,");
    3.52      st->print("hash %#lx,", hash());
    3.53      st->print("age %d)", age());
    3.54    }
     4.1 --- a/src/share/vm/opto/callnode.cpp	Wed Feb 11 18:56:26 2015 -0800
     4.2 +++ b/src/share/vm/opto/callnode.cpp	Fri Feb 20 22:12:53 2015 -0500
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -23,6 +23,7 @@
    4.11   */
    4.12  
    4.13  #include "precompiled.hpp"
    4.14 +#include "compiler/compileLog.hpp"
    4.15  #include "ci/bcEscapeAnalyzer.hpp"
    4.16  #include "compiler/oopMap.hpp"
    4.17  #include "opto/callGenerator.hpp"
    4.18 @@ -1670,6 +1671,9 @@
    4.19        // The lock could be marked eliminated by lock coarsening
    4.20        // code during first IGVN before EA. Replace coarsened flag
    4.21        // to eliminate all associated locks/unlocks.
    4.22 +#ifdef ASSERT
    4.23 +      this->log_lock_optimization(phase->C,"eliminate_lock_set_non_esc1");
    4.24 +#endif
    4.25        this->set_non_esc_obj();
    4.26        return result;
    4.27      }
    4.28 @@ -1731,6 +1735,9 @@
    4.29            AbstractLockNode* lock = lock_ops.at(i);
    4.30  
    4.31            // Mark it eliminated by coarsening and update any counters
    4.32 +#ifdef ASSERT
    4.33 +          lock->log_lock_optimization(phase->C, "eliminate_lock_set_coarsened");
    4.34 +#endif
    4.35            lock->set_coarsened();
    4.36          }
    4.37        } else if (ctrl->is_Region() &&
    4.38 @@ -1749,16 +1756,33 @@
    4.39  
    4.40  //=============================================================================
    4.41  bool LockNode::is_nested_lock_region() {
    4.42 +  return is_nested_lock_region(NULL);
    4.43 +}
    4.44 +
    4.45 +// p is used for access to compilation log; no logging if NULL
    4.46 +bool LockNode::is_nested_lock_region(Compile * c) {
    4.47    BoxLockNode* box = box_node()->as_BoxLock();
    4.48    int stk_slot = box->stack_slot();
    4.49 -  if (stk_slot <= 0)
    4.50 +  if (stk_slot <= 0) {
    4.51 +#ifdef ASSERT
    4.52 +    this->log_lock_optimization(c, "eliminate_lock_INLR_1");
    4.53 +#endif
    4.54      return false; // External lock or it is not Box (Phi node).
    4.55 +  }
    4.56  
    4.57    // Ignore complex cases: merged locks or multiple locks.
    4.58    Node* obj = obj_node();
    4.59    LockNode* unique_lock = NULL;
    4.60 -  if (!box->is_simple_lock_region(&unique_lock, obj) ||
    4.61 -      (unique_lock != this)) {
    4.62 +  if (!box->is_simple_lock_region(&unique_lock, obj)) {
    4.63 +#ifdef ASSERT
    4.64 +    this->log_lock_optimization(c, "eliminate_lock_INLR_2a");
    4.65 +#endif
    4.66 +    return false;
    4.67 +  }
    4.68 +  if (unique_lock != this) {
    4.69 +#ifdef ASSERT
    4.70 +    this->log_lock_optimization(c, "eliminate_lock_INLR_2b");
    4.71 +#endif
    4.72      return false;
    4.73    }
    4.74  
    4.75 @@ -1778,6 +1802,9 @@
    4.76        }
    4.77      }
    4.78    }
    4.79 +#ifdef ASSERT
    4.80 +  this->log_lock_optimization(c, "eliminate_lock_INLR_3");
    4.81 +#endif
    4.82    return false;
    4.83  }
    4.84  
    4.85 @@ -1809,8 +1836,40 @@
    4.86        // The lock could be marked eliminated by lock coarsening
    4.87        // code during first IGVN before EA. Replace coarsened flag
    4.88        // to eliminate all associated locks/unlocks.
    4.89 +#ifdef ASSERT
    4.90 +      this->log_lock_optimization(phase->C, "eliminate_lock_set_non_esc2");
    4.91 +#endif
    4.92        this->set_non_esc_obj();
    4.93      }
    4.94    }
    4.95    return result;
    4.96  }
    4.97 +
    4.98 +const char * AbstractLockNode::kind_as_string() const {
    4.99 +  return is_coarsened()   ? "coarsened" :
   4.100 +         is_nested()      ? "nested" :
   4.101 +         is_non_esc_obj() ? "non_escaping" :
   4.102 +         "?";
   4.103 +}
   4.104 +
   4.105 +void AbstractLockNode::log_lock_optimization(Compile *C, const char * tag)  const {
   4.106 +  if (C == NULL) {
   4.107 +    return;
   4.108 +  }
   4.109 +  CompileLog* log = C->log();
   4.110 +  if (log != NULL) {
   4.111 +    log->begin_head("%s lock='%d' compile_id='%d' class_id='%s' kind='%s'",
   4.112 +          tag, is_Lock(), C->compile_id(),
   4.113 +          is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?",
   4.114 +          kind_as_string());
   4.115 +    log->stamp();
   4.116 +    log->end_head();
   4.117 +    JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms();
   4.118 +    while (p != NULL) {
   4.119 +      log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
   4.120 +      p = p->caller();
   4.121 +    }
   4.122 +    log->tail(tag);
   4.123 +  }
   4.124 +}
   4.125 +
     5.1 --- a/src/share/vm/opto/callnode.hpp	Wed Feb 11 18:56:26 2015 -0800
     5.2 +++ b/src/share/vm/opto/callnode.hpp	Fri Feb 20 22:12:53 2015 -0500
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -985,6 +985,9 @@
    5.11    bool is_coarsened()   const { return (_kind == Coarsened); }
    5.12    bool is_nested()      const { return (_kind == Nested); }
    5.13  
    5.14 +  const char * kind_as_string() const;
    5.15 +  void log_lock_optimization(Compile* c, const char * tag) const;
    5.16 +
    5.17    void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
    5.18    void set_coarsened()   { _kind = Coarsened; set_eliminated_lock_counter(); }
    5.19    void set_nested()      { _kind = Nested; set_eliminated_lock_counter(); }
    5.20 @@ -1045,15 +1048,24 @@
    5.21    }
    5.22  
    5.23    bool is_nested_lock_region(); // Is this Lock nested?
    5.24 +  bool is_nested_lock_region(Compile * c); // Why isn't this Lock nested?
    5.25  };
    5.26  
    5.27  //------------------------------Unlock---------------------------------------
    5.28  // High-level unlock operation
    5.29  class UnlockNode : public AbstractLockNode {
    5.30 +private:
    5.31 +#ifdef ASSERT
    5.32 +  JVMState* const _dbg_jvms;      // Pointer to list of JVM State objects
    5.33 +#endif
    5.34  public:
    5.35    virtual int Opcode() const;
    5.36    virtual uint size_of() const; // Size is bigger
    5.37 -  UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf ) {
    5.38 +  UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf )
    5.39 +#ifdef ASSERT
    5.40 +    , _dbg_jvms(NULL)
    5.41 +#endif
    5.42 +  {
    5.43      init_class_id(Class_Unlock);
    5.44      init_flags(Flag_is_macro);
    5.45      C->add_macro_node(this);
    5.46 @@ -1061,6 +1073,14 @@
    5.47    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
    5.48    // unlock is never a safepoint
    5.49    virtual bool        guaranteed_safepoint()  { return false; }
    5.50 +#ifdef ASSERT
    5.51 +  void set_dbg_jvms(JVMState* s) {
    5.52 +    *(JVMState**)&_dbg_jvms = s;  // override const attribute in the accessor
    5.53 +  }
    5.54 +  JVMState* dbg_jvms() const { return _dbg_jvms; }
    5.55 +#else
    5.56 +  JVMState* dbg_jvms() const { return NULL; }
    5.57 +#endif
    5.58  };
    5.59  
    5.60  #endif // SHARE_VM_OPTO_CALLNODE_HPP
     6.1 --- a/src/share/vm/opto/escape.cpp	Wed Feb 11 18:56:26 2015 -0800
     6.2 +++ b/src/share/vm/opto/escape.cpp	Fri Feb 20 22:12:53 2015 -0500
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -1794,6 +1794,9 @@
    6.11              // The lock could be marked eliminated by lock coarsening
    6.12              // code during first IGVN before EA. Replace coarsened flag
    6.13              // to eliminate all associated locks/unlocks.
    6.14 +#ifdef ASSERT
    6.15 +            alock->log_lock_optimization(C, "eliminate_lock_set_non_esc3");
    6.16 +#endif
    6.17              alock->set_non_esc_obj();
    6.18            }
    6.19          }
     7.1 --- a/src/share/vm/opto/graphKit.cpp	Wed Feb 11 18:56:26 2015 -0800
     7.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Feb 20 22:12:53 2015 -0500
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -3211,6 +3211,9 @@
    7.11  
    7.12    const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
    7.13    UnlockNode *unlock = new (C) UnlockNode(C, tf);
    7.14 +#ifdef ASSERT
    7.15 +  unlock->set_dbg_jvms(sync_jvms());
    7.16 +#endif
    7.17    uint raw_idx = Compile::AliasIdxRaw;
    7.18    unlock->init_req( TypeFunc::Control, control() );
    7.19    unlock->init_req( TypeFunc::Memory , memory(raw_idx) );
     8.1 --- a/src/share/vm/opto/macro.cpp	Wed Feb 11 18:56:26 2015 -0800
     8.2 +++ b/src/share/vm/opto/macro.cpp	Fri Feb 20 22:12:53 2015 -0500
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -1890,7 +1890,7 @@
    8.11      // Box is used only in one lock region. Mark this box as eliminated.
    8.12      _igvn.hash_delete(oldbox);
    8.13      oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
    8.14 -    _igvn.hash_insert(oldbox);
    8.15 +     _igvn.hash_insert(oldbox);
    8.16  
    8.17      for (uint i = 0; i < oldbox->outcnt(); i++) {
    8.18        Node* u = oldbox->raw_out(i);
    8.19 @@ -1899,6 +1899,9 @@
    8.20          // Check lock's box since box could be referenced by Lock's debug info.
    8.21          if (alock->box_node() == oldbox) {
    8.22            // Mark eliminated all related locks and unlocks.
    8.23 +#ifdef ASSERT
    8.24 +          alock->log_lock_optimization(C, "eliminate_lock_set_non_esc4");
    8.25 +#endif
    8.26            alock->set_non_esc_obj();
    8.27          }
    8.28        }
    8.29 @@ -1925,6 +1928,9 @@
    8.30        AbstractLockNode* alock = u->as_AbstractLock();
    8.31        if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
    8.32          // Replace Box and mark eliminated all related locks and unlocks.
    8.33 +#ifdef ASSERT
    8.34 +        alock->log_lock_optimization(C, "eliminate_lock_set_non_esc5");
    8.35 +#endif
    8.36          alock->set_non_esc_obj();
    8.37          _igvn.rehash_node_delayed(alock);
    8.38          alock->set_box_node(newbox);
    8.39 @@ -1971,26 +1977,38 @@
    8.40         return;
    8.41      } else if (!alock->is_non_esc_obj()) { // Not eliminated or coarsened
    8.42        // Only Lock node has JVMState needed here.
    8.43 -      if (alock->jvms() != NULL && alock->as_Lock()->is_nested_lock_region()) {
    8.44 -        // Mark eliminated related nested locks and unlocks.
    8.45 -        Node* obj = alock->obj_node();
    8.46 -        BoxLockNode* box_node = alock->box_node()->as_BoxLock();
    8.47 -        assert(!box_node->is_eliminated(), "should not be marked yet");
    8.48 -        // Note: BoxLock node is marked eliminated only here
    8.49 -        // and it is used to indicate that all associated lock
    8.50 -        // and unlock nodes are marked for elimination.
    8.51 -        box_node->set_eliminated(); // Box's hash is always NO_HASH here
    8.52 -        for (uint i = 0; i < box_node->outcnt(); i++) {
    8.53 -          Node* u = box_node->raw_out(i);
    8.54 -          if (u->is_AbstractLock()) {
    8.55 -            alock = u->as_AbstractLock();
    8.56 -            if (alock->box_node() == box_node) {
    8.57 -              // Verify that this Box is referenced only by related locks.
    8.58 -              assert(alock->obj_node()->eqv_uncast(obj), "");
    8.59 -              // Mark all related locks and unlocks.
    8.60 -              alock->set_nested();
    8.61 +      // Not that preceding claim is documented anywhere else.
    8.62 +      if (alock->jvms() != NULL) {
    8.63 +        if (alock->as_Lock()->is_nested_lock_region()) {
    8.64 +          // Mark eliminated related nested locks and unlocks.
    8.65 +          Node* obj = alock->obj_node();
    8.66 +          BoxLockNode* box_node = alock->box_node()->as_BoxLock();
    8.67 +          assert(!box_node->is_eliminated(), "should not be marked yet");
    8.68 +          // Note: BoxLock node is marked eliminated only here
    8.69 +          // and it is used to indicate that all associated lock
    8.70 +          // and unlock nodes are marked for elimination.
    8.71 +          box_node->set_eliminated(); // Box's hash is always NO_HASH here
    8.72 +          for (uint i = 0; i < box_node->outcnt(); i++) {
    8.73 +            Node* u = box_node->raw_out(i);
    8.74 +            if (u->is_AbstractLock()) {
    8.75 +              alock = u->as_AbstractLock();
    8.76 +              if (alock->box_node() == box_node) {
    8.77 +                // Verify that this Box is referenced only by related locks.
    8.78 +                assert(alock->obj_node()->eqv_uncast(obj), "");
    8.79 +                // Mark all related locks and unlocks.
    8.80 +#ifdef ASSERT
    8.81 +                alock->log_lock_optimization(C, "eliminate_lock_set_nested");
    8.82 +#endif
    8.83 +                alock->set_nested();
    8.84 +              }
    8.85              }
    8.86            }
    8.87 +        } else {
    8.88 +#ifdef ASSERT
    8.89 +          alock->log_lock_optimization(C, "eliminate_lock_NOT_nested_lock_region");
    8.90 +          if (C->log() != NULL)
    8.91 +            alock->as_Lock()->is_nested_lock_region(C); // rerun for debugging output
    8.92 +#endif
    8.93          }
    8.94        }
    8.95        return;
    8.96 @@ -2035,19 +2053,10 @@
    8.97      assert(oldbox->is_eliminated(), "should be done already");
    8.98    }
    8.99  #endif
   8.100 -  CompileLog* log = C->log();
   8.101 -  if (log != NULL) {
   8.102 -    log->head("eliminate_lock lock='%d'",
   8.103 -              alock->is_Lock());
   8.104 -    JVMState* p = alock->jvms();
   8.105 -    while (p != NULL) {
   8.106 -      log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
   8.107 -      p = p->caller();
   8.108 -    }
   8.109 -    log->tail("eliminate_lock");
   8.110 -  }
   8.111  
   8.112 -  #ifndef PRODUCT
   8.113 +  alock->log_lock_optimization(C, "eliminate_lock");
   8.114 +
   8.115 +#ifndef PRODUCT
   8.116    if (PrintEliminateLocks) {
   8.117      if (alock->is_Lock()) {
   8.118        tty->print_cr("++++ Eliminated: %d Lock", alock->_idx);
   8.119 @@ -2055,7 +2064,7 @@
   8.120        tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx);
   8.121      }
   8.122    }
   8.123 -  #endif
   8.124 +#endif
   8.125  
   8.126    Node* mem  = alock->in(TypeFunc::Memory);
   8.127    Node* ctrl = alock->in(TypeFunc::Control);
     9.1 --- a/src/share/vm/runtime/basicLock.cpp	Wed Feb 11 18:56:26 2015 -0800
     9.2 +++ b/src/share/vm/runtime/basicLock.cpp	Fri Feb 20 22:12:53 2015 -0500
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -28,6 +28,9 @@
    9.11  
    9.12  void BasicLock::print_on(outputStream* st) const {
    9.13    st->print("monitor");
    9.14 +  markOop moop = displaced_header();
    9.15 +  if (moop != NULL)
    9.16 +    moop->print_on(st);
    9.17  }
    9.18  
    9.19  void BasicLock::move_to(oop obj, BasicLock* dest) {
    10.1 --- a/src/share/vm/runtime/vframe.cpp	Wed Feb 11 18:56:26 2015 -0800
    10.2 +++ b/src/share/vm/runtime/vframe.cpp	Fri Feb 20 22:12:53 2015 -0500
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -189,6 +189,7 @@
   10.11        if (monitor->eliminated() && is_compiled_frame()) { // Eliminated in compiled code
   10.12          if (monitor->owner_is_scalar_replaced()) {
   10.13            Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
   10.14 +          // format below for lockbits matches this one.
   10.15            st->print("\t- eliminated <owner is scalar replaced> (a %s)", k->external_name());
   10.16          } else {
   10.17            oop obj = monitor->owner();
   10.18 @@ -206,9 +207,10 @@
   10.19          // see if we have completed the lock or we are blocked trying to
   10.20          // acquire it - we can only be blocked if the monitor is inflated
   10.21  
   10.22 +        markOop mark = NULL;
   10.23          const char *lock_state = "locked"; // assume we have the monitor locked
   10.24          if (!found_first_monitor && frame_count == 0) {
   10.25 -          markOop mark = monitor->owner()->mark();
   10.26 +          mark = monitor->owner()->mark();
   10.27            if (mark->has_monitor() &&
   10.28                ( // we have marked ourself as pending on this monitor
   10.29                  mark->monitor() == thread()->current_pending_monitor() ||
   10.30 @@ -216,11 +218,19 @@
   10.31                  !mark->monitor()->is_entered(thread())
   10.32                )) {
   10.33              lock_state = "waiting to lock";
   10.34 +          } else {
   10.35 +            mark = NULL; // Disable printing below
   10.36            }
   10.37          }
   10.38 +        print_locked_object_class_name(st, monitor->owner(), lock_state);
   10.39 +        if (Verbose && mark != NULL) {
   10.40 +          // match with format above, replacing "-" with " ".
   10.41 +          st->print("\t  lockbits=");
   10.42 +          mark->print_on(st);
   10.43 +          st->cr();
   10.44 +        }
   10.45  
   10.46          found_first_monitor = true;
   10.47 -        print_locked_object_class_name(st, monitor->owner(), lock_state);
   10.48        }
   10.49      }
   10.50    }
   10.51 @@ -578,10 +588,15 @@
   10.52        tty->print("( null )");
   10.53      } else {
   10.54        monitor->owner()->print_value();
   10.55 -      tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
   10.56 +      tty->print("(owner=" INTPTR_FORMAT ")", (address)monitor->owner());
   10.57      }
   10.58 -    if (monitor->eliminated() && is_compiled_frame())
   10.59 -      tty->print(" ( lock is eliminated )");
   10.60 +    if (monitor->eliminated()) {
   10.61 +      if(is_compiled_frame()) {
   10.62 +        tty->print(" ( lock is eliminated in compiled frame )");
   10.63 +      } else {
   10.64 +        tty->print(" ( lock is eliminated, frame not compiled )");
   10.65 +      }
   10.66 +    }
   10.67      tty->cr();
   10.68      tty->print("\t  ");
   10.69      monitor->lock()->print_on(tty);

mercurial