1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Platform-specific code for FreeBSD goes here. For the POSIX-compatible 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// parts, the implementation is in platform-posix.cc. 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <pthread.h> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <semaphore.h> 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <signal.h> 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdlib.h> 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/resource.h> 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/time.h> 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/types.h> 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/ucontext.h> 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/fcntl.h> // open 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/mman.h> // mmap & munmap 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/stat.h> // open 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/types.h> // mmap & munmap 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <unistd.h> // getpagesize 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If you don't have execinfo.h then you need devel/libexecinfo from ports. 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <errno.h> 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <limits.h> 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdarg.h> 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <strings.h> // index 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath> 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAP_TYPE 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/macros.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base { 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (std::isnan(time)) return ""; 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (NULL == t) return ""; 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return t->tm_zone; 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble OS::LocalTimeOffset(TimezoneCache* cache) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = time(NULL); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tm_gmtoff includes any daylight savings offset, so subtract it. 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<double>(t->tm_gmtoff * msPerSecond - 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* OS::Allocate(const size_t requested, 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t* allocated, 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool executable) { 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const size_t msize = RoundUp(requested, getpagesize()); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mbase == MAP_FAILED) return NULL; 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *allocated = msize; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mbase; 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PosixMemoryMappedFile(FILE* file, void* memory, int size) 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : file_(file), memory_(memory), size_(size) { } 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~PosixMemoryMappedFile(); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void* memory() { return memory_; } 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual int size() { return size_; } 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file_; 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory_; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file = fopen(name, "r+"); 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (file == NULL) return NULL; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fseek(file, 0, SEEK_END); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = ftell(file); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory = 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* initial) { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file = fopen(name, "w+"); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (file == NULL) return NULL; 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = fwrite(initial, size, 1, file); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result < 1) { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory = 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPosixMemoryMappedFile::~PosixMemoryMappedFile() { 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (memory_) munmap(memory_, size_); 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file_); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic unsigned StringToLong(char* buffer) { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<unsigned>(strtol(buffer, NULL, 16)); // NOLINT 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::vector<SharedLibraryAddress> result; 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int MAP_LENGTH = 1024; 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int fd = open("/proc/self/maps", O_RDONLY); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fd < 0) return result; 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (true) { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char addr_buffer[11]; 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addr_buffer[0] = '0'; 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addr_buffer[1] = 'x'; 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addr_buffer[10] = 0; 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ssize_t bytes_read = read(fd, addr_buffer + 2, 8); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bytes_read < 8) break; 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned start = StringToLong(addr_buffer); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bytes_read = read(fd, addr_buffer + 2, 1); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bytes_read < 1) break; 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (addr_buffer[2] != '-') break; 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bytes_read = read(fd, addr_buffer + 2, 8); 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bytes_read < 8) break; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned end = StringToLong(addr_buffer); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char buffer[MAP_LENGTH]; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bytes_read = -1; 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch do { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bytes_read++; 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bytes_read >= MAP_LENGTH - 1) 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bytes_read = read(fd, buffer + bytes_read, 1); 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (bytes_read < 1) break; 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (buffer[bytes_read] != '\n'); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer[bytes_read] = 0; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ignore mappings that are not executable. 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer[3] != 'x') continue; 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char* start_of_path = index(buffer, '/'); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There may be no filename in this line. Skip to next. 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (start_of_path == NULL) continue; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer[bytes_read] = 0; 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result.push_back(SharedLibraryAddress(start_of_path, start, end)); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch close(fd); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid OS::SignalCodeMovingGC() { 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Constants used for mmap. 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFd = -1; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFdOffset = 0; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size) 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(ReserveRegion(size)), size_(size) { } 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size, size_t alignment) 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(NULL), size_(0) { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((alignment % OS::AllocateAlignment()) == 0); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t request_size = RoundUp(size + alignment, 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<intptr_t>(OS::AllocateAlignment())); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* reservation = mmap(OS::GetRandomMmapAddr(), 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size, 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reservation == MAP_FAILED) return; 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* base = static_cast<uint8_t*>(reservation); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* aligned_base = RoundUp(base, alignment); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(base, aligned_base); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unmap extra memory reserved before and after the desired block. 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_base != base) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t prefix_size = static_cast<size_t>(aligned_base - base); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(base, prefix_size); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= prefix_size; 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(aligned_size, request_size); 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_size != request_size) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t suffix_size = request_size - aligned_size; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(aligned_base + aligned_size, suffix_size); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= suffix_size; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(aligned_size == request_size); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = static_cast<void*>(aligned_base); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = aligned_size; 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::~VirtualMemory() { 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsReserved()) { 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = ReleaseRegion(address(), size()); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(result); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::IsReserved() { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return address_ != NULL; 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid VirtualMemory::Reset() { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = NULL; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = 0; 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CommitRegion(address, size, is_executable); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Uncommit(void* address, size_t size) { 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return UncommitRegion(address, size); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Guard(void* address) { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Guard(address, OS::CommitPageSize()); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* VirtualMemory::ReserveRegion(size_t size) { 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* result = mmap(OS::GetRandomMmapAddr(), 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == MAP_FAILED) return NULL; 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (MAP_FAILED == mmap(base, 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prot, 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_FIXED, 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset)) { 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::UncommitRegion(void* base, size_t size) { 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mmap(base, 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset) != MAP_FAILED; 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::ReleaseRegion(void* base, size_t size) { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return munmap(base, size) == 0; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::HasLazyCommits() { 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(alph): implement for the platform. 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} } // namespace v8::base 308