src/share/vm/code/nmethod.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6766644 Sdiff src/share/vm/code

src/share/vm/code/nmethod.cpp

Print this page
rev 2029 : 6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
Summary: Defer posting events from the compiler thread: use service thread
Reviewed-by:
* * *


  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "code/codeCache.hpp"
  27 #include "code/compiledIC.hpp"
  28 #include "code/nmethod.hpp"
  29 #include "code/scopeDesc.hpp"
  30 #include "compiler/abstractCompiler.hpp"
  31 #include "compiler/compileLog.hpp"
  32 #include "compiler/compilerOracle.hpp"
  33 #include "compiler/disassembler.hpp"
  34 #include "interpreter/bytecode.hpp"
  35 #include "oops/methodDataOop.hpp"
  36 #include "prims/jvmtiRedefineClassesTrace.hpp"

  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/sweeper.hpp"
  39 #include "utilities/dtrace.hpp"
  40 #include "utilities/events.hpp"
  41 #include "utilities/xmlstream.hpp"
  42 #ifdef SHARK
  43 #include "shark/sharkCompiler.hpp"
  44 #endif
  45 
  46 #ifdef DTRACE_ENABLED
  47 
  48 // Only bother with this argument setup if dtrace is available
  49 
  50 HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load,
  51   const char*, int, const char*, int, const char*, int, void*, size_t);
  52 
  53 HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload,
  54   char*, int, char*, int, char*, int);
  55 
  56 #define DTRACE_METHOD_UNLOAD_PROBE(method)                                \


1516 // new method for install_code() path
1517 // Transfer information from compilation to jvmti
1518 void nmethod::post_compiled_method_load_event() {
1519 
1520   methodOop moop = method();
1521   HS_DTRACE_PROBE8(hotspot, compiled__method__load,
1522       moop->klass_name()->bytes(),
1523       moop->klass_name()->utf8_length(),
1524       moop->name()->bytes(),
1525       moop->name()->utf8_length(),
1526       moop->signature()->bytes(),
1527       moop->signature()->utf8_length(),
1528       insts_begin(), insts_size());
1529 
1530   if (JvmtiExport::should_post_compiled_method_load() ||
1531       JvmtiExport::should_post_compiled_method_unload()) {
1532     get_and_cache_jmethod_id();
1533   }
1534 
1535   if (JvmtiExport::should_post_compiled_method_load()) {
1536     JvmtiExport::post_compiled_method_load(this);



1537   }
1538 }
1539 
1540 jmethodID nmethod::get_and_cache_jmethod_id() {
1541   if (_jmethod_id == NULL) {
1542     // Cache the jmethod_id since it can no longer be looked up once the
1543     // method itself has been marked for unloading.
1544     _jmethod_id = method()->jmethod_id();
1545   }
1546   return _jmethod_id;
1547 }
1548 
1549 void nmethod::post_compiled_method_unload() {
1550   if (unload_reported()) {
1551     // During unloading we transition to unloaded and then to zombie
1552     // and the unloading is reported during the first transition.
1553     return;
1554   }
1555 
1556   assert(_method != NULL && !is_unloaded(), "just checking");
1557   DTRACE_METHOD_UNLOAD_PROBE(method());
1558 
1559   // If a JVMTI agent has enabled the CompiledMethodUnload event then
1560   // post the event. Sometime later this nmethod will be made a zombie
1561   // by the sweeper but the methodOop will not be valid at that point.
1562   // If the _jmethod_id is null then no load event was ever requested
1563   // so don't bother posting the unload.  The main reason for this is
1564   // that the jmethodID is a weak reference to the methodOop so if
1565   // it's being unloaded there's no way to look it up since the weak
1566   // ref will have been cleared.
1567   if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
1568     assert(!unload_reported(), "already unloaded");
1569     HandleMark hm;
1570     JvmtiExport::post_compiled_method_unload(_jmethod_id, insts_begin());









1571   }

1572 
1573   // The JVMTI CompiledMethodUnload event can be enabled or disabled at
1574   // any time. As the nmethod is being unloaded now we mark it has
1575   // having the unload event reported - this will ensure that we don't
1576   // attempt to report the event in the unlikely scenario where the
1577   // event is enabled at the time the nmethod is made a zombie.
1578   set_unload_reported();
1579 }
1580 
1581 // This is called at the end of the strong tracing/marking phase of a
1582 // GC to unload an nmethod if it contains otherwise unreachable
1583 // oops.
1584 
1585 void nmethod::do_unloading(BoolObjectClosure* is_alive,
1586                            OopClosure* keep_alive, bool unloading_occurred) {
1587   // Make sure the oop's ready to receive visitors
1588   assert(!is_zombie() && !is_unloaded(),
1589          "should not call follow on zombie or unloaded nmethod");
1590 
1591   // If the method is not entrant then a JMP is plastered over the




  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "code/codeCache.hpp"
  27 #include "code/compiledIC.hpp"
  28 #include "code/nmethod.hpp"
  29 #include "code/scopeDesc.hpp"
  30 #include "compiler/abstractCompiler.hpp"
  31 #include "compiler/compileLog.hpp"
  32 #include "compiler/compilerOracle.hpp"
  33 #include "compiler/disassembler.hpp"
  34 #include "interpreter/bytecode.hpp"
  35 #include "oops/methodDataOop.hpp"
  36 #include "prims/jvmtiRedefineClassesTrace.hpp"
  37 #include "prims/jvmtiImpl.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 #include "runtime/sweeper.hpp"
  40 #include "utilities/dtrace.hpp"
  41 #include "utilities/events.hpp"
  42 #include "utilities/xmlstream.hpp"
  43 #ifdef SHARK
  44 #include "shark/sharkCompiler.hpp"
  45 #endif
  46 
  47 #ifdef DTRACE_ENABLED
  48 
  49 // Only bother with this argument setup if dtrace is available
  50 
  51 HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load,
  52   const char*, int, const char*, int, const char*, int, void*, size_t);
  53 
  54 HS_DTRACE_PROBE_DECL6(hotspot, compiled__method__unload,
  55   char*, int, char*, int, char*, int);
  56 
  57 #define DTRACE_METHOD_UNLOAD_PROBE(method)                                \


1517 // new method for install_code() path
1518 // Transfer information from compilation to jvmti
1519 void nmethod::post_compiled_method_load_event() {
1520 
1521   methodOop moop = method();
1522   HS_DTRACE_PROBE8(hotspot, compiled__method__load,
1523       moop->klass_name()->bytes(),
1524       moop->klass_name()->utf8_length(),
1525       moop->name()->bytes(),
1526       moop->name()->utf8_length(),
1527       moop->signature()->bytes(),
1528       moop->signature()->utf8_length(),
1529       insts_begin(), insts_size());
1530 
1531   if (JvmtiExport::should_post_compiled_method_load() ||
1532       JvmtiExport::should_post_compiled_method_unload()) {
1533     get_and_cache_jmethod_id();
1534   }
1535 
1536   if (JvmtiExport::should_post_compiled_method_load()) {
1537     // Let the Service thread (which is a real Java thread) post the event
1538     MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
1539     JvmtiDeferredEventQueue::enqueue(
1540       JvmtiDeferredEvent::compiled_method_loaded_event(this));
1541   }
1542 }
1543 
1544 jmethodID nmethod::get_and_cache_jmethod_id() {
1545   if (_jmethod_id == NULL) {
1546     // Cache the jmethod_id since it can no longer be looked up once the
1547     // method itself has been marked for unloading.
1548     _jmethod_id = method()->jmethod_id();
1549   }
1550   return _jmethod_id;
1551 }
1552 
1553 void nmethod::post_compiled_method_unload() {
1554   if (unload_reported()) {
1555     // During unloading we transition to unloaded and then to zombie
1556     // and the unloading is reported during the first transition.
1557     return;
1558   }
1559 
1560   assert(_method != NULL && !is_unloaded(), "just checking");
1561   DTRACE_METHOD_UNLOAD_PROBE(method());
1562 
1563   // If a JVMTI agent has enabled the CompiledMethodUnload event then
1564   // post the event. Sometime later this nmethod will be made a zombie
1565   // by the sweeper but the methodOop will not be valid at that point.
1566   // If the _jmethod_id is null then no load event was ever requested
1567   // so don't bother posting the unload.  The main reason for this is
1568   // that the jmethodID is a weak reference to the methodOop so if
1569   // it's being unloaded there's no way to look it up since the weak
1570   // ref will have been cleared.
1571   if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
1572     assert(!unload_reported(), "already unloaded");
1573     HandleMark hm;
1574     JvmtiDeferredEvent event =
1575       JvmtiDeferredEvent::compiled_method_unloaded_event(
1576           _jmethod_id, insts_begin());
1577     if (SafepointSynchronize::is_at_safepoint()) {
1578       // Don't want to take the queueing lock. Add it as pending and
1579       // it will get enqueued later.
1580       JvmtiDeferredEventQueue::add_pending_event(event);
1581     } else {
1582       MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
1583       JvmtiDeferredEventQueue::enqueue(event);
1584     }
1585   }
1586 
1587   // The JVMTI CompiledMethodUnload event can be enabled or disabled at
1588   // any time. As the nmethod is being unloaded now we mark it has
1589   // having the unload event reported - this will ensure that we don't
1590   // attempt to report the event in the unlikely scenario where the
1591   // event is enabled at the time the nmethod is made a zombie.
1592   set_unload_reported();
1593 }
1594 
1595 // This is called at the end of the strong tracing/marking phase of a
1596 // GC to unload an nmethod if it contains otherwise unreachable
1597 // oops.
1598 
1599 void nmethod::do_unloading(BoolObjectClosure* is_alive,
1600                            OopClosure* keep_alive, bool unloading_occurred) {
1601   // Make sure the oop's ready to receive visitors
1602   assert(!is_zombie() && !is_unloaded(),
1603          "should not call follow on zombie or unloaded nmethod");
1604 
1605   // If the method is not entrant then a JMP is plastered over the


src/share/vm/code/nmethod.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File