'variables': {
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or \
- OS=="netbsd" or OS=="mac" or OS=="qnx"', {
+ OS=="netbsd" or OS=="mac" or OS=="qnx" or OS=="aix"', {
# 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
'host_arch%': '<!pymod_do_main(detect_v8_host_arch)',
}, {
# OS!="linux" and OS!="freebsd" and OS!="openbsd" and
- # OS!="netbsd" and OS!="mac"
+ # OS!="netbsd" and OS!="mac" and OS!="aix"
'host_arch%': 'ia32',
}],
],
'_GLIBCXX_DEBUG'
],
}],
+ [ 'OS=="aix"', {
+ 'cflags': [ '-gxcoff' ],
+ }],
],
},
'Optdebug': {
},
}],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
- or OS=="netbsd"', {
+ or OS=="netbsd" or OS=="aix"', {
'target_defaults': {
'cflags': [
'-Wall',
'cflags_cc': [ '-Wnon-virtual-dtor', '-fno-rtti', '-std=gnu++0x' ],
'ldflags': [ '-pthread', ],
'conditions': [
+ [ 'host_arch=="ppc64"', {
+ 'cflags': [ '-mminimal-toc' ],
+ }],
[ 'visibility=="hidden" and v8_enable_backtrace==0', {
'cflags': [ '-fvisibility=hidden' ],
}],
'defines': [
'V8_TARGET_ARCH_PPC_BE',
],
+ 'conditions': [
+ ['OS=="aix"', {
+ # Work around AIX ceil, trunc and round oddities.
+ 'cflags': [ '-mcpu=power5+ -mfprnd' ],
+ }],
+ ['OS=="aix"', {
+ # Work around AIX assembler popcntb bug.
+ 'cflags': [ '-mno-popcntb' ],
+ }],
+ ],
}],
],
}], # ppc
],
}],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
- or OS=="netbsd" or OS=="qnx"', {
+ or OS=="netbsd" or OS=="qnx" or OS=="aix"', {
'conditions': [
[ 'v8_no_strict_aliasing==1', {
'cflags': [ '-fno-strict-aliasing' ],
['OS=="netbsd"', {
'cflags': [ '-I/usr/pkg/include' ],
}],
+ ['OS=="aix"', {
+ 'defines': [
+ # Support for malloc(0)
+ '_LINUX_SOURCE_COMPAT=1',
+ '_ALL_SOURCE=1'],
+ 'conditions': [
+ [ 'v8_target_arch=="ppc"', {
+ 'ldflags': [ '-Wl,-bmaxdata:0x60000000/dsa' ],
+ }],
+ [ 'v8_target_arch=="ppc64"', {
+ 'cflags': [ '-maix64' ],
+ 'ldflags': [ '-maix64' ],
+ }],
+ ],
+ }],
], # conditions
'configurations': {
# Abstract configuration for v8_optimized_debug == 0.
},
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
- OS=="qnx"', {
+ OS=="qnx" or OS=="aix"', {
'cflags!': [
'-O3',
'-O2',
},
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
- OS=="qnx"', {
+ OS=="qnx" or OS=="aix"', {
'cflags!': [
'-O0',
'-O1',
],
'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
- OS=="qnx"', {
+ OS=="qnx" or OS=="aix"', {
'cflags': [ '-Woverloaded-virtual', '<(wno_array_bounds)', ],
}],
['OS=="linux" and v8_enable_backtrace==1', {
# Support for backtrace_symbols.
'ldflags': [ '-rdynamic' ],
}],
+ ['OS=="aix"', {
+ 'ldflags': [ '-Wl,-bbigtoc' ],
+ }],
['OS=="android"', {
'variables': {
'android_full_debug%': 1,
'v8_enable_slow_dchecks%': 0,
},
'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=="aix"', {
'cflags!': [
'-Os',
],
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris
+// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__)
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
+#elif defined(_AIX)
+#define V8_OS_POSIX 1
+#define V8_OS_AIX 1
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
double power_double_double(double x, double y) {
-#if defined(__MINGW64_VERSION_MAJOR) && \
- (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)
- // MinGW64 has a custom implementation for pow. This handles certain
+#if (defined(__MINGW64_VERSION_MAJOR) && \
+ (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)) || \
+ defined(V8_OS_AIX)
+ // MinGW64 and AIX have a custom implementation for pow. This handles certain
// special cases that are different.
- if ((x == 0.0 || std::isinf(x)) && std::isfinite(y)) {
+ if ((x == 0.0 || std::isinf(x)) && y != 0.0 && std::isfinite(y)) {
double f;
- if (std::modf(y, &f) != 0.0) {
- return ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
- }
+ double result = ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
+ /* retain sign if odd integer exponent */
+ return ((std::modf(y, &f) == 0.0) && (static_cast<int64_t>(y) & 1))
+ ? copysign(result, x)
+ : result;
}
if (x == 2.0) {
// On some platforms we need additional declarations to make
// AtomicWord compatible with our other Atomic* types.
-#if defined(__APPLE__) || defined(__OpenBSD__)
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(V8_OS_AIX)
#include "src/base/atomicops_internals_atomicword_compat.h"
#endif
#if V8_OS_LINUX && V8_HOST_ARCH_PPC
#include <elf.h>
#endif
+#if V8_OS_AIX
+#include <sys/systemcfg.h> // _system_configuration
+#ifndef POWER_8
+#define POWER_8 0x10000
+#endif
+#endif
#if V8_OS_POSIX
#include <unistd.h> // sysconf()
#endif
}
}
-#endif // V8_OS_LINUX
+#elif V8_OS_AIX
+ switch (_system_configuration.implementation) {
+ case POWER_8:
+ part_ = PPC_POWER8;
+ break;
+ case POWER_7:
+ part_ = PPC_POWER7;
+ break;
+ case POWER_6:
+ part_ = PPC_POWER6;
+ break;
+ case POWER_5:
+ part_ = PPC_POWER5;
+ break;
+ }
+#endif // V8_OS_AIX
#endif // !USE_SIMULATOR
#endif // V8_HOST_ARCH_PPC
}
}
+// 32-bit AIX defines intptr_t as long int.
+#if V8_OS_AIX && V8_HOST_ARCH_32_BIT
+// Helper function used by the CHECK_EQ function when given intptr_t
+// arguments. Should not be called directly.
+inline void CheckEqualsHelper(const char* file, int line,
+ const char* expected_source, intptr_t expected,
+ const char* value_source, intptr_t value) {
+ if (expected != value) {
+ V8_Fatal(file, line,
+ "CHECK_EQ(%s, %s) failed\n#"
+ " Expected: 0x%lx\n# Found: 0x%lx",
+ expected_source, value_source, expected, value);
+ }
+}
+#endif
+
+
// Helper function used by the CHECK_NE function when given int
// arguments. Should not be called directly.
inline void CheckNonEqualsHelper(const char* file,
# define V8_UINT64_C(x) (x ## ULL)
# define V8_INT64_C(x) (x ## LL)
# define V8_INTPTR_C(x) (x)
+#if V8_OS_AIX
+#define V8_PTR_PREFIX "l"
+#else
# define V8_PTR_PREFIX ""
#endif
+#endif
#define V8PRIxPTR V8_PTR_PREFIX "x"
#define V8PRIdPTR V8_PTR_PREFIX "d"
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Platform specific code for AIX goes here. For the POSIX comaptible parts
+// the implementation is in platform-posix.cc.
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+
+#include <errno.h>
+#include <fcntl.h> // open
+#include <limits.h>
+#include <stdarg.h>
+#include <strings.h> // index
+#include <sys/mman.h> // mmap & munmap
+#include <sys/stat.h> // open
+#include <sys/types.h> // mmap & munmap
+#include <unistd.h> // getpagesize
+
+#include <cmath>
+
+#undef MAP_TYPE
+
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+
+
+namespace v8 {
+namespace base {
+
+
+static inline void* mmapHelper(size_t len, int prot, int flags, int fildes,
+ off_t off) {
+ void* addr = OS::GetRandomMmapAddr();
+ return mmap(addr, len, prot, flags, fildes, off);
+}
+
+
+const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
+ if (std::isnan(time)) return "";
+ time_t tv = static_cast<time_t>(floor(time / msPerSecond));
+ struct tm* t = localtime(&tv);
+ if (NULL == t) return "";
+ return tzname[0]; // The location of the timezone string on AIX.
+}
+
+
+double OS::LocalTimeOffset(TimezoneCache* cache) {
+ // On AIX, struct tm does not contain a tm_gmtoff field.
+ time_t utc = time(NULL);
+ DCHECK(utc != -1);
+ struct tm* loc = localtime(&utc);
+ DCHECK(loc != NULL);
+ return static_cast<double>((mktime(loc) - utc) * msPerSecond);
+}
+
+
+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 = mmapHelper(msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ if (mbase == MAP_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 =
+ mmapHelper(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 =
+ mmapHelper(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
+}
+
+
+std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
+ std::vector<SharedLibraryAddress> result;
+ static const int MAP_LENGTH = 1024;
+ int fd = open("/proc/self/maps", O_RDONLY);
+ if (fd < 0) return result;
+ while (true) {
+ char addr_buffer[11];
+ addr_buffer[0] = '0';
+ addr_buffer[1] = 'x';
+ addr_buffer[10] = 0;
+ ssize_t rc = read(fd, addr_buffer + 2, 8);
+ if (rc < 8) break;
+ unsigned start = StringToLong(addr_buffer);
+ rc = read(fd, addr_buffer + 2, 1);
+ if (rc < 1) break;
+ if (addr_buffer[2] != '-') break;
+ rc = read(fd, addr_buffer + 2, 8);
+ if (rc < 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;
+ rc = read(fd, buffer + bytes_read, 1);
+ if (rc < 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;
+ result.push_back(SharedLibraryAddress(start_of_path, start, end));
+ }
+ close(fd);
+ return result;
+}
+
+
+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) {
+ DCHECK((alignment % OS::AllocateAlignment()) == 0);
+ size_t request_size =
+ RoundUp(size + alignment, static_cast<intptr_t>(OS::AllocateAlignment()));
+ void* reservation =
+ mmapHelper(request_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, kMmapFd,
+ kMmapFdOffset);
+ if (reservation == MAP_FAILED) return;
+
+ uint8_t* base = static_cast<uint8_t*>(reservation);
+ uint8_t* aligned_base = RoundUp(base, alignment);
+ DCHECK_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());
+ DCHECK_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;
+ }
+
+ DCHECK(aligned_size == request_size);
+
+ address_ = static_cast<void*>(aligned_base);
+ size_ = aligned_size;
+}
+
+
+VirtualMemory::~VirtualMemory() {
+ if (IsReserved()) {
+ bool result = ReleaseRegion(address(), size());
+ DCHECK(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 = mmapHelper(size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
+ kMmapFd, kMmapFdOffset);
+
+ if (result == MAP_FAILED) return NULL;
+
+ return result;
+}
+
+
+bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
+#if defined(__native_client__)
+ // The Native Client port of V8 uses an interpreter,
+ // so code pages don't need PROT_EXEC.
+ int prot = PROT_READ | PROT_WRITE;
+#else
+ int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+#endif
+ if (mprotect(base, size, prot) == -1) return false;
+
+ return true;
+}
+
+
+bool VirtualMemory::UncommitRegion(void* base, size_t size) {
+ return mprotect(base, size, PROT_NONE) != -1;
+}
+
+
+bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+ return munmap(base, size) == 0;
+}
+
+
+bool VirtualMemory::HasLazyCommits() { return true; }
+}
+} // namespace v8::base
#include <sys/prctl.h> // NOLINT, for prctl
#endif
-#if !V8_OS_NACL
+#if !defined(V8_OS_NACL) && !defined(_AIX)
#include <sys/syscall.h>
#endif
// fulfilling our placement request.
raw_addr &= V8_UINT64_C(0x3ffffffff000);
#elif V8_TARGET_ARCH_PPC64
-#if V8_TARGET_BIG_ENDIAN
+#if V8_OS_AIX
+ // AIX: 64 bits of virtual addressing, but we limit address range to:
+ // a) minimize Segment Lookaside Buffer (SLB) misses and
+ raw_addr &= V8_UINT64_C(0x3ffff000);
+ // Use extra address space to isolate the mmap regions.
+ raw_addr += V8_UINT64_C(0x400000000000);
+#elif V8_TARGET_BIG_ENDIAN
// Big-endian Linux: 44 bits of virtual addressing.
raw_addr &= V8_UINT64_C(0x03fffffff000);
#else
// no hint at all. The high hint prevents the break from getting hemmed in
// at low values, ceding half of the address space to the system heap.
raw_addr += 0x80000000;
+#elif V8_OS_AIX
+ // The range 0x30000000 - 0xD0000000 is available on AIX;
+ // choose the upper range.
+ raw_addr += 0x90000000;
# else
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
return static_cast<int>(syscall(__NR_gettid));
#elif V8_OS_ANDROID
return static_cast<int>(gettid());
+#elif V8_OS_AIX
+ return static_cast<int>(thread_self());
#else
return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self()));
#endif
DCHECK_EQ(0, result);
// Native client uses default stack size.
#if !V8_OS_NACL
- if (stack_size_ > 0) {
- result = pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
+ size_t stack_size = stack_size_;
+#if V8_OS_AIX
+ if (stack_size == 0) {
+ // Default on AIX is 96KB -- bump up to 2MB
+ stack_size = 2 * 1024 * 1024;
+ }
+#endif
+ if (stack_size > 0) {
+ result = pthread_attr_setstacksize(&attr, stack_size);
DCHECK_EQ(0, result);
}
#endif
#elif V8_OS_NACL
// No support for _SC_PHYS_PAGES, assume 2GB.
return static_cast<int64_t>(1) << 31;
+#elif V8_OS_AIX
+ int64_t result = sysconf(_SC_AIX_REALMEM);
+ return static_cast<int64_t>(result) * 1024L;
#elif V8_OS_POSIX
long pages = sysconf(_SC_PHYS_PAGES); // NOLINT(runtime/int)
long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int)
: PlatformCodeStub(isolate) {
minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs);
DCHECK(result_size == 1 || result_size == 2);
-#if _WIN64 || (V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS)
+#if _WIN64 || V8_TARGET_ARCH_PPC
minor_key_ = ResultSizeBits::update(minor_key_, result_size);
#endif // _WIN64
}
private:
bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
-#if _WIN64 || (V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS)
+#if _WIN64 || V8_TARGET_ARCH_PPC
int result_size() const { return ResultSizeBits::decode(minor_key_); }
#endif // _WIN64
#include "src/v8.h"
+#if defined(V8_OS_AIX)
+#include <fenv.h>
+#endif
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/compiler.h"
#else // POSIX
double modulo(double x, double y) {
+#if defined(V8_OS_AIX)
+ // AIX raises an underflow exception for (Number.MIN_VALUE % Number.MAX_VALUE)
+ feclearexcept(FE_ALL_EXCEPT);
+ double result = std::fmod(x, y);
+ int exception = fetestexcept(FE_UNDERFLOW);
+ return (exception ? x : result);
+#else
return std::fmod(x, y);
+#endif
}
#endif // defined(_WIN64)
class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
- void* Allocate(size_t) OVERRIDE { return malloc(0); }
- void* AllocateUninitialized(size_t length) OVERRIDE { return malloc(0); }
+ void* Allocate(size_t) OVERRIDE { return malloc(1); }
+ void* AllocateUninitialized(size_t length) OVERRIDE { return malloc(1); }
void Free(void* p, size_t) OVERRIDE { free(p); }
};
}],
['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \
or OS=="openbsd" or OS=="solaris" or OS=="android" \
- or OS=="qnx")', {
+ or OS=="qnx" or OS=="aix")', {
'sources': [ 'd8-posix.cc', ]
}],
[ 'OS=="win"', {
// Handle the jump to continue execution after break point depending on the
// break location.
if (at_js_return) {
- // If the break point as return is still active jump to the corresponding
+ // If the break point at return is still active jump to the corresponding
// place in the original code. If not the break point was removed during
// break point processing.
if (break_at_js_return_active) {
} else {
// No relocation information when printing code stubs.
}
+#if !V8_TARGET_ARCH_PPC
int constants = -1; // no constants being decoded at the start
+#endif
while (pc < end) {
// First decode instruction so that we know its length.
byte* prev_pc = pc;
+#if !V8_TARGET_ARCH_PPC
if (constants > 0) {
SNPrintF(decode_buffer,
"%08x constant",
pc += d.InstructionDecode(decode_buffer, pc);
}
}
+#else // !V8_TARGET_ARCH_PPC
+#if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+ // Function descriptors are specially decoded and skipped.
+ // Other internal references (load of ool constant pool pointer)
+ // are not since they are a encoded as a regular mov sequence.
+ int skip;
+ if (it != NULL && !it->done() && it->rinfo()->pc() == pc &&
+ it->rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE &&
+ (skip = Assembler::DecodeInternalReference(decode_buffer, pc))) {
+ pc += skip;
+ } else {
+ decode_buffer[0] = '\0';
+ pc += d.InstructionDecode(decode_buffer, pc);
+ }
+#else
+ decode_buffer[0] = '\0';
+ pc += d.InstructionDecode(decode_buffer, pc);
+#endif // ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+#endif // !V8_TARGET_ARCH_PPC
// Collect RelocInfo for this instruction (prev_pc .. pc-1)
List<const char*> comments(4);
# define V8_INFINITY std::numeric_limits<double>::infinity()
#elif V8_LIBC_MSVCRT
# define V8_INFINITY HUGE_VAL
+#elif V8_OS_AIX
+#define V8_INFINITY (__builtin_inff())
#else
# define V8_INFINITY INFINITY
#endif
#include <signal.h>
#include <sys/time.h>
-#if !V8_OS_QNX && !V8_OS_NACL
+#if !V8_OS_QNX && !V8_OS_NACL && !V8_OS_AIX
#include <sys/syscall.h> // NOLINT
#endif
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
+#elif V8_OS_AIX
+ state.pc = reinterpret_cast<Address>(mcontext.jmp_context.iar);
+ state.sp = reinterpret_cast<Address>(mcontext.jmp_context.gpr[1]);
+ state.fp = reinterpret_cast<Address>(mcontext.jmp_context.gpr[31]);
+#endif // V8_OS_AIX
#endif // USE_SIMULATOR
sampler->SampleStack(state);
}
DCHECK(space_number != CODE_SPACE);
}
#endif
+#if V8_TARGET_ARCH_PPC && \
+ (ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL)
+ // If we're on a platform that uses function descriptors
+ // these jump tables make use of RelocInfo::INTERNAL_REFERENCE.
+ // As the V8 serialization code doesn't handle that relocation type
+ // we use this to fix up code that has function descriptors.
+ if (space_number == CODE_SPACE) {
+ Code* code = reinterpret_cast<Code*>(HeapObject::FromAddress(address));
+ for (RelocIterator it(code); !it.done(); it.next()) {
+ RelocInfo::Mode rmode = it.rinfo()->rmode();
+ if (rmode == RelocInfo::INTERNAL_REFERENCE) {
+ Assembler::RelocateInternalReference(it.rinfo()->pc(), 0,
+ code->instruction_start());
+ }
+ }
+ }
+#endif
}
bool DoubleToBoolean(double d) {
// NaN, +0, and -0 should return the false object
-#if __BYTE_ORDER == __LITTLE_ENDIAN
+#if V8_TARGET_LITTLE_ENDIAN
union IeeeDoubleLittleEndianArchType u;
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#else
union IeeeDoubleBigEndianArchType u;
#endif
u.d = d;
'test-accessors/Gc' : [SKIP],
}], # 'arch == nacl_ia32 or arch == nacl_x64'
+
+['arch == ppc64', {
+ #issue 2857
+ 'test-log/EquivalenceOfLoggingAndTraversal' : [SKIP],
+}], # 'arch == ppc64'
]
simulator_->get_register(v8::internal::Simulator::sp));
state->fp = reinterpret_cast<void*>(
simulator_->get_register(v8::internal::Simulator::fp));
+#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
+ state->pc = reinterpret_cast<void*>(simulator_->get_pc());
+ state->sp = reinterpret_cast<void*>(
+ simulator_->get_register(v8::internal::Simulator::sp));
+ state->fp = reinterpret_cast<void*>(
+ simulator_->get_register(v8::internal::Simulator::fp));
#endif
}
assertThrows("os.system('sleep', ['2000'], -1, 20);", "sleep 2");
// Check that -1 means no timeout.
- os.system('sleep', ['0.1'], -1, -1);
+ os.system('sleep', ['1'], -1, -1);
}
'debug-stepframe': [SKIP],
}], # 'gc_stress == True'
+##############################################################################
+['byteorder == big', {
+ # Emscripten requires little-endian, skip all tests on big endian platforms.
+ 'asm/embenchen/*': [SKIP],
+}], # 'byteorder == big'
+
##############################################################################
['arch == arm64 or arch == android_arm64', {
['arch == mips', {
# Flaky with TF.
'mirror-script': [PASS, NO_VARIANTS],
-
- # Emscripten requires little-endian, skip all tests on MIPS EB.
- 'asm/embenchen/*': [SKIP],
}], # 'arch == mips'
##############################################################################
],
}
],
+ ['OS=="aix"', {
+ 'sources': [
+ '../../src/base/platform/platform-aix.cc',
+ '../../src/base/platform/platform-posix.cc'
+ ]},
+ ],
['OS=="solaris"', {
'link_settings': {
'libraries': [
"tsan": False,
"msan": False,
"dcheck_always_on": options.dcheck_always_on,
+ "byteorder": sys.byteorder,
}
all_tests = []
num_tests = 0
# TODO(all): Combine "simulator" and "simulator_run".
simulator_run = not options.dont_skip_simulator_slow_tests and \
- arch in ['arm64', 'arm', 'mipsel', 'mips', 'mips64el'] and \
+ arch in ['arm64', 'arm', 'mipsel', 'mips', 'mips64el', \
+ 'ppc', 'ppc64'] and \
ARCH_GUESS and arch != ARCH_GUESS
# Find available test suites and read test cases from them.
variables = {
"tsan": options.tsan,
"msan": options.msan,
"dcheck_always_on": options.dcheck_always_on,
+ "byteorder": sys.byteorder,
}
all_tests = []
num_tests = 0
# Support arches, modes to be written as keywords instead of strings.
VARIABLES = {ALWAYS: True}
-for var in ["debug", "release", "android_arm", "android_arm64", "android_ia32", "android_x87",
+for var in ["debug", "release", "big", "little",
+ "android_arm", "android_arm64", "android_ia32", "android_x87",
"arm", "arm64", "ia32", "mips", "mipsel", "mips64el", "x64", "x87", "nacl_ia32",
"nacl_x64", "ppc", "ppc64", "macos", "windows", "linux", "aix"]:
VARIABLES[var] = var
return 'solaris'
elif system == 'NetBSD':
return 'netbsd'
+ elif system == 'AIX':
+ return 'aix'
else:
return None
return 'ia32'
elif machine == 'amd64':
return 'ia32'
- elif id == 'ppc64':
+ elif machine == 'ppc64':
return 'ppc'
else:
return None