hotspot/src/share/vm/prims/jvmtiExport.cpp
changeset 8110 c992c8d52344
parent 8076 96d498ec7ae1
child 8475 c2b97a27943a
equal deleted inserted replaced
8109:26c288ddbec3 8110:c992c8d52344
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   748 ///////////////////////////////////////////////////////////////
   748 ///////////////////////////////////////////////////////////////
   749 //
   749 //
   750 // pending CompiledMethodUnload support
   750 // pending CompiledMethodUnload support
   751 //
   751 //
   752 
   752 
   753 bool JvmtiExport::_have_pending_compiled_method_unload_events;
   753 void JvmtiExport::post_compiled_method_unload(
   754 GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids;
   754        jmethodID method, const void *code_begin) {
   755 GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;
   755   JavaThread* thread = JavaThread::current();
   756 JavaThread* JvmtiExport::_current_poster;
       
   757 
       
   758 void JvmtiExport::post_compiled_method_unload_internal(JavaThread* self, jmethodID method, const void *code_begin) {
       
   759   EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
   756   EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
   760                  ("JVMTI [%s] method compile unload event triggered",
   757                  ("JVMTI [%s] method compile unload event triggered",
   761                   JvmtiTrace::safe_get_thread_name(self)));
   758                   JvmtiTrace::safe_get_thread_name(thread)));
   762 
   759 
   763   // post the event for each environment that has this event enabled.
   760   // post the event for each environment that has this event enabled.
   764   JvmtiEnvIterator it;
   761   JvmtiEnvIterator it;
   765   for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
   762   for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
   766     if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
   763     if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
   767 
   764 
   768       EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
   765       EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
   769                 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
   766                 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
   770                  JvmtiTrace::safe_get_thread_name(self), method));
   767                  JvmtiTrace::safe_get_thread_name(thread), method));
   771 
   768 
   772       ResourceMark rm(self);
   769       ResourceMark rm(thread);
   773 
   770 
   774       JvmtiEventMark jem(self);
   771       JvmtiEventMark jem(thread);
   775       JvmtiJavaThreadEventTransition jet(self);
   772       JvmtiJavaThreadEventTransition jet(thread);
   776       jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
   773       jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
   777       if (callback != NULL) {
   774       if (callback != NULL) {
   778         (*callback)(env->jvmti_external(), method, code_begin);
   775         (*callback)(env->jvmti_external(), method, code_begin);
   779       }
   776       }
   780     }
       
   781   }
       
   782 }
       
   783 
       
   784 // post any pending CompiledMethodUnload events
       
   785 
       
   786 void JvmtiExport::post_pending_compiled_method_unload_events() {
       
   787   JavaThread* self = JavaThread::current();
       
   788   assert(!self->owns_locks(), "can't hold locks");
       
   789 
       
   790   // Indicates if this is the first activiation of this function.
       
   791   // In theory the profiler's callback could call back into VM and provoke
       
   792   // another CompiledMethodLoad event to be posted from this thread. As the
       
   793   // stack rewinds we need to ensure that the original activation does the
       
   794   // completion and notifies any waiters.
       
   795   bool first_activation = false;
       
   796 
       
   797   // the jmethodID (may not be valid) to be used for a single event
       
   798   jmethodID method;
       
   799   const void *code_begin;
       
   800 
       
   801   // grab the monitor and check if another thread is already posting
       
   802   // events. If there is another thread posting events then we wait
       
   803   // until it completes. (In theory we could check the pending events to
       
   804   // see if any of the addresses overlap with the event that we want to
       
   805   // post but as it will happen so rarely we just block any thread waiting
       
   806   // to post a CompiledMethodLoad or DynamicCodeGenerated event until all
       
   807   // pending CompiledMethodUnload events have been posted).
       
   808   //
       
   809   // If another thread isn't posting we examine the list of pending jmethodIDs.
       
   810   // If the list is empty then we are done. If it's not empty then this thread
       
   811   // (self) becomes the pending event poster and we remove the top (last)
       
   812   // event from the list. Note that this means we remove the newest event first
       
   813   // but as they are all CompiledMethodUnload events the order doesn't matter.
       
   814   // Once we have removed a jmethodID then we exit the monitor. Any other thread
       
   815   // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will
       
   816   // be forced to wait on the monitor.
       
   817   {
       
   818     MutexLocker mu(JvmtiPendingEvent_lock);
       
   819     if (_current_poster != self) {
       
   820       while (_current_poster != NULL) {
       
   821         JvmtiPendingEvent_lock->wait();
       
   822       }
       
   823     }
       
   824     if ((_pending_compiled_method_unload_method_ids == NULL) ||
       
   825         (_pending_compiled_method_unload_method_ids->length() == 0)) {
       
   826       return;
       
   827     }
       
   828     if (_current_poster == NULL) {
       
   829       _current_poster = self;
       
   830       first_activation = true;
       
   831     } else {
       
   832       // re-entrant
       
   833       guarantee(_current_poster == self, "checking");
       
   834     }
       
   835     method = _pending_compiled_method_unload_method_ids->pop();
       
   836     code_begin = _pending_compiled_method_unload_code_begins->pop();
       
   837   }
       
   838 
       
   839   // This thread is the pending event poster so it first posts the CompiledMethodUnload
       
   840   // event for the jmethodID that has been removed from the list. Once posted it
       
   841   // re-grabs the monitor and checks the list again. If the list is empty then and this
       
   842   // is the first activation of the function then we reset the _have_pending_events
       
   843   // flag, cleanup _current_poster to indicate that no thread is now servicing the
       
   844   // pending events list, and finally notify any thread that might be waiting.
       
   845   for (;;) {
       
   846     post_compiled_method_unload_internal(self, method, code_begin);
       
   847 
       
   848     // event posted, now re-grab monitor and get the next event
       
   849     // If there's no next event then we are done. If this is the first
       
   850     // activiation of this function by this thread notify any waiters
       
   851     // so that they can post.
       
   852     {
       
   853       MutexLocker ml(JvmtiPendingEvent_lock);
       
   854       if (_pending_compiled_method_unload_method_ids->length() == 0) {
       
   855         if (first_activation) {
       
   856           _have_pending_compiled_method_unload_events = false;
       
   857           _current_poster = NULL;
       
   858           JvmtiPendingEvent_lock->notify_all();
       
   859         }
       
   860         return;
       
   861       }
       
   862       method = _pending_compiled_method_unload_method_ids->pop();
       
   863       code_begin = _pending_compiled_method_unload_code_begins->pop();
       
   864     }
   777     }
   865   }
   778   }
   866 }
   779 }
   867 
   780 
   868 ///////////////////////////////////////////////////////////////
   781 ///////////////////////////////////////////////////////////////
  1828   }
  1741   }
  1829   return record;
  1742   return record;
  1830 }
  1743 }
  1831 
  1744 
  1832 void JvmtiExport::post_compiled_method_load(nmethod *nm) {
  1745 void JvmtiExport::post_compiled_method_load(nmethod *nm) {
  1833   // If there are pending CompiledMethodUnload events then these are
       
  1834   // posted before this CompiledMethodLoad event. We "lock" the nmethod and
       
  1835   // maintain a handle to the methodOop to ensure that the nmethod isn't
       
  1836   // flushed or unloaded while posting the events.
       
  1837   JavaThread* thread = JavaThread::current();
  1746   JavaThread* thread = JavaThread::current();
  1838   if (have_pending_compiled_method_unload_events()) {
       
  1839     methodHandle mh(thread, nm->method());
       
  1840     nmethodLocker nml(nm);
       
  1841     post_pending_compiled_method_unload_events();
       
  1842   }
       
  1843 
  1747 
  1844   EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
  1748   EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
  1845                  ("JVMTI [%s] method compile load event triggered",
  1749                  ("JVMTI [%s] method compile load event triggered",
  1846                  JvmtiTrace::safe_get_thread_name(thread)));
  1750                  JvmtiTrace::safe_get_thread_name(thread)));
  1847 
  1751 
  1852       EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
  1756       EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
  1853                 ("JVMTI [%s] class compile method load event sent %s.%s  ",
  1757                 ("JVMTI [%s] class compile method load event sent %s.%s  ",
  1854                 JvmtiTrace::safe_get_thread_name(thread),
  1758                 JvmtiTrace::safe_get_thread_name(thread),
  1855                 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
  1759                 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
  1856                 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
  1760                 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
  1857 
       
  1858       ResourceMark rm(thread);
  1761       ResourceMark rm(thread);
       
  1762       HandleMark hm(thread);
  1859 
  1763 
  1860       // Add inlining information
  1764       // Add inlining information
  1861       jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
  1765       jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
  1862       // Pass inlining information through the void pointer
  1766       // Pass inlining information through the void pointer
  1863       JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
  1767       JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
  1894     if (callback != NULL) {
  1798     if (callback != NULL) {
  1895       (*callback)(env->jvmti_external(), method,
  1799       (*callback)(env->jvmti_external(), method,
  1896                   length, code_begin, map_length,
  1800                   length, code_begin, map_length,
  1897                   map, NULL);
  1801                   map, NULL);
  1898     }
  1802     }
  1899   }
       
  1900 }
       
  1901 
       
  1902 // used at a safepoint to post a CompiledMethodUnload event
       
  1903 void JvmtiExport::post_compiled_method_unload(jmethodID mid, const void *code_begin) {
       
  1904   if (SafepointSynchronize::is_at_safepoint()) {
       
  1905     // Class unloading can cause nmethod unloading which is reported
       
  1906     // by the VMThread.  These must be batched to be processed later.
       
  1907     if (_pending_compiled_method_unload_method_ids == NULL) {
       
  1908       // create list lazily
       
  1909       _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
       
  1910       _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
       
  1911     }
       
  1912     _pending_compiled_method_unload_method_ids->append(mid);
       
  1913     _pending_compiled_method_unload_code_begins->append(code_begin);
       
  1914     _have_pending_compiled_method_unload_events = true;
       
  1915   } else {
       
  1916     // Unloading caused by the sweeper can be reported synchronously.
       
  1917     if (have_pending_compiled_method_unload_events()) {
       
  1918       post_pending_compiled_method_unload_events();
       
  1919     }
       
  1920     post_compiled_method_unload_internal(JavaThread::current(), mid, code_begin);
       
  1921   }
  1803   }
  1922 }
  1804 }
  1923 
  1805 
  1924 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
  1806 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
  1925   JavaThread* thread = JavaThread::current();
  1807   JavaThread* thread = JavaThread::current();
  1951   if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {
  1833   if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {
  1952     post_dynamic_code_generated_internal(name, code_begin, code_end);
  1834     post_dynamic_code_generated_internal(name, code_begin, code_end);
  1953     return;
  1835     return;
  1954   }
  1836   }
  1955 
  1837 
  1956   if (have_pending_compiled_method_unload_events()) {
  1838   // Blocks until everything now in the queue has been posted
  1957     post_pending_compiled_method_unload_events();
  1839   JvmtiDeferredEventQueue::flush_queue(Thread::current());
  1958   }
  1840 
  1959   post_dynamic_code_generated_internal(name, code_begin, code_end);
  1841   post_dynamic_code_generated_internal(name, code_begin, code_end);
  1960 }
  1842 }
  1961 
  1843 
  1962 
  1844 
  1963 // post a DYNAMIC_CODE_GENERATED event for a given environment
  1845 // post a DYNAMIC_CODE_GENERATED event for a given environment