< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page

        

@@ -1610,10 +1610,12 @@
 int java_lang_Thread::_eetop_offset = 0;
 int java_lang_Thread::_daemon_offset = 0;
 int java_lang_Thread::_stillborn_offset = 0;
 int java_lang_Thread::_stackSize_offset = 0;
 int java_lang_Thread::_tid_offset = 0;
+int java_lang_Thread::_continuation_offset = 0;
+int java_lang_Thread::_fiber_offset = 0 ;
 int java_lang_Thread::_thread_status_offset = 0;
 int java_lang_Thread::_park_blocker_offset = 0;
 
 #define THREAD_FIELDS_DO(macro) \
   macro(_name_offset,          k, vmSymbols::name_name(), string_signature, false); \

@@ -1625,11 +1627,13 @@
   macro(_eetop_offset,         k, "eetop", long_signature, false); \
   macro(_stillborn_offset,     k, "stillborn", bool_signature, false); \
   macro(_stackSize_offset,     k, "stackSize", long_signature, false); \
   macro(_tid_offset,           k, "tid", long_signature, false); \
   macro(_thread_status_offset, k, "threadStatus", int_signature, false); \
-  macro(_park_blocker_offset,  k, "parkBlocker", object_signature, false)
+  macro(_park_blocker_offset,  k, "parkBlocker", object_signature, false); \
+  macro(_continuation_offset,  k, "cont", continuation_signature, false); \
+  macro(_fiber_offset,         k, "fiber", fiber_signature, false)
 
 void java_lang_Thread::compute_offsets() {
   assert(_group_offset == 0, "offsets should be initialized only once");
 
   InstanceKlass* k = SystemDictionary::Thread_klass();

@@ -1735,10 +1739,23 @@
 
 jlong java_lang_Thread::thread_id(oop java_thread) {
   return java_thread->long_field(_tid_offset);
 }
 
+oop java_lang_Thread::continuation(oop java_thread) {
+  return java_thread->obj_field(_continuation_offset);
+}
+
+void java_lang_Thread::set_continuation(oop java_thread, oop continuation) {
+  tty->print_cr(">>> java_lang_Thread::set_continuation %p", (oopDesc*)continuation);
+  return java_thread->obj_field_put(_continuation_offset, continuation);
+}
+
+oop java_lang_Thread::fiber(oop java_thread) {
+  return java_thread->obj_field(_fiber_offset);
+}
+
 oop java_lang_Thread::park_blocker(oop java_thread) {
   return java_thread->obj_field(_park_blocker_offset);
 }
 
 const char* java_lang_Thread::thread_status_name(oop java_thread) {

@@ -1842,10 +1859,62 @@
 void java_lang_ThreadGroup::serialize_offsets(SerializeClosure* f) {
   THREADGROUP_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
 }
 #endif
 
+
+// java_lang_Fiber
+
+int java_lang_Fiber::static_notify_jvmti_events_offset = 0;
+int java_lang_Fiber::_carrierThread_offset = 0;
+int java_lang_Fiber::_continuation_offset = 0;
+
+#define FIBER_FIELDS_DO(macro) \
+  macro(static_notify_jvmti_events_offset,  k, "notifyJvmtiEvents",  bool_signature, true); \
+  macro(_carrierThread_offset,  k, "carrierThread",  thread_signature, false); \
+  macro(_continuation_offset,  k, "cont",  continuation_signature, false)
+
+static jboolean fiber_notify_jvmti_events = JNI_FALSE;
+
+void java_lang_Fiber::compute_offsets() {
+  InstanceKlass* k = SystemDictionary::Fiber_klass();
+  FIBER_FIELDS_DO(FIELD_COMPUTE_OFFSET);
+}
+
+void java_lang_Fiber::init_static_notify_jvmti_events() {
+  if (fiber_notify_jvmti_events) {
+    InstanceKlass* ik = SystemDictionary::Fiber_klass();
+    oop base = ik->static_field_base_raw();
+    base->release_bool_field_put(static_notify_jvmti_events_offset, fiber_notify_jvmti_events);
+  }
+}
+
+bool java_lang_Fiber::is_instance(oop obj) {
+  return obj != NULL && is_subclass(obj->klass());
+}
+
+oop java_lang_Fiber::carrier_thread(oop fiber) {
+  oop thread = fiber->obj_field(_carrierThread_offset);
+  return thread;
+}
+ 
+oop java_lang_Fiber::continuation(oop fiber) {
+  oop cont = fiber->obj_field(_continuation_offset);
+  return cont;
+}
+
+#if INCLUDE_CDS
+void java_lang_Fiber::serialize_offsets(SerializeClosure* f) {
+   FIBER_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif
+
+void java_lang_Fiber::set_notify_jvmti_events(jboolean enable) {
+  fiber_notify_jvmti_events = enable;
+}
+
+
 #define THROWABLE_FIELDS_DO(macro) \
   macro(backtrace_offset,     k, "backtrace",     object_signature,                  false); \
   macro(detailMessage_offset, k, "detailMessage", string_signature,                  false); \
   macro(stackTrace_offset,    k, "stackTrace",    java_lang_StackTraceElement_array, false); \
   macro(depth_offset,         k, "depth",         int_signature,                     false); \

@@ -1944,18 +2013,20 @@
   objArrayOop     _head;
   typeArrayOop    _methods;
   typeArrayOop    _bcis;
   objArrayOop     _mirrors;
   typeArrayOop    _names; // needed to insulate method name against redefinition
+  objArrayOop     _conts;
   int             _index;
   NoSafepointVerifier _nsv;
 
   enum {
     trace_methods_offset = java_lang_Throwable::trace_methods_offset,
     trace_bcis_offset    = java_lang_Throwable::trace_bcis_offset,
     trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
     trace_names_offset   = java_lang_Throwable::trace_names_offset,
+    trace_conts_offset   = java_lang_Throwable::trace_conts_offset,
     trace_next_offset    = java_lang_Throwable::trace_next_offset,
     trace_size           = java_lang_Throwable::trace_size,
     trace_chunk_size     = java_lang_Throwable::trace_chunk_size
   };
 

@@ -1978,28 +2049,35 @@
   static typeArrayOop get_names(objArrayHandle chunk) {
     typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset));
     assert(names != NULL, "names array should be initialized in backtrace");
     return names;
   }
+  static objArrayOop get_conts(objArrayHandle chunk) {
+    objArrayOop conts = objArrayOop(chunk->obj_at(trace_conts_offset));
+    assert(conts != NULL, "conts array should be initialized in backtrace");
+    return conts;
+  }
 
  public:
 
   // constructor for new backtrace
-  BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL) {
+  BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL), _conts(NULL) {
     expand(CHECK);
     _backtrace = Handle(THREAD, _head);
     _index = 0;
   }
 
   BacktraceBuilder(Thread* thread, objArrayHandle backtrace) {
     _methods = get_methods(backtrace);
     _bcis = get_bcis(backtrace);
     _mirrors = get_mirrors(backtrace);
     _names = get_names(backtrace);
+    _conts = get_conts(backtrace);
     assert(_methods->length() == _bcis->length() &&
            _methods->length() == _mirrors->length() &&
-           _mirrors->length() == _names->length(),
+           _mirrors->length() == _names->length() && 
+           _names->length() == _conts->length(),
            "method and source information arrays should match");
 
     // head is the preallocated backtrace
     _head = backtrace();
     _backtrace = Handle(thread, _head);

@@ -2023,31 +2101,36 @@
     objArrayHandle new_mirrors(THREAD, mirrors);
 
     typeArrayOop names = oopFactory::new_symbolArray(trace_chunk_size, CHECK);
     typeArrayHandle new_names(THREAD, names);
 
+    objArrayOop conts = oopFactory::new_objectArray(trace_chunk_size, CHECK);
+    objArrayHandle new_conts(THREAD, conts);
+
     if (!old_head.is_null()) {
       old_head->obj_at_put(trace_next_offset, new_head());
     }
     new_head->obj_at_put(trace_methods_offset, new_methods());
     new_head->obj_at_put(trace_bcis_offset, new_bcis());
     new_head->obj_at_put(trace_mirrors_offset, new_mirrors());
     new_head->obj_at_put(trace_names_offset, new_names());
+    new_head->obj_at_put(trace_conts_offset, new_conts());
 
     _head    = new_head();
     _methods = new_methods();
     _bcis = new_bcis();
     _mirrors = new_mirrors();
     _names  = new_names();
+    _conts  = new_conts();
     _index = 0;
   }
 
   oop backtrace() {
     return _backtrace();
   }
 
-  inline void push(Method* method, int bci, TRAPS) {
+  inline void push(Method* method, int bci, oop contScopeName, TRAPS) {
     // Smear the -1 bci to 0 since the array only holds unsigned
     // shorts.  The later line number lookup would just smear the -1
     // to a 0 even if it could be recorded.
     if (bci == SynchronizationEntryBCI) bci = 0;
 

@@ -2067,10 +2150,13 @@
 
     // We need to save the mirrors in the backtrace to keep the class
     // from being unloaded while we still have this stack trace.
     assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror");
     _mirrors->obj_at_put(_index, method->method_holder()->java_mirror());
+
+    _conts->obj_at_put(_index, contScopeName);
+
     _index++;
   }
 
 };
 

@@ -2078,30 +2164,33 @@
   int _method_id;
   int _bci;
   int _version;
   Symbol* _name;
   Handle _mirror;
-  BacktraceElement(Handle mirror, int mid, int version, int bci, Symbol* name) :
-                   _method_id(mid), _bci(bci), _version(version), _name(name), _mirror(mirror) {}
+  Handle _cont; // the continuation scope name (String)
+  BacktraceElement(Handle mirror, int mid, int version, int bci, Symbol* name, Handle cont) :
+                   _method_id(mid), _bci(bci), _version(version), _name(name), _mirror(mirror), _cont(cont) {}
 };
 
 class BacktraceIterator : public StackObj {
   int _index;
   objArrayHandle  _result;
   objArrayHandle  _mirrors;
   typeArrayHandle _methods;
   typeArrayHandle _bcis;
   typeArrayHandle _names;
+  objArrayHandle  _conts;
 
   void init(objArrayHandle result, Thread* thread) {
     // Get method id, bci, version and mirror from chunk
     _result = result;
     if (_result.not_null()) {
       _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result));
       _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result));
       _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result));
       _names = typeArrayHandle(thread, BacktraceBuilder::get_names(_result));
+      _conts = objArrayHandle(thread, BacktraceBuilder::get_conts(_result));
       _index = 0;
     }
   }
  public:
   BacktraceIterator(objArrayHandle result, Thread* thread) {

@@ -2112,11 +2201,12 @@
   BacktraceElement next(Thread* thread) {
     BacktraceElement e (Handle(thread, _mirrors->obj_at(_index)),
                         _methods->ushort_at(_index),
                         Backtrace::version_at(_bcis->int_at(_index)),
                         Backtrace::bci_at(_bcis->int_at(_index)),
-                        _names->symbol_at(_index));
+                        _names->symbol_at(_index),
+                        Handle(thread, _conts->obj_at(_index)));
     _index++;
 
     if (_index >= java_lang_Throwable::trace_chunk_size) {
       int next_offset = java_lang_Throwable::trace_next_offset;
       // Get next chunk

@@ -2275,11 +2365,13 @@
                           vmSymbols::printStackTrace_name(),
                           vmSymbols::void_method_signature(),
                           THREAD);
 }
 
-void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS) {
+extern "C" void pfl();
+
+void java_lang_Throwable::fill_in_stack_trace(Handle throwable, Handle contScope, const methodHandle& method, TRAPS) {
   if (!StackTraceInThrowable) return;
   ResourceMark rm(THREAD);
 
   // Start out by clearing the backtrace for this object, in case the VM
   // runs out of memory while allocating the stack trace

@@ -2295,11 +2387,11 @@
 
   // If there is no Java frame just return the method that was being called
   // with bci 0
   if (!thread->has_last_Java_frame()) {
     if (max_depth >= 1 && method() != NULL) {
-      bt.push(method(), 0, CHECK);
+      bt.push(method(), 0, NULL, CHECK);
       log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), 1);
       set_depth(throwable(), 1);
       set_backtrace(throwable(), bt.backtrace());
     }
     return;

@@ -2310,37 +2402,63 @@
   // speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows.
   // See bug 6333838 for  more details.
   // The "ASSERT" here is to verify this method generates the exactly same stack
   // trace as utilizing vframe.
 #ifdef ASSERT
-  vframeStream st(thread);
+  vframeStream st(thread, contScope);
   methodHandle st_method(THREAD, st.method());
 #endif
   int total_count = 0;
-  RegisterMap map(thread, false);
+  RegisterMap map(thread, false, true);
   int decode_offset = 0;
   CompiledMethod* nm = NULL;
   bool skip_fillInStackTrace_check = false;
   bool skip_throwableInit_check = false;
   bool skip_hidden = !ShowHiddenFrames;
-
+  bool is_last = false;
+  oop cont = thread->last_continuation();
   for (frame fr = thread->last_frame(); max_depth == 0 || max_depth != total_count;) {
     Method* method = NULL;
     int bci = 0;
+    oop contScopeName = (cont != NULL) ? java_lang_ContinuationScope::name(java_lang_Continuation::scope(cont)) : (oop)NULL;
 
     // Compiled java method case.
     if (decode_offset != 0) {
       DebugInfoReadStream stream(nm, decode_offset);
       decode_offset = stream.read_int();
       method = (Method*)nm->metadata_at(stream.read_int());
       bci = stream.read_bci();
     } else {
       if (fr.is_first_frame()) break;
+
+      assert (contScope.is_null() || cont != NULL, "must be");
+      if (cont != NULL && Continuation::is_continuation_entry_frame(fr, &map)) {
+        oop scope = java_lang_Continuation::scope(cont);
+        if (contScope.not_null() && oopDesc::equals(scope, contScope())) {
+          is_last = true;
+        } else {
+          // if (!Continuation::is_frame_in_continuation(fr, cont)) {
+          //   tty->print_cr(">>>>>");
+          //   fr.print_on(tty);
+          //   tty->print_cr("<<<<<");
+          //   pfl();
+          // }
+          assert (Continuation::is_frame_in_continuation(fr, cont), "must be");
+          cont = java_lang_Continuation::parent(cont);
+        }
+      }
+
       address pc = fr.pc();
       if (fr.is_interpreted_frame()) {
-        address bcp = fr.interpreter_frame_bcp();
-        method = fr.interpreter_frame_method();
+        address bcp;
+        if (!map.in_cont()) {
+          bcp = fr.interpreter_frame_bcp();
+          method = fr.interpreter_frame_method();
+        } else {
+          bcp = Continuation::interpreter_frame_bcp(fr, &map);
+          method = Continuation::interpreter_frame_method(fr, &map);
+        }
         bci =  method->bci_from(bcp);
         fr = fr.sender(&map);
       } else {
         CodeBlob* cb = fr.cb();
         // HMMM QQQ might be nice to have frame return nm as NULL if cb is non-NULL

@@ -2348,10 +2466,11 @@
         fr = fr.sender(&map);
         if (cb == NULL || !cb->is_compiled()) {
           continue;
         }
         nm = cb->as_compiled_method();
+        assert (nm->method() != NULL, "must be");
         if (nm->method()->is_native()) {
           method = nm->method();
           bci = 0;
         } else {
           PcDesc* pd = nm->pc_desc_at(pc);

@@ -2361,18 +2480,13 @@
           continue;
         }
       }
     }
 #ifdef ASSERT
-    assert(st_method() == method && st.bci() == bci,
-           "Wrong stack trace");
+    assert(st_method() == method && st.bci() == bci, "Wrong stack trace");
     st.next();
-    // vframeStream::method isn't GC-safe so store off a copy
-    // of the Method* in case we GC.
-    if (!st.at_end()) {
-      st_method = st.method();
-    }
+    if (!st.at_end()) st_method = st.method();// vframeStream::method isn't GC-safe so store off a copy of the Method* in case we GC.
 #endif
 
     // the format of the stacktrace will be:
     // - 1 or more fillInStackTrace frames for the exception class (skipped)
     // - 0 or more <init> methods for the exception class (skipped)

@@ -2401,22 +2515,24 @@
       }
     }
     if (method->is_hidden()) {
       if (skip_hidden)  continue;
     }
-    bt.push(method, bci, CHECK);
+
+    bt.push(method, bci, contScopeName, CHECK);
     total_count++;
+    if (is_last) break;
   }
 
   log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), total_count);
 
   // Put completed stack trace into throwable object
   set_backtrace(throwable(), bt.backtrace());
   set_depth(throwable(), total_count);
 }
 
-void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method) {
+void java_lang_Throwable::fill_in_stack_trace(Handle throwable, Handle contScope, const methodHandle& method) {
   // No-op if stack trace is disabled
   if (!StackTraceInThrowable) {
     return;
   }
 

@@ -2426,11 +2542,11 @@
   }
 
   PRESERVE_EXCEPTION_MARK;
 
   JavaThread* thread = JavaThread::active();
-  fill_in_stack_trace(throwable, method, thread);
+  fill_in_stack_trace(throwable, contScope, method, thread);
   // ignore exceptions thrown during stack trace filling
   CLEAR_PENDING_EXCEPTION;
 }
 
 void java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) {

@@ -2465,11 +2581,11 @@
   // methods as preallocated errors aren't created by "java" code.
 
   // fill in as much stack trace as possible
   int chunk_count = 0;
   for (;!st.at_end(); st.next()) {
-    bt.push(st.method(), st.bci(), CHECK);
+    bt.push(st.method(), st.bci(), NULL, CHECK);
     chunk_count++;
 
     // Bail-out for deep stacks
     if (chunk_count >= trace_chunk_size) break;
   }

@@ -2512,32 +2628,34 @@
 
     java_lang_StackTraceElement::fill_in(stack_trace_element, holder,
                                          method,
                                          bte._version,
                                          bte._bci,
-                                         bte._name, CHECK);
+                                         bte._name, 
+                                         bte._cont,
+                                         CHECK);
   }
 }
 
-oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) {
+oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, Handle contScope, TRAPS) {
   // Allocate java.lang.StackTraceElement instance
   InstanceKlass* k = SystemDictionary::StackTraceElement_klass();
   assert(k != NULL, "must be loaded in 1.4+");
   if (k->should_be_initialized()) {
     k->initialize(CHECK_0);
   }
 
   Handle element = k->allocate_instance_handle(CHECK_0);
 
   int version = method->constants()->version();
-  fill_in(element, method->method_holder(), method, version, bci, method->name(), CHECK_0);
+  fill_in(element, method->method_holder(), method, version, bci, method->name(), contScope, CHECK_0);
   return element();
 }
 
 void java_lang_StackTraceElement::fill_in(Handle element,
                                           InstanceKlass* holder, const methodHandle& method,
-                                          int version, int bci, Symbol* name, TRAPS) {
+                                          int version, int bci, Symbol* name, Handle contScopeName, TRAPS) {
   assert(element->is_a(SystemDictionary::StackTraceElement_klass()), "sanity check");
 
   ResourceMark rm(THREAD);
   HandleMark hm(THREAD);
 

@@ -2601,10 +2719,13 @@
     java_lang_StackTraceElement::set_fileName(element(), source_file);
 
     int line_number = Backtrace::get_line_number(method, bci);
     java_lang_StackTraceElement::set_lineNumber(element(), line_number);
   }
+
+  // Fill in continuation scope
+  java_lang_StackTraceElement::set_contScopeName(element(), contScopeName());
 }
 
 #if INCLUDE_JVMCI
 void java_lang_StackTraceElement::decode(Handle mirror, methodHandle method, int bci, Symbol*& methodname, Symbol*& filename, int& line_number) {
   int method_id = method->orig_method_idnum();

@@ -2651,11 +2772,11 @@
   // we should expand MemberName::name when Throwable uses StackTrace
   // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
   return method;
 }
 
-void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, TRAPS) {
+void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, oop cont, TRAPS) {
   // set Method* or mid/cpref
   HandleMark hm(THREAD);
   Handle mname(Thread::current(), stackFrame->obj_field(_memberName_offset));
   InstanceKlass* ik = method->method_holder();
   CallInfo info(method(), ik, CHECK);

@@ -2664,29 +2785,35 @@
   java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
   // method may be redefined; store the version
   int version = method->constants()->version();
   assert((jushort)version == version, "version should be short");
   java_lang_StackFrameInfo::set_version(stackFrame(), (short)version);
+
+  oop contScope = cont != NULL ? java_lang_Continuation::scope(cont) : (oop)NULL;
+  java_lang_StackFrameInfo::set_contScope(stackFrame(), contScope);
 }
 
 void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) {
   ResourceMark rm(THREAD);
   HandleMark hm(THREAD);
   Handle mname(THREAD, stackFrame->obj_field(java_lang_StackFrameInfo::_memberName_offset));
   Klass* clazz = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
   InstanceKlass* holder = InstanceKlass::cast(clazz);
   Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
+  oop contScope = stackFrame->obj_field(java_lang_StackFrameInfo::_contScope_offset);
+  Handle contScopeName(THREAD, contScope != (oop)NULL ? java_lang_ContinuationScope::name(contScope) : (oop)NULL);
 
   short version = stackFrame->short_field(_version_offset);
   short bci = stackFrame->short_field(_bci_offset);
   Symbol* name = method->name();
-  java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, name, CHECK);
+  java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, name, contScopeName, CHECK);
 }
 
 #define STACKFRAMEINFO_FIELDS_DO(macro) \
-  macro(_memberName_offset,     k, "memberName",  object_signature, false); \
-  macro(_bci_offset,            k, "bci",         short_signature,  false)
+  macro(_memberName_offset,     k, "memberName", object_signature,            false); \
+  macro(_bci_offset,            k, "bci",        short_signature,             false); \
+  macro(_contScope_offset,      k, "contScope",  continuationscope_signature, false)
 
 void java_lang_StackFrameInfo::compute_offsets() {
   InstanceKlass* k = SystemDictionary::StackFrameInfo_klass();
   STACKFRAMEINFO_FIELDS_DO(FIELD_COMPUTE_OFFSET);
   STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);

@@ -4124,10 +4251,31 @@
 int java_lang_ref_Reference::queue_offset;
 int java_lang_ref_Reference::next_offset;
 int java_lang_ref_Reference::discovered_offset;
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
+int java_lang_ContinuationScope::_name_offset;
+int java_lang_Continuation::_scope_offset;
+int java_lang_Continuation::_target_offset;
+int java_lang_Continuation::_stack_offset;
+int java_lang_Continuation::_maxSize_offset;
+int java_lang_Continuation::_numFrames_offset;
+int java_lang_Continuation::_numInterpretedFrames_offset;
+int java_lang_Continuation::_refStack_offset;
+int java_lang_Continuation::_parent_offset;
+int java_lang_Continuation::_yieldInfo_offset;
+int java_lang_Continuation::_entrySP_offset;
+int java_lang_Continuation::_entryFP_offset;
+int java_lang_Continuation::_entryPC_offset;
+int java_lang_Continuation::_fp_offset;
+int java_lang_Continuation::_sp_offset;
+int java_lang_Continuation::_pc_offset;
+int java_lang_Continuation::_refSP_offset;
+int java_lang_Continuation::_cs_offset;
+int java_lang_Continuation::_flags_offset;
+int java_lang_Continuation::_reset_offset;
+int java_lang_Continuation::_mounted_offset;
 int java_lang_ClassLoader::parent_offset;
 int java_lang_System::static_in_offset;
 int java_lang_System::static_out_offset;
 int java_lang_System::static_err_offset;
 int java_lang_System::static_security_offset;

@@ -4137,13 +4285,15 @@
 int java_lang_StackTraceElement::moduleName_offset;
 int java_lang_StackTraceElement::moduleVersion_offset;
 int java_lang_StackTraceElement::classLoaderName_offset;
 int java_lang_StackTraceElement::declaringClass_offset;
 int java_lang_StackTraceElement::declaringClassObject_offset;
+int java_lang_StackTraceElement::contScope_offset;
 int java_lang_StackFrameInfo::_memberName_offset;
 int java_lang_StackFrameInfo::_bci_offset;
 int java_lang_StackFrameInfo::_version_offset;
+int java_lang_StackFrameInfo::_contScope_offset;
 int java_lang_LiveStackFrameInfo::_monitors_offset;
 int java_lang_LiveStackFrameInfo::_locals_offset;
 int java_lang_LiveStackFrameInfo::_operands_offset;
 int java_lang_LiveStackFrameInfo::_mode_offset;
 int java_lang_AssertionStatusDirectives::classes_offset;

@@ -4171,11 +4321,12 @@
   macro(moduleName_offset,      k, "moduleName",      string_signature, false); \
   macro(moduleVersion_offset,   k, "moduleVersion",   string_signature, false); \
   macro(declaringClass_offset,  k, "declaringClass",  string_signature, false); \
   macro(methodName_offset,      k, "methodName",      string_signature, false); \
   macro(fileName_offset,        k, "fileName",        string_signature, false); \
-  macro(lineNumber_offset,      k, "lineNumber",      int_signature,    false)
+  macro(lineNumber_offset,      k, "lineNumber",      int_signature,    false); \
+  macro(contScope_offset,       k, "contScopeName",   string_signature, false)
 
 // Support for java_lang_StackTraceElement
 void java_lang_StackTraceElement::compute_offsets() {
   InstanceKlass* k = SystemDictionary::StackTraceElement_klass();
   STACKTRACEELEMENT_FIELDS_DO(FIELD_COMPUTE_OFFSET);

@@ -4217,18 +4368,26 @@
 
 void java_lang_StackTraceElement::set_declaringClassObject(oop element, oop value) {
   element->obj_field_put(declaringClassObject_offset, value);
 }
 
+void java_lang_StackTraceElement::set_contScopeName(oop element, oop value) {
+  element->obj_field_put(contScope_offset, value);
+}
+
 void java_lang_StackFrameInfo::set_version(oop element, short value) {
   element->short_field_put(_version_offset, value);
 }
 
 void java_lang_StackFrameInfo::set_bci(oop element, int value) {
   element->int_field_put(_bci_offset, value);
 }
 
+void java_lang_StackFrameInfo::set_contScope(oop element, oop value) {
+  element->obj_field_put(_contScope_offset, value);
+}
+
 void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
   element->obj_field_put(_monitors_offset, value);
 }
 
 void java_lang_LiveStackFrameInfo::set_locals(oop element, oop value) {

@@ -4280,10 +4439,71 @@
 
 void java_lang_AssertionStatusDirectives::set_deflt(oop o, bool val) {
   o->bool_field_put(deflt_offset, val);
 }
 
+// Support for java.lang.ContinuationScope
+
+#define CONTINUATIONSCOPE_FIELDS_DO(macro) \
+  macro(_name_offset, k, vmSymbols::name_name(), string_signature, false);
+
+void java_lang_ContinuationScope::compute_offsets() {
+  InstanceKlass* k = SystemDictionary::ContinuationScope_klass();
+  CONTINUATIONSCOPE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
+}
+
+#if INCLUDE_CDS
+void java_lang_ContinuationScope::serialize_offsets(SerializeClosure* f) {
+  CONTINUATIONSCOPE_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif
+
+// Support for java.lang.Continuation
+
+#define CONTINUATION_FIELDS_DO(macro) \
+  macro(_scope_offset,     k, vmSymbols::scope_name(),     continuationscope_signature, false); \
+  macro(_target_offset,    k, vmSymbols::target_name(),    runnable_signature,          false); \
+  macro(_parent_offset,    k, vmSymbols::parent_name(),    continuation_signature,      false); \
+  macro(_yieldInfo_offset, k, vmSymbols::yieldInfo_name(), object_signature,            false); \
+  macro(_stack_offset,     k, vmSymbols::stack_name(),     int_array_signature,         false); \
+  macro(_maxSize_offset,   k, vmSymbols::maxSize_name(),   int_signature,               false); \
+  macro(_refStack_offset,  k, vmSymbols::refStack_name(),  object_array_signature,      false); \
+  macro(_entrySP_offset,   k, vmSymbols::entrySP_name(),   long_signature,              false); \
+  macro(_entryFP_offset,   k, vmSymbols::entryFP_name(),   long_signature,              false); \
+  macro(_entryPC_offset,   k, vmSymbols::entryPC_name(),   long_signature,              false); \
+  macro(_fp_offset,        k, vmSymbols::fp_name(),        long_signature,              false); \
+  macro(_sp_offset,        k, vmSymbols::sp_name(),        int_signature,               false); \
+  macro(_pc_offset,        k, vmSymbols::pc_name(),        long_signature,              false); \
+  macro(_refSP_offset,     k, vmSymbols::refSP_name(),     int_signature,               false); \
+  macro(_flags_offset,     k, vmSymbols::flags_name(),     byte_signature,              false); \
+  macro(_cs_offset,        k, vmSymbols::cs_name(),        short_signature,             false); \
+  macro(_reset_offset,     k, vmSymbols::reset_name(),     bool_signature,              false); \
+  macro(_mounted_offset,   k, vmSymbols::mounted_name(),   bool_signature,              false); \
+  macro(_numFrames_offset, k, vmSymbols::numFrames_name(), short_signature,             false); \
+  macro(_numInterpretedFrames_offset, k, vmSymbols::numInterpretedFrames_name(), short_signature, false);
+
+void java_lang_Continuation::compute_offsets() {
+  InstanceKlass* k = SystemDictionary::Continuation_klass();
+  CONTINUATION_FIELDS_DO(FIELD_COMPUTE_OFFSET);
+}
+
+#if INCLUDE_CDS
+void java_lang_Continuation::serialize_offsets(SerializeClosure* f) {
+  CONTINUATION_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif
+
+bool java_lang_Continuation::on_local_stack(oop ref, address adr) {
+  arrayOop s = stack(ref);
+  void* base = s->base(T_INT);
+  return adr >= base && (char*)adr < ((char*)base + (s->length() * 4));
+}
+ 
+bool java_lang_Continuation::is_mounted(oop ref) {
+  return ref->bool_field(_mounted_offset) != 0;
+}
+
 
 // Support for intrinsification of java.nio.Buffer.checkIndex
 int java_nio_Buffer::limit_offset() {
   return _limit_offset;
 }

@@ -4302,11 +4522,11 @@
   BUFFER_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
 }
 #endif
 
 #define AOS_FIELDS_DO(macro) \
-  macro(_owner_offset, k, "exclusiveOwnerThread", thread_signature, false)
+  macro(_owner_offset, k, "exclusiveOwner", object_signature, false)
 
 void java_util_concurrent_locks_AbstractOwnableSynchronizer::compute_offsets() {
   InstanceKlass* k = SystemDictionary::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass();
   AOS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
 }

@@ -4524,10 +4744,20 @@
   // java_lang_ref_Reference
   java_lang_ref_Reference::referent_offset    = member_offset(java_lang_ref_Reference::hc_referent_offset);
   java_lang_ref_Reference::queue_offset       = member_offset(java_lang_ref_Reference::hc_queue_offset);
   java_lang_ref_Reference::next_offset        = member_offset(java_lang_ref_Reference::hc_next_offset);
   java_lang_ref_Reference::discovered_offset  = member_offset(java_lang_ref_Reference::hc_discovered_offset);
+
+  // // java_lang_Continuation Class
+  // java_lang_Continuation::target_offset       = member_offset(java_lang_Continuation::hc_target_offset);
+  // java_lang_Continuation::parent_offset       = member_offset(java_lang_Continuation::hc_parent_offset);
+  // java_lang_Continuation::entrySP_offset      = member_offset(java_lang_Continuation::hc_entrySP_offset);
+  // java_lang_Continuation::entryFP_offset      = member_offset(java_lang_Continuation::hc_entryFP_offset);
+  // java_lang_Continuation::entryPC_offset      = member_offset(java_lang_Continuation::hc_entryPC_offset);
+  // java_lang_Continuation::stack_offset        = member_offset(java_lang_Continuation::hc_stack_offset);
+  // java_lang_Continuation::lastFP_offset       = member_offset(java_lang_Continuation::hc_lastFP_offset);
+  // java_lang_Continuation::lastSP_offset       = member_offset(java_lang_Continuation::hc_lastSP_offset);
 }
 
 #define DO_COMPUTE_OFFSETS(k) k::compute_offsets();
 
 // Compute non-hard-coded field offsets of all the classes in this file

@@ -4616,10 +4846,21 @@
   CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, queue, "Ljava/lang/ref/ReferenceQueue;");
   CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;");
   // Fake field
   //CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, discovered, "Ljava/lang/ref/Reference;");
 
+  // java.lang.Continuation
+
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, target,   "Ljava/lang/Runnable;");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, stack,    "[I");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, parent,   "Ljava/lang/Continuation;");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, entrySP,  "J");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, entryFP,  "J");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, entryPC,  "J");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, lastFP,   "I");
+  // CHECK_OFFSET("java/lang/Continuation", java_lang_Continuation, lastSP,   "I");
+
   if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed");
 }
 
 #endif // PRODUCT
 

@@ -4648,7 +4889,8 @@
 }
 
 void javaClasses_init() {
   JavaClasses::compute_offsets();
   JavaClasses::check_offsets();
+  java_lang_Fiber::init_static_notify_jvmti_events();
   FilteredFieldsMap::initialize();  // must be done after computing offsets.
 }
< prev index next >