Commit f1ba8d8f authored by michael_dawson's avatar michael_dawson Committed by Commit bot

Contribution of PowerPC port (continuation of 422063005) - AIX Common1

Contribution of PowerPC port (continuation of 422063005 and 817143002). This patch covers
the key changes needed to the common files needed to support AIX. Subsequent
patches will cover:
- changes to update the ppc directories so they are current with the changes
in the rest of the project.
- remaining AIX changes not resolved by 4.8 compiler
- individual optimizations for PPC

This is based off of the GitHub repository
https://github.com/andrewlow/v8ppc

R=danno@chromium.org, svenpanne@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#26343}
parent 88385229
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
'variables': { 'variables': {
'conditions': [ 'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or \ ['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. # This handles the Unix platforms we generally deal with.
# Anything else gets passed through, which probably won't work # Anything else gets passed through, which probably won't work
# very well; such hosts should pass an explicit target_arch # very well; such hosts should pass an explicit target_arch
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
'host_arch%': '<!pymod_do_main(detect_v8_host_arch)', 'host_arch%': '<!pymod_do_main(detect_v8_host_arch)',
}, { }, {
# OS!="linux" and OS!="freebsd" and OS!="openbsd" and # 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', 'host_arch%': 'ia32',
}], }],
], ],
...@@ -183,6 +183,9 @@ ...@@ -183,6 +183,9 @@
'_GLIBCXX_DEBUG' '_GLIBCXX_DEBUG'
], ],
}], }],
[ 'OS=="aix"', {
'cflags': [ '-gxcoff' ],
}],
], ],
}, },
'Optdebug': { 'Optdebug': {
...@@ -284,7 +287,7 @@ ...@@ -284,7 +287,7 @@
}, },
}], }],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
or OS=="netbsd"', { or OS=="netbsd" or OS=="aix"', {
'target_defaults': { 'target_defaults': {
'cflags': [ 'cflags': [
'-Wall', '-Wall',
...@@ -301,6 +304,9 @@ ...@@ -301,6 +304,9 @@
'cflags_cc': [ '-Wnon-virtual-dtor', '-fno-rtti', '-std=gnu++0x' ], 'cflags_cc': [ '-Wnon-virtual-dtor', '-fno-rtti', '-std=gnu++0x' ],
'ldflags': [ '-pthread', ], 'ldflags': [ '-pthread', ],
'conditions': [ 'conditions': [
[ 'host_arch=="ppc64"', {
'cflags': [ '-mminimal-toc' ],
}],
[ 'visibility=="hidden" and v8_enable_backtrace==0', { [ 'visibility=="hidden" and v8_enable_backtrace==0', {
'cflags': [ '-fvisibility=hidden' ], 'cflags': [ '-fvisibility=hidden' ],
}], }],
......
...@@ -279,6 +279,16 @@ ...@@ -279,6 +279,16 @@
'defines': [ 'defines': [
'V8_TARGET_ARCH_PPC_BE', '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 }], # ppc
...@@ -889,7 +899,7 @@ ...@@ -889,7 +899,7 @@
], ],
}], }],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \ ['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': [ 'conditions': [
[ 'v8_no_strict_aliasing==1', { [ 'v8_no_strict_aliasing==1', {
'cflags': [ '-fno-strict-aliasing' ], 'cflags': [ '-fno-strict-aliasing' ],
...@@ -905,6 +915,21 @@ ...@@ -905,6 +915,21 @@
['OS=="netbsd"', { ['OS=="netbsd"', {
'cflags': [ '-I/usr/pkg/include' ], '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 ], # conditions
'configurations': { 'configurations': {
# Abstract configuration for v8_optimized_debug == 0. # Abstract configuration for v8_optimized_debug == 0.
...@@ -930,7 +955,7 @@ ...@@ -930,7 +955,7 @@
}, },
'conditions': [ 'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
OS=="qnx"', { OS=="qnx" or OS=="aix"', {
'cflags!': [ 'cflags!': [
'-O3', '-O3',
'-O2', '-O2',
...@@ -984,7 +1009,7 @@ ...@@ -984,7 +1009,7 @@
}, },
'conditions': [ 'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
OS=="qnx"', { OS=="qnx" or OS=="aix"', {
'cflags!': [ 'cflags!': [
'-O0', '-O0',
'-O1', '-O1',
...@@ -1033,13 +1058,16 @@ ...@@ -1033,13 +1058,16 @@
], ],
'conditions': [ 'conditions': [
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \ ['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)', ], 'cflags': [ '-Woverloaded-virtual', '<(wno_array_bounds)', ],
}], }],
['OS=="linux" and v8_enable_backtrace==1', { ['OS=="linux" and v8_enable_backtrace==1', {
# Support for backtrace_symbols. # Support for backtrace_symbols.
'ldflags': [ '-rdynamic' ], 'ldflags': [ '-rdynamic' ],
}], }],
['OS=="aix"', {
'ldflags': [ '-Wl,-bbigtoc' ],
}],
['OS=="android"', { ['OS=="android"', {
'variables': { 'variables': {
'android_full_debug%': 1, 'android_full_debug%': 1,
...@@ -1072,7 +1100,8 @@ ...@@ -1072,7 +1100,8 @@
'v8_enable_slow_dchecks%': 0, 'v8_enable_slow_dchecks%': 0,
}, },
'conditions': [ '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!': [ 'cflags!': [
'-Os', '-Os',
], ],
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows) // V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino // V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris // V8_OS_SOLARIS - Sun Solaris and OpenSolaris
// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows // V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__) #if defined(__ANDROID__)
...@@ -89,6 +90,9 @@ ...@@ -89,6 +90,9 @@
#elif defined(__sun) #elif defined(__sun)
# define V8_OS_POSIX 1 # define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1 # define V8_OS_SOLARIS 1
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
# define V8_OS_BSD 1 # define V8_OS_BSD 1
# define V8_OS_FREEBSD 1 # define V8_OS_FREEBSD 1
......
...@@ -1441,15 +1441,18 @@ double power_double_int(double x, int y) { ...@@ -1441,15 +1441,18 @@ double power_double_int(double x, int y) {
double power_double_double(double x, double y) { double power_double_double(double x, double y) {
#if defined(__MINGW64_VERSION_MAJOR) && \ #if (defined(__MINGW64_VERSION_MAJOR) && \
(!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1) (!defined(__MINGW64_VERSION_RC) || __MINGW64_VERSION_RC < 1)) || \
// MinGW64 has a custom implementation for pow. This handles certain defined(V8_OS_AIX)
// MinGW64 and AIX have a custom implementation for pow. This handles certain
// special cases that are different. // 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; double f;
if (std::modf(y, &f) != 0.0) { double result = ((x == 0.0) ^ (y > 0)) ? V8_INFINITY : 0;
return ((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) { if (x == 2.0) {
......
...@@ -162,7 +162,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr); ...@@ -162,7 +162,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
// On some platforms we need additional declarations to make // On some platforms we need additional declarations to make
// AtomicWord compatible with our other Atomic* types. // 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" #include "src/base/atomicops_internals_atomicword_compat.h"
#endif #endif
......
...@@ -19,6 +19,12 @@ ...@@ -19,6 +19,12 @@
#if V8_OS_LINUX && V8_HOST_ARCH_PPC #if V8_OS_LINUX && V8_HOST_ARCH_PPC
#include <elf.h> #include <elf.h>
#endif #endif
#if V8_OS_AIX
#include <sys/systemcfg.h> // _system_configuration
#ifndef POWER_8
#define POWER_8 0x10000
#endif
#endif
#if V8_OS_POSIX #if V8_OS_POSIX
#include <unistd.h> // sysconf() #include <unistd.h> // sysconf()
#endif #endif
...@@ -654,7 +660,22 @@ CPU::CPU() ...@@ -654,7 +660,22 @@ CPU::CPU()
} }
} }
#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 // !USE_SIMULATOR
#endif // V8_HOST_ARCH_PPC #endif // V8_HOST_ARCH_PPC
} }
......
...@@ -76,6 +76,23 @@ inline void CheckEqualsHelper(const char* file, int line, ...@@ -76,6 +76,23 @@ inline void CheckEqualsHelper(const char* file, int line,
} }
// 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 // Helper function used by the CHECK_NE function when given int
// arguments. Should not be called directly. // arguments. Should not be called directly.
inline void CheckNonEqualsHelper(const char* file, inline void CheckNonEqualsHelper(const char* file,
......
...@@ -346,8 +346,12 @@ inline void USE(T) { } ...@@ -346,8 +346,12 @@ inline void USE(T) { }
# define V8_UINT64_C(x) (x ## ULL) # define V8_UINT64_C(x) (x ## ULL)
# define V8_INT64_C(x) (x ## LL) # define V8_INT64_C(x) (x ## LL)
# define V8_INTPTR_C(x) (x) # define V8_INTPTR_C(x) (x)
#if V8_OS_AIX
#define V8_PTR_PREFIX "l"
#else
# define V8_PTR_PREFIX "" # define V8_PTR_PREFIX ""
#endif #endif
#endif
#define V8PRIxPTR V8_PTR_PREFIX "x" #define V8PRIxPTR V8_PTR_PREFIX "x"
#define V8PRIdPTR V8_PTR_PREFIX "d" #define V8PRIdPTR V8_PTR_PREFIX "d"
......
// 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
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#include <sys/prctl.h> // NOLINT, for prctl #include <sys/prctl.h> // NOLINT, for prctl
#endif #endif
#if !V8_OS_NACL #if !defined(V8_OS_NACL) && !defined(_AIX)
#include <sys/syscall.h> #include <sys/syscall.h>
#endif #endif
...@@ -172,7 +172,13 @@ void* OS::GetRandomMmapAddr() { ...@@ -172,7 +172,13 @@ void* OS::GetRandomMmapAddr() {
// fulfilling our placement request. // fulfilling our placement request.
raw_addr &= V8_UINT64_C(0x3ffffffff000); raw_addr &= V8_UINT64_C(0x3ffffffff000);
#elif V8_TARGET_ARCH_PPC64 #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. // Big-endian Linux: 44 bits of virtual addressing.
raw_addr &= V8_UINT64_C(0x03fffffff000); raw_addr &= V8_UINT64_C(0x03fffffff000);
#else #else
...@@ -193,6 +199,10 @@ void* OS::GetRandomMmapAddr() { ...@@ -193,6 +199,10 @@ void* OS::GetRandomMmapAddr() {
// no hint at all. The high hint prevents the break from getting hemmed in // 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. // at low values, ceding half of the address space to the system heap.
raw_addr += 0x80000000; raw_addr += 0x80000000;
#elif V8_OS_AIX
// The range 0x30000000 - 0xD0000000 is available on AIX;
// choose the upper range.
raw_addr += 0x90000000;
# else # else
// The range 0x20000000 - 0x60000000 is relatively unpopulated across a // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
// variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
...@@ -261,6 +271,8 @@ int OS::GetCurrentThreadId() { ...@@ -261,6 +271,8 @@ int OS::GetCurrentThreadId() {
return static_cast<int>(syscall(__NR_gettid)); return static_cast<int>(syscall(__NR_gettid));
#elif V8_OS_ANDROID #elif V8_OS_ANDROID
return static_cast<int>(gettid()); return static_cast<int>(gettid());
#elif V8_OS_AIX
return static_cast<int>(thread_self());
#else #else
return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self())); return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self()));
#endif #endif
...@@ -524,8 +536,15 @@ void Thread::Start() { ...@@ -524,8 +536,15 @@ void Thread::Start() {
DCHECK_EQ(0, result); DCHECK_EQ(0, result);
// Native client uses default stack size. // Native client uses default stack size.
#if !V8_OS_NACL #if !V8_OS_NACL
if (stack_size_ > 0) { size_t stack_size = stack_size_;
result = pthread_attr_setstacksize(&attr, static_cast<size_t>(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); DCHECK_EQ(0, result);
} }
#endif #endif
......
...@@ -88,6 +88,9 @@ int64_t SysInfo::AmountOfPhysicalMemory() { ...@@ -88,6 +88,9 @@ int64_t SysInfo::AmountOfPhysicalMemory() {
#elif V8_OS_NACL #elif V8_OS_NACL
// No support for _SC_PHYS_PAGES, assume 2GB. // No support for _SC_PHYS_PAGES, assume 2GB.
return static_cast<int64_t>(1) << 31; 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 #elif V8_OS_POSIX
long pages = sysconf(_SC_PHYS_PAGES); // NOLINT(runtime/int) long pages = sysconf(_SC_PHYS_PAGES); // NOLINT(runtime/int)
long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int) long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int)
......
...@@ -1519,7 +1519,7 @@ class CEntryStub : public PlatformCodeStub { ...@@ -1519,7 +1519,7 @@ class CEntryStub : public PlatformCodeStub {
: PlatformCodeStub(isolate) { : PlatformCodeStub(isolate) {
minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs); minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs);
DCHECK(result_size == 1 || result_size == 2); 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); minor_key_ = ResultSizeBits::update(minor_key_, result_size);
#endif // _WIN64 #endif // _WIN64
} }
...@@ -1532,7 +1532,7 @@ class CEntryStub : public PlatformCodeStub { ...@@ -1532,7 +1532,7 @@ class CEntryStub : public PlatformCodeStub {
private: private:
bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); } 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_); } int result_size() const { return ResultSizeBits::decode(minor_key_); }
#endif // _WIN64 #endif // _WIN64
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include "src/v8.h" #include "src/v8.h"
#if defined(V8_OS_AIX)
#include <fenv.h>
#endif
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/compiler.h" #include "src/compiler.h"
...@@ -48,7 +51,15 @@ double modulo(double x, double y) { ...@@ -48,7 +51,15 @@ double modulo(double x, double y) {
#else // POSIX #else // POSIX
double modulo(double x, double y) { 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); return std::fmod(x, y);
#endif
} }
#endif // defined(_WIN64) #endif // defined(_WIN64)
......
...@@ -1539,8 +1539,8 @@ class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator { ...@@ -1539,8 +1539,8 @@ class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator { class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public: public:
void* Allocate(size_t) OVERRIDE { return malloc(0); } void* Allocate(size_t) OVERRIDE { return malloc(1); }
void* AllocateUninitialized(size_t length) OVERRIDE { return malloc(0); } void* AllocateUninitialized(size_t length) OVERRIDE { return malloc(1); }
void Free(void* p, size_t) OVERRIDE { free(p); } void Free(void* p, size_t) OVERRIDE { free(p); }
}; };
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
}], }],
['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \ ['(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")', { or OS=="qnx" or OS=="aix")', {
'sources': [ 'd8-posix.cc', ] 'sources': [ 'd8-posix.cc', ]
}], }],
[ 'OS=="win"', { [ 'OS=="win"', {
......
...@@ -2351,7 +2351,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { ...@@ -2351,7 +2351,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
// Handle the jump to continue execution after break point depending on the // Handle the jump to continue execution after break point depending on the
// break location. // break location.
if (at_js_return) { 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 // place in the original code. If not the break point was removed during
// break point processing. // break point processing.
if (break_at_js_return_active) { if (break_at_js_return_active) {
......
...@@ -85,11 +85,14 @@ static int DecodeIt(Isolate* isolate, std::ostream* os, ...@@ -85,11 +85,14 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
} else { } else {
// No relocation information when printing code stubs. // No relocation information when printing code stubs.
} }
#if !V8_TARGET_ARCH_PPC
int constants = -1; // no constants being decoded at the start int constants = -1; // no constants being decoded at the start
#endif
while (pc < end) { while (pc < end) {
// First decode instruction so that we know its length. // First decode instruction so that we know its length.
byte* prev_pc = pc; byte* prev_pc = pc;
#if !V8_TARGET_ARCH_PPC
if (constants > 0) { if (constants > 0) {
SNPrintF(decode_buffer, SNPrintF(decode_buffer,
"%08x constant", "%08x constant",
...@@ -118,6 +121,25 @@ static int DecodeIt(Isolate* isolate, std::ostream* os, ...@@ -118,6 +121,25 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
pc += d.InstructionDecode(decode_buffer, pc); 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) // Collect RelocInfo for this instruction (prev_pc .. pc-1)
List<const char*> comments(4); List<const char*> comments(4);
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
# define V8_INFINITY std::numeric_limits<double>::infinity() # define V8_INFINITY std::numeric_limits<double>::infinity()
#elif V8_LIBC_MSVCRT #elif V8_LIBC_MSVCRT
# define V8_INFINITY HUGE_VAL # define V8_INFINITY HUGE_VAL
#elif V8_OS_AIX
#define V8_INFINITY (__builtin_inff())
#else #else
# define V8_INFINITY INFINITY # define V8_INFINITY INFINITY
#endif #endif
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <signal.h> #include <signal.h>
#include <sys/time.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 #include <sys/syscall.h> // NOLINT
#endif #endif
...@@ -479,7 +479,11 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, ...@@ -479,7 +479,11 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]); state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]);
state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]); state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]);
#endif // V8_HOST_ARCH_* #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 #endif // USE_SIMULATOR
sampler->SampleStack(state); sampler->SampleStack(state);
} }
......
...@@ -899,6 +899,23 @@ void Deserializer::ReadObject(int space_number, Object** write_back) { ...@@ -899,6 +899,23 @@ void Deserializer::ReadObject(int space_number, Object** write_back) {
DCHECK(space_number != CODE_SPACE); DCHECK(space_number != CODE_SPACE);
} }
#endif #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
} }
......
...@@ -408,9 +408,9 @@ void init_memcopy_functions() { ...@@ -408,9 +408,9 @@ void init_memcopy_functions() {
bool DoubleToBoolean(double d) { bool DoubleToBoolean(double d) {
// NaN, +0, and -0 should return the false object // NaN, +0, and -0 should return the false object
#if __BYTE_ORDER == __LITTLE_ENDIAN #if V8_TARGET_LITTLE_ENDIAN
union IeeeDoubleLittleEndianArchType u; union IeeeDoubleLittleEndianArchType u;
#elif __BYTE_ORDER == __BIG_ENDIAN #else
union IeeeDoubleBigEndianArchType u; union IeeeDoubleBigEndianArchType u;
#endif #endif
u.d = d; u.d = d;
......
...@@ -399,4 +399,9 @@ ...@@ -399,4 +399,9 @@
'test-accessors/Gc' : [SKIP], 'test-accessors/Gc' : [SKIP],
}], # 'arch == nacl_ia32 or arch == nacl_x64' }], # 'arch == nacl_ia32 or arch == nacl_x64'
['arch == ppc64', {
#issue 2857
'test-log/EquivalenceOfLoggingAndTraversal' : [SKIP],
}], # 'arch == ppc64'
] ]
...@@ -65,6 +65,12 @@ class SimulatorHelper { ...@@ -65,6 +65,12 @@ class SimulatorHelper {
simulator_->get_register(v8::internal::Simulator::sp)); simulator_->get_register(v8::internal::Simulator::sp));
state->fp = reinterpret_cast<void*>( state->fp = reinterpret_cast<void*>(
simulator_->get_register(v8::internal::Simulator::fp)); 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 #endif
} }
......
...@@ -135,7 +135,7 @@ if (this.os && os.system) { ...@@ -135,7 +135,7 @@ if (this.os && os.system) {
assertThrows("os.system('sleep', ['2000'], -1, 20);", "sleep 2"); assertThrows("os.system('sleep', ['2000'], -1, 20);", "sleep 2");
// Check that -1 means no timeout. // Check that -1 means no timeout.
os.system('sleep', ['0.1'], -1, -1); os.system('sleep', ['1'], -1, -1);
} }
......
...@@ -251,6 +251,12 @@ ...@@ -251,6 +251,12 @@
'debug-stepframe': [SKIP], 'debug-stepframe': [SKIP],
}], # 'gc_stress == True' }], # '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 == arm64 or arch == android_arm64', {
...@@ -440,9 +446,6 @@ ...@@ -440,9 +446,6 @@
['arch == mips', { ['arch == mips', {
# Flaky with TF. # Flaky with TF.
'mirror-script': [PASS, NO_VARIANTS], 'mirror-script': [PASS, NO_VARIANTS],
# Emscripten requires little-endian, skip all tests on MIPS EB.
'asm/embenchen/*': [SKIP],
}], # 'arch == mips' }], # 'arch == mips'
############################################################################## ##############################################################################
......
...@@ -1497,6 +1497,12 @@ ...@@ -1497,6 +1497,12 @@
], ],
} }
], ],
['OS=="aix"', {
'sources': [
'../../src/base/platform/platform-aix.cc',
'../../src/base/platform/platform-posix.cc'
]},
],
['OS=="solaris"', { ['OS=="solaris"', {
'link_settings': { 'link_settings': {
'libraries': [ 'libraries': [
......
...@@ -397,6 +397,7 @@ def Execute(arch, mode, args, options, suites, workspace): ...@@ -397,6 +397,7 @@ def Execute(arch, mode, args, options, suites, workspace):
"tsan": False, "tsan": False,
"msan": False, "msan": False,
"dcheck_always_on": options.dcheck_always_on, "dcheck_always_on": options.dcheck_always_on,
"byteorder": sys.byteorder,
} }
all_tests = [] all_tests = []
num_tests = 0 num_tests = 0
......
...@@ -531,7 +531,8 @@ def Execute(arch, mode, args, options, suites, workspace): ...@@ -531,7 +531,8 @@ def Execute(arch, mode, args, options, suites, workspace):
# TODO(all): Combine "simulator" and "simulator_run". # TODO(all): Combine "simulator" and "simulator_run".
simulator_run = not options.dont_skip_simulator_slow_tests and \ 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 ARCH_GUESS and arch != ARCH_GUESS
# Find available test suites and read test cases from them. # Find available test suites and read test cases from them.
variables = { variables = {
...@@ -549,6 +550,7 @@ def Execute(arch, mode, args, options, suites, workspace): ...@@ -549,6 +550,7 @@ def Execute(arch, mode, args, options, suites, workspace):
"tsan": options.tsan, "tsan": options.tsan,
"msan": options.msan, "msan": options.msan,
"dcheck_always_on": options.dcheck_always_on, "dcheck_always_on": options.dcheck_always_on,
"byteorder": sys.byteorder,
} }
all_tests = [] all_tests = []
num_tests = 0 num_tests = 0
......
...@@ -53,7 +53,8 @@ DEFS = {FAIL_OK: [FAIL, OKAY], ...@@ -53,7 +53,8 @@ DEFS = {FAIL_OK: [FAIL, OKAY],
# Support arches, modes to be written as keywords instead of strings. # Support arches, modes to be written as keywords instead of strings.
VARIABLES = {ALWAYS: True} 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", "arm", "arm64", "ia32", "mips", "mipsel", "mips64el", "x64", "x87", "nacl_ia32",
"nacl_x64", "ppc", "ppc64", "macos", "windows", "linux", "aix"]: "nacl_x64", "ppc", "ppc64", "macos", "windows", "linux", "aix"]:
VARIABLES[var] = var VARIABLES[var] = var
......
...@@ -73,6 +73,8 @@ def GuessOS(): ...@@ -73,6 +73,8 @@ def GuessOS():
return 'solaris' return 'solaris'
elif system == 'NetBSD': elif system == 'NetBSD':
return 'netbsd' return 'netbsd'
elif system == 'AIX':
return 'aix'
else: else:
return None return None
...@@ -99,7 +101,7 @@ def DefaultArch(): ...@@ -99,7 +101,7 @@ def DefaultArch():
return 'ia32' return 'ia32'
elif machine == 'amd64': elif machine == 'amd64':
return 'ia32' return 'ia32'
elif id == 'ppc64': elif machine == 'ppc64':
return 'ppc' return 'ppc'
else: else:
return None return None
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment