19ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 49ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 59ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// Platform-specific code for QNX goes here. For the POSIX-compatible 69ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// parts the implementation is in platform-posix.cc. 79ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 89ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <pthread.h> 99ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <semaphore.h> 109ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <signal.h> 119ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/time.h> 129ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/resource.h> 139ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/types.h> 149ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <stdlib.h> 159ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <ucontext.h> 169ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <backtrace.h> 179ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 189ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// QNX requires memory pages to be marked as executable. 199ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// Otherwise, the OS raises an exception when executing code in that page. 209ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/types.h> // mmap & munmap 219ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/mman.h> // mmap & munmap 229ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/stat.h> // open 239ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <fcntl.h> // open 249ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <unistd.h> // sysconf 259ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <strings.h> // index 269ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <errno.h> 279ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <stdarg.h> 289ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#include <sys/procfs.h> 299ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 309ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#undef MAP_TYPE 319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 339ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform.h" 359ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 369ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 379ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgnamespace v8 { 389ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgnamespace internal { 399ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 409ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// 0 is never a valid thread id on Qnx since tids and pids share a 419ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// name space and pid 0 is reserved (see man 2 kill). 429ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgstatic const pthread_t kNoThread = (pthread_t) 0; 439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 449ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 459ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#ifdef __arm__ 469ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 479ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool OS::ArmUsingHardFloat() { 489ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify 499ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // the Floating Point ABI used (PCS stands for Procedure Call Standard). 509ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // We use these as well as a couple of other defines to statically determine 519ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // what FP ABI used. 529ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // GCC versions 4.4 and below don't support hard-fp. 539ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or 549ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // __ARM_PCS_VFP. 559ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 569ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#define GCC_VERSION (__GNUC__ * 10000 \ 579ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org + __GNUC_MINOR__ * 100 \ 589ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org + __GNUC_PATCHLEVEL__) 599ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#if GCC_VERSION >= 40600 609ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#if defined(__ARM_PCS_VFP) 619ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return true; 629ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#else 639ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return false; 649ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#endif 659ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 669ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#elif GCC_VERSION < 40500 679ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return false; 689ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 699ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#else 709ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#if defined(__ARM_PCS_VFP) 719ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return true; 729ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \ 739ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org !defined(__VFP_FP__) 749ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return false; 759ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#else 769ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#error "Your version of GCC does not report the FP ABI compiled for." \ 779ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org "Please report it on this issue" \ 789ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org "http://code.google.com/p/v8/issues/detail?id=2140" 799ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 809ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#endif 819ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#endif 829ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#undef GCC_VERSION 839ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 849ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 859ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#endif // __arm__ 869ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 879ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 886b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 899ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (std::isnan(time)) return ""; 909ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 919ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org struct tm* t = localtime(&tv); 929ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (NULL == t) return ""; 939ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return t->tm_zone; 949ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 959ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 969ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 976b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) { 989ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org time_t tv = time(NULL); 999ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org struct tm* t = localtime(&tv); 1009ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // tm_gmtoff includes any daylight savings offset, so subtract it. 1019ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return static_cast<double>(t->tm_gmtoff * msPerSecond - 1029ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 1039ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 1049ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1059ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1069ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgvoid* OS::Allocate(const size_t requested, 1079ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_t* allocated, 1089ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org bool is_executable) { 1099ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org const size_t msize = RoundUp(requested, AllocateAlignment()); 1109ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 1119ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* addr = OS::GetRandomMmapAddr(); 1129ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 1131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (mbase == MAP_FAILED) return NULL; 1149ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org *allocated = msize; 1159ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return mbase; 1169ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 1179ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1189ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1199ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 1209ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org public: 1219ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PosixMemoryMappedFile(FILE* file, void* memory, int size) 1229ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org : file_(file), memory_(memory), size_(size) { } 1239ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org virtual ~PosixMemoryMappedFile(); 1249ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org virtual void* memory() { return memory_; } 1259ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org virtual int size() { return size_; } 1269ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org private: 1279ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org FILE* file_; 1289ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* memory_; 1299ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int size_; 1309ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org}; 1319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1329ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1339ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 1349ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org FILE* file = fopen(name, "r+"); 1359ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (file == NULL) return NULL; 1369ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1379ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org fseek(file, 0, SEEK_END); 1389ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int size = ftell(file); 1399ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1409ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* memory = 1419ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org mmap(OS::GetRandomMmapAddr(), 1429ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size, 1439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PROT_READ | PROT_WRITE, 1449ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_SHARED, 1459ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org fileno(file), 1469ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 0); 1479ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return new PosixMemoryMappedFile(file, memory, size); 1489ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 1499ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1509ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1519ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 1529ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* initial) { 1539ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org FILE* file = fopen(name, "w+"); 1549ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (file == NULL) return NULL; 1559ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int result = fwrite(initial, size, 1, file); 1569ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (result < 1) { 1579ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org fclose(file); 1589ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return NULL; 1599ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 1609ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* memory = 1619ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org mmap(OS::GetRandomMmapAddr(), 1629ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size, 1639ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PROT_READ | PROT_WRITE, 1649ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_SHARED, 1659ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org fileno(file), 1669ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 0); 1679ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return new PosixMemoryMappedFile(file, memory, size); 1689ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 1699ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1709ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1719ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgPosixMemoryMappedFile::~PosixMemoryMappedFile() { 1729ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (memory_) OS::Free(memory_, size_); 1739ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org fclose(file_); 1749ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 1759ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1769ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 1781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::vector<SharedLibraryAddress> result; 1799ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org procfs_mapinfo *mapinfos = NULL, *mapinfo; 1809ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int proc_fd, num, i; 1819ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1829ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org struct { 1839ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org procfs_debuginfo info; 1849ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org char buff[PATH_MAX]; 1859ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } map; 1869ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1879ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org char buf[PATH_MAX + 1]; 1889ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org snprintf(buf, PATH_MAX + 1, "/proc/%d/as", getpid()); 1899ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1909ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if ((proc_fd = open(buf, O_RDONLY)) == -1) { 1919ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org close(proc_fd); 1921845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 1939ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 1949ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 1959ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org /* Get the number of map entries. */ 1969ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (devctl(proc_fd, DCMD_PROC_MAPINFO, NULL, 0, &num) != EOK) { 1979ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org close(proc_fd); 1981845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 1999ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2009ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2019ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org mapinfos = reinterpret_cast<procfs_mapinfo *>( 2029ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org malloc(num * sizeof(procfs_mapinfo))); 2039ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (mapinfos == NULL) { 2049ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org close(proc_fd); 2051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 2069ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2079ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2089ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org /* Fill the map entries. */ 2099ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (devctl(proc_fd, DCMD_PROC_PAGEDATA, 2109ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org mapinfos, num * sizeof(procfs_mapinfo), &num) != EOK) { 2119ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org free(mapinfos); 2129ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org close(proc_fd); 2131845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 2149ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2159ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2169ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org for (i = 0; i < num; i++) { 2179ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org mapinfo = mapinfos + i; 2189ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (mapinfo->flags & MAP_ELF) { 2199ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org map.info.vaddr = mapinfo->vaddr; 2209ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) { 2219ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org continue; 2229ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result.push_back(SharedLibraryAddress( 2241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org map.info.path, mapinfo->vaddr, mapinfo->vaddr + mapinfo->size)); 2259ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2269ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2279ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org free(mapinfos); 2289ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org close(proc_fd); 2291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 2309ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 2319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2329ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2339ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgvoid OS::SignalCodeMovingGC() { 2349ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 2359ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2369ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2379ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org// Constants used for mmap. 2389ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgstatic const int kMmapFd = -1; 2399ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgstatic const int kMmapFdOffset = 0; 2409ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2419ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2429ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 2439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2449ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2459ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgVirtualMemory::VirtualMemory(size_t size) 2469ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org : address_(ReserveRegion(size)), size_(size) { } 2479ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2489ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2499ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgVirtualMemory::VirtualMemory(size_t size, size_t alignment) 2509ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org : address_(NULL), size_(0) { 2519ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); 2529ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_t request_size = RoundUp(size + alignment, 2539ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org static_cast<intptr_t>(OS::AllocateAlignment())); 2549ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* reservation = mmap(OS::GetRandomMmapAddr(), 2559ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org request_size, 2569ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PROT_NONE, 2579ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY, 2589ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFd, 2599ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFdOffset); 2609ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (reservation == MAP_FAILED) return; 2619ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2629ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org Address base = static_cast<Address>(reservation); 2639ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org Address aligned_base = RoundUp(base, alignment); 2649ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org ASSERT_LE(base, aligned_base); 2659ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2669ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org // Unmap extra memory reserved before and after the desired block. 2679ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (aligned_base != base) { 2689ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_t prefix_size = static_cast<size_t>(aligned_base - base); 2699ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org OS::Free(base, prefix_size); 2709ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org request_size -= prefix_size; 2719ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2729ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2739ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 2749ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org ASSERT_LE(aligned_size, request_size); 2759ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2769ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (aligned_size != request_size) { 2779ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_t suffix_size = request_size - aligned_size; 2789ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org OS::Free(aligned_base + aligned_size, suffix_size); 2799ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org request_size -= suffix_size; 2809ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2819ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2829ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org ASSERT(aligned_size == request_size); 2839ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2849ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org address_ = static_cast<void*>(aligned_base); 2859ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_ = aligned_size; 2869ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 2879ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2889ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2899ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgVirtualMemory::~VirtualMemory() { 2909ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (IsReserved()) { 2919ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org bool result = ReleaseRegion(address(), size()); 2929ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org ASSERT(result); 2939ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org USE(result); 2949ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 2959ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 2969ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2979ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 2989ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::IsReserved() { 2999ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return address_ != NULL; 3009ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3019ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3029ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3039ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgvoid VirtualMemory::Reset() { 3049ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org address_ = NULL; 3059ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size_ = 0; 3069ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3079ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3089ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3099ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 3109ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return CommitRegion(address, size, is_executable); 3119ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3129ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3139ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3149ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) { 3159ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return UncommitRegion(address, size); 3169ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3179ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3189ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3199ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::Guard(void* address) { 3209ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org OS::Guard(address, OS::CommitPageSize()); 3219ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return true; 3229ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3239ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3249ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3259ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgvoid* VirtualMemory::ReserveRegion(size_t size) { 3269ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org void* result = mmap(OS::GetRandomMmapAddr(), 3279ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size, 3289ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PROT_NONE, 3299ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY, 3309ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFd, 3319ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFdOffset); 3329ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3339ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (result == MAP_FAILED) return NULL; 3349ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3359ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return result; 3369ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3379ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3389ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3399ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 3409ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 3419ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org if (MAP_FAILED == mmap(base, 3429ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size, 3439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org prot, 3449ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 3459ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFd, 3469ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFdOffset)) { 3479ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return false; 3489ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org } 3499ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3509ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return true; 3519ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3529ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3539ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3549ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::UncommitRegion(void* base, size_t size) { 3559ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return mmap(base, 3569ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org size, 3579ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org PROT_NONE, 3589ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LAZY, 3599ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFd, 3609ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org kMmapFdOffset) != MAP_FAILED; 3619ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3629ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3639ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3649ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::ReleaseRegion(void* base, size_t size) { 3659ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return munmap(base, size) == 0; 3669ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3679ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3689ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3699ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.orgbool VirtualMemory::HasLazyCommits() { 3709ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org return false; 3719ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} 3729ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 3739ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org} } // namespace v8::internal 374