Contribution of PowerPC port (continuation of 422063005) - AIX Common1
authormichael_dawson <michael_dawson@ca.ibm.com>
Fri, 30 Jan 2015 08:01:53 +0000 (00:01 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 30 Jan 2015 08:02:08 +0000 (08:02 +0000)
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}

30 files changed:
build/standalone.gypi
build/toolchain.gypi
include/v8config.h
src/assembler.cc
src/base/atomicops.h
src/base/cpu.cc
src/base/logging.h
src/base/macros.h
src/base/platform/platform-aix.cc [new file with mode: 0644]
src/base/platform/platform-posix.cc
src/base/sys-info.cc
src/code-stubs.h
src/codegen.cc
src/d8.cc
src/d8.gyp
src/debug.cc
src/disassembler.cc
src/globals.h
src/sampler.cc
src/serialize.cc
src/utils.cc
test/cctest/cctest.status
test/cctest/test-sampler-api.cc
test/mjsunit/d8-os.js
test/mjsunit/mjsunit.status
tools/gyp/v8.gyp
tools/run-deopt-fuzzer.py
tools/run-tests.py
tools/testrunner/local/statusfile.py
tools/testrunner/local/utils.py

index 15e856c4fab9abaf123196b55c59d9218e61d594..56cebbe1f3fd278c7f7531d3c2ce9f1154ff6aac 100644 (file)
@@ -46,7 +46,7 @@
         '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
@@ -54,7 +54,7 @@
               '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' ],
           }],
index ed0dd36907bf6fae9b042e214f1738bd5e20038f..e0d6d7452e852bc66f8edc10e7c83e46c25a5566 100644 (file)
             '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',
             ],
index d1ca22c229708a1611e065c4dbe8be10d20504ad..8497abd81fe4501238f1946e97f4311ea763f26f 100644 (file)
@@ -67,6 +67,7 @@
 //  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__)
@@ -89,6 +90,9 @@
 #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
index 21f1715859859fb5cd54107a26e06b218c43a3cd..deabe3b776a9377e10f0f4d3346946ab036c10af 100644 (file)
@@ -1441,15 +1441,18 @@ double power_double_int(double x, int y) {
 
 
 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) {
index d059a019647bb4860fb20618907954687d5167ec..e76b3d02d24a3fdad887f82dbcb489ec20a6584b 100644 (file)
@@ -162,7 +162,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
 
 // 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
 
index fa212e0e045b572078f9782cbbc49020d00f4cb7..84cd231f611f206f17d5fed7fddda7942b83e20a 100644 (file)
 #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
@@ -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  // V8_HOST_ARCH_PPC
 }
index e73fac46adc1b771ee44da70143d81cbb8ceae61..d228eb0bf4df9500d881311acabbbf71cd641808 100644 (file)
@@ -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
 // arguments.  Should not be called directly.
 inline void CheckNonEqualsHelper(const char* file,
index 8742519a6139b7746b6c5e8fff94ccc072513c92..ce75f8bed757145f2c4687431f1dda023f43aec9 100644 (file)
@@ -346,8 +346,12 @@ inline void USE(T) { }
 # 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"
diff --git a/src/base/platform/platform-aix.cc b/src/base/platform/platform-aix.cc
new file mode 100644 (file)
index 0000000..3083f75
--- /dev/null
@@ -0,0 +1,292 @@
+// 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
index 5393dd57c9563545991e76e5d58960b0f4a5c888..ec666641a1d43bc560bdd8606bc969d0b9eb02ca 100644 (file)
@@ -55,7 +55,7 @@
 #include <sys/prctl.h>  // NOLINT, for prctl
 #endif
 
-#if !V8_OS_NACL
+#if !defined(V8_OS_NACL) && !defined(_AIX)
 #include <sys/syscall.h>
 #endif
 
@@ -172,7 +172,13 @@ void* OS::GetRandomMmapAddr() {
   // 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
@@ -193,6 +199,10 @@ void* OS::GetRandomMmapAddr() {
   // 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
@@ -261,6 +271,8 @@ int OS::GetCurrentThreadId() {
   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
@@ -524,8 +536,15 @@ void Thread::Start() {
   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
index c665771b8b73c49d93bb44a20aa916560fa3d78c..617a88ea818c969865082d779be86fcbbef06153 100644 (file)
@@ -88,6 +88,9 @@ int64_t SysInfo::AmountOfPhysicalMemory() {
 #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)
index b5ea4427c3369c91190e7c95c08fb16c06a54d58..a0ffd129c309a3a5a7a7f6764829ecad1562579c 100644 (file)
@@ -1519,7 +1519,7 @@ class CEntryStub : public PlatformCodeStub {
       : 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
   }
@@ -1532,7 +1532,7 @@ class CEntryStub : public PlatformCodeStub {
 
  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
 
index 66b605a4206658d2feebf56c084d2ff03b2e530c..178ba4a69df8d1e423a6d9611518c11307135678 100644 (file)
@@ -4,6 +4,9 @@
 
 #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"
@@ -48,7 +51,15 @@ double modulo(double x, double y) {
 #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)
 
index 7157cb81acf85171b94e331ad02e8404323dd0c5..943855bcedc6b85f757a14255394e707816622b8 100644 (file)
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1539,8 +1539,8 @@ class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
 
 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); }
 };
 
index e53658493a4e0e27d8cc2e109e2db006875da0e8..aa8a81a8cce8539bf427874d4b9706f37993ddf2 100644 (file)
@@ -60,7 +60,7 @@
         }],
         ['(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"', {
index 07ad71bf347d30304227890e2e907bc4962713ff..310c3fdbe2455fe4726cf9f64aee34459cb34d39 100644 (file)
@@ -2351,7 +2351,7 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
   // 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) {
index bedff451e9f87d0e4bcaae5a21c5b4ed9b6d34b3..215e2b88911c164d0857da74188c388ee4081c94 100644 (file)
@@ -85,11 +85,14 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
   } 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",
@@ -118,6 +121,25 @@ static int DecodeIt(Isolate* isolate, std::ostream* os,
         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);
index 7180b811499dbd3355d92f7d510a5ea076f61a5d..1eb12953035604b4811d00075b782687a3470bc9 100644 (file)
@@ -22,6 +22,8 @@
 # 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
index 19c5cacee6bbc6398507fd45e1df2e47e986872e..2c6cac669317f3f5c1cae58580f65527f9f54f91 100644 (file)
@@ -13,7 +13,7 @@
 #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
 
@@ -479,7 +479,11 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
   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);
 }
index 0c9df8e51be5b97523b3480074ba060e232f1dd8..fcc0b190a46a8ca1f0b5f15c29856014ee7e15c3 100644 (file)
@@ -899,6 +899,23 @@ void Deserializer::ReadObject(int space_number, Object** write_back) {
     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
 }
 
 
index 40c8b404fdfd57ebb7ce3a7db98a814705aa5994..c6fe55b5c65d309c190ff3bd3568247c5dc7774f 100644 (file)
@@ -408,9 +408,9 @@ void init_memcopy_functions() {
 
 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;
index 15a4bab28c2a271457e36fbecc3965e276920074..25c67350358743f5c293836109adcc2e7fda6ca4 100644 (file)
   'test-accessors/Gc' : [SKIP],
 
 }],  # 'arch == nacl_ia32 or arch == nacl_x64'
+
+['arch == ppc64', {
+  #issue 2857
+  'test-log/EquivalenceOfLoggingAndTraversal' : [SKIP],
+}],  # 'arch == ppc64'
 ]
index 2f6f92eb19c26556104a6920a6958d51b5a7f7c6..a877ee9e1ce6ca34549dda52e45d73e7e85ffd3b 100644 (file)
@@ -65,6 +65,12 @@ class SimulatorHelper {
         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
   }
 
index f6b98396e58f442812026678ac28a102592c4327..29d31032e741cc11a40179289747227b93068797 100644 (file)
@@ -135,7 +135,7 @@ if (this.os && os.system) {
       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);
 
     }
 
index b23d7e530d4714e98f23d6be7c8586258dbc3234..b0c7407f0c8631f1e2504ed6b21054b53dac47d5 100644 (file)
   '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'
 
 ##############################################################################
index a5763a6f8105ebaaf4823608ee9624568206b3c8..9538646d5d0c6d214d2ed7736efa88db78d63617 100644 (file)
             ],
           }
         ],
+        ['OS=="aix"', {
+          'sources': [
+            '../../src/base/platform/platform-aix.cc',
+            '../../src/base/platform/platform-posix.cc'
+          ]},
+        ],
         ['OS=="solaris"', {
             'link_settings': {
               'libraries': [
index 9af864df3c57651abe89762df03ba239b2d2b474..ec79cbb51de5f22a5db8bfeae051857f0273f469 100755 (executable)
@@ -397,6 +397,7 @@ def Execute(arch, mode, args, options, suites, workspace):
     "tsan": False,
     "msan": False,
     "dcheck_always_on": options.dcheck_always_on,
+    "byteorder": sys.byteorder,
   }
   all_tests = []
   num_tests = 0
index afc9d83fa3c769cef91ad1c1575ec4199bb54d4c..8627319359418391efbbeb9e044365e7b2731d81 100755 (executable)
@@ -531,7 +531,8 @@ def Execute(arch, mode, args, options, suites, workspace):
 
   # 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 = {
@@ -549,6 +550,7 @@ def Execute(arch, mode, args, options, suites, workspace):
     "tsan": options.tsan,
     "msan": options.msan,
     "dcheck_always_on": options.dcheck_always_on,
+    "byteorder": sys.byteorder,
   }
   all_tests = []
   num_tests = 0
index 13d62cb472d40d5dd6c06df08e7a3062fa4e94ba..a52fa566b85b1213051efc913cc89030b6fc8c9f 100644 (file)
@@ -53,7 +53,8 @@ DEFS = {FAIL_OK: [FAIL, OKAY],
 
 # 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
index 961b4924740e9b2f634313230e0bc48b51326d4a..13bd28012e7fb5cb8865d43871c4ed69cefbcf66 100644 (file)
@@ -73,6 +73,8 @@ def GuessOS():
     return 'solaris'
   elif system == 'NetBSD':
     return 'netbsd'
+  elif system == 'AIX':
+    return 'aix'
   else:
     return None
 
@@ -99,7 +101,7 @@ def DefaultArch():
     return 'ia32'
   elif machine == 'amd64':
     return 'ia32'
-  elif id == 'ppc64':
+  elif machine == 'ppc64':
     return 'ppc'
   else:
     return None