Guest User

Untitled

a guest
Jul 22nd, 2018
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.01 KB | None | 0 0
  1. From 66d5f3ef44faa468127d35da8c9f254bb179d154 Mon Sep 17 00:00:00 2001
  2. From: Bert Belder <bertbelder@gmail.com>
  3. Date: Tue, 15 Feb 2011 20:48:05 +0100
  4. Subject: [PATCH 1/1] Improve V8 support for Cygwin
  5.  
  6. Should re-enable crankshaft; can build w/ snapshot again.
  7. ---
  8. deps/v8/SConstruct | 7 +-
  9. deps/v8/src/SConscript | 3 +
  10. deps/v8/src/platform-cygwin.cc | 287 ++++++++++++++++++++--------------------
  11. wscript | 2 +-
  12. 4 files changed, 148 insertions(+), 151 deletions(-)
  13.  
  14. diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct
  15. index b2542fd..f877392 100644
  16. --- a/deps/v8/SConstruct
  17. +++ b/deps/v8/SConstruct
  18. @@ -188,9 +188,6 @@ LIBRARY_FLAGS = {
  19. 'LIBPATH' : ['/usr/local/lib'],
  20. 'CCFLAGS': ['-ansi'],
  21. },
  22. - 'os:cygwin': {
  23. - 'WARNINGFLAGS': ['-Werror'],
  24. - },
  25. 'os:win32': {
  26. 'CCFLAGS': ['-DWIN32'],
  27. 'CXXFLAGS': ['-DWIN32'],
  28. @@ -672,8 +669,8 @@ def GuessToolchain(os):
  29.  
  30.  
  31. def GuessVisibility(os, toolchain):
  32. - if os == 'win32' and toolchain == 'gcc':
  33. - # MinGW can't do it.
  34. + if (os == 'win32' or os == 'cygwin') and toolchain == 'gcc':
  35. + # MinGW / Cygwin can't do it.
  36. return 'default'
  37. elif os == 'solaris':
  38. return 'default'
  39. diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript
  40. index e85f022..44129f6 100755
  41. --- a/deps/v8/src/SConscript
  42. +++ b/deps/v8/src/SConscript
  43. @@ -266,6 +266,9 @@ D8_FILES = {
  44. 'os:solaris': [
  45. 'd8-posix.cc'
  46. ],
  47. + 'os:cygwin': [
  48. + 'd8-posix.cc'
  49. + ],
  50. 'os:win32': [
  51. 'd8-windows.cc'
  52. ],
  53. diff --git a/deps/v8/src/platform-cygwin.cc b/deps/v8/src/platform-cygwin.cc
  54. index 8c7bde9..46cebff 100644
  55. --- a/deps/v8/src/platform-cygwin.cc
  56. +++ b/deps/v8/src/platform-cygwin.cc
  57. @@ -31,22 +31,17 @@
  58. #include <pthread.h>
  59. #include <semaphore.h>
  60. #include <signal.h>
  61. +#include <cygwin/signal.h>
  62. #include <sys/time.h>
  63. #include <sys/resource.h>
  64. #include <sys/types.h>
  65. #include <stdlib.h>
  66.  
  67. -// Ubuntu Dapper requires memory pages to be marked as
  68. -// executable. Otherwise, OS raises an exception when executing code
  69. -// in that page.
  70. #include <sys/types.h> // mmap & munmap
  71. #include <sys/mman.h> // mmap & munmap
  72. #include <sys/stat.h> // open
  73. #include <fcntl.h> // open
  74. #include <unistd.h> // sysconf
  75. -#ifdef __GLIBC__
  76. -#include <execinfo.h> // backtrace, backtrace_symbols
  77. -#endif // def __GLIBC__
  78. #include <strings.h> // index
  79. #include <errno.h>
  80. #include <stdarg.h>
  81. @@ -60,12 +55,10 @@
  82. #include "v8threads.h"
  83. #include "vm-state-inl.h"
  84.  
  85. -
  86. namespace v8 {
  87. namespace internal {
  88.  
  89. -// 0 is never a valid thread id on Linux since tids and pids share a
  90. -// name space and pid 0 is reserved (see man 2 kill).
  91. +// 0 is never a valid thread id
  92. static const pthread_t kNoThread = (pthread_t) 0;
  93.  
  94.  
  95. @@ -86,98 +79,11 @@ void OS::Setup() {
  96.  
  97.  
  98. uint64_t OS::CpuFeaturesImpliedByPlatform() {
  99. -#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
  100. - // Here gcc is telling us that we are on an ARM and gcc is assuming that we
  101. - // have VFP3 instructions. If gcc can assume it then so can we.
  102. - return 1u << VFP3;
  103. -#elif CAN_USE_ARMV7_INSTRUCTIONS
  104. - return 1u << ARMv7;
  105. -#else
  106. - return 0; // Linux runs on anything.
  107. -#endif
  108. + return 0; // Nothing special about cygwin
  109. }
  110.  
  111.  
  112. -#ifdef __arm__
  113. -static bool CPUInfoContainsString(const char * search_string) {
  114. - const char* file_name = "/proc/cpuinfo";
  115. - // This is written as a straight shot one pass parser
  116. - // and not using STL string and ifstream because,
  117. - // on Linux, it's reading from a (non-mmap-able)
  118. - // character special device.
  119. - FILE* f = NULL;
  120. - const char* what = search_string;
  121. -
  122. - if (NULL == (f = fopen(file_name, "r")))
  123. - return false;
  124. -
  125. - int k;
  126. - while (EOF != (k = fgetc(f))) {
  127. - if (k == *what) {
  128. - ++what;
  129. - while ((*what != '\0') && (*what == fgetc(f))) {
  130. - ++what;
  131. - }
  132. - if (*what == '\0') {
  133. - fclose(f);
  134. - return true;
  135. - } else {
  136. - what = search_string;
  137. - }
  138. - }
  139. - }
  140. - fclose(f);
  141. -
  142. - // Did not find string in the proc file.
  143. - return false;
  144. -}
  145. -
  146. -bool OS::ArmCpuHasFeature(CpuFeature feature) {
  147. - const char* search_string = NULL;
  148. - // Simple detection of VFP at runtime for Linux.
  149. - // It is based on /proc/cpuinfo, which reveals hardware configuration
  150. - // to user-space applications. According to ARM (mid 2009), no similar
  151. - // facility is universally available on the ARM architectures,
  152. - // so it's up to individual OSes to provide such.
  153. - switch (feature) {
  154. - case VFP3:
  155. - search_string = "vfpv3";
  156. - break;
  157. - case ARMv7:
  158. - search_string = "ARMv7";
  159. - break;
  160. - default:
  161. - UNREACHABLE();
  162. - }
  163. -
  164. - if (CPUInfoContainsString(search_string)) {
  165. - return true;
  166. - }
  167. -
  168. - if (feature == VFP3) {
  169. - // Some old kernels will report vfp not vfpv3. Here we make a last attempt
  170. - // to detect vfpv3 by checking for vfp *and* neon, since neon is only
  171. - // available on architectures with vfpv3.
  172. - // Checking neon on its own is not enough as it is possible to have neon
  173. - // without vfp.
  174. - if (CPUInfoContainsString("vfp") && CPUInfoContainsString("neon")) {
  175. - return true;
  176. - }
  177. - }
  178. -
  179. - return false;
  180. -}
  181. -#endif // def __arm__
  182. -
  183. -
  184. int OS::ActivationFrameAlignment() {
  185. -#ifdef V8_TARGET_ARCH_ARM
  186. - // On EABI ARM targets this is required for fp correctness in the
  187. - // runtime system.
  188. - return 8;
  189. -#elif V8_TARGET_ARCH_MIPS
  190. - return 8;
  191. -#endif
  192. // With gcc 4.4 the tree vectorization optimizer can generate code
  193. // that requires 16 byte alignment such as movdqa on x86.
  194. return 16;
  195. @@ -195,7 +101,7 @@ const char* OS::LocalTimezone(double time) {
  196. time_t tv = static_cast<time_t>(floor(time/msPerSecond));
  197. struct tm* t = localtime(&tv);
  198. if (NULL == t) return "";
  199. - return tzname[0]; // The location of the timezone string on Cywin.
  200. + return tzname[0]; // The location of the timezone string on Cygwin.
  201. }
  202.  
  203.  
  204. @@ -205,7 +111,9 @@ double OS::LocalTimeOffset() {
  205. ASSERT(utc != -1);
  206. struct tm* loc = localtime(&utc);
  207. ASSERT(loc != NULL);
  208. - return static_cast<double>((mktime(loc) - utc) * msPerSecond);
  209. + // time - localtime includes any daylight savings offset, so subtract it.
  210. + return static_cast<double>((mktime(loc) - utc) * msPerSecond -
  211. + (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
  212. }
  213.  
  214.  
  215. @@ -290,16 +198,7 @@ void OS::Abort() {
  216.  
  217.  
  218. void OS::DebugBreak() {
  219. -// TODO(lrn): Introduce processor define for runtime system (!= V8_ARCH_x,
  220. -// which is the architecture of generated code).
  221. -#if (defined(__arm__) || defined(__thumb__)) && \
  222. - defined(CAN_USE_ARMV5_INSTRUCTIONS)
  223. - asm("bkpt 0");
  224. -#elif defined(__mips__)
  225. - asm("break");
  226. -#else
  227. asm("int $3");
  228. -#endif
  229. }
  230.  
  231.  
  232. @@ -413,39 +312,13 @@ void OS::LogSharedLibraryAddresses() {
  233.  
  234.  
  235. void OS::SignalCodeMovingGC() {
  236. + // Nothing to do on Cygwin
  237. }
  238.  
  239.  
  240. int OS::StackWalk(Vector<OS::StackFrame> frames) {
  241. - // backtrace is a glibc extension.
  242. -#ifdef __GLIBC__
  243. - int frames_size = frames.length();
  244. - ScopedVector<void*> addresses(frames_size);
  245. -
  246. - int frames_count = backtrace(addresses.start(), frames_size);
  247. -
  248. - char** symbols = backtrace_symbols(addresses.start(), frames_count);
  249. - if (symbols == NULL) {
  250. - return kStackWalkError;
  251. - }
  252. -
  253. - for (int i = 0; i < frames_count; i++) {
  254. - frames[i].address = addresses[i];
  255. - // Format a text representation of the frame based on the information
  256. - // available.
  257. - SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen),
  258. - "%s",
  259. - symbols[i]);
  260. - // Make sure line termination is in place.
  261. - frames[i].text[kStackWalkMaxTextLen - 1] = '\0';
  262. - }
  263. -
  264. - free(symbols);
  265. -
  266. - return frames_count;
  267. -#else // ndef __GLIBC__
  268. + // Not supported on Cygwin
  269. return 0;
  270. -#endif // ndef __GLIBC__
  271. }
  272.  
  273.  
  274. @@ -488,7 +361,7 @@ bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
  275.  
  276. bool VirtualMemory::Uncommit(void* address, size_t size) {
  277. return mmap(address, size, PROT_NONE,
  278. - MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, // | MAP_FIXED, - Cygwin doesn't have MAP_FIXED
  279. + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
  280. kMmapFd, kMmapFdOffset) != MAP_FAILED;
  281. }
  282.  
  283. @@ -713,11 +586,6 @@ bool CygwinSemaphore::Wait(int timeout) {
  284. while (true) {
  285. int result = sem_timedwait(&sem_, &ts);
  286. if (result == 0) return true; // Successfully got semaphore.
  287. - if (result > 0) {
  288. - // For glibc prior to 2.3.4 sem_timedwait returns the error instead of -1.
  289. - errno = result;
  290. - result = -1;
  291. - }
  292. if (result == -1 && errno == ETIMEDOUT) return false; // Timeout.
  293. CHECK(result == -1 && errno == EINTR); // Signal caused spurious wakeup.
  294. }
  295. @@ -731,25 +599,112 @@ Semaphore* OS::CreateSemaphore(int count) {
  296.  
  297. #ifdef ENABLE_LOGGING_AND_PROFILING
  298.  
  299. +typedef struct ucontext ucontext_t;
  300. +
  301. +static Sampler* active_sampler_ = NULL;
  302. +static pthread_t vm_tid_ = 0;
  303. +
  304. +
  305. +static pthread_t GetThreadID() {
  306. + return pthread_self();
  307. +}
  308. +
  309. +
  310. +static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
  311. + USE(info);
  312. + if (signal != SIGPROF) return;
  313. + if (active_sampler_ == NULL || !active_sampler_->IsActive()) return;
  314. + if (vm_tid_ != GetThreadID()) return;
  315. +
  316. + TickSample sample_obj;
  317. + TickSample* sample = CpuProfiler::TickSampleEvent();
  318. + if (sample == NULL) sample = &sample_obj;
  319. +
  320. + // Extracting the sample from the context is extremely machine dependent.
  321. + ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
  322. + sample->state = Top::current_vm_state();
  323. +#if V8_HOST_ARCH_IA32
  324. + sample->pc = reinterpret_cast<Address>(ucontext->eip);
  325. + sample->sp = reinterpret_cast<Address>(ucontext->esp);
  326. + sample->fp = reinterpret_cast<Address>(ucontext->ebp);
  327. +#else
  328. + UNIMPLEMENTED();
  329. +#endif
  330. + active_sampler_->SampleStack(sample);
  331. + active_sampler_->Tick(sample);
  332. +}
  333. +
  334. +
  335. class Sampler::PlatformData : public Malloced {
  336. public:
  337. + enum SleepInterval {
  338. + FULL_INTERVAL,
  339. + HALF_INTERVAL
  340. + };
  341. +
  342. explicit PlatformData(Sampler* sampler)
  343. : sampler_(sampler),
  344. - signal_handler_installed_(false) {
  345. + signal_handler_installed_(false),
  346. + vm_tgid_(getpid()),
  347. + signal_sender_launched_(false) {
  348. }
  349.  
  350. void SignalSender() {
  351. + while (sampler_->IsActive()) {
  352. + if (rate_limiter_.SuspendIfNecessary()) continue;
  353. + if (sampler_->IsProfiling() && RuntimeProfiler::IsEnabled()) {
  354. + SendProfilingSignal();
  355. + Sleep(HALF_INTERVAL);
  356. + RuntimeProfiler::NotifyTick();
  357. + Sleep(HALF_INTERVAL);
  358. + } else {
  359. + if (sampler_->IsProfiling()) SendProfilingSignal();
  360. + if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
  361. + Sleep(FULL_INTERVAL);
  362. + }
  363. + }
  364. }
  365.  
  366. void SendProfilingSignal() {
  367. + pthread_kill(vm_tid_, SIGPROF);
  368. + }
  369. +
  370. + void Sleep(SleepInterval full_or_half) {
  371. + // Convert ms to us and subtract 100 us to compensate delays
  372. + // occuring during signal delivery.
  373. + useconds_t interval = sampler_->interval_ * 1000 - 100;
  374. + if (full_or_half == HALF_INTERVAL) interval /= 2;
  375. + int result = usleep(interval);
  376. +#ifdef DEBUG
  377. + if (result != 0 && errno != EINTR) {
  378. + fprintf(stderr,
  379. + "SignalSender usleep error; interval = %u, errno = %d\n",
  380. + static_cast<int>(interval),
  381. + errno);
  382. + ASSERT(result == 0 || errno == EINTR);
  383. + }
  384. +#endif
  385. + USE(result);
  386. }
  387.  
  388. Sampler* sampler_;
  389. bool signal_handler_installed_;
  390. struct sigaction old_signal_handler_;
  391. + int vm_tgid_;
  392. + bool signal_sender_launched_;
  393. + pthread_t signal_sender_thread_;
  394. + RuntimeProfilerRateLimiter rate_limiter_;
  395. };
  396.  
  397.  
  398. +static void* SenderEntry(void* arg) {
  399. + Sampler::PlatformData* data =
  400. + reinterpret_cast<Sampler::PlatformData*>(arg);
  401. + data->SignalSender();
  402. + return 0;
  403. +}
  404. +
  405. +
  406. Sampler::Sampler(int interval)
  407. : interval_(interval),
  408. profiling_(false),
  409. @@ -760,19 +715,61 @@ Sampler::Sampler(int interval)
  410.  
  411.  
  412. Sampler::~Sampler() {
  413. + ASSERT(!data_->signal_sender_launched_);
  414. delete data_;
  415. }
  416.  
  417.  
  418. void Sampler::Start() {
  419. - active_ = true;
  420. + // There can only be one active sampler at the time on POSIX
  421. + // platforms.
  422. + ASSERT(!IsActive());
  423. + vm_tid_ = pthread_self();
  424. +
  425. + // Request profiling signals.
  426. + struct sigaction sa;
  427. + sa.sa_sigaction = ProfilerSignalHandler;
  428. + sigemptyset(&sa.sa_mask);
  429. + sa.sa_flags = SA_RESTART | SA_SIGINFO;
  430. + if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
  431. + data_->signal_handler_installed_ = true;
  432. +
  433. + // Start a thread that sends SIGPROF signal to VM thread.
  434. + // Sending the signal ourselves instead of relying on itimer provides
  435. + // much better accuracy.
  436. + SetActive(true);
  437. + if (pthread_create(
  438. + &data_->signal_sender_thread_, NULL, SenderEntry, data_) == 0) {
  439. + data_->signal_sender_launched_ = true;
  440. + }
  441. +
  442. + // Set this sampler as the active sampler.
  443. + active_sampler_ = this;
  444. }
  445.  
  446.  
  447. void Sampler::Stop() {
  448. - active_ = false;
  449. + SetActive(false);
  450. +
  451. + // Wait for signal sender termination (it will exit after setting
  452. + // active_ to false).
  453. + if (data_->signal_sender_launched_) {
  454. + Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
  455. + pthread_join(data_->signal_sender_thread_, NULL);
  456. + data_->signal_sender_launched_ = false;
  457. + }
  458. +
  459. + // Restore old signal handler
  460. + if (data_->signal_handler_installed_) {
  461. + sigaction(SIGPROF, &data_->old_signal_handler_, 0);
  462. + data_->signal_handler_installed_ = false;
  463. + }
  464. +
  465. + // This sampler is no longer the active sampler.
  466. + active_sampler_ = NULL;
  467. }
  468.  
  469. +
  470. #endif // ENABLE_LOGGING_AND_PROFILING
  471.  
  472. } } // namespace v8::internal
  473. diff --git a/wscript b/wscript
  474. index a19d89d..53d1e50 100644
  475. --- a/wscript
  476. +++ b/wscript
  477. @@ -196,7 +196,7 @@ def configure(conf):
  478.  
  479. conf.env["USE_DEBUG"] = o.debug
  480. # Snapshot building does noet seem to work on cygwin and mingw32
  481. - conf.env["SNAPSHOT_V8"] = not o.without_snapshot and not sys.platform.startswith("cygwin") and not sys.platform.startswith("win32")
  482. + conf.env["SNAPSHOT_V8"] = not o.without_snapshot and not sys.platform.startswith("win32")
  483. if sys.platform.startswith("sunos"):
  484. conf.env["SNAPSHOT_V8"] = False
  485. conf.env["USE_PROFILING"] = o.profile
  486. --
  487. 1.7.2.3
Add Comment
Please, Sign In to add comment