Add support for the QNX operating system.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 2 Jan 2014 07:04:05 +0000 (07:04 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 2 Jan 2014 07:04:05 +0000 (07:04 +0000)
This patch contains contributions from the following members of the
BlackBerry Web Technologies team:

Eli Fidler <efidler@blackberry.com>
Konrad Piascik <kpiascik@blackberry.com>
Jeff Rogers <jrogers@blackberry.com>
Cosmin Truta <ctruta@blackberry.com>
Peter Wang <peter.wang@torchmobile.com.cn>
Xiaobo Wang <xiaobwang@blackberry.com>
Ming Xie <mxie@blackberry.com>
Leo Yang <leoyang@blackberry.com>

R=bmeurer@chromium.org, jkummerow@chromium.org

Review URL: https://codereview.chromium.org/61153009

Patch from Cosmin Truta <ctruta@blackberry.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18430 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

16 files changed:
AUTHORS
build/standalone.gypi
build/toolchain.gypi
include/v8config.h
src/arm/cpu-arm.cc
src/checks.cc
src/cpu.cc
src/d8.gyp
src/platform-posix.cc
src/platform-qnx.cc [new file with mode: 0644]
src/platform.h
src/qnx-math.h [new file with mode: 0644]
src/sampler.cc
test/cctest/cctest.gyp
test/cctest/test-time.cc
tools/gyp/v8.gyp

diff --git a/AUTHORS b/AUTHORS
index 46e3a14..ededa56 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -11,6 +11,7 @@ Igalia, S.L.
 Joyent, Inc.
 Bloomberg Finance L.P.
 NVIDIA Corporation
+BlackBerry Limited
 
 Akinori MUSHA <knu@FreeBSD.org>
 Alexander Botero-Lowry <alexbl@FreeBSD.org>
index cf45ee9..e498f4c 100644 (file)
@@ -45,7 +45,7 @@
         'variables': {
           'conditions': [
             ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or \
-               OS=="netbsd" or OS=="mac"', {
+               OS=="netbsd" or OS=="mac" or OS=="qnx"', {
               # This handles the Unix platforms we generally deal with.
               # Anything else gets passed through, which probably won't work
               # very well; such hosts should pass an explicit target_arch
@@ -99,7 +99,7 @@
       ['(v8_target_arch=="arm" and host_arch!="arm") or \
         (v8_target_arch=="mipsel" and host_arch!="mipsel") or \
         (v8_target_arch=="x64" and host_arch!="x64") or \
-        (OS=="android")', {
+        (OS=="android" or OS=="qnx")', {
         'want_separate_host_toolset': 1,
       }, {
         'want_separate_host_toolset': 0,
     }],
     # 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"
     #  or OS=="netbsd"'
+    ['OS=="qnx"', {
+      'target_defaults': {
+        'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
+                    '-fno-exceptions' ],
+        'cflags_cc': [ '-Wnon-virtual-dtor', '-fno-rtti' ],
+        'conditions': [
+          [ 'visibility=="hidden"', {
+            'cflags': [ '-fvisibility=hidden' ],
+          }],
+          [ 'component=="shared_library"', {
+            'cflags': [ '-fPIC' ],
+          }],
+        ],
+        'target_conditions': [
+          [ '_toolset=="host" and host_os=="linux"', {
+            'cflags': [ '-pthread' ],
+            'ldflags': [ '-pthread' ],
+            'libraries': [ '-lrt' ],
+          }],
+          [ '_toolset=="target"', {
+            'cflags': [ '-Wno-psabi' ],
+            'libraries': [ '-lbacktrace', '-lsocket', '-lm' ],
+          }],
+        ],
+      },
+    }],  # OS=="qnx"
     ['OS=="win"', {
       'target_defaults': {
         'defines': [
index 684db74..c3b1de0 100644 (file)
         },
       }],
       ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
-         or OS=="netbsd"', {
+         or OS=="netbsd" or OS=="qnx"', {
         'conditions': [
           [ 'v8_no_strict_aliasing==1', {
             'cflags': [ '-fno-strict-aliasing' ],
         'defines': [ '__C99FEATURES__=1' ],  # isinf() etc.
       }],
       ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
-         or OS=="netbsd" or OS=="mac" or OS=="android") and \
+         or OS=="netbsd" or OS=="mac" or OS=="android" or OS=="qnx") and \
         (v8_target_arch=="arm" or v8_target_arch=="ia32" or \
          v8_target_arch=="mipsel")', {
         # Check whether the host compiler and target compiler support the
               'clang%': 0,
             },
             'conditions': [
-              ['(OS!="android" or clang==1) and \
+              ['((OS!="android" and OS!="qnx") or clang==1) and \
                 nacl_target_arch!="nacl_x64"', {
                 'cflags': [ '<(m32flag)' ],
                 'ldflags': [ '<(m32flag)' ],
           },
         },
         'conditions': [
-          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
+          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
+            OS=="qnx"', {
             'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
                         '-Wnon-virtual-dtor', '-Woverloaded-virtual',
                         '<(wno_array_bounds)' ],
index 631ad0d..8661a0d 100644 (file)
@@ -88,6 +88,7 @@
 //  V8_OS_NETBSD        - NetBSD
 //  V8_OS_OPENBSD       - OpenBSD
 //  V8_OS_POSIX         - POSIX compatible (mostly everything except Windows)
+//  V8_OS_QNX           - QNX Neutrino
 //  V8_OS_SOLARIS       - Sun Solaris and OpenSolaris
 //  V8_OS_WIN           - Microsoft Windows
 
 # define V8_OS_BSD 1
 # define V8_OS_OPENBSD 1
 # define V8_OS_POSIX 1
+#elif defined(__QNXNTO__)
+# define V8_OS_POSIX 1
+# define V8_OS_QNX 1
 #elif defined(_WIN32)
 # define V8_OS_WIN 1
 #endif
index cf531e1..20c6a5d 100644 (file)
 
 // CPU specific code for arm independent of OS goes here.
 #ifdef __arm__
+#ifdef __QNXNTO__
+#include <sys/mman.h>  // for cache flushing.
+#undef MAP_TYPE
+#else
 #include <sys/syscall.h>  // for cache flushing.
 #endif
+#endif
 
 #include "v8.h"
 
@@ -57,13 +62,15 @@ void CPU::FlushICache(void* start, size_t size) {
     return;
   }
 
-#if defined (USE_SIMULATOR)
+#if defined(USE_SIMULATOR)
   // Not generating ARM instructions for C-code. This means that we are
   // building an ARM emulator based target.  We should notify the simulator
   // that the Icache was flushed.
   // None of this code ends up in the snapshot so there are no issues
   // around whether or not to generate the code when building snapshots.
   Simulator::FlushICache(Isolate::Current()->simulator_i_cache(), start, size);
+#elif V8_OS_QNX
+  msync(start, size, MS_SYNC | MS_INVALIDATE_ICACHE);
 #else
   // Ideally, we would call
   //   syscall(__ARM_NR_cacheflush, start,
index a4514bf..2b1c76c 100644 (file)
@@ -30,6 +30,8 @@
 #if V8_LIBC_GLIBC || V8_OS_BSD
 # include <cxxabi.h>
 # include <execinfo.h>
+#elif V8_OS_QNX
+# include <backtrace.h>
 #endif  // V8_LIBC_GLIBC || V8_OS_BSD
 #include <stdio.h>
 
@@ -64,6 +66,26 @@ static V8_INLINE void DumpBacktrace() {
     }
   }
   free(symbols);
+#elif V8_OS_QNX
+  char out[1024];
+  bt_accessor_t acc;
+  bt_memmap_t memmap;
+  bt_init_accessor(&acc, BT_SELF);
+  bt_load_memmap(&acc, &memmap);
+  bt_sprn_memmap(&memmap, out, sizeof(out));
+  i::OS::PrintError(out);
+  bt_addr_t trace[100];
+  int size = bt_get_backtrace(&acc, trace, ARRAY_SIZE(trace));
+  i::OS::PrintError("\n==== C stack trace ===============================\n\n");
+  if (size == 0) {
+    i::OS::PrintError("(empty)\n");
+  } else {
+    bt_sprnf_addrs(&memmap, trace, size, const_cast<char*>("%a\n"),
+                   out, sizeof(out), NULL);
+    i::OS::PrintError(out);
+  }
+  bt_unload_memmap(&memmap);
+  bt_release_accessor(&acc);
 #endif  // V8_LIBC_GLIBC || V8_OS_BSD
 }
 
index 2bf51a7..8a9aa97 100644 (file)
@@ -33,6 +33,9 @@
 #if V8_OS_POSIX
 #include <unistd.h>  // sysconf()
 #endif
+#if V8_OS_QNX
+#include <sys/syspage.h>  // cpuinfo
+#endif
 
 #include <algorithm>
 #include <cctype>
@@ -78,6 +81,8 @@ static V8_INLINE void __cpuid(int cpu_info[4], int info_type) {
 
 #elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_MIPS
 
+#if V8_OS_LINUX
+
 #if V8_HOST_ARCH_ARM
 
 // See <uapi/asm/hwcap.h> kernel header.
@@ -249,6 +254,8 @@ static bool HasListItem(const char* list, const char* item) {
   return false;
 }
 
+#endif  // V8_OS_LINUX
+
 #endif  // V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
 
 CPU::CPU() : stepping_(0),
@@ -328,7 +335,11 @@ CPU::CPU() : stepping_(0),
     has_sahf_ = (cpu_info[2] & 0x00000001) != 0;
 #endif
   }
+
 #elif V8_HOST_ARCH_ARM
+
+#if V8_OS_LINUX
+
   CPUInfo cpu_info;
 
   // Extract implementor from the "CPU implementer" field.
@@ -438,7 +449,34 @@ CPU::CPU() : stepping_(0),
 
   // We don't support any FPUs other than VFP.
   has_fpu_ = has_vfp_;
+
+#elif V8_OS_QNX
+
+  uint32_t cpu_flags = SYSPAGE_ENTRY(cpuinfo)->flags;
+  if (cpu_flags & ARM_CPU_FLAG_V7) {
+    architecture_ = 7;
+    has_thumbee_ = true;
+  } else if (cpu_flags & ARM_CPU_FLAG_V6) {
+    architecture_ = 6;
+    // QNX doesn't say if ThumbEE is available.
+    // Assume false for the architectures older than ARMv7.
+  }
+  ASSERT(architecture_ >= 6);
+  has_fpu_ = (cpu_flags & CPU_FLAG_FPU) != 0;
+  has_vfp_ = has_fpu_;
+  if (cpu_flags & ARM_CPU_FLAG_NEON) {
+    has_neon_ = true;
+    has_vfp3_ = has_vfp_;
+#ifdef ARM_CPU_FLAG_VFP_D32
+    has_vfp3_d32_ = (cpu_flags & ARM_CPU_FLAG_VFP_D32) != 0;
+#endif
+  }
+  has_idiva_ = (cpu_flags & ARM_CPU_FLAG_IDIV) != 0;
+
+#endif  // V8_OS_LINUX
+
 #elif V8_HOST_ARCH_MIPS
+
   // Simple detection of FPU at runtime for Linux.
   // It is based on /proc/cpuinfo, which reveals hardware configuration
   // to user-space applications.  According to MIPS (early 2010), no similar
@@ -448,6 +486,7 @@ CPU::CPU() : stepping_(0),
   char* cpu_model = cpu_info.ExtractField("cpu model");
   has_fpu_ = HasListItem(cpu_model, "FPU");
   delete[] cpu_model;
+
 #endif
 }
 
index 097abc0..bc1dedc 100644 (file)
@@ -66,7 +66,8 @@
               ],
             }],
             ['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \
-               or OS=="openbsd" or OS=="solaris" or OS=="android")', {
+               or OS=="openbsd" or OS=="solaris" or OS=="android" \
+               or OS=="qnx")', {
               'sources': [ 'd8-posix.cc', ]
             }],
             [ 'OS=="win"', {
index 02a7b76..087625a 100644 (file)
@@ -130,6 +130,13 @@ uint64_t OS::TotalPhysicalMemory() {
     return 0;
   }
   return static_cast<uint64_t>(memory_info.dwTotalPhys);
+#elif V8_OS_QNX
+  struct stat stat_buf;
+  if (stat("/proc", &stat_buf) != 0) {
+    UNREACHABLE();
+    return 0;
+  }
+  return static_cast<uint64_t>(stat_buf.st_size);
 #else
   intptr_t pages = sysconf(_SC_PHYS_PAGES);
   intptr_t page_size = sysconf(_SC_PAGESIZE);
@@ -247,7 +254,7 @@ void* OS::GetRandomMmapAddr() {
 
 
 size_t OS::AllocateAlignment() {
-  return getpagesize();
+  return static_cast<size_t>(sysconf(_SC_PAGESIZE));
 }
 
 
diff --git a/src/platform-qnx.cc b/src/platform-qnx.cc
new file mode 100644 (file)
index 0000000..cd031e7
--- /dev/null
@@ -0,0 +1,401 @@
+// Copyright 2013 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 QNX goes here. For the POSIX-compatible
+// 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 <stdlib.h>
+#include <ucontext.h>
+#include <backtrace.h>
+
+// QNX requires memory pages to be marked as executable.
+// Otherwise, the 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
+#include <strings.h>    // index
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/procfs.h>
+
+#undef MAP_TYPE
+
+#include "v8.h"
+
+#include "platform.h"
+#include "v8threads.h"
+#include "vm-state-inl.h"
+
+
+namespace v8 {
+namespace internal {
+
+// 0 is never a valid thread id on Qnx since tids and pids share a
+// name space and pid 0 is reserved (see man 2 kill).
+static const pthread_t kNoThread = (pthread_t) 0;
+
+
+#ifdef __arm__
+
+bool OS::ArmUsingHardFloat() {
+  // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
+  // the Floating Point ABI used (PCS stands for Procedure Call Standard).
+  // We use these as well as a couple of other defines to statically determine
+  // what FP ABI used.
+  // GCC versions 4.4 and below don't support hard-fp.
+  // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
+  // __ARM_PCS_VFP.
+
+#define GCC_VERSION (__GNUC__ * 10000                                          \
+                     + __GNUC_MINOR__ * 100                                    \
+                     + __GNUC_PATCHLEVEL__)
+#if GCC_VERSION >= 40600
+#if defined(__ARM_PCS_VFP)
+  return true;
+#else
+  return false;
+#endif
+
+#elif GCC_VERSION < 40500
+  return false;
+
+#else
+#if defined(__ARM_PCS_VFP)
+  return true;
+#elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \
+      !defined(__VFP_FP__)
+  return false;
+#else
+#error "Your version of GCC does not report the FP ABI compiled for."          \
+       "Please report it on this issue"                                        \
+       "http://code.google.com/p/v8/issues/detail?id=2140"
+
+#endif
+#endif
+#undef GCC_VERSION
+}
+
+#endif  // __arm__
+
+
+const char* OS::LocalTimezone(double time) {
+  if (std::isnan(time)) return "";
+  time_t tv = static_cast<time_t>(std::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));
+}
+
+
+void* OS::Allocate(const size_t requested,
+                   size_t* allocated,
+                   bool is_executable) {
+  const size_t msize = RoundUp(requested, AllocateAlignment());
+  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+  void* addr = OS::GetRandomMmapAddr();
+  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (mbase == MAP_FAILED) {
+    LOG(i::Isolate::Current(),
+        StringEvent("OS::Allocate", "mmap failed"));
+    return NULL;
+  }
+  *allocated = msize;
+  return mbase;
+}
+
+
+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(OS::GetRandomMmapAddr(),
+           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(OS::GetRandomMmapAddr(),
+           size,
+           PROT_READ | PROT_WRITE,
+           MAP_SHARED,
+           fileno(file),
+           0);
+  return new PosixMemoryMappedFile(file, memory, size);
+}
+
+
+PosixMemoryMappedFile::~PosixMemoryMappedFile() {
+  if (memory_) OS::Free(memory_, size_);
+  fclose(file_);
+}
+
+
+void OS::LogSharedLibraryAddresses(Isolate* isolate) {
+  procfs_mapinfo *mapinfos = NULL, *mapinfo;
+  int proc_fd, num, i;
+
+  struct {
+    procfs_debuginfo info;
+    char buff[PATH_MAX];
+  } map;
+
+  char buf[PATH_MAX + 1];
+  snprintf(buf, PATH_MAX + 1, "/proc/%d/as", getpid());
+
+  if ((proc_fd = open(buf, O_RDONLY)) == -1) {
+    close(proc_fd);
+    return;
+  }
+
+  /* Get the number of map entries.  */
+  if (devctl(proc_fd, DCMD_PROC_MAPINFO, NULL, 0, &num) != EOK) {
+    close(proc_fd);
+    return;
+  }
+
+  mapinfos = reinterpret_cast<procfs_mapinfo *>(
+      malloc(num * sizeof(procfs_mapinfo)));
+  if (mapinfos == NULL) {
+    close(proc_fd);
+    return;
+  }
+
+  /* Fill the map entries.  */
+  if (devctl(proc_fd, DCMD_PROC_PAGEDATA,
+      mapinfos, num * sizeof(procfs_mapinfo), &num) != EOK) {
+    free(mapinfos);
+    close(proc_fd);
+    return;
+  }
+
+  for (i = 0; i < num; i++) {
+    mapinfo = mapinfos + i;
+    if (mapinfo->flags & MAP_ELF) {
+      map.info.vaddr = mapinfo->vaddr;
+      if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) {
+        continue;
+      }
+      LOG(isolate, SharedLibraryEvent(map.info.path,
+                                      mapinfo->vaddr,
+                                      mapinfo->vaddr + mapinfo->size));
+    }
+  }
+  free(mapinfos);
+  close(proc_fd);
+}
+
+
+void OS::SignalCodeMovingGC() {
+}
+
+
+// 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_ANONYMOUS | MAP_LAZY,
+                           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_ANONYMOUS | MAP_LAZY,
+                      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_ANONYMOUS | MAP_FIXED,
+                         kMmapFd,
+                         kMmapFdOffset)) {
+    return false;
+  }
+
+  return true;
+}
+
+
+bool VirtualMemory::UncommitRegion(void* base, size_t size) {
+  return mmap(base,
+              size,
+              PROT_NONE,
+              MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LAZY,
+              kMmapFd,
+              kMmapFdOffset) != MAP_FAILED;
+}
+
+
+bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+  return munmap(base, size) == 0;
+}
+
+
+bool VirtualMemory::HasLazyCommits() {
+  return false;
+}
+
+} }  // namespace v8::internal
index 6cf3062..acb4f94 100644 (file)
@@ -59,6 +59,10 @@ int signbit(double x);
 # endif
 #endif
 
+#if V8_OS_QNX
+#include "qnx-math.h"
+#endif
+
 // Microsoft Visual C++ specific stuff.
 #if V8_CC_MSVC
 
diff --git a/src/qnx-math.h b/src/qnx-math.h
new file mode 100644 (file)
index 0000000..bd84745
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2013 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.
+
+#ifndef V8_QNX_MATH_H_
+#define V8_QNX_MATH_H_
+
+#include <cmath>
+
+#undef fpclassify
+#undef isfinite
+#undef isinf
+#undef isnan
+#undef isnormal
+#undef signbit
+
+using std::lrint;
+
+#endif  // V8_QNX_MATH_H_
index 684ef48..cb98b6f 100644 (file)
 #include <pthread.h>
 #include <signal.h>
 #include <sys/time.h>
+
+#if !V8_OS_QNX
 #include <sys/syscall.h>
+#endif
 
 #if V8_OS_MACOSX
 #include <mach/mach.h>
@@ -45,6 +48,7 @@
     && !V8_OS_OPENBSD
 #include <ucontext.h>
 #endif
+
 #include <unistd.h>
 
 // GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
@@ -266,7 +270,11 @@ class SignalHandler : public AllStatic {
     struct sigaction sa;
     sa.sa_sigaction = &HandleProfilerSignal;
     sigemptyset(&sa.sa_mask);
+#if V8_OS_QNX
+    sa.sa_flags = SA_SIGINFO;
+#else
     sa.sa_flags = SA_RESTART | SA_SIGINFO;
+#endif
     signal_handler_installed_ =
         (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
   }
@@ -415,7 +423,17 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
   state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
   state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
   state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
-#endif  // V8_OS_SOLARIS
+#elif V8_OS_QNX
+#if V8_HOST_ARCH_IA32
+  state.pc = reinterpret_cast<Address>(mcontext.cpu.eip);
+  state.sp = reinterpret_cast<Address>(mcontext.cpu.esp);
+  state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp);
+#elif V8_HOST_ARCH_ARM
+  state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]);
+  state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]);
+  state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]);
+#endif  // V8_HOST_ARCH_*
+#endif  // V8_OS_QNX
 #endif  // USE_SIMULATOR
   sampler->SampleStack(state);
 #endif  // V8_OS_NACL
index 546198a..8f4a160 100644 (file)
             'test-macro-assembler-mips.cc'
           ],
         }],
-        [ 'OS=="linux"', {
+        [ 'OS=="linux" or OS=="qnx"', {
           'sources': [
             'test-platform-linux.cc',
           ],
index 28d647a..f7329b5 100644 (file)
 
 #include "v8.h"
 
+#if V8_OS_POSIX
+#include <sys/time.h>  // NOLINT
+#endif
+
 #include "cctest.h"
 #if V8_OS_WIN
 #include "win32-headers.h"
index 5b6f4c2..06060a5 100644 (file)
             ],
           },
         ],
+        ['OS=="qnx"', {
+            'link_settings': {
+              'target_conditions': [
+                ['_toolset=="host" and host_os=="linux"', {
+                  'libraries': [
+                    '-lrt'
+                  ],
+                }],
+                ['_toolset=="target"', {
+                  'libraries': [
+                    '-lbacktrace', '-lsocket'
+                  ],
+                }],
+              ],
+            },
+            'sources': [
+              '../../src/platform-posix.cc',
+            ],
+            'target_conditions': [
+              ['_toolset=="host" and host_os=="linux"', {
+                'sources': [
+                  '../../src/platform-linux.cc'
+                ],
+              }],
+              ['_toolset=="host" and host_os=="mac"', {
+                'sources': [
+                  '../../src/platform-macos.cc'
+                ],
+              }],
+              ['_toolset=="target"', {
+                'sources': [
+                  '../../src/platform-qnx.cc'
+                ],
+              }],
+            ],
+          },
+        ],
         ['OS=="freebsd"', {
             'link_settings': {
               'libraries': [