Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 66d5f3ef44faa468127d35da8c9f254bb179d154 Mon Sep 17 00:00:00 2001
- From: Bert Belder <bertbelder@gmail.com>
- Date: Tue, 15 Feb 2011 20:48:05 +0100
- Subject: [PATCH 1/1] Improve V8 support for Cygwin
- Should re-enable crankshaft; can build w/ snapshot again.
- ---
- deps/v8/SConstruct | 7 +-
- deps/v8/src/SConscript | 3 +
- deps/v8/src/platform-cygwin.cc | 287 ++++++++++++++++++++--------------------
- wscript | 2 +-
- 4 files changed, 148 insertions(+), 151 deletions(-)
- diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct
- index b2542fd..f877392 100644
- --- a/deps/v8/SConstruct
- +++ b/deps/v8/SConstruct
- @@ -188,9 +188,6 @@ LIBRARY_FLAGS = {
- 'LIBPATH' : ['/usr/local/lib'],
- 'CCFLAGS': ['-ansi'],
- },
- - 'os:cygwin': {
- - 'WARNINGFLAGS': ['-Werror'],
- - },
- 'os:win32': {
- 'CCFLAGS': ['-DWIN32'],
- 'CXXFLAGS': ['-DWIN32'],
- @@ -672,8 +669,8 @@ def GuessToolchain(os):
- def GuessVisibility(os, toolchain):
- - if os == 'win32' and toolchain == 'gcc':
- - # MinGW can't do it.
- + if (os == 'win32' or os == 'cygwin') and toolchain == 'gcc':
- + # MinGW / Cygwin can't do it.
- return 'default'
- elif os == 'solaris':
- return 'default'
- diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript
- index e85f022..44129f6 100755
- --- a/deps/v8/src/SConscript
- +++ b/deps/v8/src/SConscript
- @@ -266,6 +266,9 @@ D8_FILES = {
- 'os:solaris': [
- 'd8-posix.cc'
- ],
- + 'os:cygwin': [
- + 'd8-posix.cc'
- + ],
- 'os:win32': [
- 'd8-windows.cc'
- ],
- diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc
- index 8c7bde9..46cebff 100644
- --- a/deps/v8/src/platform-cygwin.cc
- +++ b/deps/v8/src/platform-cygwin.cc
- @@ -31,22 +31,17 @@
- #include <pthread.h>
- #include <semaphore.h>
- #include <signal.h>
- +#include <cygwin/signal.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <sys/types.h>
- #include <stdlib.h>
- -// Ubuntu Dapper requires memory pages to be marked as
- -// executable. Otherwise, OS raises an exception when executing code
- -// in that page.
- #include <sys/types.h> // mmap & munmap
- #include <sys/mman.h> // mmap & munmap
- #include <sys/stat.h> // open
- #include <fcntl.h> // open
- #include <unistd.h> // sysconf
- -#ifdef __GLIBC__
- -#include <execinfo.h> // backtrace, backtrace_symbols
- -#endif // def __GLIBC__
- #include <strings.h> // index
- #include <errno.h>
- #include <stdarg.h>
- @@ -60,12 +55,10 @@
- #include "v8threads.h"
- #include "vm-state-inl.h"
- -
- namespace v8 {
- namespace internal {
- -// 0 is never a valid thread id on Linux since tids and pids share a
- -// name space and pid 0 is reserved (see man 2 kill).
- +// 0 is never a valid thread id
- static const pthread_t kNoThread = (pthread_t) 0;
- @@ -86,98 +79,11 @@ void OS::Setup() {
- uint64_t OS::CpuFeaturesImpliedByPlatform() {
- -#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
- - // Here gcc is telling us that we are on an ARM and gcc is assuming that we
- - // have VFP3 instructions. If gcc can assume it then so can we.
- - return 1u << VFP3;
- -#elif CAN_USE_ARMV7_INSTRUCTIONS
- - return 1u << ARMv7;
- -#else
- - return 0; // Linux runs on anything.
- -#endif
- + return 0; // Nothing special about cygwin
- }
- -#ifdef __arm__
- -static bool CPUInfoContainsString(const char * search_string) {
- - const char* file_name = "/proc/cpuinfo";
- - // This is written as a straight shot one pass parser
- - // and not using STL string and ifstream because,
- - // on Linux, it's reading from a (non-mmap-able)
- - // character special device.
- - FILE* f = NULL;
- - const char* what = search_string;
- -
- - if (NULL == (f = fopen(file_name, "r")))
- - return false;
- -
- - int k;
- - while (EOF != (k = fgetc(f))) {
- - if (k == *what) {
- - ++what;
- - while ((*what != '\0') && (*what == fgetc(f))) {
- - ++what;
- - }
- - if (*what == '\0') {
- - fclose(f);
- - return true;
- - } else {
- - what = search_string;
- - }
- - }
- - }
- - fclose(f);
- -
- - // Did not find string in the proc file.
- - return false;
- -}
- -
- -bool OS::ArmCpuHasFeature(CpuFeature feature) {
- - const char* search_string = NULL;
- - // Simple detection of VFP at runtime for Linux.
- - // It is based on /proc/cpuinfo, which reveals hardware configuration
- - // to user-space applications. According to ARM (mid 2009), no similar
- - // facility is universally available on the ARM architectures,
- - // so it's up to individual OSes to provide such.
- - switch (feature) {
- - case VFP3:
- - search_string = "vfpv3";
- - break;
- - case ARMv7:
- - search_string = "ARMv7";
- - break;
- - default:
- - UNREACHABLE();
- - }
- -
- - if (CPUInfoContainsString(search_string)) {
- - return true;
- - }
- -
- - if (feature == VFP3) {
- - // Some old kernels will report vfp not vfpv3. Here we make a last attempt
- - // to detect vfpv3 by checking for vfp *and* neon, since neon is only
- - // available on architectures with vfpv3.
- - // Checking neon on its own is not enough as it is possible to have neon
- - // without vfp.
- - if (CPUInfoContainsString("vfp") && CPUInfoContainsString("neon")) {
- - return true;
- - }
- - }
- -
- - return false;
- -}
- -#endif // def __arm__
- -
- -
- int OS::ActivationFrameAlignment() {
- -#ifdef V8_TARGET_ARCH_ARM
- - // On EABI ARM targets this is required for fp correctness in the
- - // runtime system.
- - return 8;
- -#elif V8_TARGET_ARCH_MIPS
- - return 8;
- -#endif
- // With gcc 4.4 the tree vectorization optimizer can generate code
- // that requires 16 byte alignment such as movdqa on x86.
- return 16;
- @@ -195,7 +101,7 @@ const char* OS::LocalTimezone(double time) {
- time_t tv = static_cast<time_t>(floor(time/msPerSecond));
- struct tm* t = localtime(&tv);
- if (NULL == t) return "";
- - return tzname[0]; // The location of the timezone string on Cywin.
- + return tzname[0]; // The location of the timezone string on Cygwin.
- }
- @@ -205,7 +111,9 @@ double OS::LocalTimeOffset() {
- ASSERT(utc != -1);
- struct tm* loc = localtime(&utc);
- ASSERT(loc != NULL);
- - return static_cast<double>((mktime(loc) - utc) * msPerSecond);
- + // time - localtime includes any daylight savings offset, so subtract it.
- + return static_cast<double>((mktime(loc) - utc) * msPerSecond -
- + (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
- }
- @@ -290,16 +198,7 @@ void OS::Abort() {
- void OS::DebugBreak() {
- -// TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x,
- -// which is the architecture of generated code).
- -#if (defined(__arm__) || defined(__thumb__)) && \
- - defined(CAN_USE_ARMV5_INSTRUCTIONS)
- - asm("bkpt 0");
- -#elif defined(__mips__)
- - asm("break");
- -#else
- asm("int $3");
- -#endif
- }
- @@ -413,39 +312,13 @@ void OS::LogSharedLibraryAddresses() {
- void OS::SignalCodeMovingGC() {
- + // Nothing to do on Cygwin
- }
- int OS::StackWalk(Vector<OS::StackFrame> frames) {
- - // backtrace is a glibc extension.
- -#ifdef __GLIBC__
- - int frames_size = frames.length();
- - ScopedVector<void*> addresses(frames_size);
- -
- - int frames_count = backtrace(addresses.start(), frames_size);
- -
- - char** symbols = backtrace_symbols(addresses.start(), frames_count);
- - if (symbols == NULL) {
- - return kStackWalkError;
- - }
- -
- - for (int i = 0; i < frames_count; i++) {
- - frames[i].address = addresses[i];
- - // Format a text representation of the frame based on the information
- - // available.
- - SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
- - "%s",
- - symbols[i]);
- - // Make sure line termination is in place.
- - frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
- - }
- -
- - free(symbols);
- -
- - return frames_count;
- -#else // ndef __GLIBC__
- + // Not supported on Cygwin
- return 0;
- -#endif // ndef __GLIBC__
- }
- @@ -488,7 +361,7 @@ bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
- bool VirtualMemory::Uncommit(void* address, size_t size) {
- return mmap(address, size, PROT_NONE,
- - MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, // | MAP_FIXED, - Cygwin doesn't have MAP_FIXED
- + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
- kMmapFd, kMmapFdOffset) != MAP_FAILED;
- }
- @@ -713,11 +586,6 @@ bool CygwinSemaphore::Wait(int timeout) {
- while (true) {
- int result = sem_timedwait(&sem_, &ts);
- if (result == 0) return true; // Successfully got semaphore.
- - if (result > 0) {
- - // For glibc prior to 2.3.4 sem_timedwait returns the error instead of -1.
- - errno = result;
- - result = -1;
- - }
- if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
- CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
- }
- @@ -731,25 +599,112 @@ Semaphore* OS::CreateSemaphore(int count) {
- #ifdef ENABLE_LOGGING_AND_PROFILING
- +typedef struct ucontext ucontext_t;
- +
- +static Sampler* active_sampler_ = NULL;
- +static pthread_t vm_tid_ = 0;
- +
- +
- +static pthread_t GetThreadID() {
- + return pthread_self();
- +}
- +
- +
- +static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
- + USE(info);
- + if (signal != SIGPROF) return;
- + if (active_sampler_ == NULL || !active_sampler_->IsActive()) return;
- + if (vm_tid_ != GetThreadID()) return;
- +
- + TickSample sample_obj;
- + TickSample* sample = CpuProfiler::TickSampleEvent();
- + if (sample == NULL) sample = &sample_obj;
- +
- + // Extracting the sample from the context is extremely machine dependent.
- + ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
- + sample->state = Top::current_vm_state();
- +#if V8_HOST_ARCH_IA32
- + sample->pc = reinterpret_cast<Address>(ucontext->eip);
- + sample->sp = reinterpret_cast<Address>(ucontext->esp);
- + sample->fp = reinterpret_cast<Address>(ucontext->ebp);
- +#else
- + UNIMPLEMENTED();
- +#endif
- + active_sampler_->SampleStack(sample);
- + active_sampler_->Tick(sample);
- +}
- +
- +
- class Sampler::PlatformData : public Malloced {
- public:
- + enum SleepInterval {
- + FULL_INTERVAL,
- + HALF_INTERVAL
- + };
- +
- explicit PlatformData(Sampler* sampler)
- : sampler_(sampler),
- - signal_handler_installed_(false) {
- + signal_handler_installed_(false),
- + vm_tgid_(getpid()),
- + signal_sender_launched_(false) {
- }
- void SignalSender() {
- + while (sampler_->IsActive()) {
- + if (rate_limiter_.SuspendIfNecessary()) continue;
- + if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
- + SendProfilingSignal();
- + Sleep(HALF_INTERVAL);
- + RuntimeProfiler::NotifyTick();
- + Sleep(HALF_INTERVAL);
- + } else {
- + if (sampler_->IsProfiling()) SendProfilingSignal();
- + if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
- + Sleep(FULL_INTERVAL);
- + }
- + }
- }
- void SendProfilingSignal() {
- + pthread_kill(vm_tid_, SIGPROF);
- + }
- +
- + void Sleep(SleepInterval full_or_half) {
- + // Convert ms to us and subtract 100 us to compensate delays
- + // occuring during signal delivery.
- + useconds_t interval = sampler_->interval_ * 1000 - 100;
- + if (full_or_half == HALF_INTERVAL) interval /= 2;
- + int result = usleep(interval);
- +#ifdef DEBUG
- + if (result != 0 && errno != EINTR) {
- + fprintf(stderr,
- + "SignalSender usleep error; interval = %u, errno = %d\n",
- + static_cast<int>(interval),
- + errno);
- + ASSERT(result == 0 || errno == EINTR);
- + }
- +#endif
- + USE(result);
- }
- Sampler* sampler_;
- bool signal_handler_installed_;
- struct sigaction old_signal_handler_;
- + int vm_tgid_;
- + bool signal_sender_launched_;
- + pthread_t signal_sender_thread_;
- + RuntimeProfilerRateLimiter rate_limiter_;
- };
- +static void* SenderEntry(void* arg) {
- + Sampler::PlatformData* data =
- + reinterpret_cast<Sampler::PlatformData*>(arg);
- + data->SignalSender();
- + return 0;
- +}
- +
- +
- Sampler::Sampler(int interval)
- : interval_(interval),
- profiling_(false),
- @@ -760,19 +715,61 @@ Sampler::Sampler(int interval)
- Sampler::~Sampler() {
- + ASSERT(!data_->signal_sender_launched_);
- delete data_;
- }
- void Sampler::Start() {
- - active_ = true;
- + // There can only be one active sampler at the time on POSIX
- + // platforms.
- + ASSERT(!IsActive());
- + vm_tid_ = pthread_self();
- +
- + // Request profiling signals.
- + struct sigaction sa;
- + sa.sa_sigaction = ProfilerSignalHandler;
- + sigemptyset(&sa.sa_mask);
- + sa.sa_flags = SA_RESTART | SA_SIGINFO;
- + if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
- + data_->signal_handler_installed_ = true;
- +
- + // Start a thread that sends SIGPROF signal to VM thread.
- + // Sending the signal ourselves instead of relying on itimer provides
- + // much better accuracy.
- + SetActive(true);
- + if (pthread_create(
- + &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
- + data_->signal_sender_launched_ = true;
- + }
- +
- + // Set this sampler as the active sampler.
- + active_sampler_ = this;
- }
- void Sampler::Stop() {
- - active_ = false;
- + SetActive(false);
- +
- + // Wait for signal sender termination (it will exit after setting
- + // active_ to false).
- + if (data_->signal_sender_launched_) {
- + Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
- + pthread_join(data_->signal_sender_thread_, NULL);
- + data_->signal_sender_launched_ = false;
- + }
- +
- + // Restore old signal handler
- + if (data_->signal_handler_installed_) {
- + sigaction(SIGPROF, &data_->old_signal_handler_, 0);
- + data_->signal_handler_installed_ = false;
- + }
- +
- + // This sampler is no longer the active sampler.
- + active_sampler_ = NULL;
- }
- +
- #endif // ENABLE_LOGGING_AND_PROFILING
- } } // namespace v8::internal
- diff --git a/wscript b/wscript
- index a19d89d..53d1e50 100644
- --- a/wscript
- +++ b/wscript
- @@ -196,7 +196,7 @@ def configure(conf):
- conf.env["USE_DEBUG"] = o.debug
- # Snapshot building does noet seem to work on cygwin and mingw32
- - conf.env["SNAPSHOT_V8"] = not o.without_snapshot and not sys.platform.startswith("cygwin") and not sys.platform.startswith("win32")
- + conf.env["SNAPSHOT_V8"] = not o.without_snapshot and not sys.platform.startswith("win32")
- if sys.platform.startswith("sunos"):
- conf.env["SNAPSHOT_V8"] = False
- conf.env["USE_PROFILING"] = o.profile
- --
- 1.7.2.3
Add Comment
Please, Sign In to add comment