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 <mach/mach_init.h> 10e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#include <mach-o/dyld.h> 11e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#include <mach-o/getsect.h> 124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/mman.h> 134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <unistd.h> 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <AvailabilityMacros.h> 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <errno.h> 189155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org#include <libkern/OSAtomic.h> 192abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org#include <mach/mach.h> 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <mach/semaphore.h> 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <mach/task.h> 22c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org#include <mach/vm_statistics.h> 234b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <pthread.h> 244b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <semaphore.h> 254b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <signal.h> 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdarg.h> 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <stdlib.h> 28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#include <string.h> 294b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/resource.h> 304b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/sysctl.h> 314b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/time.h> 324b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <sys/types.h> 33381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 34248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#include <cmath> 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#undef MAP_TYPE 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 385de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/macros.h" 395de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 435de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgnamespace base { 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// Constants used for mmap. 47c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// kMmapFd is used to pass vm_alloc flags to tag the region with the user 48c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// defined tag 255 This helps identify V8-allocated regions in memory analysis 49c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// tools like vmmap(1). 50c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgstatic const int kMmapFd = VM_MAKE_TAG(255); 51c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgstatic const off_t kMmapFdOffset = 0; 52c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 53c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 547276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid* OS::Allocate(const size_t requested, 557276f14ca716596e0a0d17539516370c1f453847kasper.lund size_t* allocated, 56f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org bool is_executable) { 577276f14ca716596e0a0d17539516370c1f453847kasper.lund const size_t msize = RoundUp(requested, getpagesize()); 58f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 59b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* mbase = mmap(OS::GetRandomMmapAddr(), 60b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org msize, 61b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org prot, 62c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org MAP_PRIVATE | MAP_ANON, 63b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kMmapFd, 64b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kMmapFdOffset); 651845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (mbase == MAP_FAILED) return NULL; 667276f14ca716596e0a0d17539516370c1f453847kasper.lund *allocated = msize; 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mbase; 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass PosixMemoryMappedFile : public OS::MemoryMappedFile { 7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PosixMemoryMappedFile(FILE* file, void* memory, int size) 7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : file_(file), memory_(memory), size_(size) { } 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~PosixMemoryMappedFile(); 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void* memory() { return memory_; } 770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() { return size_; } 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE* file_; 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory_; 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int size_; 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org FILE* file = fopen(name, "r+"); 870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (file == NULL) return NULL; 880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org fseek(file, 0, SEEK_END); 900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size = ftell(file); 910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory = 93b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mmap(OS::GetRandomMmapAddr(), 94b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org size, 95b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org PROT_READ | PROT_WRITE, 96b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org MAP_SHARED, 97b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org fileno(file), 98b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 0); 990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new PosixMemoryMappedFile(file, memory, size); 1000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 1010a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* initial) { 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE* file = fopen(name, "w+"); 10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file == NULL) return NULL; 107303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org int result = fwrite(initial, size, 1, file); 108303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result < 1) { 109303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org fclose(file); 110303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return NULL; 111303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory = 113b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org mmap(OS::GetRandomMmapAddr(), 114b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org size, 115b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org PROT_READ | PROT_WRITE, 116b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org MAP_SHARED, 117b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org fileno(file), 118b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 0); 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return new PosixMemoryMappedFile(file, memory, size); 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenPosixMemoryMappedFile::~PosixMemoryMappedFile() { 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (memory_) OS::Free(memory_, size_); 12543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen fclose(file_); 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1291845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() { 1301845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::vector<SharedLibraryAddress> result; 131e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org unsigned int images_count = _dyld_image_count(); 132e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org for (unsigned int i = 0; i < images_count; ++i) { 133e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const mach_header* header = _dyld_get_image_header(i); 134e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (header == NULL) continue; 135a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#if V8_HOST_ARCH_X64 136a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org uint64_t size; 137a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org char* code_ptr = getsectdatafromheader_64( 138a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org reinterpret_cast<const mach_header_64*>(header), 139a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org SEG_TEXT, 140a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org SECT_TEXT, 141a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org &size); 142a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#else 143e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org unsigned int size; 144e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size); 145a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 146e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org if (code_ptr == NULL) continue; 147e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const uintptr_t slide = _dyld_get_image_vmaddr_slide(i); 148e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide; 1491845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org result.push_back( 1501845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org SharedLibraryAddress(_dyld_get_image_name(i), start, start + size)); 151e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 1521845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org return result; 15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1564a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() { 1574a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 1584a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1594a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1606b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) { 16177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(time)) return ""; 162e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); 163b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (NULL == t) return ""; 165b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return t->tm_zone; 166b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 167b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 168b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1696b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) { 170b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org time_t tv = time(NULL); 171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org struct tm* t = localtime(&tv); 172b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // tm_gmtoff includes any daylight savings offset, so subtract it. 173b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return static_cast<double>(t->tm_gmtoff * msPerSecond - 174b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 175b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size) 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(ReserveRegion(size)), size_(size) { } 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size, size_t alignment) 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(NULL), size_(0) { 187e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org DCHECK((alignment % OS::AllocateAlignment()) == 0); 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t request_size = RoundUp(size + alignment, 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<intptr_t>(OS::AllocateAlignment())); 190b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* reservation = mmap(OS::GetRandomMmapAddr(), 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size, 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset); 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (reservation == MAP_FAILED) return; 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 198248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org uint8_t* base = static_cast<uint8_t*>(reservation); 199248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org uint8_t* aligned_base = RoundUp(base, alignment); 200e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(base, aligned_base); 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Unmap extra memory reserved before and after the desired block. 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (aligned_base != base) { 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t prefix_size = static_cast<size_t>(aligned_base - base); 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OS::Free(base, prefix_size); 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size -= prefix_size; 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t aligned_size = RoundUp(size, OS::AllocateAlignment()); 210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(aligned_size, request_size); 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (aligned_size != request_size) { 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t suffix_size = request_size - aligned_size; 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OS::Free(aligned_base + aligned_size, suffix_size); 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size -= suffix_size; 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(aligned_size == request_size); 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = static_cast<void*>(aligned_base); 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = aligned_size; 22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVirtualMemory::~VirtualMemory() { 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsReserved()) { 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool result = ReleaseRegion(address(), size()); 228e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result); 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 234e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::IsReserved() { 235e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return address_ != NULL; 236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 237e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 238e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid VirtualMemory::Reset() { 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = NULL; 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = 0; 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return CommitRegion(address, size, is_executable); 247e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 248e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 250e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) { 251e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return UncommitRegion(address, size); 252e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 253e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 254e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 255e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Guard(void* address) { 256e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::Guard(address, OS::CommitPageSize()); 257e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 258e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 260e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid* VirtualMemory::ReserveRegion(size_t size) { 262b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org void* result = mmap(OS::GetRandomMmapAddr(), 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset); 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (result == MAP_FAILED) return NULL; 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return result; 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::CommitRegion(void* address, 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size, 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool is_executable) { 278f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (MAP_FAILED == mmap(address, 280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com prot, 28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MAP_PRIVATE | MAP_ANON | MAP_FIXED, 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset)) { 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::UncommitRegion(void* address, size_t size) { 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return mmap(address, 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size, 294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PROT_NONE, 295a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED, 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFd, 297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kMmapFdOffset) != MAP_FAILED; 298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::ReleaseRegion(void* address, size_t size) { 302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return munmap(address, size) == 0; 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 305f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org 30672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 30772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 30872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 30972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 3105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org} } // namespace v8::base 311