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.
4b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// Platform-specific code for Solaris 10 goes here. For the POSIX-compatible
6e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org// parts, the implementation is in platform-posix.cc.
7b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
8b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef __sparc
9b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org# error "V8 does not support the SPARC CPU architecture."
10b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif
11b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
12b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <sys/stack.h>  // for stack alignment
13b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <unistd.h>  // getpagesize(), usleep()
14b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <sys/mman.h>  // mmap()
159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#include <ucontext.h>  // walkstack(), getcontext()
169dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#include <dlfcn.h>     // dladdr
17b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <pthread.h>
18b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <semaphore.h>
19b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <time.h>
20b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <sys/time.h>  // gettimeofday(), timeradd()
21b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <errno.h>
22b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <ieeefp.h>  // finite()
23b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#include <signal.h>  // sigemptyset(), etc
24b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org#include <sys/regset.h>
25b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
26b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
27b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#undef MAP_TYPE
28b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
29196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
30b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/platform.h"
32b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// It seems there is a bug in some Solaris distributions (experienced in
359dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// SunOS 5.10 Generic_141445-09) which make it difficult or impossible to
369dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// access signbit() despite the availability of other C99 math functions.
379dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#ifndef signbit
3877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgnamespace std {
399dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com// Test sign - usually defined in math.h
409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comint signbit(double x) {
419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // We need to take care of the special case of both positive and negative
429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // versions of zero.
439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  if (x == 0) {
449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    return fpclass(x) & FP_NZERO;
459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  } else {
469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    // This won't detect negative NaN but that should be okay since we don't
479dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    // assume that behavior.
489dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com    return x < 0;
499dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  }
509dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com}
5177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org}  // namespace std
529dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // signbit
539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace v8 {
55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace internal {
56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
57b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
586b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgconst char* OS::LocalTimezone(double time, TimezoneCache* cache) {
5977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(time)) return "";
60e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
61b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  struct tm* t = localtime(&tv);
62b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (NULL == t) return "";
63b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return tzname[0];  // The location of the timezone string on Solaris.
64b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
65b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
66b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
676b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgdouble OS::LocalTimeOffset(TimezoneCache* cache) {
6872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  tzset();
6972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return -static_cast<double>(timezone * msPerSecond);
70b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
71b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
72b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
73b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid* OS::Allocate(const size_t requested,
74b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                   size_t* allocated,
75b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                   bool is_executable) {
76b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  const size_t msize = RoundUp(requested, getpagesize());
77b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
78b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
79b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
801845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  if (mbase == MAP_FAILED) return NULL;
81b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  *allocated = msize;
82b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return mbase;
83b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
84b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
85b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
86b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass PosixMemoryMappedFile : public OS::MemoryMappedFile {
87b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public:
88b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  PosixMemoryMappedFile(FILE* file, void* memory, int size)
89b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    : file_(file), memory_(memory), size_(size) { }
90b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  virtual ~PosixMemoryMappedFile();
91b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  virtual void* memory() { return memory_; }
920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  virtual int size() { return size_; }
93b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org private:
94b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  FILE* file_;
95b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void* memory_;
96b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int size_;
97b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org};
98b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
99b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
1013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  FILE* file = fopen(name, "r+");
1020a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  if (file == NULL) return NULL;
1030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  fseek(file, 0, SEEK_END);
1050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  int size = ftell(file);
1060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  void* memory =
1080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
1090a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  return new PosixMemoryMappedFile(file, memory, size);
1100a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
1110a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
113b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
114b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    void* initial) {
115b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  FILE* file = fopen(name, "w+");
116b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (file == NULL) return NULL;
117b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int result = fwrite(initial, size, 1, file);
118b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (result < 1) {
119b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    fclose(file);
120b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return NULL;
121b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
122b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void* memory =
123b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
124b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return new PosixMemoryMappedFile(file, memory, size);
125b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
126b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
127b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
128b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgPosixMemoryMappedFile::~PosixMemoryMappedFile() {
129b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (memory_) munmap(memory_, size_);
130b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  fclose(file_);
131b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
132b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
133b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1341845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.orgstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
1351845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org  return std::vector<SharedLibraryAddress>();
136b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
137b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
138b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1394a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() {
1404a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org}
1414a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
1424a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
143b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Constants used for mmap.
144b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgstatic const int kMmapFd = -1;
145b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgstatic const int kMmapFdOffset = 0;
146b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
147b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
14805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
14905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
150e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgVirtualMemory::VirtualMemory(size_t size)
152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    : address_(ReserveRegion(size)), size_(size) { }
153b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
154b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
15505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgVirtualMemory::VirtualMemory(size_t size, size_t alignment)
15605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    : address_(NULL), size_(0) {
15705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
15805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  size_t request_size = RoundUp(size + alignment,
15905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                                static_cast<intptr_t>(OS::AllocateAlignment()));
16005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void* reservation = mmap(OS::GetRandomMmapAddr(),
16105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           request_size,
16205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           PROT_NONE,
16305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
16405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           kMmapFd,
16505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           kMmapFdOffset);
16605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (reservation == MAP_FAILED) return;
16705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
16805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  Address base = static_cast<Address>(reservation);
16905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  Address aligned_base = RoundUp(base, alignment);
17005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  ASSERT_LE(base, aligned_base);
17105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
17205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Unmap extra memory reserved before and after the desired block.
17305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (aligned_base != base) {
17405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    size_t prefix_size = static_cast<size_t>(aligned_base - base);
17505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    OS::Free(base, prefix_size);
17605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    request_size -= prefix_size;
17705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
17805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
17905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
18005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  ASSERT_LE(aligned_size, request_size);
18105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
18205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (aligned_size != request_size) {
18305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    size_t suffix_size = request_size - aligned_size;
18405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    OS::Free(aligned_base + aligned_size, suffix_size);
18505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    request_size -= suffix_size;
18605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
18705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
18805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  ASSERT(aligned_size == request_size);
18905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
19005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  address_ = static_cast<void*>(aligned_base);
19105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  size_ = aligned_size;
19205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
19305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
19405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
195b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgVirtualMemory::~VirtualMemory() {
196b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  if (IsReserved()) {
19705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    bool result = ReleaseRegion(address(), size());
19805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    ASSERT(result);
19905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    USE(result);
200b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
201b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
202b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
203b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
204b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgbool VirtualMemory::IsReserved() {
20505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return address_ != NULL;
20605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
20705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
20805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
20905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgvoid VirtualMemory::Reset() {
21005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  address_ = NULL;
21105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  size_ = 0;
21205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
21305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
21405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
21505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
21605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return CommitRegion(address, size, is_executable);
21705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
21805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
21905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
22005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgbool VirtualMemory::Uncommit(void* address, size_t size) {
22105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return UncommitRegion(address, size);
22205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
22305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
22405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
225ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.orgbool VirtualMemory::Guard(void* address) {
226ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  OS::Guard(address, OS::CommitPageSize());
227ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  return true;
228ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org}
229ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
230ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
23105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgvoid* VirtualMemory::ReserveRegion(size_t size) {
23205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void* result = mmap(OS::GetRandomMmapAddr(),
23305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      size,
23405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      PROT_NONE,
23505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
23605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      kMmapFd,
23705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      kMmapFdOffset);
23805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
23905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (result == MAP_FAILED) return NULL;
24005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
24105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return result;
242b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
243b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
244b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
24505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
24605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
24705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (MAP_FAILED == mmap(base,
24805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         size,
24905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         prot,
25005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
25105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         kMmapFd,
25205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         kMmapFdOffset)) {
253b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return false;
254b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
255b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return true;
256b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
257b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
258b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
25905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgbool VirtualMemory::UncommitRegion(void* base, size_t size) {
26005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return mmap(base,
26105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org              size,
26205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org              PROT_NONE,
26305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED,
26405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org              kMmapFd,
26505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org              kMmapFdOffset) != MAP_FAILED;
26605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org}
26705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
26805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
26905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgbool VirtualMemory::ReleaseRegion(void* base, size_t size) {
27005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  return munmap(base, size) == 0;
271b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
272b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
273b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
27472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() {
27572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  // TODO(alph): implement for the platform.
27672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return false;
27772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
27872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org
279b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} }  // namespace v8::internal
280