V8 Project
platform-cygwin.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Platform-specific code for Cygwin goes here. For the POSIX-compatible
6 // parts, the implementation is in platform-posix.cc.
7 
8 #include <errno.h>
9 #include <pthread.h>
10 #include <semaphore.h>
11 #include <stdarg.h>
12 #include <strings.h> // index
13 #include <sys/mman.h> // mmap & munmap
14 #include <sys/time.h>
15 #include <unistd.h> // sysconf
16 
17 #include <cmath>
18 
19 #undef MAP_TYPE
20 
21 #include "src/base/macros.h"
23 #include "src/base/win32-headers.h"
24 
25 namespace v8 {
26 namespace base {
27 
28 
29 const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
30  if (std::isnan(time)) return "";
31  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
32  struct tm* t = localtime(&tv);
33  if (NULL == t) return "";
34  return tzname[0]; // The location of the timezone string on Cygwin.
35 }
36 
37 
39  // On Cygwin, struct tm does not contain a tm_gmtoff field.
40  time_t utc = time(NULL);
41  DCHECK(utc != -1);
42  struct tm* loc = localtime(&utc);
43  DCHECK(loc != NULL);
44  // time - localtime includes any daylight savings offset, so subtract it.
45  return static_cast<double>((mktime(loc) - utc) * msPerSecond -
46  (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
47 }
48 
49 
50 void* OS::Allocate(const size_t requested,
51  size_t* allocated,
52  bool is_executable) {
53  const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE));
54  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
55  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
56  if (mbase == MAP_FAILED) return NULL;
57  *allocated = msize;
58  return mbase;
59 }
60 
61 
63  public:
65  : file_(file), memory_(memory), size_(size) { }
66  virtual ~PosixMemoryMappedFile();
67  virtual void* memory() { return memory_; }
68  virtual int size() { return size_; }
69  private:
70  FILE* file_;
71  void* memory_;
72  int size_;
73 };
74 
75 
77  FILE* file = fopen(name, "r+");
78  if (file == NULL) return NULL;
79 
80  fseek(file, 0, SEEK_END);
81  int size = ftell(file);
82 
83  void* memory =
84  mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
85  return new PosixMemoryMappedFile(file, memory, size);
86 }
87 
88 
90  void* initial) {
91  FILE* file = fopen(name, "w+");
92  if (file == NULL) return NULL;
93  int result = fwrite(initial, size, 1, file);
94  if (result < 1) {
95  fclose(file);
96  return NULL;
97  }
98  void* memory =
99  mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
100  return new PosixMemoryMappedFile(file, memory, size);
101 }
102 
103 
105  if (memory_) munmap(memory_, size_);
106  fclose(file_);
107 }
108 
109 
110 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
111  std::vector<SharedLibraryAddresses> result;
112  // This function assumes that the layout of the file is as follows:
113  // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
114  // If we encounter an unexpected situation we abort scanning further entries.
115  FILE* fp = fopen("/proc/self/maps", "r");
116  if (fp == NULL) return result;
117 
118  // Allocate enough room to be able to store a full file name.
119  const int kLibNameLen = FILENAME_MAX + 1;
120  char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen));
121 
122  // This loop will terminate once the scanning hits an EOF.
123  while (true) {
124  uintptr_t start, end;
125  char attr_r, attr_w, attr_x, attr_p;
126  // Parse the addresses and permission bits at the beginning of the line.
127  if (fscanf(fp, "%" V8PRIxPTR "-%" V8PRIxPTR, &start, &end) != 2) break;
128  if (fscanf(fp, " %c%c%c%c", &attr_r, &attr_w, &attr_x, &attr_p) != 4) break;
129 
130  int c;
131  if (attr_r == 'r' && attr_w != 'w' && attr_x == 'x') {
132  // Found a read-only executable entry. Skip characters until we reach
133  // the beginning of the filename or the end of the line.
134  do {
135  c = getc(fp);
136  } while ((c != EOF) && (c != '\n') && (c != '/'));
137  if (c == EOF) break; // EOF: Was unexpected, just exit.
138 
139  // Process the filename if found.
140  if (c == '/') {
141  ungetc(c, fp); // Push the '/' back into the stream to be read below.
142 
143  // Read to the end of the line. Exit if the read fails.
144  if (fgets(lib_name, kLibNameLen, fp) == NULL) break;
145 
146  // Drop the newline character read by fgets. We do not need to check
147  // for a zero-length string because we know that we at least read the
148  // '/' character.
149  lib_name[strlen(lib_name) - 1] = '\0';
150  } else {
151  // No library name found, just record the raw address range.
152  snprintf(lib_name, kLibNameLen,
153  "%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
154  }
155  result.push_back(SharedLibraryAddress(lib_name, start, end));
156  } else {
157  // Entry not describing executable data. Skip to end of line to set up
158  // reading the next entry.
159  do {
160  c = getc(fp);
161  } while ((c != EOF) && (c != '\n'));
162  if (c == EOF) break;
163  }
164  }
165  free(lib_name);
166  fclose(fp);
167  return result;
168 }
169 
170 
172  // Nothing to do on Cygwin.
173 }
174 
175 
176 // The VirtualMemory implementation is taken from platform-win32.cc.
177 // The mmap-based virtual memory implementation as it is used on most posix
178 // platforms does not work well because Cygwin does not support MAP_FIXED.
179 // This causes VirtualMemory::Commit to not always commit the memory region
180 // specified.
181 
182 static void* RandomizedVirtualAlloc(size_t size, int action, int protection) {
183  LPVOID base = NULL;
184 
185  if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) {
186  // For exectutable pages try and randomize the allocation address
187  for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) {
188  base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection);
189  }
190  }
191 
192  // After three attempts give up and let the OS find an address to use.
193  if (base == NULL) base = VirtualAlloc(NULL, size, action, protection);
194 
195  return base;
196 }
197 
198 
199 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
200 
201 
203  : address_(ReserveRegion(size)), size_(size) { }
204 
205 
206 VirtualMemory::VirtualMemory(size_t size, size_t alignment)
207  : address_(NULL), size_(0) {
208  DCHECK((alignment % OS::AllocateAlignment()) == 0);
209  size_t request_size = RoundUp(size + alignment,
210  static_cast<intptr_t>(OS::AllocateAlignment()));
211  void* address = ReserveRegion(request_size);
212  if (address == NULL) return;
213  uint8_t* base = RoundUp(static_cast<uint8_t*>(address), alignment);
214  // Try reducing the size by freeing and then reallocating a specific area.
215  bool result = ReleaseRegion(address, request_size);
216  USE(result);
217  DCHECK(result);
218  address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
219  if (address != NULL) {
220  request_size = size;
221  DCHECK(base == static_cast<uint8_t*>(address));
222  } else {
223  // Resizing failed, just go with a bigger area.
224  address = ReserveRegion(request_size);
225  if (address == NULL) return;
226  }
227  address_ = address;
228  size_ = request_size;
229 }
230 
231 
233  if (IsReserved()) {
234  bool result = ReleaseRegion(address_, size_);
235  DCHECK(result);
236  USE(result);
237  }
238 }
239 
240 
242  return address_ != NULL;
243 }
244 
245 
247  address_ = NULL;
248  size_ = 0;
249 }
250 
251 
252 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
253  return CommitRegion(address, size, is_executable);
254 }
255 
256 
257 bool VirtualMemory::Uncommit(void* address, size_t size) {
258  DCHECK(IsReserved());
259  return UncommitRegion(address, size);
260 }
261 
262 
264  return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);
265 }
266 
267 
268 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
269  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
270  if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) {
271  return false;
272  }
273  return true;
274 }
275 
276 
277 bool VirtualMemory::Guard(void* address) {
278  if (NULL == VirtualAlloc(address,
280  MEM_COMMIT,
281  PAGE_NOACCESS)) {
282  return false;
283  }
284  return true;
285 }
286 
287 
288 bool VirtualMemory::UncommitRegion(void* base, size_t size) {
289  return VirtualFree(base, size, MEM_DECOMMIT) != 0;
290 }
291 
292 
293 bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
294  return VirtualFree(base, 0, MEM_RELEASE) != 0;
295 }
296 
297 
299  // TODO(alph): implement for the platform.
300  return false;
301 }
302 
303 } } // namespace v8::base
static MemoryMappedFile * create(const char *name, int size, void *initial)
static MemoryMappedFile * open(const char *name)
static void * GetRandomMmapAddr()
static size_t AllocateAlignment()
static void SignalCodeMovingGC()
static intptr_t CommitPageSize()
static void * Allocate(const size_t requested, size_t *allocated, bool is_executable)
static const char * LocalTimezone(double time, TimezoneCache *cache)
static std::vector< SharedLibraryAddress > GetSharedLibraryAddresses()
static double LocalTimeOffset(TimezoneCache *cache)
static const int msPerSecond
Definition: platform.h:303
PosixMemoryMappedFile(FILE *file, void *memory, int size)
bool Commit(void *address, size_t size, bool is_executable)
static bool UncommitRegion(void *base, size_t size)
static bool ReleaseRegion(void *base, size_t size)
bool Guard(void *address)
bool Uncommit(void *address, size_t size)
static bool CommitRegion(void *base, size_t size, bool is_executable)
static void * ReserveRegion(size_t size)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
void USE(T)
Definition: macros.h:322
T RoundUp(T x, intptr_t m)
Definition: macros.h:407
#define V8PRIxPTR
Definition: macros.h:363
static void * RandomizedVirtualAlloc(size_t size, int action, int protection)
const Register fp
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20