Your message dated Tue, 06 May 2014 21:22:48 +0000
with message-id <e1whmp6-0004q1...@franck.debian.org>
and subject line Bug#747246: fixed in libv8-3.14 3.14.5.8-8
has caused the Debian Bug report #747246,
regarding libv8-3.14: Add support for hurd-i386
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
747246: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=747246
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Source: libv8-3.14
Version: 3.14.5.8-7
Severity: important
Tags: patch
User: debian-h...@lists.debian.org
Usertags: hurd

Hi,

Currently libv8-3.14 fails to build from source since libv8-3.14 is not
yet ported to GNU/Hurd. In fact it is not even in the architecture
list, please add hurd-i386 to it. Attached are three patches, the last
two applicable to submit upstream:

- rules.patch: Add support for hurd-i386 in the architecture list
- 0015_v8.patch: tools/gyp/v8.gyp: add platform-gnu.cc
- 0016_gnu.patch: src/platform-gnu.cc: new file with platform specific code

The test suite reports all local tests pass :)

Thanks!




--- a/tools/gyp/v8.gyp.orig	2014-05-01 14:21:58.000000000 +0200
+++ b/tools/gyp/v8.gyp	2014-05-01 17:22:42.000000000 +0200
@@ -723,6 +723,17 @@
                 '../../src/platform-posix.cc'
               ]},
             ],
+            ['OS=="hurd"', {
+                'link_settings': {
+                  'libraries': [
+                    '-lpthread',
+                ]},
+                'sources': [
+                  '../../src/platform-gnu.cc',
+                  '../../src/platform-posix.cc'
+                ],
+              }
+            ],
             ['OS=="win"', {
               'sources': [
                 '../../src/platform-win32.cc',
--- /dev/null
+++ b/src/platform-gnu.cc
@@ -0,0 +1,890 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Platform specific code for GNU/Hurd goes here. For the POSIX comaptible parts
+// the implementation is in platform-posix.cc.
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <stdlib.h>
+
+#include <sys/types.h>  // mmap & munmap
+#include <sys/mman.h>   // mmap & munmap
+#include <sys/stat.h>   // open
+#include <sys/fcntl.h>  // open
+#include <unistd.h>     // getpagesize
+// If you don't have execinfo.h then you need devel/libexecinfo from ports.
+#include <execinfo.h>   // backtrace, backtrace_symbols
+#include <strings.h>    // index
+#include <errno.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#undef MAP_TYPE
+
+#include "v8.h"
+#include "v8threads.h"
+
+#include "platform-posix.h"
+#include "platform.h"
+#include "vm-state-inl.h"
+
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
+namespace v8 {
+namespace internal {
+
+// 0 is never a valid thread id on GNU/Hurd
+static const pthread_t kNoThread = (pthread_t) 0;
+
+
+double ceiling(double x) {
+  return ceil(x);
+}
+
+
+static Mutex* limit_mutex = NULL;
+
+
+void OS::PostSetUp() {
+  POSIXPostSetUp();
+}
+
+
+void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
+  __asm__ __volatile__("" : : : "memory");
+  *ptr = value;
+}
+
+
+uint64_t OS::CpuFeaturesImpliedByPlatform() {
+  return 0;  // GNU/Hurd runs on anything.
+}
+
+
+int OS::ActivationFrameAlignment() {
+  // 16 byte alignment on GNU/Hurd
+  return 16;
+}
+
+
+const char* OS::LocalTimezone(double time) {
+  if (isnan(time)) return "";
+  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
+  struct tm* t = localtime(&tv);
+  if (NULL == t) return "";
+  return t->tm_zone;
+}
+
+
+double OS::LocalTimeOffset() {
+  time_t tv = time(NULL);
+  struct tm* t = localtime(&tv);
+  // tm_gmtoff includes any daylight savings offset, so subtract it.
+  return static_cast<double>(t->tm_gmtoff * msPerSecond -
+                             (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
+}
+
+
+// We keep the lowest and highest addresses mapped as a quick way of
+// determining that pointers are outside the heap (used mostly in assertions
+// and verification).  The estimate is conservative, i.e., not all addresses in
+// 'allocated' space are actually allocated to our heap.  The range is
+// [lowest, highest), inclusive on the low and and exclusive on the high end.
+static void* lowest_ever_allocated = reinterpret_cast<void*>(-1);
+static void* highest_ever_allocated = reinterpret_cast<void*>(0);
+
+
+static void UpdateAllocatedSpaceLimits(void* address, int size) {
+  ASSERT(limit_mutex != NULL);
+  ScopedLock lock(limit_mutex);
+
+  lowest_ever_allocated = Min(lowest_ever_allocated, address);
+  highest_ever_allocated =
+      Max(highest_ever_allocated,
+          reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size));
+}
+
+
+bool OS::IsOutsideAllocatedSpace(void* address) {
+  return address < lowest_ever_allocated || address >= highest_ever_allocated;
+}
+
+
+size_t OS::AllocateAlignment() {
+  return getpagesize();
+}
+
+
+void* OS::Allocate(const size_t requested,
+                   size_t* allocated,
+                   bool executable) {
+  const size_t msize = RoundUp(requested, getpagesize());
+  int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0);
+  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
+
+  if (mbase == MAP_FAILED) {
+    LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed"));
+    return NULL;
+  }
+  *allocated = msize;
+  UpdateAllocatedSpaceLimits(mbase, msize);
+  return mbase;
+}
+
+
+void OS::Free(void* buf, const size_t length) {
+  // TODO(1240712): munmap has a return value which is ignored here.
+  int result = munmap(buf, length);
+  USE(result);
+  ASSERT(result == 0);
+}
+
+
+void OS::Sleep(int milliseconds) {
+  unsigned int ms = static_cast<unsigned int>(milliseconds);
+  usleep(1000 * ms);
+}
+
+
+void OS::Abort() {
+  // Redirect to std abort to signal abnormal program termination.
+  abort();
+}
+
+
+void OS::DebugBreak() {
+#if (defined(__arm__) || defined(__thumb__))
+# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
+  asm("bkpt 0");
+# endif
+#else
+  asm("int $3");
+#endif
+}
+
+
+class PosixMemoryMappedFile : public OS::MemoryMappedFile {
+ public:
+  PosixMemoryMappedFile(FILE* file, void* memory, int size)
+    : file_(file), memory_(memory), size_(size) { }
+  virtual ~PosixMemoryMappedFile();
+  virtual void* memory() { return memory_; }
+  virtual int size() { return size_; }
+ private:
+  FILE* file_;
+  void* memory_;
+  int size_;
+};
+
+
+OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
+  FILE* file = fopen(name, "r+");
+  if (file == NULL) return NULL;
+
+  fseek(file, 0, SEEK_END);
+  int size = ftell(file);
+
+  void* memory =
+      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
+  return new PosixMemoryMappedFile(file, memory, size);
+}
+
+
+OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
+    void* initial) {
+  FILE* file = fopen(name, "w+");
+  if (file == NULL) return NULL;
+  int result = fwrite(initial, size, 1, file);
+  if (result < 1) {
+    fclose(file);
+    return NULL;
+  }
+  void* memory =
+      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
+  return new PosixMemoryMappedFile(file, memory, size);
+}
+
+
+PosixMemoryMappedFile::~PosixMemoryMappedFile() {
+  if (memory_) munmap(memory_, size_);
+  fclose(file_);
+}
+
+
+static unsigned StringToLong(char* buffer) {
+  return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
+}
+
+
+void OS::LogSharedLibraryAddresses() {
+  static const int MAP_LENGTH = 1024;
+  int fd = open("/proc/self/maps", O_RDONLY);
+  if (fd < 0) return;
+  while (true) {
+    char addr_buffer[11];
+    addr_buffer[0] = '0';
+    addr_buffer[1] = 'x';
+    addr_buffer[10] = 0;
+    int result = read(fd, addr_buffer + 2, 8);
+    if (result < 8) break;
+    unsigned start = StringToLong(addr_buffer);
+    result = read(fd, addr_buffer + 2, 1);
+    if (result < 1) break;
+    if (addr_buffer[2] != '-') break;
+    result = read(fd, addr_buffer + 2, 8);
+    if (result < 8) break;
+    unsigned end = StringToLong(addr_buffer);
+    char buffer[MAP_LENGTH];
+    int bytes_read = -1;
+    do {
+      bytes_read++;
+      if (bytes_read >= MAP_LENGTH - 1)
+        break;
+      result = read(fd, buffer + bytes_read, 1);
+      if (result < 1) break;
+    } while (buffer[bytes_read] != '\n');
+    buffer[bytes_read] = 0;
+    // Ignore mappings that are not executable.
+    if (buffer[3] != 'x') continue;
+    char* start_of_path = index(buffer, '/');
+    // There may be no filename in this line.  Skip to next.
+    if (start_of_path == NULL) continue;
+    buffer[bytes_read] = 0;
+    LOG(i::Isolate::Current(), SharedLibraryEvent(start_of_path, start, end));
+  }
+  close(fd);
+}
+
+
+void OS::SignalCodeMovingGC() {
+}
+
+
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  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;
+}
+
+
+// Constants used for mmap.
+static const int kMmapFd = -1;
+static const int kMmapFdOffset = 0;
+
+VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
+
+VirtualMemory::VirtualMemory(size_t size) {
+  address_ = ReserveRegion(size);
+  size_ = size;
+}
+
+
+VirtualMemory::VirtualMemory(size_t size, size_t alignment)
+    : address_(NULL), size_(0) {
+  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
+  size_t request_size = RoundUp(size + alignment,
+                                static_cast<intptr_t>(OS::AllocateAlignment()));
+  void* reservation = mmap(OS::GetRandomMmapAddr(),
+                           request_size,
+                           PROT_NONE,
+                           MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+                           kMmapFd,
+                           kMmapFdOffset);
+  if (reservation == MAP_FAILED) return;
+
+  Address base = static_cast<Address>(reservation);
+  Address aligned_base = RoundUp(base, alignment);
+  ASSERT_LE(base, aligned_base);
+
+  // Unmap extra memory reserved before and after the desired block.
+  if (aligned_base != base) {
+    size_t prefix_size = static_cast<size_t>(aligned_base - base);
+    OS::Free(base, prefix_size);
+    request_size -= prefix_size;
+  }
+
+  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
+  ASSERT_LE(aligned_size, request_size);
+
+  if (aligned_size != request_size) {
+    size_t suffix_size = request_size - aligned_size;
+    OS::Free(aligned_base + aligned_size, suffix_size);
+    request_size -= suffix_size;
+  }
+
+  ASSERT(aligned_size == request_size);
+
+  address_ = static_cast<void*>(aligned_base);
+  size_ = aligned_size;
+}
+
+
+VirtualMemory::~VirtualMemory() {
+  if (IsReserved()) {
+    bool result = ReleaseRegion(address(), size());
+    ASSERT(result);
+    USE(result);
+  }
+}
+
+
+bool VirtualMemory::IsReserved() {
+  return address_ != NULL;
+}
+
+
+void VirtualMemory::Reset() {
+  address_ = NULL;
+  size_ = 0;
+}
+
+
+bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
+  return CommitRegion(address, size, is_executable);
+}
+
+
+bool VirtualMemory::Uncommit(void* address, size_t size) {
+  return UncommitRegion(address, size);
+}
+
+
+bool VirtualMemory::Guard(void* address) {
+  OS::Guard(address, OS::CommitPageSize());
+  return true;
+}
+
+
+void* VirtualMemory::ReserveRegion(size_t size) {
+  void* result = mmap(OS::GetRandomMmapAddr(),
+                      size,
+                      PROT_NONE,
+                      MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
+                      kMmapFd,
+                      kMmapFdOffset);
+
+  if (result == MAP_FAILED) return NULL;
+
+  return result;
+}
+
+
+bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
+  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+  if (MAP_FAILED == mmap(base,
+                         size,
+                         prot,
+                         MAP_PRIVATE | MAP_ANON | MAP_FIXED,
+                         kMmapFd,
+                         kMmapFdOffset)) {
+    return false;
+  }
+
+  UpdateAllocatedSpaceLimits(base, size);
+  return true;
+}
+
+
+bool VirtualMemory::UncommitRegion(void* base, size_t size) {
+  return mmap(base,
+              size,
+              PROT_NONE,
+              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
+              kMmapFd,
+              kMmapFdOffset) != MAP_FAILED;
+}
+
+
+bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+  return munmap(base, size) == 0;
+}
+
+
+class Thread::PlatformData : public Malloced {
+ public:
+  pthread_t thread_;  // Thread handle for pthread.
+};
+
+
+Thread::Thread(const Options& options)
+    : data_(new PlatformData),
+      stack_size_(options.stack_size()) {
+  set_name(options.name());
+}
+
+
+Thread::~Thread() {
+  delete data_;
+}
+
+
+static void* ThreadEntry(void* arg) {
+  Thread* thread = reinterpret_cast<Thread*>(arg);
+  // This is also initialized by the first argument to pthread_create() but we
+  // don't know which thread will run first (the original thread or the new
+  // one) so we initialize it here too.
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
+  thread->Run();
+  return NULL;
+}
+
+
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
+void Thread::Start() {
+  pthread_attr_t* attr_ptr = NULL;
+  pthread_attr_t attr;
+  if (stack_size_ > 0) {
+    pthread_attr_init(&attr);
+    pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
+    attr_ptr = &attr;
+  }
+  pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+  ASSERT(data_->thread_ != kNoThread);
+}
+
+
+void Thread::Join() {
+  pthread_join(data_->thread_, NULL);
+}
+
+
+Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
+  pthread_key_t key;
+  int result = pthread_key_create(&key, NULL);
+  USE(result);
+  ASSERT(result == 0);
+  return static_cast<LocalStorageKey>(key);
+}
+
+
+void Thread::DeleteThreadLocalKey(LocalStorageKey key) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  int result = pthread_key_delete(pthread_key);
+  USE(result);
+  ASSERT(result == 0);
+}
+
+
+void* Thread::GetThreadLocal(LocalStorageKey key) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  return pthread_getspecific(pthread_key);
+}
+
+
+void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  pthread_setspecific(pthread_key, value);
+}
+
+
+void Thread::YieldCPU() {
+  sched_yield();
+}
+
+
+class GNUMutex : public Mutex {
+ public:
+  GNUMutex() {
+    pthread_mutexattr_t attrs;
+    int result = pthread_mutexattr_init(&attrs);
+    ASSERT(result == 0);
+    result = pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE);
+    ASSERT(result == 0);
+    result = pthread_mutex_init(&mutex_, &attrs);
+    ASSERT(result == 0);
+    USE(result);
+  }
+
+  virtual ~GNUMutex() { pthread_mutex_destroy(&mutex_); }
+
+  virtual int Lock() {
+    int result = pthread_mutex_lock(&mutex_);
+    return result;
+  }
+
+  virtual int Unlock() {
+    int result = pthread_mutex_unlock(&mutex_);
+    return result;
+  }
+
+  virtual bool TryLock() {
+    int result = pthread_mutex_trylock(&mutex_);
+    // Return false if the lock is busy and locking failed.
+    if (result == EBUSY) {
+      return false;
+    }
+    ASSERT(result == 0);  // Verify no other errors.
+    return true;
+  }
+
+ private:
+  pthread_mutex_t mutex_;   // Pthread mutex for POSIX platforms.
+};
+
+
+Mutex* OS::CreateMutex() {
+  return new GNUMutex();
+}
+
+
+class GNUSemaphore : public Semaphore {
+ public:
+  explicit GNUSemaphore(int count) {  sem_init(&sem_, 0, count); }
+  virtual ~GNUSemaphore() { sem_destroy(&sem_); }
+
+  virtual void Wait();
+  virtual bool Wait(int timeout);
+  virtual void Signal() { sem_post(&sem_); }
+ private:
+  sem_t sem_;
+};
+
+
+void GNUSemaphore::Wait() {
+  while (true) {
+    int result = sem_wait(&sem_);
+    if (result == 0) return;  // Successfully got semaphore.
+    CHECK(result == -1 && errno == EINTR);  // Signal caused spurious wakeup.
+  }
+}
+
+
+bool GNUSemaphore::Wait(int timeout) {
+  const long kOneSecondMicros = 1000000;  // NOLINT
+
+  // Split timeout into second and nanosecond parts.
+  struct timeval delta;
+  delta.tv_usec = timeout % kOneSecondMicros;
+  delta.tv_sec = timeout / kOneSecondMicros;
+
+  struct timeval current_time;
+  // Get the current time.
+  if (gettimeofday(&current_time, NULL) == -1) {
+    return false;
+  }
+
+  // Calculate time for end of timeout.
+  struct timeval end_time;
+  timeradd(&current_time, &delta, &end_time);
+
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC(&end_time, &ts);
+  while (true) {
+    int result = sem_timedwait(&sem_, &ts);
+    if (result == 0) return true;  // Successfully got semaphore.
+    if (result == -1 && errno == ETIMEDOUT) return false;  // Timeout.
+    CHECK(result == -1 && errno == EINTR);  // Signal caused spurious wakeup.
+  }
+}
+
+
+Semaphore* OS::CreateSemaphore(int count) {
+  return new GNUSemaphore(count);
+}
+
+
+static pthread_t GetThreadID() {
+  pthread_t thread_id = pthread_self();
+  return thread_id;
+}
+
+
+class Sampler::PlatformData : public Malloced {
+ public:
+  PlatformData() : vm_tid_(GetThreadID()) {}
+
+  pthread_t vm_tid() const { return vm_tid_; }
+
+ private:
+  pthread_t vm_tid_;
+};
+
+
+static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
+  USE(info);
+  if (signal != SIGPROF) return;
+  Isolate* isolate = Isolate::UncheckedCurrent();
+  if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
+    // We require a fully initialized and entered isolate.
+    return;
+  }
+  if (v8::Locker::IsActive() &&
+      !isolate->thread_manager()->IsLockedByCurrentThread()) {
+    return;
+  }
+
+  Sampler* sampler = isolate->logger()->sampler();
+  if (sampler == NULL || !sampler->IsActive()) return;
+
+  TickSample sample_obj;
+  TickSample* sample = CpuProfiler::TickSampleEvent(isolate);
+  if (sample == NULL) sample = &sample_obj;
+
+  // Extracting the sample from the context is extremely machine dependent.
+  ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
+  mcontext_t& mcontext = ucontext->uc_mcontext;
+  sample->state = isolate->current_vm_state();
+#if V8_HOST_ARCH_IA32
+  sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
+  sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
+  sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
+#endif
+  sampler->SampleStack(sample);
+  sampler->Tick(sample);
+}
+
+
+class SignalSender : public Thread {
+ public:
+  enum SleepInterval {
+    HALF_INTERVAL,
+    FULL_INTERVAL
+  };
+
+  static const int kSignalSenderStackSize = 64 * KB;
+
+  explicit SignalSender(int interval)
+      : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
+        interval_(interval) {}
+
+  static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); }
+  static void TearDown() { delete mutex_; }
+
+  static void AddActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::AddActiveSampler(sampler);
+    if (instance_ == NULL) {
+      // Install a signal handler.
+      struct sigaction sa;
+      sa.sa_sigaction = ProfilerSignalHandler;
+      sigemptyset(&sa.sa_mask);
+      sa.sa_flags = SA_RESTART | SA_SIGINFO;
+      signal_handler_installed_ =
+          (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
+
+      // Start a thread that sends SIGPROF signal to VM threads.
+      instance_ = new SignalSender(sampler->interval());
+      instance_->Start();
+    } else {
+      ASSERT(instance_->interval_ == sampler->interval());
+    }
+  }
+
+  static void RemoveActiveSampler(Sampler* sampler) {
+    ScopedLock lock(mutex_);
+    SamplerRegistry::RemoveActiveSampler(sampler);
+    if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
+      RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
+      delete instance_;
+      instance_ = NULL;
+
+      // Restore the old signal handler.
+      if (signal_handler_installed_) {
+        sigaction(SIGPROF, &old_signal_handler_, 0);
+        signal_handler_installed_ = false;
+      }
+    }
+  }
+
+  // Implement Thread::Run().
+  virtual void Run() {
+    SamplerRegistry::State state;
+    while ((state = SamplerRegistry::GetState()) !=
+           SamplerRegistry::HAS_NO_SAMPLERS) {
+      bool cpu_profiling_enabled =
+          (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
+      bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
+      // When CPU profiling is enabled both JavaScript and C++ code is
+      // profiled. We must not suspend.
+      if (!cpu_profiling_enabled) {
+        if (rate_limiter_.SuspendIfNecessary()) continue;
+      }
+      if (cpu_profiling_enabled && runtime_profiler_enabled) {
+        if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
+          return;
+        }
+        Sleep(HALF_INTERVAL);
+        if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
+          return;
+        }
+        Sleep(HALF_INTERVAL);
+      } else {
+        if (cpu_profiling_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile,
+                                                      this)) {
+            return;
+          }
+        }
+        if (runtime_profiler_enabled) {
+          if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile,
+                                                      NULL)) {
+            return;
+          }
+        }
+        Sleep(FULL_INTERVAL);
+      }
+    }
+  }
+
+  static void DoCpuProfile(Sampler* sampler, void* raw_sender) {
+    if (!sampler->IsProfiling()) return;
+    SignalSender* sender = reinterpret_cast<SignalSender*>(raw_sender);
+    sender->SendProfilingSignal(sampler->platform_data()->vm_tid());
+  }
+
+  static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
+    if (!sampler->isolate()->IsInitialized()) return;
+    sampler->isolate()->runtime_profiler()->NotifyTick();
+  }
+
+  void SendProfilingSignal(pthread_t tid) {
+    if (!signal_handler_installed_) return;
+    pthread_kill(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 = 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",
+              interval,
+              errno);
+      ASSERT(result == 0 || errno == EINTR);
+    }
+#endif
+    USE(result);
+  }
+
+  const int interval_;
+  RuntimeProfilerRateLimiter rate_limiter_;
+
+  // Protects the process wide state below.
+  static Mutex* mutex_;
+  static SignalSender* instance_;
+  static bool signal_handler_installed_;
+  static struct sigaction old_signal_handler_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SignalSender);
+};
+
+Mutex* SignalSender::mutex_ = NULL;
+SignalSender* SignalSender::instance_ = NULL;
+struct sigaction SignalSender::old_signal_handler_;
+bool SignalSender::signal_handler_installed_ = false;
+
+
+void OS::SetUp() {
+  // Seed the random number generator.
+  // Convert the current time to a 64-bit integer first, before converting it
+  // to an unsigned. Going directly can cause an overflow and the seed to be
+  // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SignalSender::SetUp();
+}
+
+
+void OS::TearDown() {
+  SignalSender::TearDown();
+  delete limit_mutex;
+}
+
+
+Sampler::Sampler(Isolate* isolate, int interval)
+    : isolate_(isolate),
+      interval_(interval),
+      profiling_(false),
+      active_(false),
+      samples_taken_(0) {
+  data_ = new PlatformData;
+}
+
+
+Sampler::~Sampler() {
+  ASSERT(!IsActive());
+  delete data_;
+}
+
+
+void Sampler::Start() {
+  ASSERT(!IsActive());
+  SetActive(true);
+  SignalSender::AddActiveSampler(this);
+}
+
+
+void Sampler::Stop() {
+  ASSERT(IsActive());
+  SignalSender::RemoveActiveSampler(this);
+  SetActive(false);
+}
+
+
+} }  // namespace v8::internal
--- a/debian/rules.orig	2014-04-14 14:37:03.000000000 +0200
+++ b/debian/rules	2014-05-01 17:24:04.000000000 +0200
@@ -31,7 +31,7 @@
 DEB_UPSTREAM_TARBALL_MD5 = be049128a44adf26f4dfb7d1ab55acfd
 
 # Supported archs
-ARCHS = i386 kfreebsd-i386 amd64 kfreebsd-amd64 armel armhf mipsel mips
+ARCHS = i386 kfreebsd-i386 hurd-i386 amd64 kfreebsd-amd64 armel armhf mipsel mips
 
 # allow parallel builds
 DEB_BUILD_PARALLEL=1
@@ -45,6 +45,7 @@
 # map HOST ARCH AND OS to v8 options
 v8arch := $(or $(v8arch),$(if $(filter i386,$(DEB_HOST_ARCH)),ia32))
 v8arch := $(or $(v8arch),$(if $(filter kfreebsd-i386,$(DEB_HOST_ARCH)),ia32))
+v8arch := $(or $(v8arch),$(if $(filter hurd-i386,$(DEB_HOST_ARCH)),ia32))
 v8arch := $(or $(v8arch),$(if $(filter amd64,$(DEB_HOST_ARCH)),x64))
 v8arch := $(or $(v8arch),$(if $(filter kfreebsd-amd64,$(DEB_HOST_ARCH)),x64))
 v8arch := $(or $(v8arch),$(if $(filter armel,$(DEB_HOST_ARCH)),arm))

--- End Message ---
--- Begin Message ---
Source: libv8-3.14
Source-Version: 3.14.5.8-8

We believe that the bug you reported is fixed in the latest version of
libv8-3.14, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 747...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Jérémy Lal <kapo...@melix.org> (supplier of updated libv8-3.14 package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Tue, 06 May 2014 21:35:20 +0200
Source: libv8-3.14
Binary: libv8-dev libv8-3.14-dev libv8-3.14.5 libv8-3.14-dbg
Architecture: source amd64
Version: 3.14.5.8-8
Distribution: unstable
Urgency: medium
Maintainer: Debian Javascript Maintainers 
<pkg-javascript-devel@lists.alioth.debian.org>
Changed-By: Jérémy Lal <kapo...@melix.org>
Description: 
 libv8-3.14-dbg - V8 JavaScript engine - debugging symbols
 libv8-3.14-dev - V8 JavaScript engine - development files for 3.14 branch
 libv8-3.14.5 - V8 JavaScript engine - runtime library
 libv8-dev  - V8 JavaScript engine - development files for latest branch
Closes: 747246
Changes: 
 libv8-3.14 (3.14.5.8-8) unstable; urgency=medium
 .
   * Add 0004_hurd.patch, add Architecture: hurd-i386.
     Thanks to Svante Signell (Closes: #747246).
Checksums-Sha1: 
 37fa388d2d6e610b5146d7975f115748d4aa0377 2537 libv8-3.14_3.14.5.8-8.dsc
 7e56678e9030cf88e41200cef3fd49ea3cde755e 41564 
libv8-3.14_3.14.5.8-8.debian.tar.xz
 1432f2aff1c3995f4b04b244a9d5dc27dba29407 108244 libv8-dev_3.14.5.8-8_amd64.deb
 f187822492e42733dc207d474b1488d05f7fd1d8 108252 
libv8-3.14-dev_3.14.5.8-8_amd64.deb
 ae58768a0ead05bed431e0fedd237e3fe25bdc26 1236534 
libv8-3.14.5_3.14.5.8-8_amd64.deb
 cd6e86212068b325e2987039a8ddfdf61300db39 15355274 
libv8-3.14-dbg_3.14.5.8-8_amd64.deb
Checksums-Sha256: 
 23e4ec44597d774fd4cf2784b4c9826841c2e5e5e52897b40f3eba997949a71a 2537 
libv8-3.14_3.14.5.8-8.dsc
 b62aadc1d8844051d49eb7b750a716ee6e27d3814635af9c39a6f2ef1de80c34 41564 
libv8-3.14_3.14.5.8-8.debian.tar.xz
 a349a297aec3673ad871cae34a07a4133c0535f611f25eafb9d8603aab0365f6 108244 
libv8-dev_3.14.5.8-8_amd64.deb
 6b19eae1d7d8b4ba92fedb45dc107e5d5fe61f0d5dece0938b25ca796ecc0abd 108252 
libv8-3.14-dev_3.14.5.8-8_amd64.deb
 ee32f5ae12f177697ffa1a8c3fba3902f17700f5cee35ca9454996d06ff526da 1236534 
libv8-3.14.5_3.14.5.8-8_amd64.deb
 a2beb8732d4e5f571e1b0c440497e87539599ed2127f87a64f0dad54654b882a 15355274 
libv8-3.14-dbg_3.14.5.8-8_amd64.deb
Files: 
 dec36df77e15972e09cb75e25f385916 108244 libdevel optional 
libv8-dev_3.14.5.8-8_amd64.deb
 db041a94954fe1fa80a39abfa1ff608c 108252 libdevel optional 
libv8-3.14-dev_3.14.5.8-8_amd64.deb
 a581128eb6768056daba95cd958cea7b 1236534 libs optional 
libv8-3.14.5_3.14.5.8-8_amd64.deb
 e3f7e8983b383d177135affaa371891d 15355274 debug extra 
libv8-3.14-dbg_3.14.5.8-8_amd64.deb
 a1e01a852bec659ff8586a0e30552a84 2537 libs optional libv8-3.14_3.14.5.8-8.dsc
 1a696019fbc33ccc02e62e9b3fe519b0 41564 libs optional 
libv8-3.14_3.14.5.8-8.debian.tar.xz

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJTaT26AAoJEGYRwF7dOfN0zVwQAI/tGaQGBqDaT99VrGCImMyk
mk9lgE9tBTBbjndv1HmAMF5pr6ub2io/8GKHEPw5OKl7uavXmpz7Px7TRKdBF8Zu
QvvthOmjEMLf/Rh+I3s38Rvt0Z1ePscTONxhBRY4UKZfDjj3+m6jDJEF1R1yCK20
X2Py1lHuXwlKAOSFsGw8GSuIs7DHnDauLi/bbAFczRSz+kl4OH2SDn35MLYvBirp
xhYc6UdO0NQq98ooyyiwb92gcZHY0bh0VWlSGEpO51vyUao6DXQ9tjfrwlCjiF6m
VXRHASULFC3v6sYiMRtgM8kkr3hx0MBdnHPbbw0ZKT3Sr+M0rS4KwumpppL6ZvJN
/SXpAN8FGOrKcvdvZV9jqnkpOE+xi8E6MKwzB61PmuEw4nAaSNlX0GXYxjIxcnkl
T5feW56Irv4w5p8So/VtHf5AFrablKdPRPKezai1j6G0JwvI29OCZaxXWYtBhtjr
vgJHPmGRPe79CibvIMrDTm2QLev4U5cdNm5siKdlUOX0eTahnabKSJ5sf40ASwnK
nUllwTT7HdLjx9gn2o4w2FTRPH0qIeceQTdpLC3p6/2VkOBQneFxJX5qKN818bIf
f7QOgEnLdkg1W7JJnt6bGqxHdj910Z3DlpwrIHojo+qSlq5MYzhkzwPUmldFVLCS
J0h8bDOTqjcq/vhWgJTI
=QD4C
-----END PGP SIGNATURE-----

--- End Message ---
_______________________________________________
Pkg-javascript-devel mailing list
Pkg-javascript-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-javascript-devel

Reply via email to