bool VM_GC_Operation::doit_prologue() { assert(Thread::current()->is_Java_thread(), "just checking"); assert(((_gc_cause != GCCause::_no_gc) && (_gc_cause != GCCause::_no_cause_specified)), "Illegal GCCause"); // To be able to handle a GC the VM initialization needs to be completed. if (!is_init_completed()) { vm_exit_during_initialization( err_msg("GC triggered before VM initialization completed. Try increasing " "NewSize, current value " UINTX_FORMAT "%s.", byte_size_in_proper_unit(NewSize), proper_unit_for_byte_size(NewSize))); } acquire_pending_list_lock(); // If the GC count has changed someone beat us to the collection // Get the Heap_lock after the pending_list_lock. Heap_lock->lock(); // Check invocations if (skip_operation()) { // skip collection Heap_lock->unlock(); release_and_notify_pending_list_lock(); _prologue_succeeded = false; } else { _prologue_succeeded = true; SharedHeap* sh = SharedHeap::heap(); if (sh != NULL) sh->_thread_holds_heap_lock_for_gc = true; } return _prologue_succeeded; }
void ConcurrentMarkSweepThread::run() { assert(this == cmst(), "just checking"); this->record_stack_base_and_size(); this->initialize_thread_local_storage(); this->set_active_handles(JNIHandleBlock::allocate_block()); // From this time Thread::current() should be working. assert(this == Thread::current(), "just checking"); if (BindCMSThreadToCPU && !os::bind_to_processor(CPUForCMSThread)) { warning("Couldn't bind CMS thread to processor %u", CPUForCMSThread); } // Wait until Universe::is_fully_initialized() { CMSLoopCountWarn loopX("CMS::run", "waiting for " "Universe::is_fully_initialized()", 2); MutexLockerEx x(CGC_lock, true); set_CMS_flag(CMS_cms_wants_token); // Wait until Universe is initialized and all initialization is completed. while (!is_init_completed() && !Universe::is_fully_initialized() && !_should_terminate) { CGC_lock->wait(true, 200); loopX.tick(); } // Wait until the surrogate locker thread that will do // pending list locking on our behalf has been created. // We cannot start the SLT thread ourselves since we need // to be a JavaThread to do so. CMSLoopCountWarn loopY("CMS::run", "waiting for SLT installation", 2); while (_slt == NULL && !_should_terminate) { CGC_lock->wait(true, 200); loopY.tick(); } clear_CMS_flag(CMS_cms_wants_token); } while (!_should_terminate) { sleepBeforeNextCycle(); if (_should_terminate) break; GCCause::Cause cause = _collector->_full_gc_requested ? _collector->_full_gc_cause : GCCause::_cms_concurrent_mark; _collector->collect_in_background(false, cause); } assert(_should_terminate, "just checking"); // Check that the state of any protocol for synchronization // between background (CMS) and foreground collector is "clean" // (i.e. will not potentially block the foreground collector, // requiring action by us). verify_ok_to_terminate(); // Signal that it is terminated { MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag); assert(_cmst == this, "Weird!"); _cmst = NULL; Terminator_lock->notify(); } // Thread destructor usually does this.. ThreadLocalStorage::set_thread(NULL); }
ExceptionMark::~ExceptionMark() { if (_thread->has_pending_exception()) { Handle exception(_thread, _thread->pending_exception()); _thread->clear_pending_exception(); // Needed to avoid infinite recursion if (is_init_completed()) { exception->print(); fatal("ExceptionMark destructor expects no pending exceptions"); } else { vm_exit_during_initialization(exception); } } }
void InterfaceSupport::zombieAll() { // This method is called by all threads when a thread make // transition to VM state (for example, runtime calls). // Divide number of calls by number of threads to avoid // dependence of ZombieAll events frequency on number of threads. int value = zombieAllCounter / Threads::number_of_threads(); if (is_init_completed() && value > ZombieALotInterval) { zombieAllCounter = 0; VM_ZombieAll op; VMThread::execute(&op); } zombieAllCounter++; }
void pd_obfuscate_location(char *buf,int buflen) { const char *tag = NULL; #ifndef PRODUCT if( is_init_completed() ) { if(os::Solaris::mutator_libthread()) { tag = " [ Patched ]"; } else { tag = " [ Unpatched ]"; } } else { tag = " [ Unknown ]"; } #else // State info // 0x00 = unpatched // 0x01 = patched // 0xFF = unknown if( is_init_completed() ) { if(os::Solaris::mutator_libthread()) { tag = " 01"; } else { tag = " 00"; } } else { tag = " FF"; } #endif if(strlen(buf) + strlen(tag) + 1 < buflen) { strcat(buf,tag); } }
void vm_perform_shutdown_actions() { // Warning: do not call 'exit_globals()' here. All threads are still running. // Calling 'exit_globals()' will disable thread-local-storage and cause all // kinds of assertions to trigger in debug mode. if (is_init_completed()) { Thread* thread = Thread::current(); if (thread->is_Java_thread()) { // We are leaving the VM, set state to native (in case any OS exit // handlers call back to the VM) JavaThread* jt = (JavaThread*)thread; // Must always be walkable or have no last_Java_frame when in // thread_in_native jt->frame_anchor()->make_walkable(jt); jt->set_thread_state(_thread_in_native); } } notify_vm_shutdown(); }
void InterfaceSupport::deoptimizeAll() { // This method is called by all threads when a thread make // transition to VM state (for example, runtime calls). // Divide number of calls by number of threads to avoid // dependence of DeoptimizeAll events frequency on number of threads. int value = deoptimizeAllCounter / Threads::number_of_threads(); if (is_init_completed()) { if (DeoptimizeALot && value > DeoptimizeALotInterval) { deoptimizeAllCounter = 0; VM_DeoptimizeAll op; VMThread::execute(&op); } else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) { VM_DeoptimizeAll op; VMThread::execute(&op); } } deoptimizeAllCounter++; }
void vm_perform_shutdown_actions() { // Warning: do not call 'exit_globals()' here. All threads are still running. // Calling 'exit_globals()' will disable thread-local-storage and cause all // kinds of assertions to trigger in debug mode. if (is_init_completed()) { Thread* thread = Thread::current(); if (thread->is_Java_thread()) { JavaThread *jt = (JavaThread*)thread; if(jt->jvm_locked_by_self()){ // We are leaving the VM, unlock the JVM lock like we would if we were // running in native code. (in case any OS exit handlers call back to // the VM) jt->jvm_unlock_self(); } } } notify_vm_shutdown(); }
void InterfaceSupport::stress_derived_pointers() { #ifdef COMPILER2 JavaThread *thread = JavaThread::current(); if (!is_init_completed()) return; ResourceMark rm(thread); bool found = false; for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) { CodeBlob* cb = sfs.current()->cb(); if (cb != NULL && cb->oop_maps() ) { // Find oopmap for current method const ImmutableOopMap* map = cb->oop_map_for_return_address(sfs.current()->pc()); assert(map != NULL, "no oopmap found for pc"); found = map->has_derived_pointer(); } } if (found) { // $$$ Not sure what to do here. /* Scavenge::invoke(0); */ } #endif }
void ConcurrentGCThread::wait_for_universe_init() { MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); while (!is_init_completed() && !_should_terminate) { CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200); } }