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-qnx.cc
Go to the documentation of this file.
1 // Copyright 2013 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 QNX goes here. For the POSIX-compatible
29 // parts the implementation is in platform-posix.cc.
30 
31 #include <pthread.h>
32 #include <semaphore.h>
33 #include <signal.h>
34 #include <sys/time.h>
35 #include <sys/resource.h>
36 #include <sys/types.h>
37 #include <stdlib.h>
38 #include <ucontext.h>
39 #include <backtrace.h>
40 
41 // QNX requires memory pages to be marked as executable.
42 // Otherwise, the OS raises an exception when executing code in that page.
43 #include <sys/types.h> // mmap & munmap
44 #include <sys/mman.h> // mmap & munmap
45 #include <sys/stat.h> // open
46 #include <fcntl.h> // open
47 #include <unistd.h> // sysconf
48 #include <strings.h> // index
49 #include <errno.h>
50 #include <stdarg.h>
51 #include <sys/procfs.h>
52 
53 #undef MAP_TYPE
54 
55 #include "v8.h"
56 
57 #include "platform.h"
58 #include "v8threads.h"
59 #include "vm-state-inl.h"
60 
61 
62 namespace v8 {
63 namespace internal {
64 
65 // 0 is never a valid thread id on Qnx since tids and pids share a
66 // name space and pid 0 is reserved (see man 2 kill).
67 static const pthread_t kNoThread = (pthread_t) 0;
68 
69 
70 #ifdef __arm__
71 
72 bool OS::ArmUsingHardFloat() {
73  // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
74  // the Floating Point ABI used (PCS stands for Procedure Call Standard).
75  // We use these as well as a couple of other defines to statically determine
76  // what FP ABI used.
77  // GCC versions 4.4 and below don't support hard-fp.
78  // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
79  // __ARM_PCS_VFP.
80 
81 #define GCC_VERSION (__GNUC__ * 10000 \
82  + __GNUC_MINOR__ * 100 \
83  + __GNUC_PATCHLEVEL__)
84 #if GCC_VERSION >= 40600
85 #if defined(__ARM_PCS_VFP)
86  return true;
87 #else
88  return false;
89 #endif
90 
91 #elif GCC_VERSION < 40500
92  return false;
93 
94 #else
95 #if defined(__ARM_PCS_VFP)
96  return true;
97 #elif defined(__ARM_PCS) || defined(__SOFTFP__) || defined(__SOFTFP) || \
98  !defined(__VFP_FP__)
99  return false;
100 #else
101 #error "Your version of GCC does not report the FP ABI compiled for." \
102  "Please report it on this issue" \
103  "http://code.google.com/p/v8/issues/detail?id=2140"
104 
105 #endif
106 #endif
107 #undef GCC_VERSION
108 }
109 
110 #endif // __arm__
111 
112 
113 const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
114  if (std::isnan(time)) return "";
115  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
116  struct tm* t = localtime(&tv);
117  if (NULL == t) return "";
118  return t->tm_zone;
119 }
120 
121 
122 double OS::LocalTimeOffset(TimezoneCache* cache) {
123  time_t tv = time(NULL);
124  struct tm* t = localtime(&tv);
125  // tm_gmtoff includes any daylight savings offset, so subtract it.
126  return static_cast<double>(t->tm_gmtoff * msPerSecond -
127  (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
128 }
129 
130 
131 void* OS::Allocate(const size_t requested,
132  size_t* allocated,
133  bool is_executable) {
134  const size_t msize = RoundUp(requested, AllocateAlignment());
135  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
136  void* addr = OS::GetRandomMmapAddr();
137  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
138  if (mbase == MAP_FAILED) {
139  LOG(i::Isolate::Current(),
140  StringEvent("OS::Allocate", "mmap failed"));
141  return NULL;
142  }
143  *allocated = msize;
144  return mbase;
145 }
146 
147 
148 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
149  public:
150  PosixMemoryMappedFile(FILE* file, void* memory, int size)
151  : file_(file), memory_(memory), size_(size) { }
152  virtual ~PosixMemoryMappedFile();
153  virtual void* memory() { return memory_; }
154  virtual int size() { return size_; }
155  private:
156  FILE* file_;
157  void* memory_;
158  int size_;
159 };
160 
161 
162 OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
163  FILE* file = fopen(name, "r+");
164  if (file == NULL) return NULL;
165 
166  fseek(file, 0, SEEK_END);
167  int size = ftell(file);
168 
169  void* memory =
170  mmap(OS::GetRandomMmapAddr(),
171  size,
172  PROT_READ | PROT_WRITE,
173  MAP_SHARED,
174  fileno(file),
175  0);
176  return new PosixMemoryMappedFile(file, memory, size);
177 }
178 
179 
180 OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
181  void* initial) {
182  FILE* file = fopen(name, "w+");
183  if (file == NULL) return NULL;
184  int result = fwrite(initial, size, 1, file);
185  if (result < 1) {
186  fclose(file);
187  return NULL;
188  }
189  void* memory =
190  mmap(OS::GetRandomMmapAddr(),
191  size,
192  PROT_READ | PROT_WRITE,
193  MAP_SHARED,
194  fileno(file),
195  0);
196  return new PosixMemoryMappedFile(file, memory, size);
197 }
198 
199 
201  if (memory_) OS::Free(memory_, size_);
202  fclose(file_);
203 }
204 
205 
206 void OS::LogSharedLibraryAddresses(Isolate* isolate) {
207  procfs_mapinfo *mapinfos = NULL, *mapinfo;
208  int proc_fd, num, i;
209 
210  struct {
211  procfs_debuginfo info;
212  char buff[PATH_MAX];
213  } map;
214 
215  char buf[PATH_MAX + 1];
216  snprintf(buf, PATH_MAX + 1, "/proc/%d/as", getpid());
217 
218  if ((proc_fd = open(buf, O_RDONLY)) == -1) {
219  close(proc_fd);
220  return;
221  }
222 
223  /* Get the number of map entries. */
224  if (devctl(proc_fd, DCMD_PROC_MAPINFO, NULL, 0, &num) != EOK) {
225  close(proc_fd);
226  return;
227  }
228 
229  mapinfos = reinterpret_cast<procfs_mapinfo *>(
230  malloc(num * sizeof(procfs_mapinfo)));
231  if (mapinfos == NULL) {
232  close(proc_fd);
233  return;
234  }
235 
236  /* Fill the map entries. */
237  if (devctl(proc_fd, DCMD_PROC_PAGEDATA,
238  mapinfos, num * sizeof(procfs_mapinfo), &num) != EOK) {
239  free(mapinfos);
240  close(proc_fd);
241  return;
242  }
243 
244  for (i = 0; i < num; i++) {
245  mapinfo = mapinfos + i;
246  if (mapinfo->flags & MAP_ELF) {
247  map.info.vaddr = mapinfo->vaddr;
248  if (devctl(proc_fd, DCMD_PROC_MAPDEBUG, &map, sizeof(map), 0) != EOK) {
249  continue;
250  }
251  LOG(isolate, SharedLibraryEvent(map.info.path,
252  mapinfo->vaddr,
253  mapinfo->vaddr + mapinfo->size));
254  }
255  }
256  free(mapinfos);
257  close(proc_fd);
258 }
259 
260 
261 void OS::SignalCodeMovingGC() {
262 }
263 
264 
265 // Constants used for mmap.
266 static const int kMmapFd = -1;
267 static const int kMmapFdOffset = 0;
268 
269 
270 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
271 
272 
273 VirtualMemory::VirtualMemory(size_t size)
274  : address_(ReserveRegion(size)), size_(size) { }
275 
276 
277 VirtualMemory::VirtualMemory(size_t size, size_t alignment)
278  : address_(NULL), size_(0) {
279  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
280  size_t request_size = RoundUp(size + alignment,
281  static_cast<intptr_t>(OS::AllocateAlignment()));
282  void* reservation = mmap(OS::GetRandomMmapAddr(),
283  request_size,
284  PROT_NONE,
285  MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY,
286  kMmapFd,
287  kMmapFdOffset);
288  if (reservation == MAP_FAILED) return;
289 
290  Address base = static_cast<Address>(reservation);
291  Address aligned_base = RoundUp(base, alignment);
292  ASSERT_LE(base, aligned_base);
293 
294  // Unmap extra memory reserved before and after the desired block.
295  if (aligned_base != base) {
296  size_t prefix_size = static_cast<size_t>(aligned_base - base);
297  OS::Free(base, prefix_size);
298  request_size -= prefix_size;
299  }
300 
301  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
302  ASSERT_LE(aligned_size, request_size);
303 
304  if (aligned_size != request_size) {
305  size_t suffix_size = request_size - aligned_size;
306  OS::Free(aligned_base + aligned_size, suffix_size);
307  request_size -= suffix_size;
308  }
309 
310  ASSERT(aligned_size == request_size);
311 
312  address_ = static_cast<void*>(aligned_base);
313  size_ = aligned_size;
314 }
315 
316 
318  if (IsReserved()) {
319  bool result = ReleaseRegion(address(), size());
320  ASSERT(result);
321  USE(result);
322  }
323 }
324 
325 
327  return address_ != NULL;
328 }
329 
330 
331 void VirtualMemory::Reset() {
332  address_ = NULL;
333  size_ = 0;
334 }
335 
336 
337 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
338  return CommitRegion(address, size, is_executable);
339 }
340 
341 
342 bool VirtualMemory::Uncommit(void* address, size_t size) {
343  return UncommitRegion(address, size);
344 }
345 
346 
347 bool VirtualMemory::Guard(void* address) {
348  OS::Guard(address, OS::CommitPageSize());
349  return true;
350 }
351 
352 
353 void* VirtualMemory::ReserveRegion(size_t size) {
354  void* result = mmap(OS::GetRandomMmapAddr(),
355  size,
356  PROT_NONE,
357  MAP_PRIVATE | MAP_ANONYMOUS | MAP_LAZY,
358  kMmapFd,
359  kMmapFdOffset);
360 
361  if (result == MAP_FAILED) return NULL;
362 
363  return result;
364 }
365 
366 
367 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
368  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
369  if (MAP_FAILED == mmap(base,
370  size,
371  prot,
372  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
373  kMmapFd,
374  kMmapFdOffset)) {
375  return false;
376  }
377 
378  return true;
379 }
380 
381 
382 bool VirtualMemory::UncommitRegion(void* base, size_t size) {
383  return mmap(base,
384  size,
385  PROT_NONE,
386  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_LAZY,
387  kMmapFd,
388  kMmapFdOffset) != MAP_FAILED;
389 }
390 
391 
392 bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
393  return munmap(base, size) == 0;
394 }
395 
396 
398  return false;
399 }
400 
401 } } // 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
static void Free(void *address, const size_t size)
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 map
Definition: flags.cc:350
static void LogSharedLibraryAddresses(Isolate *isolate)
#define LOG(isolate, Call)
Definition: log.h:86
static bool ArmUsingHardFloat()
static void SignalCodeMovingGC()
static void * GetRandomMmapAddr()
static void * ReserveRegion(size_t size)
PosixMemoryMappedFile(FILE *file, void *memory, int size)
#define ASSERT(condition)
Definition: checks.h:329
static MemoryMappedFile * open(const char *name)
int isnan(double x)
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)
static void Guard(void *address, const size_t size)
T RoundUp(T x, intptr_t m)
Definition: utils.h:144
#define ASSERT_LE(v1, v2)
Definition: checks.h:334
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)
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 info
Definition: flags.cc:317
static void * Allocate(const size_t requested, size_t *allocated, bool is_executable)
static bool UncommitRegion(void *base, size_t size)
void USE(T)
Definition: globals.h:341
static size_t AllocateAlignment()
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)