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