OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Platform-specific code for Linux goes here. For the POSIX-compatible | 5 // Platform-specific code for Linux goes here. For the POSIX-compatible |
6 // parts, the implementation is in platform-posix.cc. | 6 // parts, the implementation is in platform-posix.cc. |
7 | 7 |
8 #include <pthread.h> | 8 #include <pthread.h> |
9 #include <semaphore.h> | 9 #include <semaphore.h> |
10 #include <signal.h> | 10 #include <signal.h> |
11 #include <stdlib.h> | 11 #include <stdlib.h> |
12 #include <sys/prctl.h> | |
13 #include <sys/resource.h> | 12 #include <sys/resource.h> |
14 #include <sys/syscall.h> | |
15 #include <sys/time.h> | 13 #include <sys/time.h> |
16 #include <sys/types.h> | 14 #include <sys/types.h> |
17 | 15 |
18 // Ubuntu Dapper requires memory pages to be marked as | 16 // Ubuntu Dapper requires memory pages to be marked as |
19 // executable. Otherwise, OS raises an exception when executing code | 17 // executable. Otherwise, OS raises an exception when executing code |
20 // in that page. | 18 // in that page. |
21 #include <errno.h> | 19 #include <errno.h> |
22 #include <fcntl.h> // open | 20 #include <fcntl.h> // open |
23 #include <stdarg.h> | 21 #include <stdarg.h> |
24 #include <strings.h> // index | 22 #include <strings.h> // index |
(...skipping 14 matching lines...) Expand all Loading... |
39 #include <sanitizer/lsan_interface.h> | 37 #include <sanitizer/lsan_interface.h> |
40 #endif | 38 #endif |
41 | 39 |
42 #include <cmath> | 40 #include <cmath> |
43 | 41 |
44 #undef MAP_TYPE | 42 #undef MAP_TYPE |
45 | 43 |
46 #include "src/base/macros.h" | 44 #include "src/base/macros.h" |
47 #include "src/base/platform/platform.h" | 45 #include "src/base/platform/platform.h" |
48 | 46 |
| 47 #if V8_OS_NACL |
| 48 // PNaCL doesn't have this, so we always grab all of the memory, which is bad. |
| 49 #define MAP_NORESERVE 0 |
| 50 #else |
| 51 #include <sys/prctl.h> |
| 52 #include <sys/syscall.h> |
| 53 #endif |
49 | 54 |
50 namespace v8 { | 55 namespace v8 { |
51 namespace base { | 56 namespace base { |
52 | 57 |
53 | 58 |
54 #ifdef __arm__ | 59 #ifdef __arm__ |
55 | 60 |
56 bool OS::ArmUsingHardFloat() { | 61 bool OS::ArmUsingHardFloat() { |
57 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify | 62 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify |
58 // the Floating Point ABI used (PCS stands for Procedure Call Standard). | 63 // the Floating Point ABI used (PCS stands for Procedure Call Standard). |
(...skipping 29 matching lines...) Expand all Loading... |
88 | 93 |
89 #endif | 94 #endif |
90 #endif | 95 #endif |
91 #undef GCC_VERSION | 96 #undef GCC_VERSION |
92 } | 97 } |
93 | 98 |
94 #endif // def __arm__ | 99 #endif // def __arm__ |
95 | 100 |
96 | 101 |
97 const char* OS::LocalTimezone(double time, TimezoneCache* cache) { | 102 const char* OS::LocalTimezone(double time, TimezoneCache* cache) { |
| 103 #if V8_OS_NACL |
| 104 // Missing support for tm_zone field. |
| 105 return ""; |
| 106 #else |
98 if (std::isnan(time)) return ""; | 107 if (std::isnan(time)) return ""; |
99 time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); | 108 time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); |
100 struct tm* t = localtime(&tv); | 109 struct tm* t = localtime(&tv); |
101 if (NULL == t) return ""; | 110 if (NULL == t) return ""; |
102 return t->tm_zone; | 111 return t->tm_zone; |
| 112 #endif |
103 } | 113 } |
104 | 114 |
105 | 115 |
106 double OS::LocalTimeOffset(TimezoneCache* cache) { | 116 double OS::LocalTimeOffset(TimezoneCache* cache) { |
| 117 #if V8_OS_NACL |
| 118 // Missing support for tm_zone field. |
| 119 return 0; |
| 120 #else |
107 time_t tv = time(NULL); | 121 time_t tv = time(NULL); |
108 struct tm* t = localtime(&tv); | 122 struct tm* t = localtime(&tv); |
109 // tm_gmtoff includes any daylight savings offset, so subtract it. | 123 // tm_gmtoff includes any daylight savings offset, so subtract it. |
110 return static_cast<double>(t->tm_gmtoff * msPerSecond - | 124 return static_cast<double>(t->tm_gmtoff * msPerSecond - |
111 (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); | 125 (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); |
| 126 #endif |
112 } | 127 } |
113 | 128 |
114 | 129 |
115 void* OS::Allocate(const size_t requested, | 130 void* OS::Allocate(const size_t requested, |
116 size_t* allocated, | 131 size_t* allocated, |
117 bool is_executable) { | 132 bool is_executable) { |
118 const size_t msize = RoundUp(requested, AllocateAlignment()); | 133 const size_t msize = RoundUp(requested, AllocateAlignment()); |
119 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 134 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
120 void* addr = OS::GetRandomMmapAddr(); | 135 void* addr = OS::GetRandomMmapAddr(); |
121 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 136 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // do a mmap with a name known by ll_prof.py and immediately munmap | 268 // do a mmap with a name known by ll_prof.py and immediately munmap |
254 // it. This injects a GC marker into the stream of events generated | 269 // it. This injects a GC marker into the stream of events generated |
255 // by the kernel and allows us to synchronize V8 code log and the | 270 // by the kernel and allows us to synchronize V8 code log and the |
256 // kernel log. | 271 // kernel log. |
257 int size = sysconf(_SC_PAGESIZE); | 272 int size = sysconf(_SC_PAGESIZE); |
258 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); | 273 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); |
259 if (f == NULL) { | 274 if (f == NULL) { |
260 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); | 275 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); |
261 OS::Abort(); | 276 OS::Abort(); |
262 } | 277 } |
263 void* addr = mmap(OS::GetRandomMmapAddr(), | 278 void* addr = mmap(OS::GetRandomMmapAddr(), size, |
264 size, | 279 #if V8_OS_NACL |
265 #if defined(__native_client__) | |
266 // The Native Client port of V8 uses an interpreter, | 280 // The Native Client port of V8 uses an interpreter, |
267 // so code pages don't need PROT_EXEC. | 281 // so code pages don't need PROT_EXEC. |
268 PROT_READ, | 282 PROT_READ, |
269 #else | 283 #else |
270 PROT_READ | PROT_EXEC, | 284 PROT_READ | PROT_EXEC, |
271 #endif | 285 #endif |
272 MAP_PRIVATE, | 286 MAP_PRIVATE, fileno(f), 0); |
273 fileno(f), | |
274 0); | |
275 DCHECK(addr != MAP_FAILED); | 287 DCHECK(addr != MAP_FAILED); |
276 OS::Free(addr, size); | 288 OS::Free(addr, size); |
277 fclose(f); | 289 fclose(f); |
278 } | 290 } |
279 | 291 |
280 | 292 |
281 // Constants used for mmap. | 293 // Constants used for mmap. |
282 static const int kMmapFd = -1; | 294 static const int kMmapFd = -1; |
283 static const int kMmapFdOffset = 0; | 295 static const int kMmapFdOffset = 0; |
284 | 296 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 if (result == MAP_FAILED) return NULL; | 392 if (result == MAP_FAILED) return NULL; |
381 | 393 |
382 #if defined(LEAK_SANITIZER) | 394 #if defined(LEAK_SANITIZER) |
383 __lsan_register_root_region(result, size); | 395 __lsan_register_root_region(result, size); |
384 #endif | 396 #endif |
385 return result; | 397 return result; |
386 } | 398 } |
387 | 399 |
388 | 400 |
389 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { | 401 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { |
390 #if defined(__native_client__) | 402 #if V8_OS_NACL |
391 // The Native Client port of V8 uses an interpreter, | 403 // The Native Client port of V8 uses an interpreter, |
392 // so code pages don't need PROT_EXEC. | 404 // so code pages don't need PROT_EXEC. |
393 int prot = PROT_READ | PROT_WRITE; | 405 int prot = PROT_READ | PROT_WRITE; |
394 #else | 406 #else |
395 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 407 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
396 #endif | 408 #endif |
397 if (MAP_FAILED == mmap(base, | 409 if (MAP_FAILED == mmap(base, |
398 size, | 410 size, |
399 prot, | 411 prot, |
400 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | 412 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
(...skipping 22 matching lines...) Expand all Loading... |
423 #endif | 435 #endif |
424 return munmap(base, size) == 0; | 436 return munmap(base, size) == 0; |
425 } | 437 } |
426 | 438 |
427 | 439 |
428 bool VirtualMemory::HasLazyCommits() { | 440 bool VirtualMemory::HasLazyCommits() { |
429 return true; | 441 return true; |
430 } | 442 } |
431 | 443 |
432 } } // namespace v8::base | 444 } } // namespace v8::base |
OLD | NEW |