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. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// Platform-specific code for MacOS goes here. For the POSIX-compatible 6e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// parts, the implementation is in platform-posix.cc. 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org#include <dlfcn.h> 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <unistd.h> 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <sys/mman.h> 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <mach/mach_init.h> 12e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#include <mach-o/dyld.h> 13e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#include <mach-o/getsect.h> 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <AvailabilityMacros.h> 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <pthread.h> 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <semaphore.h> 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <signal.h> 209155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org#include <libkern/OSAtomic.h> 212abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#include <mach/mach.h> 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <mach/semaphore.h> 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <mach/task.h> 24c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org#include <mach/vm_statistics.h> 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <sys/time.h> 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <sys/resource.h> 27381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org#include <sys/types.h> 28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#include <sys/sysctl.h> 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdarg.h> 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdlib.h> 31c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#include <string.h> 32381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org#include <errno.h> 33381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef MAP_TYPE 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform.h" 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// Constants used for mmap. 46c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// kMmapFd is used to pass vm_alloc flags to tag the region with the user 47c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// defined tag 255 This helps identify V8-allocated regions in memory analysis 48c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// tools like vmmap(1). 49c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgstatic const int kMmapFd = VM_MAKE_TAG(255); 50c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgstatic const off_t kMmapFdOffset = 0; 51c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 52c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 537276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid* OS::Allocate(const size_t requested, 547276f14ca716596e0a0d17539516370c1f453847kasper.lund size_t* allocated, 55f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org bool is_executable) { 567276f14ca716596e0a0d17539516370c1f453847kasper.lund const size_t msize = RoundUp(requested, getpagesize()); 57f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 58b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* mbase = mmap(OS::GetRandomMmapAddr(), 59b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org msize, 60b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org prot, 61c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org MAP_PRIVATE | MAP_ANON, 62b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kMmapFd, 63b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kMmapFdOffset); 641845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (mbase == MAP_FAILED) return NULL; 657276f14ca716596e0a0d17539516370c1f453847kasper.lund *allocated = msize; 6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mbase; 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PosixMemoryMappedFile(FILE* file, void* memory, int size) 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : file_(file), memory_(memory), size_(size) { } 7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~PosixMemoryMappedFile(); 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void* memory() { return memory_; } 760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() { return size_; } 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE* file_; 7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory_; 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int size_; 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 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 = 92b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mmap(OS::GetRandomMmapAddr(), 93b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org size, 94b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org PROT_READ | PROT_WRITE, 95b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org MAP_SHARED, 96b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org fileno(file), 97b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 0); 980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new PosixMemoryMappedFile(file, memory, size); 990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 1000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* initial) { 10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE* file = fopen(name, "w+"); 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file == NULL) return NULL; 106303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org int result = fwrite(initial, size, 1, file); 107303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result < 1) { 108303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org fclose(file); 109303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return NULL; 110303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory = 112b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mmap(OS::GetRandomMmapAddr(), 113b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org size, 114b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org PROT_READ | PROT_WRITE, 115b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org MAP_SHARED, 116b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org fileno(file), 117b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 0); 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return new PosixMemoryMappedFile(file, memory, size); 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenPosixMemoryMappedFile::~PosixMemoryMappedFile() { 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (memory_) OS::Free(memory_, size_); 12443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fclose(file_); 12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1281845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 1291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::vector<SharedLibraryAddress> result; 130e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org unsigned int images_count = _dyld_image_count(); 131e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org for (unsigned int i = 0; i < images_count; ++i) { 132e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const mach_header* header = _dyld_get_image_header(i); 133e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (header == NULL) continue; 134a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#if V8_HOST_ARCH_X64 135a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org uint64_t size; 136a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org char* code_ptr = getsectdatafromheader_64( 137a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org reinterpret_cast<const mach_header_64*>(header), 138a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org SEG_TEXT, 139a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org SECT_TEXT, 140a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org &size); 141a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#else 142e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org unsigned int size; 143e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size); 144a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 145e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (code_ptr == NULL) continue; 146e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const uintptr_t slide = _dyld_get_image_vmaddr_slide(i); 147e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide; 1481845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result.push_back( 1491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org SharedLibraryAddress(_dyld_get_image_name(i), start, start + size)); 150e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1511845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1554a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() { 1564a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 1574a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1584a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1596b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 16077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(time)) return ""; 161e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 162b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 163b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (NULL == t) return ""; 164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return t->tm_zone; 165b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 166b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 167b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1686b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) { 169b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org time_t tv = time(NULL); 170b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // tm_gmtoff includes any daylight savings offset, so subtract it. 172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return static_cast<double>(t->tm_gmtoff * msPerSecond - 173b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 174b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 175b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size) 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(ReserveRegion(size)), size_(size) { } 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size, size_t alignment) 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(NULL), size_(0) { 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t request_size = RoundUp(size + alignment, 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<intptr_t>(OS::AllocateAlignment())); 189b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* reservation = mmap(OS::GetRandomMmapAddr(), 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size, 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset); 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (reservation == MAP_FAILED) return; 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address base = static_cast<Address>(reservation); 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address aligned_base = RoundUp(base, alignment); 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_LE(base, aligned_base); 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Unmap extra memory reserved before and after the desired block. 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (aligned_base != base) { 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t prefix_size = static_cast<size_t>(aligned_base - base); 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OS::Free(base, prefix_size); 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size -= prefix_size; 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_LE(aligned_size, request_size); 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (aligned_size != request_size) { 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t suffix_size = request_size - aligned_size; 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OS::Free(aligned_base + aligned_size, suffix_size); 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size -= suffix_size; 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(aligned_size == request_size); 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = static_cast<void*>(aligned_base); 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = aligned_size; 22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVirtualMemory::~VirtualMemory() { 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsReserved()) { 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool result = ReleaseRegion(address(), size()); 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(result); 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::IsReserved() { 234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return address_ != NULL; 235e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 237e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid VirtualMemory::Reset() { 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = NULL; 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = 0; 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 244e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return CommitRegion(address, size, is_executable); 246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 247e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 248e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) { 250e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return UncommitRegion(address, size); 251e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 252e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 253e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 254e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Guard(void* address) { 255e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::Guard(address, OS::CommitPageSize()); 256e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 257e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 258e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid* VirtualMemory::ReserveRegion(size_t size) { 261b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* result = mmap(OS::GetRandomMmapAddr(), 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset); 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (result == MAP_FAILED) return NULL; 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return result; 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::CommitRegion(void* address, 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size, 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool is_executable) { 277f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MAP_FAILED == mmap(address, 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com prot, 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MAP_PRIVATE | MAP_ANON | MAP_FIXED, 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset)) { 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::UncommitRegion(void* address, size_t size) { 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return mmap(address, 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 294a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset) != MAP_FAILED; 297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::ReleaseRegion(void* address, size_t size) { 301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return munmap(address, size) == 0; 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 304f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 30572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 30672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 30772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 30872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 310