safepoint.cpp revision 2592
// -------------------------------------------------------------------------------------------------- // Implementation of Safepoint begin/end static volatile int PageArmed = 0 ;
// safepoint polling page is RO|RW vs PROT_NONE static volatile int TryingToBlock = 0 ;
// proximate value -- for advisory use only // Roll all threads forward to a safepoint and suspend them all // In the future we should investigate whether CMS can use the // more-general mechanism below. DLD (01/05). // By getting the Threads_lock, we assure that no threads are about to start or // exit. It is released again in SafepointSynchronize::end(). // Set number of threads to wait for, before we initiate the callbacks // Save the starting time, so that it can be compared to see if this has taken // PrintSafepointStatisticsTimeout can be specified separately. When // specified, PrintSafepointStatistics will be set to true in // deferred_initialize_stat method. The initialization has to be done // early enough to avoid any races. See bug 6880029 for details. // Begin the process of bringing the system to a safepoint. // Java threads can be in several different states and are // stopped by different mechanisms: // 1. Running interpreted // The interpeter dispatch table is changed to force it to // check for a safepoint condition between bytecodes. // 2. Running in native code // When returning from the native code, a Java thread must check // the safepoint _state to see if we must block. If the // VM thread sees a Java thread in native, it does // not wait for this thread to block. The order of the memory // writes and reads of both the safepoint state and the Java // threads state is critical. In order to guarantee that the // memory writes are serialized with respect to each other, // the VM thread issues a memory barrier instruction // (on MP systems). In order to avoid the overhead of issuing // a memory barrier for each Java thread making native calls, each Java // thread performs a write to a single memory page after changing // the thread state. The VM thread performs a sequence of // mprotect OS calls which forces all previous writes from all // Java threads to be serialized. This is done in the // os::serialize_thread_states() call. This has proven to be // much more efficient than executing a membar instruction // on every call to native code. // 3. Running compiled Code // Compiled code reads a global (Safepoint Polling) page that // is set to fault if we are trying to get to a safepoint. // A thread which is blocked will not be allowed to return from the // block condition until the safepoint operation is complete. // 5. In VM or Transitioning between states // If a Java thread is currently running in the VM or transitioning // between states, the safepointing code will wait for the thread to // block itself when it attempts transitions to a new state. // Flush all thread states to memory // Make interpreter safepoint aware // Make polling safepoint aware // Consider using active_processor_count() ... but that call is expensive. // Iterate through all threads until it have been determined how to stop them all at a safepoint // consider adjusting steps downward: // steps = MIN(steps, 2000-100) // if (iterations != 0) steps -= NNN // Check for if it takes to long // Spin to avoid context switching. // There's a tension between allowing the mutators to run (and rendezvous) // vs spinning. As the VM thread spins, wasting cycles, it consumes CPU that // a mutator might otherwise use profitably to reach a safepoint. Excessive // spinning by the VM thread on a saturated system can increase rendezvous latency. // Blocking or yielding incur their own penalties in the form of context switching // and the resultant loss of $ residency. // Further complicating matters is that yield() does not work as naively expected // on many platforms -- yield() does not guarantee that any other ready threads // will run. As such we revert yield_all() after some number of iterations. // Yield_all() is implemented as a short unconditional sleep on some platforms. // Typical operating systems round a "short" sleep period up to 10 msecs, so sleeping // can actually increase the time it takes the VM thread to detect that a system-wide // stop-the-world safepoint has been reached. In a pathological scenario such as that // described in CR6415670 the VMthread may sleep just before the mutator(s) become safe. // In that case the mutators will be stalled waiting for the safepoint to complete and the // the VMthread will be sleeping, waiting for the mutators to rendezvous. The VMthread // will eventually wake up and detect that all mutators are safe, at which point // we'll again make progress. // Beware too that that the VMThread typically runs at elevated priority. // Its default priority is higher than the default mutator priority. // Obviously, this complicates spinning. // Note too that on Windows XP SwitchThreadTo() has quite different behavior than Sleep(0). // Sleep(0) will _not yield to lower priority threads, while SwitchThreadTo() will. // In the future we might: // 1. Modify the safepoint scheme to avoid potentally unbounded spinning. // This is tricky as the path used by a thread exiting the JVM (say on // on JNI call-out) simply stores into its state field. The burden // is placed on the VM thread, which must poll (spin). // 2. Find something useful to do while spinning. If the safepoint is GC-related // we might aggressively scan the stacks of threads that are already safe. // 3. Use Solaris schedctl to examine the state of the still-running mutators. // If all the mutators are ONPROC there's no reason to sleep or yield. // 4. YieldTo() any still-running mutators that are ready but OFFPROC. // 5. Check system saturation. If the system is not fully saturated then // 6. As still-running mutators rendezvous they could unpark the sleeping // VMthread. This works well for still-running mutators that become // safe. The VMthread must still poll for mutators that call-out. // 7. Drive the policy on time-since-begin instead of iterations. // 8. Consider making the spin duration a function of the # of CPUs: // Spin = (((ncpus-1) * M) + K) + F(still_running) // Alternately, instead of counting iterations of the outer loop // we could count the # of threads visited in the inner loop, above. // 9. On windows consider using the return value from SwitchThreadTo() // Instead of (ncpus > 1) consider either (still_running < (ncpus + EPSILON)) or // ((still_running + _waiting_to_block - TryingToBlock)) < ncpus) // Alternately, the VM thread could transiently depress its scheduling priority or // transiently increase the priority of the tardy mutator(s). // wait until all threads are stopped // Compute remaining time // If there is no remaining time, then there is an error tty->
print_cr(
"# SafepointSynchronize: Finished after " // Call stuff that needs to be run when a safepoint is just about to be completed // Record how much time spend on the above cleanup tasks // Wake up all threads, so they are ready to resume execution after the safepoint // operation has been carried out // memory fence isn't required here since an odd _safepoint_counter // value can do no harm and a fence is issued below anyway. // A pending_exception cannot be installed during a safepoint. The threads // may install an async exception after they come back from a safepoint into // pending_exception after they unblock. But that should happen later. "safepoint installed a pending exception");
// Make polling safepoint aware // Remove safepoint check from interpreter // Set to not synchronized, so the threads will not go into the signal_thread_blocked method // when they get restarted. // Start suspended threads // A problem occurring on Solaris is when attempting to restart threads // the first #cpus - 1 go well, but then the VMThread is preempted when we get // to the next one (since it has been running the longest). We then have // to wait for a cpu to become available before we can continue restarting // FIXME: This causes the performance of the VM to degrade when active and with // large numbers of threads. Apparently this is due to the synchronous nature // of suspending threads. // TODO-FIXME: the comments above are vestigial and no longer apply. // Furthermore, using solaris' schedctl in this particular context confers no benefit // Release threads lock, so threads can be created/destroyed again. It will also starts all threads // blocked in signal_thread_blocked // If there are any concurrent GC threads resume them. // record this time so VMThread can keep track how much time has elasped // Need a safepoint if some inline cache buffers is non-empty // Various cleaning tasks that should be done periodically at safepoints // native threads are safe if they have no java stack or have walkable stack // blocked threads should have already have walkable stack // ------------------------------------------------------------------------------------------------------- // Implementation of Safepoint callback point // Threads shouldn't block if they are in the middle of printing, but... // Only bail from the block() call if the thread is gone from the // thread list; starting to exit should still block. // block current thread if we come here from native code when VM is gone // Check that we have a valid thread_state at this point // We are highly likely to block on the Safepoint_lock. In order to avoid blocking in this case, // we pretend we are still in the VM. // We will always be holding the Safepoint_lock when we are examine the state // of a thread. Hence, the instructions between the Safepoint_lock->lock() and // Safepoint_lock->unlock() are happening atomic with regards to the safepoint code // Decrement the number of threads to wait for and signal vm thread // Consider (_waiting_to_block < 2) to pipeline the wakeup of the VM thread // We transition the thread to state _thread_blocked here, but // we can't do our usual check for external suspension and then // self-suspend after the lock_without_safepoint_check() call // below because we are often called during transitions while // we hold different locks. That would leave us suspended while // holding a resource which results in deadlocks. // We now try to acquire the threads lock. Since this lock is hold by the VM thread during // the entire safepoint, the threads will all line up here during the safepoint. // restore original state. This is important if the thread comes from compiled code, so it // will continue to execute with the _thread_in_Java state. fatal(
"Deadlock in safepoint code. " "Should have called back to the VM before blocking.");
// We transition the thread to state _thread_blocked here, but // we can't do our usual check for external suspension and then // self-suspend after the lock_without_safepoint_check() call // below because we are often called during transitions while // we hold different locks. That would leave us suspended while // holding a resource which results in deadlocks. // It is not safe to suspend a thread if we discover it is in _thread_in_native_trans. Hence, // the safepoint code might still be waiting for it to block. We need to change the state here, // so it can see that it is at a safepoint. // Block until the safepoint operation is completed. // Check for pending. async. exceptions or suspends - except if the // thread was blocked inside the VM. has_special_runtime_exit_condition() // is called last since it grabs a lock and we only want to do that when // Note: we never deliver an async exception at a polling point as the // compiler may not have an exception handler for it. The polling // code will notice the async and deoptimize and the exception will // be delivered. (Polling at a return point is ok though). Sure is // a lot of bother for a deprecated feature... // We don't deliver an async exception if the thread state is // _thread_in_native_trans so JNI functions won't be called with // a surprising pending exception. If the thread state is going back to java, // async exception is checked in check_special_condition_for_native_trans(). // ------------------------------------------------------------------------------------------------------ tty->
print_cr(
"--------+------address-----+------before-----------+-------after----------+");
const int incr =
1;
// Increment to skip a long, in units of intptr_t tty->
print_cr(
"--------+--address-+------before-----------+-------after----------+");
const int incr =
2;
// Increment to skip a long, in units of intptr_t for(
int i=0; i<
16; i++ ) {
for(
int i2=0;
i2<
16;
i2++ ) {
// Uncomment this to get some serious before/after printing of the // Sparc safepoint-blob frame structure. intptr_t* sp = thread->last_Java_sp(); intptr_t stack_copy[150]; for( int i=0; i<150; i++ ) stack_copy[i] = sp[i]; for( int i=0; i<150; i++ ) was_oops[i] = stack_copy[i] ? ((oop)stack_copy[i])->is_oop() : false; tty->
print(
"handle_polling_page_exception: ");
// print_me(sp,stack_copy,was_oops); // Print out the thread infor which didn't reach the safepoint for debugging // purposes (useful when there are lots of threads in the debugger). tty->
print_cr(
"# SafepointSynchronize::begin: Timeout detected:");
tty->
print_cr(
"# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint.");
tty->
print_cr(
"# SafepointSynchronize::begin: Timed out while waiting for threads to stop.");
tty->
print_cr(
"# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
tty->
print_cr(
"# SafepointSynchronize::begin: (End of list)");
// To debug the long safepoint, specify both DieOnSafepointTimeout & // ShowMessageBoxOnError. // ------------------------------------------------------------------------------------------------------- // Implementation of ThreadSafepointState // Save the state at the start of safepoint processing. // Check for a thread that is suspended. Note that thread resume tries // to grab the Threads_lock which we own here, so a thread cannot be // resumed during safepoint synchronization. // We check to see if this thread is suspended without locking to // avoid deadlocking with a third thread that is waiting for this // thread to be suspended. The third thread can notice the safepoint // that we're trying to start at the beginning of its SR_lock->wait() // call. If that happens, then the third thread will block on the // safepoint while still holding the underlying SR_lock. We won't be // able to get the SR_lock and we'll deadlock. // We don't need to grab the SR_lock here for two reasons: // 1) The suspend flags are both volatile and are set with an // Atomic::cmpxchg() call so we should see the suspended // 2) We're being called from the safepoint polling loop; if // we don't see the suspended state on this iteration, then // we'll come around again. // Some JavaThread states have an initial safepoint state of // running, but are actually at a safepoint. We will happily // agree and update the safepoint state here. // All other thread states will continue to run until they // transition and self-block in state _blocked // Safepoint polling in compiled code causes the Java threads to do the same. // Note: new threads may require a malloc so they must be allowed to finish // Returns true is thread could not be rolled forward at present position. " [0x%2x] State: %s _has_called_back %d _at_poll_safepoint %d",
// --------------------------------------------------------------------------------------------------------------------- // Block the thread at the safepoint poll or poll return. // Check state. block() will set thread state to thread_in_vm which will // cause the safepoint state _type to become _call_back. "polling page exception on thread not running state");
// Step 1: Find the nmethod from the return address // Should only be poll_return or poll // This is a poll immediately before a return. The exception handling code // has already had the effect of causing the return to occur, so the execution // will continue immediately after the call. In addition, the oopmap at the // return point does not mark the return value as an oop (if it is), so // it needs a handle here to be updated. // See if return type is an oop. // The oop result has been saved on the stack together with all // the other registers. In order to preserve it over GCs we need // to keep it in a handle. // restore oop result, if any // This is a safepoint poll. Verify the return address and block. // verify the blob built the "return address" correctly // If we have a pending async exception deoptimize the frame // as otherwise we may never deliver it. // If an exception has been installed we must check for a pending deoptimization // Deoptimize frame if exception has been thrown. // The exception patch will destroy registers that are still // live and will be needed during deoptimization. Defer the // Async exception should have defered the exception until the // next safepoint which will be detected when we get into // the interpreter so if we have an exception now things fatal(
"Exception installed and deoptimization is pending");
// Statistics & Instrumentations // Helper method to print the header. "[threads: total initially_running wait_to_block] ");
tty->
print(
"[time: spin block sync cleanup vmop] ");
// no page armed status printed out if it is always armed. fatal(
"Wrong PrintSafepointStatisticsCount");
// If PrintSafepointStatisticsTimeout is specified, the statistics data will // be printed right away, in which case, _safepoint_stats will regress to // a single element array. Otherwise, it is a circular ring buffer with default // size of PrintSafepointStatisticsCount. "not enough memory for safepoint instrumentation data");
// Records the start time of spinning. The real time spent on spinning // will be adjusted when spin is done. Same trick is applied for time // spent on waiting for threads to block. // Records the start time of waiting for to block. Updated when block is done. // Records the end time of sync which will be used to calculate the total // vm operation time. Again, the real time spending in syncing will be deducted // from the start of the sync time later when end_statistics is called. // Record how long spent in cleanup tasks. // Update the vm operation time. // Only the sync time longer than the specified // PrintSafepointStatisticsTimeout will be printed out right away. // By default, it is -1 meaning all samples will be put into the list. // The safepoint statistics will be printed out when the _safepoin_stats // "/ MICROUNITS " is to convert the unit from nanos to millis. // This method will be called when VM exits. It will first call // print_statistics to print out the rest of the sampling. Then // it tries to summarize the sampling. // During VM exit, end_statistics may not get called and in that // case, if the sync time is less than PrintSafepointStatisticsTimeout, // Approximate the vm op time. // Print out polling page sampling status. tty->
print_cr(
"Maximum vm operation time (except for Exit VM operation) " // ------------------------------------------------------------------------------------------------