| 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 <stdio.h> | 11 #include <stdio.h> |
| 12 #include <stdlib.h> | 12 #include <stdlib.h> |
| 13 #include <sys/prctl.h> |
| 13 #include <sys/resource.h> | 14 #include <sys/resource.h> |
| 15 #include <sys/syscall.h> |
| 14 #include <sys/time.h> | 16 #include <sys/time.h> |
| 15 | 17 |
| 16 // Ubuntu Dapper requires memory pages to be marked as | 18 // Ubuntu Dapper requires memory pages to be marked as |
| 17 // executable. Otherwise, OS raises an exception when executing code | 19 // executable. Otherwise, OS raises an exception when executing code |
| 18 // in that page. | 20 // in that page. |
| 19 #include <errno.h> | 21 #include <errno.h> |
| 20 #include <fcntl.h> // open | 22 #include <fcntl.h> // open |
| 21 #include <stdarg.h> | 23 #include <stdarg.h> |
| 22 #include <strings.h> // index | 24 #include <strings.h> // index |
| 23 #include <sys/mman.h> // mmap & munmap | 25 #include <sys/mman.h> // mmap & munmap |
| (...skipping 13 matching lines...) Expand all Loading... |
| 37 #include <sanitizer/lsan_interface.h> | 39 #include <sanitizer/lsan_interface.h> |
| 38 #endif | 40 #endif |
| 39 | 41 |
| 40 #include <cmath> | 42 #include <cmath> |
| 41 | 43 |
| 42 #undef MAP_TYPE | 44 #undef MAP_TYPE |
| 43 | 45 |
| 44 #include "src/base/macros.h" | 46 #include "src/base/macros.h" |
| 45 #include "src/base/platform/platform.h" | 47 #include "src/base/platform/platform.h" |
| 46 | 48 |
| 47 #if V8_OS_NACL | |
| 48 #if !defined(MAP_NORESERVE) | |
| 49 // PNaCL doesn't have this, so we always grab all of the memory, which is bad. | |
| 50 #define MAP_NORESERVE 0 | |
| 51 #endif | |
| 52 #else | |
| 53 #include <sys/prctl.h> | |
| 54 #include <sys/syscall.h> | |
| 55 #endif | |
| 56 | |
| 57 namespace v8 { | 49 namespace v8 { |
| 58 namespace base { | 50 namespace base { |
| 59 | 51 |
| 60 | 52 |
| 61 #ifdef __arm__ | 53 #ifdef __arm__ |
| 62 | 54 |
| 63 bool OS::ArmUsingHardFloat() { | 55 bool OS::ArmUsingHardFloat() { |
| 64 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify | 56 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify |
| 65 // the Floating Point ABI used (PCS stands for Procedure Call Standard). | 57 // the Floating Point ABI used (PCS stands for Procedure Call Standard). |
| 66 // We use these as well as a couple of other defines to statically determine | 58 // We use these as well as a couple of other defines to statically determine |
| (...skipping 28 matching lines...) Expand all Loading... |
| 95 | 87 |
| 96 #endif | 88 #endif |
| 97 #endif | 89 #endif |
| 98 #undef GCC_VERSION | 90 #undef GCC_VERSION |
| 99 } | 91 } |
| 100 | 92 |
| 101 #endif // def __arm__ | 93 #endif // def __arm__ |
| 102 | 94 |
| 103 | 95 |
| 104 const char* OS::LocalTimezone(double time, TimezoneCache* cache) { | 96 const char* OS::LocalTimezone(double time, TimezoneCache* cache) { |
| 105 #if V8_OS_NACL | |
| 106 // Missing support for tm_zone field. | |
| 107 return ""; | |
| 108 #else | |
| 109 if (std::isnan(time)) return ""; | 97 if (std::isnan(time)) return ""; |
| 110 time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); | 98 time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); |
| 111 struct tm* t = localtime(&tv); // NOLINT(runtime/threadsafe_fn) | 99 struct tm* t = localtime(&tv); // NOLINT(runtime/threadsafe_fn) |
| 112 if (!t || !t->tm_zone) return ""; | 100 if (!t || !t->tm_zone) return ""; |
| 113 return t->tm_zone; | 101 return t->tm_zone; |
| 114 #endif | |
| 115 } | 102 } |
| 116 | 103 |
| 117 | 104 |
| 118 double OS::LocalTimeOffset(TimezoneCache* cache) { | 105 double OS::LocalTimeOffset(TimezoneCache* cache) { |
| 119 #if V8_OS_NACL | |
| 120 // Missing support for tm_zone field. | |
| 121 return 0; | |
| 122 #else | |
| 123 time_t tv = time(NULL); | 106 time_t tv = time(NULL); |
| 124 struct tm* t = localtime(&tv); // NOLINT(runtime/threadsafe_fn) | 107 struct tm* t = localtime(&tv); // NOLINT(runtime/threadsafe_fn) |
| 125 // tm_gmtoff includes any daylight savings offset, so subtract it. | 108 // tm_gmtoff includes any daylight savings offset, so subtract it. |
| 126 return static_cast<double>(t->tm_gmtoff * msPerSecond - | 109 return static_cast<double>(t->tm_gmtoff * msPerSecond - |
| 127 (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); | 110 (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); |
| 128 #endif | |
| 129 } | 111 } |
| 130 | 112 |
| 131 | 113 |
| 132 void* OS::Allocate(const size_t requested, | 114 void* OS::Allocate(const size_t requested, |
| 133 size_t* allocated, | 115 size_t* allocated, |
| 134 bool is_executable) { | 116 bool is_executable) { |
| 135 const size_t msize = RoundUp(requested, AllocateAlignment()); | 117 const size_t msize = RoundUp(requested, AllocateAlignment()); |
| 136 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 118 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
| 137 void* addr = OS::GetRandomMmapAddr(); | 119 void* addr = OS::GetRandomMmapAddr(); |
| 138 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 120 void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 // it. This injects a GC marker into the stream of events generated | 195 // it. This injects a GC marker into the stream of events generated |
| 214 // by the kernel and allows us to synchronize V8 code log and the | 196 // by the kernel and allows us to synchronize V8 code log and the |
| 215 // kernel log. | 197 // kernel log. |
| 216 long size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int) | 198 long size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int) |
| 217 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); | 199 FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); |
| 218 if (f == NULL) { | 200 if (f == NULL) { |
| 219 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); | 201 OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); |
| 220 OS::Abort(); | 202 OS::Abort(); |
| 221 } | 203 } |
| 222 void* addr = mmap(OS::GetRandomMmapAddr(), size, | 204 void* addr = mmap(OS::GetRandomMmapAddr(), size, |
| 223 #if V8_OS_NACL | |
| 224 // The Native Client port of V8 uses an interpreter, | |
| 225 // so code pages don't need PROT_EXEC. | |
| 226 PROT_READ, | |
| 227 #else | |
| 228 PROT_READ | PROT_EXEC, | 205 PROT_READ | PROT_EXEC, |
| 229 #endif | |
| 230 MAP_PRIVATE, fileno(f), 0); | 206 MAP_PRIVATE, fileno(f), 0); |
| 231 DCHECK_NE(MAP_FAILED, addr); | 207 DCHECK_NE(MAP_FAILED, addr); |
| 232 OS::Free(addr, size); | 208 OS::Free(addr, size); |
| 233 fclose(f); | 209 fclose(f); |
| 234 } | 210 } |
| 235 | 211 |
| 236 | 212 |
| 237 // Constants used for mmap. | 213 // Constants used for mmap. |
| 238 static const int kMmapFd = -1; | 214 static const int kMmapFd = -1; |
| 239 static const int kMmapFdOffset = 0; | 215 static const int kMmapFdOffset = 0; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 if (result == MAP_FAILED) return NULL; | 315 if (result == MAP_FAILED) return NULL; |
| 340 | 316 |
| 341 #if defined(LEAK_SANITIZER) | 317 #if defined(LEAK_SANITIZER) |
| 342 __lsan_register_root_region(result, size); | 318 __lsan_register_root_region(result, size); |
| 343 #endif | 319 #endif |
| 344 return result; | 320 return result; |
| 345 } | 321 } |
| 346 | 322 |
| 347 | 323 |
| 348 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { | 324 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { |
| 349 #if V8_OS_NACL | |
| 350 // The Native Client port of V8 uses an interpreter, | |
| 351 // so code pages don't need PROT_EXEC. | |
| 352 int prot = PROT_READ | PROT_WRITE; | |
| 353 #else | |
| 354 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); | 325 int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0); |
| 355 #endif | |
| 356 if (MAP_FAILED == mmap(base, | 326 if (MAP_FAILED == mmap(base, |
| 357 size, | 327 size, |
| 358 prot, | 328 prot, |
| 359 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, | 329 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
| 360 kMmapFd, | 330 kMmapFd, |
| 361 kMmapFdOffset)) { | 331 kMmapFdOffset)) { |
| 362 return false; | 332 return false; |
| 363 } | 333 } |
| 364 | 334 |
| 365 return true; | 335 return true; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 391 return munmap(base, size) == 0; | 361 return munmap(base, size) == 0; |
| 392 } | 362 } |
| 393 | 363 |
| 394 | 364 |
| 395 bool VirtualMemory::HasLazyCommits() { | 365 bool VirtualMemory::HasLazyCommits() { |
| 396 return true; | 366 return true; |
| 397 } | 367 } |
| 398 | 368 |
| 399 } // namespace base | 369 } // namespace base |
| 400 } // namespace v8 | 370 } // namespace v8 |
| OLD | NEW |