105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 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. 4a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 5e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// Platform-specific code for FreeBSD goes here. For the POSIX-compatible 6e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// parts, the implementation is in platform-posix.cc. 7a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 8a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <pthread.h> 9a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <semaphore.h> 10a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <signal.h> 11a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/time.h> 12a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/resource.h> 13381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org#include <sys/types.h> 14a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/ucontext.h> 15a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <stdlib.h> 16a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 17a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/types.h> // mmap & munmap 18a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/mman.h> // mmap & munmap 19a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/stat.h> // open 20a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <sys/fcntl.h> // open 21a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <unistd.h> // getpagesize 22badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org// If you don't have execinfo.h then you need devel/libexecinfo from ports. 23a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <strings.h> // index 24a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <errno.h> 25a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <stdarg.h> 26a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include <limits.h> 27a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 28a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef MAP_TYPE 29a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 31a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform.h" 33a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 34a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 396b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 4077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(time)) return ""; 41e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 42b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 43b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (NULL == t) return ""; 44b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return t->tm_zone; 45b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 46b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 47b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 486b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) { 49b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org time_t tv = time(NULL); 50b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 51b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // tm_gmtoff includes any daylight savings offset, so subtract it. 52b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return static_cast<double>(t->tm_gmtoff * msPerSecond - 53b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 57a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgvoid* OS::Allocate(const size_t requested, 58a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org size_t* allocated, 59a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bool executable) { 60a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org const size_t msize = RoundUp(requested, getpagesize()); 61a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); 62a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); 63a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (mbase == MAP_FAILED) return NULL; 65a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org *allocated = msize; 66a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return mbase; 67a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 68a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 69a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 70a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 71a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org public: 72a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org PosixMemoryMappedFile(FILE* file, void* memory, int size) 73a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org : file_(file), memory_(memory), size_(size) { } 74a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org virtual ~PosixMemoryMappedFile(); 75a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org virtual void* memory() { return memory_; } 760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() { return size_; } 77a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org private: 78a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FILE* file_; 79a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org void* memory_; 80a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int size_; 81a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}; 82a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 83a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* file = fopen(name, "r+"); 860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (file == NULL) return NULL; 870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org fseek(file, 0, SEEK_END); 890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size = ftell(file); 900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory = 920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new PosixMemoryMappedFile(file, memory, size); 940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 950a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 97a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org void* initial) { 99a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org FILE* file = fopen(name, "w+"); 100a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (file == NULL) return NULL; 101a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int result = fwrite(initial, size, 1, file); 102a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (result < 1) { 103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org fclose(file); 104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return NULL; 105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org void* memory = 107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 108a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return new PosixMemoryMappedFile(file, memory, size); 109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 111a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgPosixMemoryMappedFile::~PosixMemoryMappedFile() { 113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (memory_) munmap(memory_, size_); 114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org fclose(file_); 115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 116a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic unsigned StringToLong(char* buffer) { 119a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return static_cast<unsigned>(strtol(buffer, NULL, 16)); // NOLINT 120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1231845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 1241845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::vector<SharedLibraryAddress> result; 125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const int MAP_LENGTH = 1024; 126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int fd = open("/proc/self/maps", O_RDONLY); 1271845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (fd < 0) return result; 128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org while (true) { 129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char addr_buffer[11]; 130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org addr_buffer[0] = '0'; 131a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org addr_buffer[1] = 'x'; 132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org addr_buffer[10] = 0; 133a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int result = read(fd, addr_buffer + 2, 8); 134a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (result < 8) break; 135a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org unsigned start = StringToLong(addr_buffer); 136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result = read(fd, addr_buffer + 2, 1); 137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (result < 1) break; 138a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (addr_buffer[2] != '-') break; 139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result = read(fd, addr_buffer + 2, 8); 140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (result < 8) break; 141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org unsigned end = StringToLong(addr_buffer); 142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char buffer[MAP_LENGTH]; 143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org int bytes_read = -1; 144a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org do { 145a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org bytes_read++; 146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (bytes_read >= MAP_LENGTH - 1) 147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org break; 148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org result = read(fd, buffer + bytes_read, 1); 149a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (result < 1) break; 150a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } while (buffer[bytes_read] != '\n'); 151a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org buffer[bytes_read] = 0; 152a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Ignore mappings that are not executable. 153a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (buffer[3] != 'x') continue; 154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org char* start_of_path = index(buffer, '/'); 155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // There may be no filename in this line. Skip to next. 156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (start_of_path == NULL) continue; 157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org buffer[bytes_read] = 0; 1581845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result.push_back(SharedLibraryAddress(start_of_path, start, end)); 159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org close(fd); 1611845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1654a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() { 1664a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 1674a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1684a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 169a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 170a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Constants used for mmap. 171a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic const int kMmapFd = -1; 172a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic const int kMmapFdOffset = 0; 173a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 174e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 176a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 177e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 178e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgVirtualMemory::VirtualMemory(size_t size) 179e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : address_(ReserveRegion(size)), size_(size) { } 180a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 181a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgVirtualMemory::VirtualMemory(size_t size, size_t alignment) 183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org : address_(NULL), size_(0) { 184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); 185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_t request_size = RoundUp(size + alignment, 186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org static_cast<intptr_t>(OS::AllocateAlignment())); 187c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void* reservation = mmap(OS::GetRandomMmapAddr(), 188c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org request_size, 189c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PROT_NONE, 190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFd, 192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFdOffset); 193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (reservation == MAP_FAILED) return; 194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Address base = static_cast<Address>(reservation); 196c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Address aligned_base = RoundUp(base, alignment); 197c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT_LE(base, aligned_base); 198c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Unmap extra memory reserved before and after the desired block. 200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (aligned_base != base) { 201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_t prefix_size = static_cast<size_t>(aligned_base - base); 202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org OS::Free(base, prefix_size); 203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org request_size -= prefix_size; 204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 207c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT_LE(aligned_size, request_size); 208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (aligned_size != request_size) { 210c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_t suffix_size = request_size - aligned_size; 211c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org OS::Free(aligned_base + aligned_size, suffix_size); 212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org request_size -= suffix_size; 213c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 214c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(aligned_size == request_size); 216c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 217c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org address_ = static_cast<void*>(aligned_base); 218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_ = aligned_size; 219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 221c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgVirtualMemory::~VirtualMemory() { 223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (IsReserved()) { 224c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org bool result = ReleaseRegion(address(), size()); 225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(result); 226c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org USE(result); 227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 231a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgbool VirtualMemory::IsReserved() { 232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return address_ != NULL; 233a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 236c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid VirtualMemory::Reset() { 237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org address_ = NULL; 238c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size_ = 0; 239c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return CommitRegion(address, size, is_executable); 244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) { 248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return UncommitRegion(address, size); 249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 252ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.orgbool VirtualMemory::Guard(void* address) { 253ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org OS::Guard(address, OS::CommitPageSize()); 254ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org return true; 255ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org} 256ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 257ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 258c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid* VirtualMemory::ReserveRegion(size_t size) { 259c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void* result = mmap(OS::GetRandomMmapAddr(), 260c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size, 261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PROT_NONE, 262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFd, 264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFdOffset); 265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 266c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (result == MAP_FAILED) return NULL; 267c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return result; 269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 271c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 274c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (MAP_FAILED == mmap(base, 275c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size, 276c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org prot, 277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org MAP_PRIVATE | MAP_ANON | MAP_FIXED, 278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFd, 279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFdOffset)) { 280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return false; 281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return true; 283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 285a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 286c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool VirtualMemory::UncommitRegion(void* base, size_t size) { 287c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return mmap(base, 288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org size, 289c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org PROT_NONE, 290a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, 291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFd, 292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org kMmapFdOffset) != MAP_FAILED; 293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 295c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool VirtualMemory::ReleaseRegion(void* base, size_t size) { 297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return munmap(base, size) == 0; 298a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} 299a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 300a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 30172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 30272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // TODO(alph): implement for the platform. 30372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 30472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 30572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 306a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} } // namespace v8::internal 307