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