// This method is safe to call without holding the CodeCache_lock, as long as a dead codeblob is not // looked up (i.e., one that has been marked for deletion). It only dependes on the _segmap to contain // valid indices, which it will always do, as long as the CodeBlob is not in the process of being recycled. CodeBlob* CodeCache::find_blob(void* start) { CodeBlob* result = find_blob_unsafe(start); if (result == NULL) return NULL; // We could potientially look up non_entrant methods guarantee(!result->is_zombie() || result->is_locked_by_vm() || is_error_reported(), "unsafe access to zombie method"); return result; }
const TypePtr *ProjNode::adr_type() const { if (bottom_type() == Type::MEMORY) { // in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM const TypePtr* adr_type = in(0)->adr_type(); #ifdef ASSERT if (!is_error_reported() && !Node::in_dump()) assert(adr_type != NULL, "source must have adr_type"); #endif return adr_type; } assert(bottom_type()->base() != Type::Memory, "no other memories?"); return NULL; }
// Note: before_exit() can be executed only once, if more than one threads // are trying to shutdown the VM at the same time, only one thread // can run before_exit() and all other threads must wait. void before_exit(JavaThread * thread) { #define BEFORE_EXIT_NOT_RUN 0 #define BEFORE_EXIT_RUNNING 1 #define BEFORE_EXIT_DONE 2 static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN; // Note: don't use a Mutex to guard the entire before_exit(), as // JVMTI post_thread_end_event and post_vm_death_event will run native code. // A CAS or OSMutex would work just fine but then we need to manipulate // thread state for Safepoint. Here we use Monitor wait() and notify_all() // for synchronization. { MutexLocker ml(BeforeExit_lock); switch (_before_exit_status) { case BEFORE_EXIT_NOT_RUN: _before_exit_status = BEFORE_EXIT_RUNNING; break; case BEFORE_EXIT_RUNNING: while (_before_exit_status == BEFORE_EXIT_RUNNING) { BeforeExit_lock->wait(); } assert(_before_exit_status == BEFORE_EXIT_DONE, "invalid state"); return; case BEFORE_EXIT_DONE: return; } } // The only difference between this and Win32's _onexit procs is that // this version is invoked before any threads get killed. ExitProc* current = exit_procs; while (current != NULL) { ExitProc* next = current->next(); current->evaluate(); delete current; current = next; } // Hang forever on exit if we're reporting an error. if (ShowMessageBoxOnError && is_error_reported()) { os::infinite_sleep(); } // Terminate watcher thread - must before disenrolling any periodic task WatcherThread::stop(); // Print statistics gathered (profiling ...) if (Arguments::has_profile()) { FlatProfiler::disengage(); FlatProfiler::print(10); } // shut down the StatSampler task StatSampler::disengage(); StatSampler::destroy(); #ifndef SERIALGC // stop CMS threads if (UseConcMarkSweepGC) { ConcurrentMarkSweepThread::stop(); } #endif // SERIALGC // Print GC/heap related information. if (PrintGCDetails) { Universe::print(); AdaptiveSizePolicyOutput(0); } if (Arguments::has_alloc_profile()) { HandleMark hm; // Do one last collection to enumerate all the objects // allocated since the last one. Universe::heap()->collect(GCCause::_allocation_profiler); AllocationProfiler::disengage(); AllocationProfiler::print(0); } if (PrintBytecodeHistogram) { BytecodeHistogram::print(); } if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(thread); } // Always call even when there are not JVMTI environments yet, since environments // may be attached late and JVMTI must track phases of VM execution JvmtiExport::post_vm_death(); Threads::shutdown_vm_agents(); // Terminate the signal thread // Note: we don't wait until it actually dies. os::terminate_signal_thread(); print_statistics(); Universe::heap()->print_tracing_info(); VTune::exit(); { MutexLocker ml(BeforeExit_lock); _before_exit_status = BEFORE_EXIT_DONE; BeforeExit_lock->notify_all(); } #undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_DONE }
static void enqueue_proc(void* cookie, char* argp, size_t arg_size, door_desc_t* dt, uint_t n_desc) { int return_fd = -1; SolarisAttachOperation* op = NULL; // no listener jint res = 0; if (!AttachListener::is_initialized()) { // how did we get here? debug_only(warning("door_call when not enabled")); res = (jint)SolarisAttachListener::ATTACH_ERROR_INTERNAL; } // check client credentials if (res == 0) { if (check_credentials() != 0) { res = (jint)SolarisAttachListener::ATTACH_ERROR_DENIED; } } // if we are stopped at ShowMessageBoxOnError then maybe we can // load a diagnostic library if (res == 0 && is_error_reported()) { if (ShowMessageBoxOnError) { // TBD - support loading of diagnostic library here } // can't enqueue operation after fatal error res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE; } // create the operation if (res == 0) { int err; op = create_operation(argp, arg_size, &err); res = (op == NULL) ? (jint)err : 0; } // create a pair of connected sockets. Store the file descriptor // for one end in the operation and enqueue the operation. The // file descriptor for the other end wil be returned to the client. if (res == 0) { int s[2]; if (socketpair(PF_UNIX, SOCK_STREAM, 0, s) < 0) { delete op; res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE; } else { op->set_socket(s[0]); return_fd = s[1]; SolarisAttachListener::enqueue(op); } } // Return 0 (success) + file descriptor, or non-0 (error) if (res == 0) { door_desc_t desc; // DOOR_RELEASE flag makes sure fd is closed after passing it to // the client. See door_return(3DOOR) man page. desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; desc.d_data.d_desc.d_descriptor = return_fd; door_return((char*)&res, sizeof(res), &desc, 1); } else { door_return((char*)&res, sizeof(res), NULL, 0); } }
// Note: before_exit() can be executed only once, if more than one threads // are trying to shutdown the VM at the same time, only one thread // can run before_exit() and all other threads must wait. void before_exit(JavaThread * thread) { #define BEFORE_EXIT_NOT_RUN 0 #define BEFORE_EXIT_RUNNING 1 #define BEFORE_EXIT_DONE 2 static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN; // Note: don't use a AzLock to guard the entire before_exit(), as // JVMTI post_thread_end_event and post_vm_death_event will run native code. // A CAS or OSMutex would work just fine but then we need to manipulate // thread state for Safepoint. Here we use Monitor wait() and notify_all() // for synchronization. { MutexLocker ml(BeforeExit_lock); switch (_before_exit_status) { case BEFORE_EXIT_NOT_RUN: _before_exit_status = BEFORE_EXIT_RUNNING; break; case BEFORE_EXIT_RUNNING: while (_before_exit_status == BEFORE_EXIT_RUNNING) { BeforeExit_lock.wait(); } assert(_before_exit_status == BEFORE_EXIT_DONE, "invalid state"); return; case BEFORE_EXIT_DONE: return; } } // The only difference between this and Win32's _onexit procs is that // this version is invoked before any threads get killed. ExitProc* current = exit_procs; while (current != NULL) { ExitProc* next = current->next(); current->evaluate(); delete current; current = next; } // Hang forever on exit if we're reporting an error. if (ShowMessageBoxOnError && is_error_reported()) { os::infinite_sleep(); } // Terminate watcher thread - must before disenrolling any periodic task WatcherThread::stop(); if (UseITR) { InstructionTraceThreads::stopAllThreads(); } if (PrintProfileAtExit) { TickProfiler::print(); } // shut down the StatSampler task StatSampler::disengage(); StatSampler::destroy(); // shut down the TimeMillisUpdateTask if (CacheTimeMillis) { TimeMillisUpdateTask::disengage(); } // Print GC/heap related information. if (PrintGCDetails) { Universe::print(); AdaptiveSizePolicyOutput(0); } if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(thread); } // Always call even when there are not JVMTI environments yet, since environments // may be attached late and JVMTI must track phases of VM execution JvmtiExport::post_vm_death(); // Terminate the signal thread // Note: we don't wait until it actually dies. os::terminate_signal_thread(); print_statistics(); if (UseSBA && PrintSBAStatistics) { // Not instead PRODUCT... StackBasedAllocation::print_statistics(NULL); } if ( !UseGenPauselessGC ) { Universe::heap()->print_tracing_info(); } { MutexLocker ml(BeforeExit_lock); _before_exit_status = BEFORE_EXIT_DONE; BeforeExit_lock.notify_all(); } #undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_DONE }