Mercurial > hg > truffle
diff src/os/linux/vm/os_linux.cpp @ 14518:d8041d695d19
Merged with jdk9/dev/hotspot changeset 3812c088b945
author | twisti |
---|---|
date | Tue, 11 Mar 2014 18:45:59 -0700 |
parents | 096c224171c4 bb9356ec5967 |
children | b51e29501f30 4ca6dc0799b6 |
line wrap: on
line diff
--- a/src/os/linux/vm/os_linux.cpp Wed Mar 12 00:00:05 2014 +0100 +++ b/src/os/linux/vm/os_linux.cpp Tue Mar 11 18:45:59 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -139,7 +139,7 @@ // For diagnostics to print a message once. see run_periodic_checks static sigset_t check_signal_done; -static bool check_signals = true;; +static bool check_signals = true; static pid_t _initial_pid = 0; @@ -257,8 +257,10 @@ static char cpu_arch[] = "amd64"; #elif defined(ARM) static char cpu_arch[] = "arm"; -#elif defined(PPC) +#elif defined(PPC32) static char cpu_arch[] = "ppc"; +#elif defined(PPC64) +static char cpu_arch[] = "ppc64"; #elif defined(SPARC) # ifdef _LP64 static char cpu_arch[] = "sparcv9"; @@ -530,6 +532,9 @@ sigaddset(&unblocked_sigs, SIGSEGV); sigaddset(&unblocked_sigs, SIGBUS); sigaddset(&unblocked_sigs, SIGFPE); +#if defined(PPC64) + sigaddset(&unblocked_sigs, SIGTRAP); +#endif sigaddset(&unblocked_sigs, SR_signum); if (!ReduceSignalUsage) { @@ -1451,7 +1456,7 @@ } jlong os::javaTimeNanos() { - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { struct timespec tp; int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); @@ -1467,7 +1472,7 @@ } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { info_ptr->max_value = ALL_64_BITS; // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past @@ -2104,6 +2109,9 @@ return res; } +void* os::get_default_process_handle() { + return (void*)::dlopen(NULL, RTLD_LAZY); +} static bool _print_ascii_file(const char* filename, outputStream* st) { int fd = ::open(filename, O_RDONLY); @@ -2257,58 +2265,12 @@ st->cr(); } -// Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific -// but they're the same for all the linux arch that we support -// and they're the same for solaris but there's no common place to put this. -const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", - "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", - "ILL_COPROC", "ILL_BADSTK" }; - -const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", - "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", - "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" }; - -const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; - -const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; - void os::print_siginfo(outputStream* st, void* siginfo) { - st->print("siginfo:"); - - const int buflen = 100; - char buf[buflen]; - siginfo_t *si = (siginfo_t*)siginfo; - st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); - if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) { - st->print("si_errno=%s", buf); - } else { - st->print("si_errno=%d", si->si_errno); - } - const int c = si->si_code; - assert(c > 0, "unexpected si_code"); - switch (si->si_signo) { - case SIGILL: - st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); - st->print(", si_addr=" PTR_FORMAT, si->si_addr); - break; - case SIGFPE: - st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); - st->print(", si_addr=" PTR_FORMAT, si->si_addr); - break; - case SIGSEGV: - st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); - st->print(", si_addr=" PTR_FORMAT, si->si_addr); - break; - case SIGBUS: - st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); - st->print(", si_addr=" PTR_FORMAT, si->si_addr); - break; - default: - st->print(", si_code=%d", si->si_code); - // no si_addr - } - - if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && + const siginfo_t* si = (const siginfo_t*)siginfo; + + os::Posix::print_siginfo_brief(st, si); + + if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && UseSharedSpaces) { FileMapInfo* mapinfo = FileMapInfo::current_info(); if (mapinfo->is_in_shared_space(si->si_addr)) { @@ -2338,6 +2300,9 @@ print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen); print_signal_handler(st, BREAK_SIGNAL, buf, buflen); +#if defined(PPC64) + print_signal_handler(st, SIGTRAP, buf, buflen); +#endif } static char saved_jvm_path[MAXPATHLEN] = {0}; @@ -2368,13 +2333,14 @@ if (rp == NULL) return; - if (Arguments::created_by_gamma_launcher()) { - // Support for the gamma launcher. Typical value for buf is - // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at - // the right place in the string, then assume we are installed in a JDK and - // we're done. Otherwise, check for a JAVA_HOME environment variable and fix - // up the path so it looks like libjvm.so is installed there (append a - // fake suffix hotspot/libjvm.so). + if (Arguments::sun_java_launcher_is_altjvm()) { + // Support for the java launcher's '-XXaltjvm=<path>' option. Typical + // value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". + // If "/jre/lib/" appears at the right place in the string, then + // assume we are installed in a JDK and we're done. Otherwise, check + // for a JAVA_HOME environment variable and fix up the path so it + // looks like libjvm.so is installed there (append a fake suffix + // hotspot/libjvm.so). const char *p = buf + strlen(buf) - 1; for (int count = 0; p > buf && count < 5; ++count) { for (--p; p > buf && *p != '/'; --p) @@ -2996,7 +2962,9 @@ unsigned char vec[1]; unsigned imin = 1, imax = pages + 1, imid; - int mincore_return_value; + int mincore_return_value = 0; + + assert(imin <= imax, "Unexpected page size"); while (imin < imax) { imid = (imax + imin) / 2; @@ -3789,88 +3757,33 @@ return ::read(fd, buf, nBytes); } -// TODO-FIXME: reconcile Solaris' os::sleep with the linux variation. -// Solaris uses poll(), linux uses park(). -// Poll() is likely a better choice, assuming that Thread.interrupt() -// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with -// SIGSEGV, see 4355769. - -int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - - ParkEvent * const slp = thread->_SleepEvent ; - slp->reset() ; - OrderAccess::fence() ; - - if (interruptible) { - jlong prevtime = javaTimeNanos(); - - for (;;) { - if (os::is_interrupted(thread, true)) { - return OS_INTRPT; - } - - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Linux::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) { - return OS_OK; - } - - prevtime = newtime; - - { - assert(thread->is_Java_thread(), "sanity check"); - JavaThread *jt = (JavaThread *) thread; - ThreadBlockInVM tbivm(jt); - OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); - - jt->set_suspend_equivalent(); - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - - slp->park(millis); - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); - } - } - } else { - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); - jlong prevtime = javaTimeNanos(); - - for (;;) { - // It'd be nice to avoid the back-to-back javaTimeNanos() calls on - // the 1st iteration ... - jlong newtime = javaTimeNanos(); - - if (newtime - prevtime < 0) { - // time moving backwards, should only happen if no monotonic clock - // not a guarantee() because JVM should not abort on kernel/glibc bugs - assert(!Linux::supports_monotonic_clock(), "time moving backwards"); - } else { - millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; - } - - if(millis <= 0) break ; - - prevtime = newtime; - slp->park(millis); - } - return OS_OK ; - } -} - -int os::naked_sleep() { - // %% make the sleep time an integer flag. for now use 1 millisec. - return os::sleep(Thread::current(), 1, false); +// +// Short sleep, direct OS call. +// +// Note: certain versions of Linux CFS scheduler (since 2.6.23) do not guarantee +// sched_yield(2) will actually give up the CPU: +// +// * Alone on this pariticular CPU, keeps running. +// * Before the introduction of "skip_buddy" with "compat_yield" disabled +// (pre 2.6.39). +// +// So calling this with 0 is an alternative. +// +void os::naked_short_sleep(jlong ms) { + struct timespec req; + + assert(ms < 1000, "Un-interruptable sleep, short time use only"); + req.tv_sec = 0; + if (ms > 0) { + req.tv_nsec = (ms % 1000) * 1000000; + } + else { + req.tv_nsec = 1; + } + + nanosleep(&req, NULL); + + return; } // Sleep forever; naked call to OS-specific sleep; use with CAUTION @@ -4196,50 +4109,6 @@ guarantee(osthread->sr.is_running(), "Must be running!"); } -//////////////////////////////////////////////////////////////////////////////// -// interrupt support - -void os::interrupt(Thread* thread) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - if (!osthread->interrupted()) { - osthread->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); - ParkEvent * const slp = thread->_SleepEvent ; - if (slp != NULL) slp->unpark() ; - } - - // For JSR166. Unpark even if interrupt status already was set - if (thread->is_Java_thread()) - ((JavaThread*)thread)->parker()->unpark(); - - ParkEvent * ev = thread->_ParkEvent ; - if (ev != NULL) ev->unpark() ; - -} - -bool os::is_interrupted(Thread* thread, bool clear_interrupted) { - assert(Thread::current() == thread || Threads_lock->owned_by_self(), - "possibility of dangling Thread pointer"); - - OSThread* osthread = thread->osthread(); - - bool interrupted = osthread->interrupted(); - - if (interrupted && clear_interrupted) { - osthread->set_interrupted(false); - // consider thread->_SleepEvent->reset() ... optional optimization - } - - return interrupted; -} - /////////////////////////////////////////////////////////////////////////////////// // signal handling (except suspend/resume) @@ -4467,6 +4336,9 @@ set_signal_handler(SIGBUS, true); set_signal_handler(SIGILL, true); set_signal_handler(SIGFPE, true); +#if defined(PPC64) + set_signal_handler(SIGTRAP, true); +#endif set_signal_handler(SIGXFSZ, true); if (libjsig_is_loaded) { @@ -4560,7 +4432,8 @@ st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); } - st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); + st->print(", sa_mask[0]="); + os::Posix::print_signal_set_short(st, &sa.sa_mask); address rh = VMError::get_resetted_sighandler(sig); // May be, handler was resetted by VMError? @@ -4569,7 +4442,8 @@ sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK; } - st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); + st->print(", sa_flags="); + os::Posix::print_sa_flags(st, sa.sa_flags); // Check: is it our handler? if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) || @@ -4607,7 +4481,9 @@ DO_SIGNAL_CHECK(SIGBUS); DO_SIGNAL_CHECK(SIGPIPE); DO_SIGNAL_CHECK(SIGXFSZ); - +#if defined(PPC64) + DO_SIGNAL_CHECK(SIGTRAP); +#endif // ReduceSignalUsage allows the user to override these handlers // see comments at the very top and jvm_solaris.h @@ -4757,7 +4633,7 @@ fatal(err_msg("pthread_condattr_init: %s", strerror(status))); } // Only set the clock if CLOCK_MONOTONIC is available - if (Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { if (status == EINVAL) { warning("Unable to use monotonic clock with relative timed-waits" \ @@ -4929,7 +4805,7 @@ // the future if the appropriate cleanup code can be added to the // VM_Exit VMOperation's doit method. if (atexit(perfMemory_exit_helper) != 0) { - warning("os::init2 atexit(perfMemory_exit_helper) failed"); + warning("os::init_2 atexit(perfMemory_exit_helper) failed"); } } @@ -4940,8 +4816,7 @@ } // this is called at the end of vm_initialization -void os::init_3(void) -{ +void os::init_3(void) { #ifdef JAVASE_EMBEDDED // Start the MemNotifyThread if (LowMemoryProtection) { @@ -5588,7 +5463,7 @@ seconds = 50000000; } - if (os::Linux::supports_monotonic_clock()) { + if (os::supports_monotonic_clock()) { struct timespec now; int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); assert_status(status == 0, status, "clock_gettime"); @@ -5805,7 +5680,7 @@ assert (time > 0, "convertTime"); time_t max_secs = 0; - if (!os::Linux::supports_monotonic_clock() || isAbsolute) { + if (!os::supports_monotonic_clock() || isAbsolute) { struct timeval now; int status = gettimeofday(&now, NULL); assert(status == 0, "gettimeofday");