changeset 52084:6f8815e8070c fibers

merge
author rpressler
date Thu, 18 Oct 2018 13:43:27 +0100
parents 7c67bc166d47 9d59e51a1914
children a3fcbe9af5a1
files
diffstat 16 files changed, 294 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot/symbols/symbols-unix	Thu Oct 18 13:41:49 2018 +0100
+++ b/make/hotspot/symbols/symbols-unix	Thu Oct 18 13:43:27 2018 +0100
@@ -195,7 +195,7 @@
 JVM_SetBootLoaderUnnamedModule
 
 # Fiber support
-JVM_FiberStart
-JVM_FiberEnd
+JVM_FiberScheduled
+JVM_FiberTerminated
 JVM_FiberMount
 JVM_FiberUnmount
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -1892,11 +1892,13 @@
 // java_lang_Fiber
 
 int java_lang_Fiber::static_notify_jvmti_events_offset = 0;
+int java_lang_Fiber::_carrierThread_offset = 0;
 
 int java_lang_Fiber::notify_jvmti_events_offset_in_bytes() { return static_notify_jvmti_events_offset; }
 
 #define FIBER_FIELDS_DO(macro) \
-  macro(static_notify_jvmti_events_offset,  k, "notifyJvmtiEvents",  bool_signature, true)
+  macro(static_notify_jvmti_events_offset,  k, "notifyJvmtiEvents",  bool_signature, true); \
+  macro(_carrierThread_offset,  k, "carrierThread",  thread_signature, false)
 
 static jboolean fiber_notify_jvmti_events = JNI_FALSE;
 
@@ -1914,6 +1916,11 @@
   return obj != NULL && is_subclass(obj->klass());
 }
 
+oop java_lang_Fiber::carrier_thread(oop fiber) {
+  oop thread = fiber->obj_field(_carrierThread_offset);
+  return thread;
+}
+
 #if INCLUDE_CDS
 void java_lang_Fiber::serialize_offsets(SerializeClosure* f) {
    FIBER_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
--- a/src/hotspot/share/classfile/javaClasses.hpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Oct 18 13:43:27 2018 +0100
@@ -502,6 +502,7 @@
 class java_lang_Fiber : AllStatic {
  private:
   static int static_notify_jvmti_events_offset;
+  static int _carrierThread_offset;
  public:
   static void compute_offsets();
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
@@ -511,6 +512,7 @@
     return klass->is_subclass_of(SystemDictionary::Fiber_klass());
   }
   static bool is_instance(oop obj);
+  static oop carrier_thread(oop fiber);
   static int notify_jvmti_events_offset_in_bytes();
   static void set_notify_jvmti_events(jboolean enable);
 };
--- a/src/hotspot/share/include/jvm.h	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/include/jvm.h	Thu Oct 18 13:43:27 2018 +0100
@@ -1228,16 +1228,16 @@
 /* Fiber support.
  */
 JNIEXPORT void JNICALL
-JVM_FiberStart(JNIEnv* env, jclass fiberClass, jobject carrierThread, jobject fiber);
+JVM_FiberScheduled(JNIEnv* env, jclass fiber_class, jobject event_thread, jobject fiber);
 
 JNIEXPORT void JNICALL
-JVM_FiberEnd(JNIEnv* env, jclass fiberClass, jobject carrierThread, jobject fiber);
+JVM_FiberTerminated(JNIEnv* env, jclass fiber_class, jobject event_hread, jobject fiber);
 
 JNIEXPORT void JNICALL
-JVM_FiberMount(JNIEnv* env, jclass fiberClass, jobject carrierThread, jobject fiber);
+JVM_FiberMount(JNIEnv* env, jclass fiber_class, jobject event_thread, jobject fiber);
 
 JNIEXPORT void JNICALL
-JVM_FiberUnmount(JNIEnv* env, jclass fiberClass, jobject carrierThread, jobject fiber);
+JVM_FiberUnmount(JNIEnv* env, jclass fiber_class, jobject event_hread, jobject fiber);
 
 
 /* =========================================================================
--- a/src/hotspot/share/prims/jvm.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvm.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -3786,30 +3786,30 @@
   return os::get_signal_number(name);
 JVM_END
 
-JVM_ENTRY(void, JVM_FiberStart(JNIEnv* env, jclass fiberClass, jthread carrierThread, jobject fiber))
-  JVMWrapper("JVM_FiberStart");
-  if (JvmtiExport::should_post_fiber_start()) {
-    JvmtiExport::post_fiber_start(carrierThread, fiber);
+JVM_ENTRY(void, JVM_FiberScheduled(JNIEnv* env, jclass fiber_class, jthread event_hread, jobject fiber))
+  JVMWrapper("JVM_FiberScheduled");
+  if (JvmtiExport::should_post_fiber_scheduled()) {
+    JvmtiExport::post_fiber_scheduled(event_hread, fiber);
   }
 JVM_END
 
-JVM_ENTRY(void, JVM_FiberEnd(JNIEnv* env, jclass fiberClass, jthread carrierThread, jobject fiber))
-  JVMWrapper("JVM_FiberEnd");
-  if (JvmtiExport::should_post_fiber_end()) {
-    JvmtiExport::post_fiber_end(carrierThread, fiber);
+JVM_ENTRY(void, JVM_FiberTerminated(JNIEnv* env, jclass fiber_class, jthread event_hread, jobject fiber))
+  JVMWrapper("JVM_FiberTerminated");
+  if (JvmtiExport::should_post_fiber_terminated()) {
+    JvmtiExport::post_fiber_terminated(event_hread, fiber);
   }
 JVM_END
 
-JVM_ENTRY(void, JVM_FiberMount(JNIEnv* env, jclass fiberClass, jthread carrierThread, jobject fiber))
+JVM_ENTRY(void, JVM_FiberMount(JNIEnv* env, jclass fiber_class, jthread event_hread, jobject fiber))
   JVMWrapper("JVM_FiberMount");
   if (JvmtiExport::should_post_fiber_mount()) {
-    JvmtiExport::post_fiber_mount(carrierThread, fiber);
+    JvmtiExport::post_fiber_mount(event_hread, fiber);
   }
 JVM_END
 
-JVM_ENTRY(void, JVM_FiberUnmount(JNIEnv* env, jclass fiberClass, jthread carrierThread, jobject fiber))
+JVM_ENTRY(void, JVM_FiberUnmount(JNIEnv* env, jclass fiber_class, jthread event_hread, jobject fiber))
   JVMWrapper("JVM_FiberUnmount");
   if (JvmtiExport::should_post_fiber_unmount()) {
-    JvmtiExport::post_fiber_unmount(carrierThread, fiber);
+    JvmtiExport::post_fiber_unmount(event_hread, fiber);
   }
 JVM_END
--- a/src/hotspot/share/prims/jvmti.xml	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmti.xml	Thu Oct 18 13:43:27 2018 +0100
@@ -2299,7 +2299,7 @@
             </description>
         </param>
         <param id="fiber_ptr">
-          <outptr><jthread/></outptr>
+          <outptr><jobject/></outptr>
           <description>
             On return, points to the fiber mounted to the specified thread, or <code>NULL</code>.
           </description>
@@ -2309,9 +2309,8 @@
       </errors>
     </function>
 
-    <!--
     <function id="GetFiberThread" num="117" since="12">
-      <synopsis>Ge Fiber Thread</synopsis>
+      <synopsis>Get Fiber Thread</synopsis>
       <description>
         Get the thread the specified fiber is mounted to.
         If the fiber is unmounted, <code>NULL</code> is returned.
@@ -2324,7 +2323,7 @@
       </capabilities>
       <parameters>
         <param id="fiber">
-          <jthread />
+          <jobject />
             <description>
               The fiber to query.
             </description>
@@ -2333,6 +2332,7 @@
           <outptr><jthread/></outptr>
           <description>
             On return, points to the thread the fiber is mounted to, or <code>NULL</code>.
+            The result is transient if not all carrier threads are suspended.
           </description>
         </param>
       </parameters>
@@ -2342,7 +2342,6 @@
         </error>
       </errors>
     </function>
-    -->
 
   </category>
 
@@ -10490,8 +10489,8 @@
           <functionlink id="GetThreadFiber"></functionlink>, 
           <functionlink id="GetFiberThread"></functionlink>
           and the following fiber aware events can be enabled:
-          <eventlink id="FiberStart"></eventlink>,
-          <eventlink id="FiberEnd"></eventlink>,
+          <eventlink id="FiberScheduled"></eventlink>,
+          <eventlink id="FiberTerminated"></eventlink>,
           <eventlink id="FiberMount"></eventlink>,
           <eventlink id="FiberUnmount"></eventlink>.
         </description>
@@ -12835,10 +12834,10 @@
     </parameters>
   </event>
 
- <event label="Fiber Start"
-         id="FiberStart" const="JVMTI_EVENT_FIBER_START" filtered="thread" num="87" phase="start">
+ <event label="Fiber Scheduled"
+         id="FiberScheduled" const="JVMTI_EVENT_FIBER_SCHEDULED" filtered="thread" num="87" phase="start">
     <description>
-      Fiber start events are generated before its initial method executes.
+      Fiber scheduled events are generated before its initial method executes.
       <p/>
       The event is sent on the <paramlink id="thread"></paramlink>.
     </description>
@@ -12860,22 +12859,22 @@
       <param id="thread">
         <jthread/>
           <description>
-            Thread starting this fiber.
+            Thread scheduling this fiber.
           </description>
       </param>
       <param id="fiber">
         <jobject/>
           <description>
-            Fiber starting.
+            Fiber scheduled for execution.
           </description>
       </param>
     </parameters>
   </event>
 
-  <event label="Fiber End"
-         id="FiberEnd" const="JVMTI_EVENT_FIBER_END" filtered="thread" num="88" phase="start">
+  <event label="Fiber Terminated"
+         id="FiberTerminated" const="JVMTI_EVENT_FIBER_TERMINATED" filtered="thread" num="88" phase="start">
     <description>
-      Fiber end events are generated after its initial method has finished execution.
+      Fiber terminated events are generated after its initial method has finished execution.
       <p/>
       The event is sent on the <paramlink id="thread"></paramlink>.
     </description>
@@ -12897,13 +12896,13 @@
       <param id="thread">
         <jthread/>
           <description>
-            Thread ending this fiber.
+            Thread terminating this fiber.
           </description>
       </param>
       <param id="fiber">
         <jobject/>
           <description>
-            Fiber ending.
+            Fiber being terminated.
           </description>
       </param>
     </parameters>
@@ -12934,7 +12933,7 @@
       <param id="thread">
         <jthread/>
           <description>
-            Thread mounting this fiber.
+            Thread the fiber is mounted to.
           </description>
       </param>
       <param id="fiber">
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -855,11 +855,11 @@
 // java_thread - pre-checked
 // fiber_ptr - pre-checked for NULL
 jvmtiError
-JvmtiEnv::GetThreadFiber(JavaThread* java_thread, jthread* fiber_ptr) {
+JvmtiEnv::GetThreadFiber(JavaThread* java_thread, jobject* fiber_ptr) {
   JavaThread* current_thread  = JavaThread::current();
+  ResourceMark rm(current_thread);
   oop fiber_oop = NULL;
   uint32_t debug_bits = 0;
-  ResourceMark rm;
 
   JvmtiThreadState *state = JvmtiThreadState::state_for(java_thread);
   if (state == NULL) {
@@ -869,10 +869,28 @@
     return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
   }
   fiber_oop = java_lang_Thread::fiber(java_thread->threadObj());
-  *fiber_ptr = (jthread)JNIHandles::make_local(current_thread, fiber_oop);
+  *fiber_ptr = JNIHandles::make_local(current_thread, fiber_oop);
   return JVMTI_ERROR_NONE;
 } /* end GetThreadFiber */
 
+// fiber - pre-checked for NULL
+// is_thread_ptr - pre-checked for NULL
+jvmtiError
+JvmtiEnv::GetFiberThread(jobject fiber, jthread* thread_ptr) {
+  JavaThread* current_thread  = JavaThread::current();
+  HandleMark hm(current_thread);
+  oop fiber_obj = JNIHandles::resolve_external_guard(fiber);
+
+  if (!java_lang_Fiber::is_instance(fiber_obj)) {
+    return JVMTI_ERROR_INVALID_FIBER;
+  }
+
+  VM_GetFiberThread op(current_thread, Handle(current_thread, fiber_obj), thread_ptr);
+  VMThread::execute(&op);
+
+  return op.result();
+} /* end GetFiberThread */
+
 
   //
   // Thread functions
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -1593,3 +1593,10 @@
                                                         _method_ptr, _location_ptr);
   }
 }
+
+void
+VM_GetFiberThread::doit() {
+  oop carrier_thread = java_lang_Fiber::carrier_thread(_fiber_h());
+  *_carrier_thread_ptr = (jthread)JNIHandles::make_local(_current_thread, carrier_thread);
+}
+
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Thu Oct 18 13:43:27 2018 +0100
@@ -555,7 +555,7 @@
   void doit();
 };
 
-// VM operation to frame location at safepoint.
+// VM operation get to frame location at safepoint.
 class VM_GetFrameLocation : public VM_Operation {
 private:
   JvmtiEnv *_env;
@@ -579,6 +579,26 @@
   void doit();
 };
 
+// VM operation get to get fiber thread at safepoint.
+class VM_GetFiberThread : public VM_Operation {
+private:
+  JavaThread* _current_thread;
+  Handle _fiber_h;
+  jthread* _carrier_thread_ptr;
+  jvmtiError _result;
+
+public:
+  VM_GetFiberThread(JavaThread* current_thread, Handle fiber_h, jthread* carrier_thread_ptr) {
+    _current_thread = current_thread;
+    _fiber_h = fiber_h;
+    _carrier_thread_ptr = carrier_thread_ptr;
+    _result = JVMTI_ERROR_NONE;
+  }
+  VMOp_Type type() const { return VMOp_GetFiberThread; }
+  jvmtiError result()    { return _result; }
+  void doit();
+};
+
 
 // ResourceTracker
 //
--- a/src/hotspot/share/prims/jvmtiEventController.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -85,8 +85,8 @@
 static const jlong  RESOURCE_EXHAUSTED_BIT = (((jlong)1) << (JVMTI_EVENT_RESOURCE_EXHAUSTED - TOTAL_MIN_EVENT_TYPE_VAL));
 static const jlong  VM_OBJECT_ALLOC_BIT = (((jlong)1) << (JVMTI_EVENT_VM_OBJECT_ALLOC - TOTAL_MIN_EVENT_TYPE_VAL));
 static const jlong  SAMPLED_OBJECT_ALLOC_BIT = (((jlong)1) << (JVMTI_EVENT_SAMPLED_OBJECT_ALLOC - TOTAL_MIN_EVENT_TYPE_VAL));
-static const jlong  FIBER_START_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_START - TOTAL_MIN_EVENT_TYPE_VAL));
-static const jlong  FIBER_END_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_END - TOTAL_MIN_EVENT_TYPE_VAL));
+static const jlong  FIBER_SCHEDULED_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_SCHEDULED - TOTAL_MIN_EVENT_TYPE_VAL));
+static const jlong  FIBER_TERMINATED_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_TERMINATED - TOTAL_MIN_EVENT_TYPE_VAL));
 static const jlong  FIBER_MOUNT_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_MOUNT - TOTAL_MIN_EVENT_TYPE_VAL));
 static const jlong  FIBER_UNMOUNT_BIT = (((jlong)1) << (JVMTI_EVENT_FIBER_UNMOUNT - TOTAL_MIN_EVENT_TYPE_VAL));
 
@@ -94,7 +94,7 @@
 static const jlong  CLASS_UNLOAD_BIT = (((jlong)1) << (EXT_EVENT_CLASS_UNLOAD - TOTAL_MIN_EVENT_TYPE_VAL));
 
 
-static const jlong  FIBER_BITS = FIBER_START_BIT | FIBER_END_BIT | FIBER_MOUNT_BIT | FIBER_UNMOUNT_BIT;
+static const jlong  FIBER_BITS = FIBER_SCHEDULED_BIT | FIBER_TERMINATED_BIT | FIBER_MOUNT_BIT | FIBER_UNMOUNT_BIT;
 static const jlong  MONITOR_BITS = MONITOR_CONTENDED_ENTER_BIT | MONITOR_CONTENDED_ENTERED_BIT |
                           MONITOR_WAIT_BIT | MONITOR_WAITED_BIT;
 static const jlong  EXCEPTION_BITS = EXCEPTION_THROW_BIT | EXCEPTION_CATCH_BIT;
@@ -627,8 +627,8 @@
     JvmtiExport::set_should_post_compiled_method_unload((any_env_thread_enabled & COMPILED_METHOD_UNLOAD_BIT) != 0);
     JvmtiExport::set_should_post_vm_object_alloc((any_env_thread_enabled & VM_OBJECT_ALLOC_BIT) != 0);
     JvmtiExport::set_should_post_sampled_object_alloc((any_env_thread_enabled & SAMPLED_OBJECT_ALLOC_BIT) != 0);
-    JvmtiExport::set_should_post_fiber_start((any_env_thread_enabled & FIBER_START_BIT) != 0);
-    JvmtiExport::set_should_post_fiber_end((any_env_thread_enabled & FIBER_END_BIT) != 0);
+    JvmtiExport::set_should_post_fiber_scheduled((any_env_thread_enabled & FIBER_SCHEDULED_BIT) != 0);
+    JvmtiExport::set_should_post_fiber_terminated((any_env_thread_enabled & FIBER_TERMINATED_BIT) != 0);
     JvmtiExport::set_should_post_fiber_mount((any_env_thread_enabled & FIBER_MOUNT_BIT) != 0);
     JvmtiExport::set_should_post_fiber_unmount((any_env_thread_enabled & FIBER_UNMOUNT_BIT) != 0);
 
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Thu Oct 18 13:43:27 2018 +0100
@@ -1209,8 +1209,8 @@
 bool              JvmtiExport::_should_post_vm_object_alloc               = false;
 bool              JvmtiExport::_should_post_sampled_object_alloc          = false;
 bool              JvmtiExport::_should_post_on_exceptions                 = false;
-bool              JvmtiExport::_should_post_fiber_start                   = false;
-bool              JvmtiExport::_should_post_fiber_end                     = false;
+bool              JvmtiExport::_should_post_fiber_scheduled               = false;
+bool              JvmtiExport::_should_post_fiber_terminated              = false;
 bool              JvmtiExport::_should_post_fiber_mount                   = false;
 bool              JvmtiExport::_should_post_fiber_unmount                 = false;
 
@@ -1460,11 +1460,11 @@
 }
 
 
-void JvmtiExport::post_fiber_start(jthread thread, jobject fiber) {
+void JvmtiExport::post_fiber_scheduled(jthread thread, jobject fiber) {
   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
     return;
   }
-  EVT_TRIG_TRACE(JVMTI_EVENT_FIBER_START, ("[%p] Trg Fiber Start event triggered", fiber));
+  EVT_TRIG_TRACE(JVMTI_EVENT_FIBER_SCHEDULED, ("[%p] Trg Fiber Scheduled event triggered", fiber));
 
   JavaThread *cur_thread = JavaThread::current();
   JvmtiThreadState *state = cur_thread->jvmti_thread_state();
@@ -1472,20 +1472,20 @@
     return;
   }
 
-  if (state->is_enabled(JVMTI_EVENT_FIBER_START)) {
+  if (state->is_enabled(JVMTI_EVENT_FIBER_SCHEDULED)) {
     JvmtiEnvThreadStateIterator it(state);
 
     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
-      if (ets->is_enabled(JVMTI_EVENT_FIBER_START)) {
+      if (ets->is_enabled(JVMTI_EVENT_FIBER_SCHEDULED)) {
         JvmtiEnv *env = ets->get_env();
         if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
           continue;
         }
-        EVT_TRACE(JVMTI_EVENT_FIBER_START, ("[%p] Evt Fiber Start event sent", fiber));
+        EVT_TRACE(JVMTI_EVENT_FIBER_SCHEDULED, ("[%p] Evt Fiber Scheduled event sent", fiber));
 
         JvmtiThreadEventMark jem(cur_thread);
         JvmtiJavaThreadEventTransition jet(cur_thread);
-        jvmtiEventFiberStart callback = env->callbacks()->FiberStart;
+        jvmtiEventFiberScheduled callback = env->callbacks()->FiberScheduled;
         if (callback != NULL) {
           (*callback)(env->jvmti_external(), jem.jni_env(), thread, fiber);
         }
@@ -1494,11 +1494,11 @@
   }
 }
 
-void JvmtiExport::post_fiber_end(jthread thread, jobject fiber) {
+void JvmtiExport::post_fiber_terminated(jthread thread, jobject fiber) {
   if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) {
     return;
   }
-  EVT_TRIG_TRACE(JVMTI_EVENT_FIBER_END, ("[%p] Trg Fiber End event triggered", fiber));
+  EVT_TRIG_TRACE(JVMTI_EVENT_FIBER_TERMINATED, ("[%p] Trg Fiber Terminated event triggered", fiber));
 
   JavaThread *cur_thread = JavaThread::current();
   JvmtiThreadState *state = cur_thread->jvmti_thread_state();
@@ -1506,20 +1506,20 @@
     return;
   }
 
-  if (state->is_enabled(JVMTI_EVENT_FIBER_END)) {
+  if (state->is_enabled(JVMTI_EVENT_FIBER_TERMINATED)) {
     JvmtiEnvThreadStateIterator it(state);
 
     for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
-      if (ets->is_enabled(JVMTI_EVENT_FIBER_END)) {
+      if (ets->is_enabled(JVMTI_EVENT_FIBER_TERMINATED)) {
         JvmtiEnv *env = ets->get_env();
         if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
           continue;
         }
-        EVT_TRACE(JVMTI_EVENT_FIBER_END, ("[%p] Evt Fiber End event sent", fiber));
+        EVT_TRACE(JVMTI_EVENT_FIBER_TERMINATED, ("[%p] Evt Fiber Terminated event sent", fiber));
 
         JvmtiThreadEventMark jem(cur_thread);
         JvmtiJavaThreadEventTransition jet(cur_thread);
-        jvmtiEventFiberEnd callback = env->callbacks()->FiberEnd;
+        jvmtiEventFiberTerminated callback = env->callbacks()->FiberTerminated;
         if (callback != NULL) {
           (*callback)(env->jvmti_external(), jem.jni_env(), thread, fiber);
         }
--- a/src/hotspot/share/prims/jvmtiExport.hpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiExport.hpp	Thu Oct 18 13:43:27 2018 +0100
@@ -125,8 +125,8 @@
   JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc)
   JVMTI_SUPPORT_FLAG(should_post_sampled_object_alloc)
 
-  JVMTI_SUPPORT_FLAG(should_post_fiber_start)
-  JVMTI_SUPPORT_FLAG(should_post_fiber_end)
+  JVMTI_SUPPORT_FLAG(should_post_fiber_scheduled)
+  JVMTI_SUPPORT_FLAG(should_post_fiber_terminated)
   JVMTI_SUPPORT_FLAG(should_post_fiber_mount)
   JVMTI_SUPPORT_FLAG(should_post_fiber_unmount)
 
@@ -326,8 +326,8 @@
   static void post_thread_start          (JavaThread *thread) NOT_JVMTI_RETURN;
   static void post_thread_end            (JavaThread *thread) NOT_JVMTI_RETURN;
 
-  static void post_fiber_start           (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
-  static void post_fiber_end             (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
+  static void post_fiber_scheduled       (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
+  static void post_fiber_terminated      (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
   static void post_fiber_mount           (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
   static void post_fiber_unmount         (jthread thread, jobject fiber) NOT_JVMTI_RETURN;
 
--- a/src/hotspot/share/runtime/vm_operations.hpp	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/hotspot/share/runtime/vm_operations.hpp	Thu Oct 18 13:43:27 2018 +0100
@@ -89,6 +89,7 @@
   template(GetThreadListStackTraces)              \
   template(GetFrameCount)                         \
   template(GetFrameLocation)                      \
+  template(GetFiberThread)                        \
   template(ChangeBreakpoints)                     \
   template(GetOrSetLocal)                         \
   template(GetCurrentLocation)                    \
--- a/src/java.base/share/classes/java/lang/Fiber.java	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Fiber.java	Thu Oct 18 13:43:27 2018 +0100
@@ -227,11 +227,10 @@
         Fiber fiber = t.getFiber();
 
         if (notifyJvmtiEvents) {
-            notifyFiberStart(t, this);
+            notifyFiberScheduled(t, this);
         }
 
         if (fiber != null) t.setFiber(null);
-        // t.setFiber(this); // SERG_TMP
         try {
             scheduler.execute(runContinuation);
         } finally {
@@ -333,7 +332,7 @@
 
         if (notifyJvmtiEvents) {
             Thread t = Thread.currentCarrierThread();
-            notifyFiberEnd(t, this);
+            notifyFiberTerminated(t, this);
         }
 
         // notify anyone waiting for this fiber to terminate
@@ -836,8 +835,8 @@
     // -- JVM TI support --
 
     private static volatile boolean notifyJvmtiEvents;  // set by VM
-    private static native void notifyFiberStart(Thread t, Fiber f);
-    private static native void notifyFiberEnd(Thread t, Fiber f);
+    private static native void notifyFiberScheduled(Thread t, Fiber f);
+    private static native void notifyFiberTerminated(Thread t, Fiber f);
     private static native void notifyFiberMount(Thread t, Fiber f);
     private static native void notifyFiberUnmount(Thread t, Fiber f);
     private static native void registerNatives();
--- a/src/java.base/share/native/libjava/Fiber.c	Thu Oct 18 13:41:49 2018 +0100
+++ b/src/java.base/share/native/libjava/Fiber.c	Thu Oct 18 13:43:27 2018 +0100
@@ -32,8 +32,8 @@
 #define FIBER  "Ljava/lang/Fiber;"
 
 static JNINativeMethod methods[] = {
-    { "notifyFiberStart",   "(" THREAD FIBER ")V", (void *)&JVM_FiberStart },
-    { "notifyFiberEnd",     "(" THREAD FIBER ")V", (void *)&JVM_FiberEnd },
+    { "notifyFiberScheduled",   "(" THREAD FIBER ")V", (void *)&JVM_FiberScheduled },
+    { "notifyFiberTerminated",  "(" THREAD FIBER ")V", (void *)&JVM_FiberTerminated },
     { "notifyFiberMount",   "(" THREAD FIBER ")V", (void *)&JVM_FiberMount },
     { "notifyFiberUnmount", "(" THREAD FIBER ")V", (void *)&JVM_FiberUnmount },
 };
--- a/test/hotspot/jtreg/serviceability/jvmti/FiberTest/libFiberTest.c	Thu Oct 18 13:41:49 2018 +0100
+++ b/test/hotspot/jtreg/serviceability/jvmti/FiberTest/libFiberTest.c	Thu Oct 18 13:43:27 2018 +0100
@@ -28,73 +28,218 @@
 extern "C" {
 #endif
 
+static jvmtiEnv *jvmti = NULL;
+static jrawMonitorID events_monitor = NULL;
+
+static void lock_events() {
+  (*jvmti)->RawMonitorEnter(jvmti, events_monitor);
+}
+
+static void unlock_events() {
+  (*jvmti)->RawMonitorExit(jvmti, events_monitor);
+}
+
 static void
-processFiberEvent(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
+print_event_info(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
+  jvmtiThreadInfo thr_info;
+  jvmtiError err = (*jvmti)->GetThreadInfo(jvmti, thread, &thr_info);
+
+  if (err != JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler failed during JVMTI GetThreadInfo call");
+  }
+  char* thr_name = (thr_info.name == NULL) ? "<Unnamed thread>" : thr_info.name;
+  printf("\n%s event: event thread: %s, fiber: %p\n", event_name, thr_name, fiber);
+}
+
+static void
+test_IsFiber(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
   jboolean is_fiber = JNI_FALSE;
-  jvmtiThreadInfo thr_info;
   jvmtiError err;
 
-  err = (*jvmti)->GetThreadInfo(jvmti, thread, &thr_info);
+  printf("\n");
 
+  // #1: Test JVMTI IsFiber function with NULL fiber
+
+  err = (*jvmti)->IsFiber(jvmti, NULL, &is_fiber);
   if (err != JVMTI_ERROR_NONE) {
-    (*jni)->FatalError(jni, "event handler failed during the JVMTI GetThreadInfo call");
+    (*jni)->FatalError(jni, "event handler: failed during JVMTI IsFiber call");
   }
-  char* thr_name = (thr_info.name == NULL) ? "<Unnamed thread>" : thr_info.name;
-  printf("%s event: carrier-thread: %s, fiber: %p\n", event_name, thr_name, fiber);
+  if (is_fiber != JNI_FALSE) {
+    (*jni)->FatalError(jni, "event handler: JVMTI IsFiber with NULL fiber failed to return JNI_FALSE");
+  }
+  printf("%s event: JVMTI IsFiber with NULL fiber returned JNI_FALSE as expected\n", event_name);
+
+  // #2: Test JVMTI IsFiber function with a bad fiber
 
   err = (*jvmti)->IsFiber(jvmti, thread, &is_fiber);
   if (err != JVMTI_ERROR_NONE) {
-    (*jni)->FatalError(jni, "event handler: failed during the JVMTI IsFiber call");
+    (*jni)->FatalError(jni, "event handler: failed during JVMTI IsFiber call");
   }
   if (is_fiber != JNI_FALSE) {
-    (*jni)->FatalError(jni, "event handler: JVMTI IsFiber failed to return FALSE for thread object");
+    (*jni)->FatalError(jni, "event handler: JVMTI IsFiber with bad fiber failed to return JNI_FALSE");
   }
-  printf("%s event: JVMTI IsFiber returned JNI_FALSE for a career thread as expected\n", event_name);
+  printf("%s event: JVMTI IsFiber with bad fiber returned JNI_FALSE as expected\n", event_name);
+
+  // #3: Test JVMTI IsFiber function with a good fiber
 
   err = (*jvmti)->IsFiber(jvmti, fiber, &is_fiber);
   if (err != JVMTI_ERROR_NONE) {
-    (*jni)->FatalError(jni, "event handler: failed during the JVMTI IsFiber call");
+    (*jni)->FatalError(jni, "event handler: failed during JVMTI IsFiber call");
   }
   if (is_fiber != JNI_TRUE) {
-    (*jni)->FatalError(jni, "event handler: JVMTI IsFiber failed to return TRUE for fiber object");
+    (*jni)->FatalError(jni, "event handler: JVMTI IsFiber with good fiber failed to return JNI_TRUE");
   }
-  printf("%s event: JVMTI IsFiber returned JNI_TRUE for a fiber as expected\n\n", event_name);
+  printf("%s event: JVMTI IsFiber with good fiber returned JNI_TRUE as expected\n", event_name);
+}
+
+static void
+test_GetThreadFiber(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
+  jobject thread_fiber = NULL;
+  jvmtiError err;
+
+  printf("\n");
+
+  // #1: Test JVMTI GetThreadFiber function NULL thread (current)
+
+  err = (*jvmti)->GetThreadFiber(jvmti, NULL, &thread_fiber);
+  if (err != JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetThreadFiber with NULL thread (current) returned error status");
+  }
+  if (thread_fiber == NULL) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetThreadFiber with NULL thread (current) failed to return non-NULL fiber");
+  }
+  printf("%s event: JVMTI GetThreadFiber with NULL thread (current) returned non-NULL fiber as expected\n", event_name);
+
+  // #2: Test JVMTI GetThreadFiber function a bad thread
+
+  err = (*jvmti)->GetThreadFiber(jvmti, fiber, &thread_fiber);
+  if (err == JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetThreadFiber with bad thread failed to return JVMTI_ERROR_INVALID_FIBER");
+  }
+  printf("%s event: JVMTI GetThreadFiber with bad thread returned JVMTI_ERROR_INVALID_THREAD as expected\n", event_name);
+
+  // #3: Test JVMTI GetThreadFiber function with a good thread
+
+  err = (*jvmti)->GetThreadFiber(jvmti, thread, &thread_fiber);
+  if (err != JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: failed during JVMTI GetThreadFiber call");
+  }
+  if (thread_fiber == NULL) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetThreadFiber with good thread failed to return non-NULL fiber");
+  }
+  printf("%s event: JVMTI GetThreadFiber with good thread returned non-NULL fiber as expected\n", event_name);
+}
+
+static void
+test_GetFiberThread(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
+  jthread fiber_thread = NULL;
+  jvmtiError err;
+
+  printf("\n");
+
+  // #1: Test JVMTI GetFiberThread function with NULL fiber
+
+  err = (*jvmti)->GetFiberThread(jvmti, NULL, &fiber_thread);
+  if (err == JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetFiberThread with NULL fiber failed to return JVMTI_ERROR_INVALID_THREAD");
+  }
+  printf("%s event: JVMTI GetFiberThread with NULL fiber returned JVMTI_ERROR_INVALID_THREAD as expected\n", event_name);
+
+  // #2: Test JVMTI GetFiberThread function with a bad fiber
+
+  err = (*jvmti)->GetFiberThread(jvmti, thread, &fiber_thread);
+  if (err == JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetFiberThread with bad fiber failed to return JVMTI_ERROR_INVALID_THREAD");
+  }
+  printf("%s event: JVMTI GetFiberThread with bad fiber returned JVMTI_ERROR_INVALID_THREAD as expected\n", event_name);
+
+  // #3: Test JVMTI GetFiberThread function with a good fiber
+
+  err = (*jvmti)->GetFiberThread(jvmti, fiber, &fiber_thread);
+  if (err != JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "event handler: failed during JVMTI GetFiberThread call");
+  }
+  if (fiber_thread == NULL) {
+    (*jni)->FatalError(jni, "event handler: JVMTI GetFiberThread with good fiber failed to return non-NULL carrier thread");
+  }
+  printf("%s event: JVMTI GetFiberThread with good fiber returned non-NULL career thread as expected\n", event_name);
+}
+
+static void
+processFiberEvent(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber, char* event_name) {
+  static int events_cnt = 0;
+
+  if (events_cnt++ > 20 && strcmp(event_name, "FiberTerminated") != 0) {
+    return; // No need to test all events
+  }
+
+  print_event_info(jvmti, jni, thread, fiber, event_name);
+  test_IsFiber(jvmti, jni, thread, fiber, event_name);
+
+  if (strcmp(event_name, "FiberScheduled") == 0 || strcmp(event_name, "FiberTerminated") == 0) {
+    return; // skip further testing for FiberScheduled and FiberTerminated events
+  }
+
+  test_GetThreadFiber(jvmti, jni, thread, fiber, event_name);
+  test_GetFiberThread(jvmti, jni, thread, fiber, event_name);
 }
 
 static void JNICALL
-FiberStart(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
+FiberScheduled(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
   jobject mounted_fiber = NULL;
   jvmtiError err;
 
-  processFiberEvent(jvmti, jni, thread, fiber, "FiberStart");
+  lock_events();
+
+  processFiberEvent(jvmti, jni, thread, fiber, "FiberScheduled");
+
   err = (*jvmti)->GetThreadFiber(jvmti, thread, &mounted_fiber);
-
   if (err != JVMTI_ERROR_NONE) {
-    (*jni)->FatalError(jni, "FiberStart event handler: failed during the JVMTI GetThreadFiber call");
+    (*jni)->FatalError(jni, "FiberScheduled event handler: failed during JVMTI GetThreadFiber call");
   }
   if (mounted_fiber != NULL) {
-    (*jni)->FatalError(jni, "FiberStart event handler: JVMTI GetThreadFiber failed to return NULL for mounted fiber");
+    (*jni)->FatalError(jni, "FiberScheduled event handler: JVMTI GetThreadFiber failed to return NULL fiber");
   }
+
+  unlock_events();
 }
 
 static void JNICALL
-FiberEnd(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
-  processFiberEvent(jvmti, jni, thread, fiber, "FiberEnd");
+FiberTerminated(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
+  jobject mounted_fiber = NULL;
+  jvmtiError err;
+
+  lock_events();
+
+  processFiberEvent(jvmti, jni, thread, fiber, "FiberTerminated");
+
+  err = (*jvmti)->GetThreadFiber(jvmti, thread, &mounted_fiber);
+  if (err != JVMTI_ERROR_NONE) {
+    (*jni)->FatalError(jni, "FiberTerminated event handler: failed during JVMTI GetThreadFiber call");
+  }
+  if (mounted_fiber != NULL) {
+    (*jni)->FatalError(jni, "FiberTerminated event handler: JVMTI GetThreadFiber failed to return NULL fiber");
+  }
+
+  unlock_events();
 }
 
 static void JNICALL
 FiberMount(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
+  lock_events();
   processFiberEvent(jvmti, jni, thread, fiber, "FiberMount");
+  unlock_events();
 }
 
 static void JNICALL
 FiberUnmount(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread, jobject fiber) {
+  lock_events();
   processFiberEvent(jvmti, jni, thread, fiber, "FiberUnmount");
+  unlock_events();
 }
 
 extern JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options,
                                            void *reserved) {
-  jvmtiEnv *jvmti;
   jvmtiEventCallbacks callbacks;
   jvmtiCapabilities caps;
   jvmtiError err;
@@ -105,8 +250,8 @@
   }
 
   memset(&callbacks, 0, sizeof(callbacks));
-  callbacks.FiberStart   = &FiberStart;
-  callbacks.FiberEnd     = &FiberEnd;
+  callbacks.FiberScheduled  = &FiberScheduled;
+  callbacks.FiberTerminated = &FiberTerminated;
   callbacks.FiberMount   = &FiberMount;
   callbacks.FiberUnmount = &FiberUnmount;
 
@@ -122,12 +267,12 @@
     printf("error in JVMTI SetEventCallbacks: %d\n", err);
   }
 
-  err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIBER_START, NULL);
+  err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIBER_SCHEDULED, NULL);
   if (err != JVMTI_ERROR_NONE) {
     printf("error in JVMTI SetEventNotificationMode: %d\n", err);
   }
 
-  err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIBER_END, NULL);
+  err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_FIBER_TERMINATED, NULL);
   if (err != JVMTI_ERROR_NONE) {
     printf("error in JVMTI SetEventNotificationMode: %d\n", err);
   }
@@ -142,6 +287,7 @@
     printf("error in JVMTI SetEventNotificationMode: %d\n", err);
   }
 
+  (*jvmti)->CreateRawMonitor(jvmti, "Events Monitor", &events_monitor);
   printf("Agent_OnLoad finished\n");
   return 0;
 }