Add support for the QNX operating system.

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
This commit is contained in:
bmeurer@chromium.org 2014-01-02 07:04:05 +00:00
parent ffb5eb6e09
commit 0899da3697
16 changed files with 625 additions and 11 deletions

View File

@ -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>

View 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,
@ -186,6 +186,32 @@
}],
# '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': [

View File

@ -357,7 +357,7 @@
},
}],
['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' ],
@ -368,7 +368,7 @@
'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
@ -390,7 +390,7 @@
'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)' ],
@ -504,7 +504,8 @@
},
},
'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)' ],

View 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
@ -127,6 +128,9 @@
# 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

View File

@ -27,8 +27,13 @@
// 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,

View 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
}

View 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
}

View 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"', {

View 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));
}

401
src/platform-qnx.cc Normal file
View File

@ -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

View 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

42
src/qnx-math.h Normal file
View File

@ -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_

View File

@ -35,7 +35,10 @@
#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

View File

@ -155,7 +155,7 @@
'test-macro-assembler-mips.cc'
],
}],
[ 'OS=="linux"', {
[ 'OS=="linux" or OS=="qnx"', {
'sources': [
'test-platform-linux.cc',
],

View File

@ -29,6 +29,10 @@
#include "v8.h"
#if V8_OS_POSIX
#include <sys/time.h> // NOLINT
#endif
#include "cctest.h"
#if V8_OS_WIN
#include "win32-headers.h"

View File

@ -811,6 +811,43 @@
],
},
],
['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': [