1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Platform-specific code for Solaris 10 goes here. For the POSIX-compatible
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// parts, the implementation is in platform-posix.cc.
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef __sparc
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# error "V8 does not support the SPARC CPU architecture."
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <dlfcn.h>  // dladdr
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <errno.h>
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <ieeefp.h>  // finite()
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <pthread.h>
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <semaphore.h>
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <signal.h>  // sigemptyset(), etc
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/mman.h>  // mmap()
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/regset.h>
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/stack.h>  // for stack alignment
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sys/time.h>  // gettimeofday(), timeradd()
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <time.h>
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <ucontext.h>  // walkstack(), getcontext()
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <unistd.h>  // getpagesize(), usleep()
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath>
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef MAP_TYPE
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/macros.h"
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h"
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// It seems there is a bug in some Solaris distributions (experienced in
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SunOS 5.10 Generic_141445-09) which make it difficult or impossible to
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// access signbit() despite the availability of other C99 math functions.
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef signbit
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace std {
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test sign - usually defined in math.h
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint signbit(double x) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need to take care of the special case of both positive and negative
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // versions of zero.
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (x == 0) {
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return fpclass(x) & FP_NZERO;
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This won't detect negative NaN but that should be okay since we don't
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // assume that behavior.
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return x < 0;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace std
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // signbit
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace base {
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* OS::LocalTimezone(double time, TimezoneCache* cache) {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (std::isnan(time)) return "";
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  struct tm* t = localtime(&tv);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (NULL == t) return "";
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return tzname[0];  // The location of the timezone string on Solaris.
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble OS::LocalTimeOffset(TimezoneCache* cache) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  tzset();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return -static_cast<double>(timezone * msPerSecond);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* OS::Allocate(const size_t requested,
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   size_t* allocated,
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   bool is_executable) {
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const size_t msize = RoundUp(requested, getpagesize());
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mbase == MAP_FAILED) return NULL;
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *allocated = msize;
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return mbase;
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PosixMemoryMappedFile : public OS::MemoryMappedFile {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PosixMemoryMappedFile(FILE* file, void* memory, int size)
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : file_(file), memory_(memory), size_(size) { }
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~PosixMemoryMappedFile();
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void* memory() { return memory_; }
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual int size() { return size_; }
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FILE* file_;
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* memory_;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size_;
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FILE* file = fopen(name, "r+");
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (file == NULL) return NULL;
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  fseek(file, 0, SEEK_END);
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int size = ftell(file);
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* memory =
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new PosixMemoryMappedFile(file, memory, size);
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void* initial) {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FILE* file = fopen(name, "w+");
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (file == NULL) return NULL;
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int result = fwrite(initial, size, 1, file);
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result < 1) {
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    fclose(file);
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* memory =
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new PosixMemoryMappedFile(file, memory, size);
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPosixMemoryMappedFile::~PosixMemoryMappedFile() {
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (memory_) munmap(memory_, size_);
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  fclose(file_);
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstd::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return std::vector<SharedLibraryAddress>();
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid OS::SignalCodeMovingGC() {
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Constants used for mmap.
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFd = -1;
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMmapFdOffset = 0;
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size)
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : address_(ReserveRegion(size)), size_(size) { }
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::VirtualMemory(size_t size, size_t alignment)
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : address_(NULL), size_(0) {
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((alignment % OS::AllocateAlignment()) == 0);
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t request_size = RoundUp(size + alignment,
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                static_cast<intptr_t>(OS::AllocateAlignment()));
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* reservation = mmap(OS::GetRandomMmapAddr(),
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           request_size,
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           PROT_NONE,
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           kMmapFd,
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           kMmapFdOffset);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reservation == MAP_FAILED) return;
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint8_t* base = static_cast<uint8_t*>(reservation);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint8_t* aligned_base = RoundUp(base, alignment);
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(base, aligned_base);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unmap extra memory reserved before and after the desired block.
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (aligned_base != base) {
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t prefix_size = static_cast<size_t>(aligned_base - base);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OS::Free(base, prefix_size);
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    request_size -= prefix_size;
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_LE(aligned_size, request_size);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (aligned_size != request_size) {
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t suffix_size = request_size - aligned_size;
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OS::Free(aligned_base + aligned_size, suffix_size);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    request_size -= suffix_size;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(aligned_size == request_size);
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  address_ = static_cast<void*>(aligned_base);
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_ = aligned_size;
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVirtualMemory::~VirtualMemory() {
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsReserved()) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool result = ReleaseRegion(address(), size());
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(result);
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    USE(result);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::IsReserved() {
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return address_ != NULL;
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid VirtualMemory::Reset() {
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  address_ = NULL;
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_ = 0;
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return CommitRegion(address, size, is_executable);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Uncommit(void* address, size_t size) {
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return UncommitRegion(address, size);
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::Guard(void* address) {
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OS::Guard(address, OS::CommitPageSize());
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* VirtualMemory::ReserveRegion(size_t size) {
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* result = mmap(OS::GetRandomMmapAddr(),
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      size,
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      PROT_NONE,
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      kMmapFd,
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      kMmapFdOffset);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result == MAP_FAILED) return NULL;
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (MAP_FAILED == mmap(base,
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         size,
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         prot,
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         kMmapFd,
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         kMmapFdOffset)) {
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::UncommitRegion(void* base, size_t size) {
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return mmap(base,
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              size,
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              PROT_NONE,
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED,
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              kMmapFd,
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              kMmapFdOffset) != MAP_FAILED;
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::ReleaseRegion(void* base, size_t size) {
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return munmap(base, size) == 0;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool VirtualMemory::HasLazyCommits() {
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(alph): implement for the platform.
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} }  // namespace v8::base
280