v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
platform-cygwin.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 // Platform-specific code for Cygwin goes here. For the POSIX-compatible
29 // parts, the implementation is in platform-posix.cc.
30 
31 #include <errno.h>
32 #include <pthread.h>
33 #include <semaphore.h>
34 #include <stdarg.h>
35 #include <strings.h> // index
36 #include <sys/time.h>
37 #include <sys/mman.h> // mmap & munmap
38 #include <unistd.h> // sysconf
39 
40 #undef MAP_TYPE
41 
42 #include "v8.h"
43 
44 #include "platform.h"
45 #include "simulator.h"
46 #include "v8threads.h"
47 #include "vm-state-inl.h"
48 #include "win32-headers.h"
49 
50 namespace v8 {
51 namespace internal {
52 
53 
54 const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
55  if (std::isnan(time)) return "";
56  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
57  struct tm* t = localtime(&tv);
58  if (NULL == t) return "";
59  return tzname[0]; // The location of the timezone string on Cygwin.
60 }
61 
62 
64  // On Cygwin, struct tm does not contain a tm_gmtoff field.
65  time_t utc = time(NULL);
66  ASSERT(utc != -1);
67  struct tm* loc = localtime(&utc);
68  ASSERT(loc != NULL);
69  // time - localtime includes any daylight savings offset, so subtract it.
70  return static_cast<double>((mktime(loc) - utc) * msPerSecond -
71  (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
72 }
73 
74 
75 void* OS::Allocate(const size_t requested,
76  size_t* allocated,
77  bool is_executable) {
78  const size_t msize = RoundUp(requested, sysconf(_SC_PAGESIZE));
79  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
80  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
81  if (mbase == MAP_FAILED) {
82  LOG(Isolate::Current(), StringEvent("OS::Allocate", "mmap failed"));
83  return NULL;
84  }
85  *allocated = msize;
86  return mbase;
87 }
88 
89 
91  public:
92  PosixMemoryMappedFile(FILE* file, void* memory, int size)
93  : file_(file), memory_(memory), size_(size) { }
94  virtual ~PosixMemoryMappedFile();
95  virtual void* memory() { return memory_; }
96  virtual int size() { return size_; }
97  private:
98  FILE* file_;
99  void* memory_;
100  int size_;
101 };
102 
103 
105  FILE* file = fopen(name, "r+");
106  if (file == NULL) return NULL;
107 
108  fseek(file, 0, SEEK_END);
109  int size = ftell(file);
110 
111  void* memory =
112  mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
113  return new PosixMemoryMappedFile(file, memory, size);
114 }
115 
116 
118  void* initial) {
119  FILE* file = fopen(name, "w+");
120  if (file == NULL) return NULL;
121  int result = fwrite(initial, size, 1, file);
122  if (result < 1) {
123  fclose(file);
124  return NULL;
125  }
126  void* memory =
127  mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
128  return new PosixMemoryMappedFile(file, memory, size);
129 }
130 
131 
133  if (memory_) munmap(memory_, size_);
134  fclose(file_);
135 }
136 
137 
139  // This function assumes that the layout of the file is as follows:
140  // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name]
141  // If we encounter an unexpected situation we abort scanning further entries.
142  FILE* fp = fopen("/proc/self/maps", "r");
143  if (fp == NULL) return;
144 
145  // Allocate enough room to be able to store a full file name.
146  const int kLibNameLen = FILENAME_MAX + 1;
147  char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen));
148 
149  // This loop will terminate once the scanning hits an EOF.
150  while (true) {
151  uintptr_t start, end;
152  char attr_r, attr_w, attr_x, attr_p;
153  // Parse the addresses and permission bits at the beginning of the line.
154  if (fscanf(fp, "%" V8PRIxPTR "-%" V8PRIxPTR, &start, &end) != 2) break;
155  if (fscanf(fp, " %c%c%c%c", &attr_r, &attr_w, &attr_x, &attr_p) != 4) break;
156 
157  int c;
158  if (attr_r == 'r' && attr_w != 'w' && attr_x == 'x') {
159  // Found a read-only executable entry. Skip characters until we reach
160  // the beginning of the filename or the end of the line.
161  do {
162  c = getc(fp);
163  } while ((c != EOF) && (c != '\n') && (c != '/'));
164  if (c == EOF) break; // EOF: Was unexpected, just exit.
165 
166  // Process the filename if found.
167  if (c == '/') {
168  ungetc(c, fp); // Push the '/' back into the stream to be read below.
169 
170  // Read to the end of the line. Exit if the read fails.
171  if (fgets(lib_name, kLibNameLen, fp) == NULL) break;
172 
173  // Drop the newline character read by fgets. We do not need to check
174  // for a zero-length string because we know that we at least read the
175  // '/' character.
176  lib_name[strlen(lib_name) - 1] = '\0';
177  } else {
178  // No library name found, just record the raw address range.
179  snprintf(lib_name, kLibNameLen,
180  "%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
181  }
182  LOG(isolate, SharedLibraryEvent(lib_name, start, end));
183  } else {
184  // Entry not describing executable data. Skip to end of line to set up
185  // reading the next entry.
186  do {
187  c = getc(fp);
188  } while ((c != EOF) && (c != '\n'));
189  if (c == EOF) break;
190  }
191  }
192  free(lib_name);
193  fclose(fp);
194 }
195 
196 
198  // Nothing to do on Cygwin.
199 }
200 
201 
202 // The VirtualMemory implementation is taken from platform-win32.cc.
203 // The mmap-based virtual memory implementation as it is used on most posix
204 // platforms does not work well because Cygwin does not support MAP_FIXED.
205 // This causes VirtualMemory::Commit to not always commit the memory region
206 // specified.
207 
208 static void* GetRandomAddr() {
209  Isolate* isolate = Isolate::UncheckedCurrent();
210  // Note that the current isolate isn't set up in a call path via
211  // CpuFeatures::Probe. We don't care about randomization in this case because
212  // the code page is immediately freed.
213  if (isolate != NULL) {
214  // The address range used to randomize RWX allocations in OS::Allocate
215  // Try not to map pages into the default range that windows loads DLLs
216  // Use a multiple of 64k to prevent committing unused memory.
217  // Note: This does not guarantee RWX regions will be within the
218  // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
219 #ifdef V8_HOST_ARCH_64_BIT
220  static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
221  static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
222 #else
223  static const intptr_t kAllocationRandomAddressMin = 0x04000000;
224  static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
225 #endif
226  uintptr_t address =
227  (isolate->random_number_generator()->NextInt() << kPageSizeBits) |
228  kAllocationRandomAddressMin;
229  address &= kAllocationRandomAddressMax;
230  return reinterpret_cast<void *>(address);
231  }
232  return NULL;
233 }
234 
235 
236 static void* RandomizedVirtualAlloc(size_t size, int action, int protection) {
237  LPVOID base = NULL;
238 
239  if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) {
240  // For exectutable pages try and randomize the allocation address
241  for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) {
242  base = VirtualAlloc(GetRandomAddr(), size, action, protection);
243  }
244  }
245 
246  // After three attempts give up and let the OS find an address to use.
247  if (base == NULL) base = VirtualAlloc(NULL, size, action, protection);
248 
249  return base;
250 }
251 
252 
253 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
254 
255 
257  : address_(ReserveRegion(size)), size_(size) { }
258 
259 
260 VirtualMemory::VirtualMemory(size_t size, size_t alignment)
261  : address_(NULL), size_(0) {
262  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
263  size_t request_size = RoundUp(size + alignment,
264  static_cast<intptr_t>(OS::AllocateAlignment()));
265  void* address = ReserveRegion(request_size);
266  if (address == NULL) return;
267  Address base = RoundUp(static_cast<Address>(address), alignment);
268  // Try reducing the size by freeing and then reallocating a specific area.
269  bool result = ReleaseRegion(address, request_size);
270  USE(result);
271  ASSERT(result);
272  address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
273  if (address != NULL) {
274  request_size = size;
275  ASSERT(base == static_cast<Address>(address));
276  } else {
277  // Resizing failed, just go with a bigger area.
278  address = ReserveRegion(request_size);
279  if (address == NULL) return;
280  }
281  address_ = address;
282  size_ = request_size;
283 }
284 
285 
287  if (IsReserved()) {
288  bool result = ReleaseRegion(address_, size_);
289  ASSERT(result);
290  USE(result);
291  }
292 }
293 
294 
296  return address_ != NULL;
297 }
298 
299 
301  address_ = NULL;
302  size_ = 0;
303 }
304 
305 
306 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
307  return CommitRegion(address, size, is_executable);
308 }
309 
310 
311 bool VirtualMemory::Uncommit(void* address, size_t size) {
312  ASSERT(IsReserved());
313  return UncommitRegion(address, size);
314 }
315 
316 
317 void* VirtualMemory::ReserveRegion(size_t size) {
318  return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);
319 }
320 
321 
322 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
323  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
324  if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) {
325  return false;
326  }
327  return true;
328 }
329 
330 
331 bool VirtualMemory::Guard(void* address) {
332  if (NULL == VirtualAlloc(address,
334  MEM_COMMIT,
335  PAGE_NOACCESS)) {
336  return false;
337  }
338  return true;
339 }
340 
341 
342 bool VirtualMemory::UncommitRegion(void* base, size_t size) {
343  return VirtualFree(base, size, MEM_DECOMMIT) != 0;
344 }
345 
346 
347 bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
348  return VirtualFree(base, 0, MEM_RELEASE) != 0;
349 }
350 
351 
353  // TODO(alph): implement for the platform.
354  return false;
355 }
356 
357 } } // namespace v8::internal
byte * Address
Definition: globals.h:186
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
#define V8PRIxPTR
Definition: globals.h:228
static void LogSharedLibraryAddresses(Isolate *isolate)
#define LOG(isolate, Call)
Definition: log.h:86
static void SignalCodeMovingGC()
static void * ReserveRegion(size_t size)
PosixMemoryMappedFile(FILE *file, void *memory, int size)
RandomNumberGenerator * random_number_generator()
Definition: isolate-inl.h:75
#define ASSERT(condition)
Definition: checks.h:329
static MemoryMappedFile * open(const char *name)
int isnan(double x)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
bool IsAligned(T value, U alignment)
Definition: utils.h:211
static MemoryMappedFile * create(const char *name, int size, void *initial)
bool Commit(void *address, size_t size, bool is_executable)
T RoundUp(T x, intptr_t m)
Definition: utils.h:144
static const char * LocalTimezone(double time, TimezoneCache *cache)
static bool ReleaseRegion(void *base, size_t size)
static bool CommitRegion(void *base, size_t size, bool is_executable)
static void * Allocate(const size_t requested, size_t *allocated, bool is_executable)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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 expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable memory(in Mbytes)") DEFINE_bool(gc_global
static bool UncommitRegion(void *base, size_t size)
void USE(T)
Definition: globals.h:341
static size_t AllocateAlignment()
const int kPageSizeBits
Definition: v8globals.h:95
const Register fp
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV 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 expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
static intptr_t CommitPageSize()
static double LocalTimeOffset(TimezoneCache *cache)
bool Uncommit(void *address, size_t size)