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 MacOS goes here. For the POSIX-compatible 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// parts, the implementation is in platform-posix.cc. 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <dlfcn.h> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach/mach_init.h> 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach-o/dyld.h> 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach-o/getsect.h> 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/mman.h> 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <unistd.h> 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <AvailabilityMacros.h> 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <errno.h> 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <libkern/OSAtomic.h> 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach/mach.h> 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach/semaphore.h> 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach/task.h> 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <mach/vm_statistics.h> 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <pthread.h> 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <semaphore.h> 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <signal.h> 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdarg.h> 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdlib.h> 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <string.h> 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/resource.h> 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/sysctl.h> 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/time.h> 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/types.h> 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath> 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAP_TYPE 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/macros.h" 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base { 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Constants used for mmap. 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// kMmapFd is used to pass vm_alloc flags to tag the region with the user 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// defined tag 255 This helps identify V8-allocated regions in memory analysis 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// tools like vmmap(1). 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFd = VM_MAKE_TAG(255); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const off_t kMmapFdOffset = 0; 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* OS::Allocate(const size_t requested, 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t* allocated, 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_executable) { 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const size_t msize = RoundUp(requested, getpagesize()); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* mbase = mmap(OS::GetRandomMmapAddr(), 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch msize, 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prot, 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON, 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 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(OS::GetRandomMmapAddr(), 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_READ | PROT_WRITE, 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_SHARED, 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fileno(file), 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* initial) { 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FILE* file = fopen(name, "w+"); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (file == NULL) return NULL; 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = fwrite(initial, size, 1, file); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result < 1) { 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* memory = 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mmap(OS::GetRandomMmapAddr(), 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_READ | PROT_WRITE, 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_SHARED, 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fileno(file), 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new PosixMemoryMappedFile(file, memory, size); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPosixMemoryMappedFile::~PosixMemoryMappedFile() { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (memory_) OS::Free(memory_, size_); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fclose(file_); 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::vector<SharedLibraryAddress> result; 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int images_count = _dyld_image_count(); 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned int i = 0; i < images_count; ++i) { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const mach_header* header = _dyld_get_image_header(i); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (header == NULL) continue; 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_HOST_ARCH_X64 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t size; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char* code_ptr = getsectdatafromheader_64( 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const mach_header_64*>(header), 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SEG_TEXT, 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SECT_TEXT, 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &size); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned int size; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_ptr == NULL) continue; 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uintptr_t slide = _dyld_get_image_vmaddr_slide(i); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide; 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result.push_back( 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedLibraryAddress(_dyld_get_image_name(i), start, start + size)); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid OS::SignalCodeMovingGC() { 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (std::isnan(time)) return ""; 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (NULL == t) return ""; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return t->tm_zone; 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble OS::LocalTimeOffset(TimezoneCache* cache) { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch time_t tv = time(NULL); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct tm* t = localtime(&tv); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tm_gmtoff includes any daylight savings offset, so subtract it. 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<double>(t->tm_gmtoff * msPerSecond - 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size) 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(ReserveRegion(size)), size_(size) { } 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size, size_t alignment) 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : address_(NULL), size_(0) { 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((alignment % OS::AllocateAlignment()) == 0); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t request_size = RoundUp(size + alignment, 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<intptr_t>(OS::AllocateAlignment())); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* reservation = mmap(OS::GetRandomMmapAddr(), 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size, 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reservation == MAP_FAILED) return; 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* base = static_cast<uint8_t*>(reservation); 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint8_t* aligned_base = RoundUp(base, alignment); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(base, aligned_base); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Unmap extra memory reserved before and after the desired block. 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_base != base) { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t prefix_size = static_cast<size_t>(aligned_base - base); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(base, prefix_size); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= prefix_size; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(aligned_size, request_size); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (aligned_size != request_size) { 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t suffix_size = request_size - aligned_size; 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Free(aligned_base + aligned_size, suffix_size); 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch request_size -= suffix_size; 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(aligned_size == request_size); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = static_cast<void*>(aligned_base); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = aligned_size; 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::~VirtualMemory() { 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsReserved()) { 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = ReleaseRegion(address(), size()); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(result); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::IsReserved() { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return address_ != NULL; 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid VirtualMemory::Reset() { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch address_ = NULL; 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_ = 0; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CommitRegion(address, size, is_executable); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Uncommit(void* address, size_t size) { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return UncommitRegion(address, size); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Guard(void* address) { 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OS::Guard(address, OS::CommitPageSize()); 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* VirtualMemory::ReserveRegion(size_t size) { 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void* result = mmap(OS::GetRandomMmapAddr(), 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset); 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (result == MAP_FAILED) return NULL; 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::CommitRegion(void* address, 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t size, 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_executable) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (MAP_FAILED == mmap(address, 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prot, 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_FIXED, 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset)) { 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::UncommitRegion(void* address, size_t size) { 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return mmap(address, 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size, 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROT_NONE, 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFd, 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kMmapFdOffset) != MAP_FAILED; 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::ReleaseRegion(void* address, size_t size) { 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return munmap(address, size) == 0; 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::HasLazyCommits() { 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} } // namespace v8::base 311