< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page
@@ -37,10 +37,11 @@
  #include "code/scopeDesc.hpp"
  #include "compiler/compileBroker.hpp"
  #include "compiler/compileTask.hpp"
  #include "compiler/compilerThread.hpp"
  #include "gc/shared/barrierSet.hpp"
+ #include "gc/shared/barrierSetNMethod.hpp"
  #include "gc/shared/collectedHeap.hpp"
  #include "gc/shared/gcId.hpp"
  #include "gc/shared/gcLocker.inline.hpp"
  #include "gc/shared/gcVMOperations.hpp"
  #include "gc/shared/oopStorage.hpp"

@@ -71,11 +72,11 @@
  #include "oops/typeArrayOop.inline.hpp"
  #include "oops/verifyOopClosure.hpp"
  #include "prims/jvm_misc.hpp"
  #include "prims/jvmtiDeferredUpdates.hpp"
  #include "prims/jvmtiExport.hpp"
- #include "prims/jvmtiThreadState.hpp"
+ #include "prims/jvmtiThreadState.inline.hpp"
  #include "runtime/arguments.hpp"
  #include "runtime/atomic.hpp"
  #include "runtime/fieldDescriptor.inline.hpp"
  #include "runtime/flags/jvmFlagLimit.hpp"
  #include "runtime/deoptimization.hpp"

@@ -268,10 +269,12 @@
    // BarrierSet::on_thread_create() for this thread is therefore deferred
    // to BarrierSet::set_barrier_set().
    BarrierSet* const barrier_set = BarrierSet::barrier_set();
    if (barrier_set != NULL) {
      barrier_set->on_thread_create(this);
+     BarrierSetNMethod* bs_nm = barrier_set->barrier_set_nmethod();
+     _nmethod_disarm_value = bs_nm->disarmed_value();
    } else {
      // Only the main thread should be created before the barrier set
      // and that happens just before Thread::current is set. No other thread
      // can attach as the VM is not created yet, so they can't execute this code.
      // If the main thread creates other threads before the barrier set that is an error.

@@ -704,12 +707,11 @@
  
    // Cannot use JavaCalls::construct_new_instance because the java.lang.Thread
    // constructor calls Thread.current(), which must be set here for the
    // initial thread.
    java_lang_Thread::set_thread(thread_oop(), thread);
-   java_lang_Thread::set_priority(thread_oop(), NormPriority);
-   thread->set_threadObj(thread_oop());
+   thread->set_threadOopHandles(thread_oop());
  
    Handle string = java_lang_String::create_from_str("main", CHECK);
  
    JavaValue result(T_VOID);
    JavaCalls::call_special(&result, thread_oop,

@@ -761,17 +763,37 @@
  }
  
  // Initialized by VMThread at vm_global_init
  static OopStorage* _thread_oop_storage = NULL;
  
- oop  JavaThread::threadObj() const    {
+ oop JavaThread::threadObj() const    {
    return _threadObj.resolve();
  }
  
- void JavaThread::set_threadObj(oop p) {
+ void JavaThread::set_threadOopHandles(oop p) {
    assert(_thread_oop_storage != NULL, "not yet initialized");
-   _threadObj = OopHandle(_thread_oop_storage, p);
+   _threadObj   = OopHandle(_thread_oop_storage, p);
+   _vthread     = OopHandle(_thread_oop_storage, p);
+   _scopeLocalCache = OopHandle(_thread_oop_storage, NULL);
+ }
+ 
+ oop JavaThread::scopeLocalCache() const {
+   return _scopeLocalCache.resolve();
+ }
+ 
+ oop JavaThread::vthread() const {
+   return _vthread.resolve();
+ }
+ 
+ void JavaThread::set_vthread(oop p) {
+   assert(_thread_oop_storage != NULL, "not yet initialized");
+   _vthread.replace(p);
+ }
+ 
+ void JavaThread::set_scopeLocalCache(oop p) {
+   assert(_thread_oop_storage != NULL, "not yet initialized");
+   _scopeLocalCache.replace(p);
  }
  
  OopStorage* JavaThread::thread_oop_storage() {
    assert(_thread_oop_storage != NULL, "not yet initialized");
    return _thread_oop_storage;

@@ -788,12 +810,11 @@
  
    // We are called from jni_AttachCurrentThread/jni_AttachCurrentThreadAsDaemon.
    // We cannot use JavaCalls::construct_new_instance because the java.lang.Thread
    // constructor calls Thread.current(), which must be set here.
    java_lang_Thread::set_thread(thread_oop(), this);
-   java_lang_Thread::set_priority(thread_oop(), NormPriority);
-   set_threadObj(thread_oop());
+   set_threadOopHandles(thread_oop());
  
    JavaValue result(T_VOID);
    if (thread_name != NULL) {
      Handle name = java_lang_String::create_from_str(thread_name, CHECK);
      // Thread gets assigned specified name and null target

@@ -815,30 +836,15 @@
                              vmSymbols::threadgroup_runnable_void_signature(),
                              thread_group,
                              Handle(),
                              THREAD);
    }
- 
+   os::set_priority(this, NormPriority);
  
    if (daemon) {
      java_lang_Thread::set_daemon(thread_oop());
    }
- 
-   if (HAS_PENDING_EXCEPTION) {
-     return;
-   }
- 
-   Klass* group = vmClasses::ThreadGroup_klass();
-   Handle threadObj(THREAD, this->threadObj());
- 
-   JavaCalls::call_special(&result,
-                           thread_group,
-                           group,
-                           vmSymbols::add_method_name(),
-                           vmSymbols::thread_void_signature(),
-                           threadObj,          // Arg 1
-                           THREAD);
  }
  
  // ======= JavaThread ========
  
  #if INCLUDE_JVMCI

@@ -987,10 +993,11 @@
    _deopt_mark(nullptr),
    _deopt_nmethod(nullptr),
    _vframe_array_head(nullptr),
    _vframe_array_last(nullptr),
    _jvmti_deferred_updates(nullptr),
+   _keepalive_cleanup(new (ResourceObj::C_HEAP, mtInternal) GrowableArray<WeakHandle>(16, mtInternal)),
    _callee_target(nullptr),
    _vm_result(nullptr),
    _vm_result_2(nullptr),
  
    _current_pending_monitor(NULL),

@@ -1015,10 +1022,14 @@
  
    _terminated(_not_terminated),
    _in_deopt_handler(0),
    _doing_unsafe_access(false),
    _do_not_unlock_if_synchronized(false),
+ #if INCLUDE_JVMTI
+   _is_in_VTMT(false),
+   _is_VTMT_disabler(false),
+ #endif
    _jni_attach_state(_not_attaching_via_jni),
  #if INCLUDE_JVMCI
    _pending_deoptimization(-1),
    _pending_monitorenter(false),
    _pending_transfer_to_interpreter(false),

@@ -1042,10 +1053,18 @@
  
    // JVMTI PopFrame support
    _popframe_condition(popframe_inactive),
    _frames_to_pop_failed_realloc(0),
  
+   _cont_entry(nullptr),
+   _cont_yield(false),
+   _cont_preempt(false),
+   _cont_fastpath_thread_state(1),
+   _cont_fastpath(0),
+   _held_monitor_count(0),
+   _mounted_vthread(oop()),
+ 
    _handshake(this),
  
    _popframe_preserved_args(nullptr),
    _popframe_preserved_args_size(0),
  

@@ -1059,18 +1078,16 @@
    _class_to_be_initialized(nullptr),
  
    _SleepEvent(ParkEvent::Allocate(this))
  {
    set_jni_functions(jni_functions());
- 
  #if INCLUDE_JVMCI
    assert(_jvmci._implicit_exception_pc == nullptr, "must be");
    if (JVMCICounterSize > 0) {
      resize_counters(0, (int) JVMCICounterSize);
    }
  #endif // INCLUDE_JVMCI
- 
    // Setup safepoint state info for this thread
    ThreadSafepointState::create(this);
  
    SafepointMechanism::initialize_header(this);
  

@@ -1182,10 +1199,11 @@
  
  JavaThread::~JavaThread() {
  
    // Ask ServiceThread to release the threadObj OopHandle
    ServiceThread::add_oop_handle_release(_threadObj);
+   ServiceThread::add_oop_handle_release(_vthread);
  
    // Return the sleep event to the free list
    ParkEvent::Release(_SleepEvent);
    _SleepEvent = NULL;
  

@@ -1358,26 +1376,21 @@
                      name());
          CLEAR_PENDING_EXCEPTION;
        }
      }
  
-     // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
-     // the execution of the method. If that is not enough, then we don't really care. Thread.stop
-     // is deprecated anyhow.
+     // Call Thread.exit()
      if (!is_Compiler_thread()) {
-       int count = 3;
-       while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) {
-         EXCEPTION_MARK;
-         JavaValue result(T_VOID);
-         Klass* thread_klass = vmClasses::Thread_klass();
-         JavaCalls::call_virtual(&result,
-                                 threadObj, thread_klass,
-                                 vmSymbols::exit_method_name(),
-                                 vmSymbols::void_method_signature(),
-                                 THREAD);
-         CLEAR_PENDING_EXCEPTION;
-       }
+       EXCEPTION_MARK;
+       JavaValue result(T_VOID);
+       Klass* thread_klass = vmClasses::Thread_klass();
+       JavaCalls::call_virtual(&result,
+                               threadObj, thread_klass,
+                               vmSymbols::exit_method_name(),
+                               vmSymbols::void_method_signature(),
+                               THREAD);
+       CLEAR_PENDING_EXCEPTION;
      }
      // notify JVMTI
      if (JvmtiExport::should_post_thread_life()) {
        JvmtiExport::post_thread_end(this);
      }

@@ -1426,10 +1439,12 @@
             "should not have a Java frame when detaching or exiting");
      ObjectSynchronizer::release_monitors_owned_by_thread(this);
      assert(!this->has_pending_exception(), "release_monitors should have cleared");
    }
  
+   assert(this->held_monitor_count() == 0, "held monitor count should be zero");
+ 
    // These things needs to be done while we are still a Java Thread. Make sure that thread
    // is in a consistent state, in case GC happens
    JFR_ONLY(Jfr::on_thread_exit(this);)
  
    if (active_handles() != NULL) {

@@ -1608,10 +1623,16 @@
      if (!has_pending_exception() || !pending_exception()->is_a(vmClasses::ThreadDeath_klass())) {
  
        // We cannot call Exceptions::_throw(...) here because we cannot block
        set_pending_exception(_pending_async_exception, __FILE__, __LINE__);
  
+       // Clear any scope-local bindings on ThreadDeath
+       set_scopeLocalCache(NULL);
+       oop threadOop = threadObj();
+       assert(threadOop != NULL, "must be");
+       java_lang_Thread::clear_scopeLocalBindings(threadOop);
+ 
        LogTarget(Info, exceptions) lt;
        if (lt.is_enabled()) {
          ResourceMark rm;
          LogStream ls(lt);
          ls.print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", p2i(this));

@@ -1664,10 +1685,15 @@
    if (check_asyncs) {
      check_and_handle_async_exceptions();
    }
  
    JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);)
+ 
+   if (is_cont_force_yield()) {
+     Continuation::jump_from_safepoint(this); // does not return
+     ShouldNotReachHere();
+   }
  }
  
  class InstallAsyncExceptionClosure : public HandshakeClosure {
    Handle _throwable; // The Throwable thrown at the target Thread
  public:

@@ -1733,18 +1759,43 @@
    // Interrupt thread so it will wake up from a potential wait()/sleep()/park()
    java_lang_Thread::set_interrupted(threadObj(), true);
    this->interrupt();
  }
  
+ #if INCLUDE_JVMTI
+ void JavaThread::set_is_in_VTMT(bool val) {
+   _is_in_VTMT = val;
+   if (val) {
+     assert(JvmtiVTMTDisabler::VTMT_disable_count() == 0, "must be 0");
+   }
+ }
+ 
+ void JavaThread::set_is_VTMT_disabler(bool val) {
+   _is_VTMT_disabler = val;
+   assert(JvmtiVTMTDisabler::VTMT_count() == 0, "must be 0");
+ }
+ #endif
  
  // External suspension mechanism.
  //
  // Guarantees on return (for a valid target thread):
  //   - Target thread will not execute any new bytecode.
  //   - Target thread will not enter any new monitors.
  //
  bool JavaThread::java_suspend() {
+ #if INCLUDE_JVMTI
+   // Suspending a JavaThread in VTMT or disabling VTMT can cause deadlocks.
+   assert(!is_in_VTMT(), "no suspend allowed in VTMT transition");
+ #ifdef ASSERT
+   if (is_VTMT_disabler()) { // TMP debugging code, should be removed after this assert is observed
+     printf("DBG: JavaThread::java_suspend: suspended jt: %p current jt: %p\n", (void*)this, (void*)JavaThread::current());
+     printf("DBG: JavaThread::java_suspend: VTMT_disable_count: %d\n", JvmtiVTMTDisabler::VTMT_disable_count());
+   }
+ #endif
+   assert(!is_VTMT_disabler(), "no suspend allowed for VTMT disablers");
+ #endif
+ 
    ThreadsListHandle tlh;
    if (!tlh.includes(this)) {
      log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " not on ThreadsList, no suspension", p2i(this));
      return false;
    }

@@ -1758,10 +1809,29 @@
      return false;
    }
    return this->handshake_state()->resume();
  }
  
+ bool JavaThread::block_suspend(JavaThread* caller) {
+   ThreadsListHandle tlh;
+   if (!tlh.includes(this)) {
+     log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " not on ThreadsList, no suspension", p2i(this));
+     return false;
+   }
+   return this->handshake_state()->block_suspend(caller);
+ }
+ 
+ bool JavaThread::continue_resume(JavaThread* caller) {
+   ThreadsListHandle tlh;
+   if (!tlh.includes(this)) {
+     log_trace(thread, suspend)("JavaThread:" INTPTR_FORMAT " not on ThreadsList, nothing to resume", p2i(this));
+     return false;
+   }
+   return this->handshake_state()->continue_resume(caller);
+ }
+ 
+ 
  // Wait for another thread to perform object reallocation and relocking on behalf of
  // this thread.
  // Raw thread state transition to _thread_blocked and back again to the original
  // state before returning are performed. The current thread is required to
  // change to _thread_blocked in order to be seen to be safepoint/handshake safe

@@ -1918,10 +1988,28 @@
        Deoptimization::deoptimize(this, *fst.current());
      }
    }
  }
  
+ void JavaThread::deoptimize_marked_methods_only_anchors() {
+   if (!has_last_Java_frame()) return;
+   bool java_callee = false;
+   StackFrameStream fst(this, false /* update */, true /* process_frames */);
+   for (; !fst.is_done(); fst.next()) {
+     if (fst.current()->should_be_deoptimized()) {
+       if (!java_callee) {
+         //tty->print_cr("Patching RA");
+         Deoptimization::deoptimize(this, *fst.current());
+       } else {
+         //tty->print_cr("Not patching RA");
+       }
+     }
+     java_callee = fst.current()->is_compiled_frame();
+   }
+ }
+ 
+ 
  #ifdef ASSERT
  void JavaThread::verify_frame_info() {
    assert((!has_last_Java_frame() && java_call_counter() == 0) ||
           (has_last_Java_frame() && java_call_counter() > 0),
           "unexpected frame info: has_last_frame=%s, java_call_counter=%d",

@@ -1965,10 +2053,12 @@
  #endif
  
    if (jvmti_thread_state() != NULL) {
      jvmti_thread_state()->oops_do(f, cf);
    }
+ 
+   f->do_oop(&_mounted_vthread);
  }
  
  void JavaThread::oops_do_frames(OopClosure* f, CodeBlobClosure* cf) {
    if (!has_last_Java_frame()) {
      return;

@@ -2038,24 +2128,25 @@
    case _thread_blocked_trans:     return "_thread_blocked_trans";
    default:                        return "unknown thread state";
    }
  }
  
- #ifndef PRODUCT
  void JavaThread::print_thread_state_on(outputStream *st) const {
    st->print_cr("   JavaThread state: %s", _get_thread_state_name(_thread_state));
  };
- #endif // PRODUCT
+ const char* JavaThread::thread_state_name() const {
+   return _get_thread_state_name(_thread_state);
+ }
  
  // Called by Threads::print() for VM_PrintThreads operation
  void JavaThread::print_on(outputStream *st, bool print_extended_info) const {
    st->print_raw("\"");
    st->print_raw(name());
    st->print_raw("\" ");
    oop thread_oop = threadObj();
    if (thread_oop != NULL) {
-     st->print("#" INT64_FORMAT " ", (int64_t)java_lang_Thread::thread_id(thread_oop));
+     st->print("#" INT64_FORMAT " [%ld] ", (int64_t)java_lang_Thread::thread_id(thread_oop), (long) osthread()->thread_id());
      if (java_lang_Thread::is_daemon(thread_oop))  st->print("daemon ");
      st->print("prio=%d ", java_lang_Thread::priority(thread_oop));
    }
    Thread::print_on(st, print_extended_info);
    // print guess for valid stack memory region (assume 4K pages); helps lock debugging

@@ -2098,10 +2189,11 @@
      st->print(", id=%d", osthread()->thread_id());
    }
    st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
              p2i(stack_end()), p2i(stack_base()));
    st->print("]");
+   DEBUG_ONLY(print_owned_locks_on(st);)
  
    ThreadsSMRSupport::print_info_on(this, st);
    return;
  }
  

@@ -2202,11 +2294,11 @@
  
    Handle thread_oop(Thread::current(),
                      JNIHandles::resolve_non_null(jni_thread));
    assert(InstanceKlass::cast(thread_oop->klass())->is_linked(),
           "must be initialized");
-   set_threadObj(thread_oop());
+   set_threadOopHandles(thread_oop());
    java_lang_Thread::set_thread(thread_oop(), this);
  
    if (prio == NoPriority) {
      prio = java_lang_Thread::priority(thread_oop());
      assert(prio != NoPriority, "A valid priority should be present");

@@ -2238,11 +2330,11 @@
  
    Thread* current_thread = Thread::current();
    ResourceMark rm(current_thread);
    HandleMark hm(current_thread);
  
-   RegisterMap reg_map(this);
+   RegisterMap reg_map(this, true, true);
    vframe* start_vf = last_java_vframe(&reg_map);
    int count = 0;
    for (vframe* f = start_vf; f != NULL; f = f->sender()) {
      if (f->is_java_frame()) {
        javaVFrame* jvf = javaVFrame::cast(f);

@@ -2260,10 +2352,24 @@
      count++;
      if (MaxJavaStackTraceDepth > 0 && MaxJavaStackTraceDepth == count) return;
    }
  }
  
+ #if INCLUDE_JVMTI
+ // Rebind JVMTI thread state from carrier to virtual or from virtual to carrier.
+ JvmtiThreadState* JavaThread::rebind_to_jvmti_thread_state_of(oop thread_oop) {
+   set_mounted_vthread(thread_oop);
+ 
+   // unbind current JvmtiThreadState from JavaThread
+   jvmti_thread_state()->unbind_from(this);
+ 
+   // bind new JvmtiThreadState to JavaThread
+   java_lang_Thread::jvmti_thread_state(thread_oop)->bind_to(this);
+ 
+   return jvmti_thread_state();
+ }
+ #endif
  
  // JVMTI PopFrame support
  void JavaThread::popframe_preserve_args(ByteSize size_in_bytes, void* start) {
    assert(_popframe_preserved_args == NULL, "should not wipe out old PopFrame preserved arguments");
    if (in_bytes(size_in_bytes) != 0) {

@@ -2333,14 +2439,16 @@
  void JavaThread::print_frame_layout(int depth, bool validate_only) {
    ResourceMark rm;
    PreserveExceptionMark pm(this);
    FrameValues values;
    int frame_no = 0;
-   for (StackFrameStream fst(this, false /* update */, true /* process_frames */); !fst.is_done(); fst.next()) {
-     fst.current()->describe(values, ++frame_no);
+   for (StackFrameStream fst(this, true, true, true); !fst.is_done(); fst.next()) {
+     if (frame_no == 0) fst.current()->describe_top(values);
+     fst.current()->describe(values, ++frame_no, fst.register_map());
      if (depth == frame_no) break;
    }
+   Continuation::describe(values);
    if (validate_only) {
      values.validate();
    } else {
      tty->print_cr("[Describe stack layout]");
      values.print(this);

@@ -2368,29 +2476,38 @@
  void JavaThread::trace_stack() {
    if (!has_last_Java_frame()) return;
    Thread* current_thread = Thread::current();
    ResourceMark rm(current_thread);
    HandleMark hm(current_thread);
-   RegisterMap reg_map(this);
+   RegisterMap reg_map(this, true, true);
    trace_stack_from(last_java_vframe(&reg_map));
  }
  
  
  #endif // PRODUCT
  
  
- javaVFrame* JavaThread::last_java_vframe(RegisterMap *reg_map) {
+ frame JavaThread::vthread_carrier_last_frame(RegisterMap* reg_map) {
+   ContinuationEntry* cont = last_continuation(java_lang_VirtualThread::vthread_scope());
+   guarantee (cont != NULL, "Not a carrier thread");
+   frame f = cont->to_frame();
+   cont->update_register_map(reg_map);
+   return f.sender(reg_map);
+ }
+ 
+ javaVFrame* JavaThread::last_java_vframe(const frame f, RegisterMap *reg_map) {
    assert(reg_map != NULL, "a map must be given");
-   frame f = last_frame();
    for (vframe* vf = vframe::new_vframe(&f, reg_map, this); vf; vf = vf->sender()) {
      if (vf->is_java_frame()) return javaVFrame::cast(vf);
    }
    return NULL;
  }
  
- 
  Klass* JavaThread::security_get_caller_class(int depth) {
+   ResetNoHandleMark rnhm;
+   HandleMark hm(Thread::current());
+ 
    vframeStream vfst(this);
    vfst.security_get_caller_frame(depth);
    if (!vfst.at_end()) {
      return vfst.method()->method_holder();
    }

@@ -3708,10 +3825,16 @@
  
    ALL_JAVA_THREADS(p) {
      ResourceMark rm;
      p->print_on(st, print_extended_info);
      if (print_stacks) {
+       // if (p->has_last_Java_frame()) {
+       //   static char buf[O_BUFLEN];
+       //   frame fr = p->last_frame();
+       //   VMError::print_native_stack(tty, fr, p, buf, sizeof(buf));
+       // }
+ 
        if (internal_format) {
          p->trace_stack();
        } else {
          p->print_stack_on(st);
        }

@@ -3826,11 +3949,10 @@
        }
      }
    }
  }
  
- 
  // Ad-hoc mutual exclusion primitives: SpinLock
  //
  // We employ SpinLocks _only for low-contention, fixed-length
  // short-duration critical sections where we're concerned
  // about native mutex_t or HotSpot Mutex:: latency.

@@ -3900,43 +4022,26 @@
     report_vm_error(__FILE__, __LINE__, "Cross modify fence failure", "%p", thread);
  }
  #endif
  
  // Helper function to create the java.lang.Thread object for a
- // VM-internal thread. The thread will have the given name, be
- // part of the System ThreadGroup and if is_visible is true will be
- // discoverable via the system ThreadGroup.
+ // VM-internal thread. The thread will have the given name, and be
+ // a member of the "system" ThreadGroup.
  Handle JavaThread::create_system_thread_object(const char* name,
                                                 bool is_visible, TRAPS) {
    Handle string = java_lang_String::create_from_str(name, CHECK_NH);
  
    // Initialize thread_oop to put it into the system threadGroup.
-   // This is done by calling the Thread(ThreadGroup tg, String name)
-   // constructor, which adds the new thread to the group as an unstarted
-   // thread.
+   // This is done by calling the Thread(ThreadGroup group, String name) constructor.
    Handle thread_group(THREAD, Universe::system_thread_group());
    Handle thread_oop =
      JavaCalls::construct_new_instance(vmClasses::Thread_klass(),
                                        vmSymbols::threadgroup_string_void_signature(),
                                        thread_group,
                                        string,
                                        CHECK_NH);
  
-   // If the Thread is intended to be visible then we have to mimic what
-   // Thread.start() would do, by adding it to its ThreadGroup: tg.add(t).
-   if (is_visible) {
-     Klass* group = vmClasses::ThreadGroup_klass();
-     JavaValue result(T_VOID);
-     JavaCalls::call_special(&result,
-                             thread_group,
-                             group,
-                             vmSymbols::add_method_name(),
-                             vmSymbols::thread_void_signature(),
-                             thread_oop,
-                             CHECK_NH);
-   }
- 
    return thread_oop;
  }
  
  // Starts the target JavaThread as a daemon of the given priority, and
  // bound to the given java.lang.Thread instance.

@@ -3959,11 +4064,11 @@
    }
  
    java_lang_Thread::set_daemon(thread_oop());
  
    // Now bind the thread_oop to the target JavaThread.
-   target->set_threadObj(thread_oop());
+   target->set_threadOopHandles(thread_oop());
  
    Threads::add(target); // target is now visible for safepoint/handshake
    Thread::start(target);
  }
  
< prev index next >